Here is a smartapp and a virtual device to create a multiple wall switch.
With old cell phones prices ranging from $15 to $25 it is cheaper to turn a cell phone into a switch than buying one.
The problem is that you can’t have in Smartthings app one screen that can controls multiple devices (except for the things page). Therefore, you have to create a virtual device that interacts through a smartapp with multiple devices (such as light switches), if you want to create a panel. Here is the finished product on the wall:
It will be nice if Samsung includes a builtin feature in the Smartthings app to create something like this. Another nice feature will be to dark the screen (or dim it) inside the app. That will allow wall switches that glow only when clicked.
here is the code for the device handler and the smartapp :
/**
* Virtual Four Switches
* Works with the fourSwitch smartapp
* Copyright 2016 Shay Z
*
* 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: "Virtual Four Switches", namespace: "shayz", author: "shayz") {
capability "Switch"
capability "Sensor"
capability "Actuator"
capability "switchLevel"
attribute "SwitchOne", "string"
attribute "SwitchTwo", "string"
attribute "SwitchThree", "string"
attribute "Switchfour", "string"
attribute "Virtual3Switch", "string"
attribute "SW1Name", "string"
attribute "SW2Name", "string"
attribute "SW3Name", "string"
attribute "SW4Name", "string"
command "switch1On"
command "switch1Off"
command "switch2On"
command "switch2Off"
command "switch3On"
command "switch3Off"
command "switch4On"
command "switch4Off"
}
preferences {
input("Switch1", "string", title:"Switch 1", description: "Please enter switch 1 name", defaultValue: "Switch One" , required: true, displayDuringSetup: true)
input("Switch2", "string", title:"Switch 2", description: "Please enter switch 2 name", defaultValue: "Switch Two" , required: true, displayDuringSetup: true)
input("Switch3", "string", title:"Switch 3", description: "Please enter switch 3 name", defaultValue: "Switch Three" , required: true, displayDuringSetup: true)
input("Switch4", "string", title:"Switch 4", description: "Please enter switch 4 name", defaultValue: "Switch Four" , required: true, displayDuringSetup: true)
}
// tile definitions
tiles {
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
state "off", label: '${name}', action: "switch.on", icon: "st.lights.multi-light-bulb-off", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "switch.off", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#79b821"
}
standardTile("switch1", "device.SwitchOne", width: 2, height: 1, canChangeIcon: true) {
state "off", label: '${name}', action: "switch1On", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "switch1Off", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#79b821"
}
standardTile("switch2", "device.SwitchTwo", width: 2, height: 1, canChangeIcon: true) {
state "off", label: '${name}', action: "switch2On", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "switch2Off", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#79b821"
}
standardTile("switch3", "device.SwitchThree", width: 2, height: 1, canChangeIcon: true) {
state "off", label: '${name}', action: "switch3On", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "switch3Off", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#79b821"
}
standardTile("switch4", "device.SwitchFour", width: 2, height: 1, canChangeIcon: true) {
state "off", label: '${name}', action: "switch4On", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#ffffff"
state "on", label: '${name}', action: "switch4Off", icon: "st.lights.multi-light-bulb-on", backgroundColor: "#79b821"
}
valueTile("devN1", "device.SW1Name", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
state "SW1Name", label: '${currentValue}', icon: ""
}
valueTile("devN2", "device.SW2Name", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
state "SW2Name", label: '${currentValue}', icon: ""
}
valueTile("devN3", "device.SW3Name", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
state "SW3Name", label: '${currentValue}', icon: ""
}
valueTile("devN4", "device.SW4Name", width: 1, height: 1, canChangeIcon: false, canChangeBackground: false, decoration: "flat") {
state "SW4Name", label: '${currentValue}', icon: ""
}
/*
multiAttributeTile(name:"switch1", type: "generic", width: 3, height: 1) {
tileAttribute ("device.SwitchOne", key: "PRIMARY_CONTROL") {
attributeState "on", action:"switch1Off", icon:"st.lights.philips.hue-single"
attributeState "off", action:"switch1On", icon:"st.lights.philips.hue-single"
}
tileAttribute ("device.SW1Name", key: "SECONDARY_CONTROL") {
attributeState "SW1Name", label:'${currentValue}', icon: ""
}
}
multiAttributeTile(name:"switch2", type: "generic", width: 3, height: 1) {
tileAttribute ("device.SwitchTwo", key: "PRIMARY_CONTROL") {
attributeState "on", action:"switch2Off", icon:"st.lights.philips.hue-single"
attributeState "off", action:"switch2On", icon:"st.lights.philips.hue-single"
}
}
multiAttributeTile(name:"switch3", type: "generic", width: 3, height: 1) {
tileAttribute ("device.SwitchThree", key: "PRIMARY_CONTROL") {
attributeState "on", action:"switch3Off", icon:"st.lights.philips.hue-single"
attributeState "off", action:"switch3On", icon:"st.lights.philips.hue-single"
}
}
*/
main "switch"
details "switch1","devN1","switch2","devN2","switch3","devN3","switch4","devN4"
}
}
def installed() {
initialize()
}
def updated() {
initialize()
}
def initialize(){
sendEvent(name: "SW1Name", value: "$Switch1")
sendEvent(name: "SW2Name", value: "$Switch2")
sendEvent(name: "SW3Name", value: "$Switch3")
sendEvent(name: "SW4Name", value: "$Switch4")
}
// handle commands
def on() {
sendEvent(name: "switch", value: "on")
}
def off() {
sendEvent(name: "switch", value: "off")
}
def switch1On(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchOne", value: "on", descriptionText: "Physical")
else sendEvent(name: "SwitchOne", value: "on")
// log.debug "sw1 vir on $evtSource"
}
def switch1Off(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchOne", value: "off", descriptionText: "Physical")
else sendEvent(name: "SwitchOne", value: "off")
// log.debug "sw1 vir off $evtSource"
}
def switch2On(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchTwo", value: "on", descriptionText: "Physical")
else sendEvent(name: "SwitchTwo", value: "on")
}
def switch2Off(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchTwo", value: "off", descriptionText: "Physical")
else sendEvent(name: "SwitchTwo", value: "off")
}
def switch3On(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchThree", value: "on", descriptionText: "Physical")
else sendEvent(name: "SwitchThree", value: "on")
}
def switch3Off(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchThree", value: "off", descriptionText: "Physical")
else sendEvent(name: "SwitchThree", value: "off")
}
def switch4On(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchFour", value: "on", descriptionText: "Physical")
else sendEvent(name: "SwitchFour", value: "on")
}
def switch4Off(evtSource) {
if (evtSource == "Physical") sendEvent(name: "SwitchFour", value: "off", descriptionText: "Physical")
else sendEvent(name: "SwitchFour", value: "off")
}
Here is the smartapp that interacts with the devicehandler:
/**
* FourSwitch device connect
* Works with the Virtual Three Switches device handler
*
* Copyright 2016 Shay Z
*
* 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: "fourSwitch",
namespace: "shayz",
author: "Shay",
description: "4 switch controller",
category: "Convenience",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
preferences {
section("Switches selection") {
input "switch1", "capability.switch", title:"Select Switch 1"
input "switch2", "capability.switch", title:"Select Switch 2"
input "switch3", "capability.switch", title:"Select Switch 3"
input "switch4", "capability.switch", title:"Select Switch 4"
input "VirtualSw", "device.virtualFourSwitches"
}
}
def installed() {
// log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
// log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
subscribe(VirtualSw, "switch", VSwitchEvt)
subscribe(VirtualSw, "SwitchOne", VSwitchEvt)
subscribe(VirtualSw, "SwitchTwo", VSwitchEvt)
subscribe(VirtualSw, "SwitchThree", VSwitchEvt)
subscribe(VirtualSw, "SwitchFour", VSwitchEvt)
subscribe(switch1, "switch", SwOneEvt)
subscribe(switch2, "switch", SwTwoEvt)
subscribe(switch3, "switch", SwThreeEvt)
subscribe(switch4, "switch", SwThreeEvt)
}
// send events to real switches
def VSwitchEvt(evt) {
//Physical prevents event loops i.e. it means it gets here when the event was triggered by the the real device then-> calls virtualSW (from below) then-> returns here without Physical to stop
if (evt.descriptionText != "Physical") {
// log.debug "turning real switch"
switch ( evt.name ) {
case "SwitchOne":
switch1."$evt.stringValue"()
break
case "SwitchTwo":
switch2."$evt.stringValue"()
break
case "SwitchThree":
switch3."$evt.stringValue"()
break
case "SwitchFour":
switch4."$evt.stringValue"()
break
case "switch":
switch1."$evt.stringValue"()
switch2."$evt.stringValue"()
switch3."$evt.stringValue"()
switch4."$evt.stringValue"()
break
}
}
}
// send events to Virtual Switch (toggle tile)
def SwOneEvt(evt) {
// Physical prevents events loop
if (evt.stringValue == 'on') VirtualSw.switch1On("Physical")
else if (evt.stringValue == 'off') VirtualSw.switch1Off("Physical")
// log.debug "send event to virtual device $evt.stringValue"
}
def SwTwoEvt(evt) {
if (evt.stringValue == 'on') VirtualSw.switch2On("Physical")
else if (evt.stringValue == 'off') VirtualSw.switch2Off("Physical")
// log.debug "event rec from real sw 2 $evt.stringValue"
}
def SwThreeEvt(evt) {
if (evt.stringValue == 'on') VirtualSw.switch3On("Physical")
else if (evt.stringValue == 'off') VirtualSw.switch3Off("Physical")
}
def SwFourEvt(evt) {
if (evt.stringValue == 'on') VirtualSw.switch4On("Physical")
else if (evt.stringValue == 'off') VirtualSw.switch4Off("Physical")
}