API and Endpoints

Try the following code -

definition(
name: "Movie Lights",
namespace: "smartthings",
author: "SmartThings",
description: "Saves the states of a specified set switches and thermostat setpoints and restores them at each mode change. To use 1) Set the mode, 2) Change switches and setpoint to where you want them for that mode, and 3) Install or update the app. Changing to that mode or touching the app will set the devices to the saved state.",
category: "My Apps",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_thermo-switch.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_thermo-switch@2x.png"
)

preferences {
section("Switches") {
input "switches", "capability.switch", multiple: true, required: false
}
section("Thermostats") {
input "thermostats", "capability.thermostat", multiple: true, required: false
}
section("Locks") {
input "locks", "capability.lock", multiple: true, required: false
}
section("Select Switch to monitor"){
input "theSwitch", "capability.switch"
}
}
def onHandler(evt) {
	log.debug "Received on from ${theSwitch}"
    restoreState(currentMode)
    theSwitch.off()
}

def offHandler(evt) {
	log.debug "Received off from ${theSwitch}"
}

def initialize() {
subscribe(theSwitch, "switch.On", onHandler)
subscribe(theSwitch, "switch.Off", offHandler)
}

def installed() {
subscribe(location, changedLocationMode)
subscribe(app, appTouch)
saveState()
initialize()
}

def updated() {
unsubscribe()
subscribe(location, changedLocationMode)
subscribe(app, appTouch)
saveState()
initialize()
}

def appTouch(evt)
{
restoreState(currentMode)
}

def changedLocationMode(evt)
{
restoreState(evt.value)
}

private restoreState(mode)
{
log.info "restoring state for mode '$mode'"
def map = state[mode] ?: [:]
switches?.each {
def value = map[it.id]
if (value?.switch == "on") {
def level = value.level
if (level) {
log.debug "setting $it.label level to $level"
it.setLevel(level)
}
else {
log.debug "turning $it.label on"
it.on()
}
}
else if (value?.switch == "off") {
log.debug "turning $it.label off"
it.off()
}
}

thermostats?.each {
	def value = map[it.id]
	if (value?.coolingSetpoint) {
		log.debug "coolingSetpoint = $value.coolingSetpoint"
		it.setCoolingSetpoint(value.coolingSetpoint)
	}
	if (value?.heatingSetpoint) {
		log.debug "heatingSetpoint = $value.heatingSetpoint"
		it.setHeatingSetpoint(value.heatingSetpoint)
	}
}

locks?.each {
	def value = map[it.id]
	if (value) {
		if (value?.locked) {
			it.lock()
		}
		else {
			it.unlock()
		}
	}
}
}

private saveState()
{
def mode = currentMode
def map = state[mode] ?: [:]

switches?.each {
	map[it.id] = [switch: it.currentSwitch, level: it.currentLevel]
}

thermostats?.each {
	map[it.id] = [coolingSetpoint: it.currentCoolingSetpoint, heatingSetpoint: it.currentHeatingSetpoint]
}

locks?.each {
	map[it.id] = [locked: it.currentLock == "locked"]
}

state[mode] = map
log.debug "saved state for mode ${mode}: ${state[mode]}"
log.debug "state: $state"
}

private getCurrentMode()
{
location.mode ?: "none"
}

Works like a charm! Now I can use Tasker/AutoVoice to run my movie lighting app! Really appreciate your help @nelemansc

no problem, glad I could help!

Hey @nelemansc, unfortunately, as I began to use this new SmartApp/Virtual Switch/Endpoint setup regularly it started giving me issues. The first issue I noticed was that the SmartApp automatically triggered when my system’s Mode changed from Home Night to Home Day (which I have setup to occur at sunrise each day). This is really weird because I didn’t select any modes as criteria within the SmartApp when I installed it. Nor do I have any Modes setup to turn on the virtual switch that controls the SmartApp.

The second issue was that after I noticed this issue occur, I tried manually activating the SmartApp by pressing the play button on it and it just stopped working. However, after each time I try this I go into the Activity Feed and surprisingly it actually shows “Movie Lights [my SmartApp’s name] was touched”. So it seems like it’s registering that I pressed the SmartApp’s button, but it doesn’t then trigger the actions I have it set to do.

What do you think?

@nelemansc - I played around with it a bit more tonight and figured out what’s going on. When I installed the SmartApp it registered not only the levels that I had all my selected light switches at, but the Mode my system was in as well. Even though I didn’t specify at the bottom of the App configuration to only work within certain Modes.

This explains why when I tried running the App at another time (when my system was in a different Mode) that it registered me pressing the play button in the Activity screen but wouldn’t actually run it.

As I was messing around with it I also noticed that when I switched away from the Mode the App was configured to work within and then back again it ran the App automatically. This explains the other issue I had in my previous post. However, I have no idea why it would do that.

Either way, if you could adjust the code so that it doesn’t save the Mode my system is in at the time of install I think that would ultimately solve both problems.

Thanks

@triggertact I’m not 100% clear on how the “Make it so” app is supposed to work, but I use something similar for “Movie Lights” that’s a bit simpler.

definition(
    name: "Movie Mode",
    namespace: "",
    author: "nelemansc@gmail.com",
    description: "Movie Mode",
    category: "My Apps",
    iconUrl: "http://i39.tinypic.com/2i9lfep.png",
    iconX2Url: "http://i39.tinypic.com/2i9lfep.png"
)

preferences {
	section("Select Switch to monitor"){
		input "theSwitch", "capability.switch"
	}
	section("Which light(s) to dim in the family room:") {
		input "switches", "capability.switchLevel", multiple: true
	}
    section("Dim to this level..."){
    	input "lvl", "number"
    }
    	section("Additionally dim these light(s) in the kitchen...") {
		input "switches1", "capability.switchLevel", multiple: true, required: false
    }
    section("To this level..."){
    	input "lvl1", "number"
    }
	section("Turn off these lights altogether..."){
		input "switch1", "capability.switch", multiple: true, required: false
	}
}

def installed()
{
	subscribe(app)
        initialize()
}

def updated()
{
	unsubscribe()
	subscribe(app)
        initialize()
}


def appTouch(evt) {
	log.info evt.value
    log.info "lvl: $lvl.value"
	log.info "lvl: $lvl1.value"
    switches.setLevel(lvl.value)
    switches1.setLevel(lvl1.value)
    switch1.off()
   
}

def onHandler(evt) {

//
	log.info evt.value
    log.info "lvl: $lvl.value"
	log.info "lvl: $lvl1.value"
    switches.setLevel(lvl.value)
    switches1.setLevel(lvl1.value)
    switch1.off()
    theSwitch.off()
}

def offHandler(evt) {
	log.debug "Received off from ${theSwitch}"
}

def initialize() {
	subscribe(theSwitch, "switch.On", onHandler)
	subscribe(theSwitch, "switch.Off", onHandler)
}

If you’re not locking doors/setting the thermostat, this one should work a bit better for you. Although it would be pretty easy to add those settings in if need be.

Awesome!! You’re the MAN! I adapted what you came up with a bit to fit my needs more closely. See below. Really appreciate the help!

definition(
    name: "Movie Mode",
    namespace: "",
    author: "nelemansc@gmail.com",
    description: "Movie Mode",
    category: "My Apps",
    iconUrl: "http://i39.tinypic.com/2i9lfep.png",
    iconX2Url: "http://i39.tinypic.com/2i9lfep.png"
)

preferences {
	section("Select Switch to monitor"){
		input "theSwitch", "capability.switch"
	}
	section("Which light(s) to dim to Level 1:") {
		input "switches1", "capability.switchLevel", multiple: true
	}
    section("Level 1"){
    	input "lvl1", "number"
    }
	section("Which light(s) to dim to Level 2:") {
		input "switches2", "capability.switchLevel", multiple: true
	}
    section("Level 2"){
    	input "lvl2", "number"
    }
    section("Turn off these lights altogether..."){
		input "switch1", "capability.switch", multiple: true, required: false
	}
}

def installed()
{
	subscribe(app)
        initialize()
}

def updated()
{
	unsubscribe()
	subscribe(app)
        initialize()
}


def appTouch(evt) {
	log.info evt.value
    log.info "lvl1: $lvl1.value"
    log.info "lvl2: $lvl2.value"
    switches1.setLevel(lvl1.value)
	switches2.setLevel(lvl2.value)
    switch1.off()

}

def onHandler(evt) {

//
	log.info evt.value
    log.info "lvl1: $lvl1.value"
    log.info "lvl2: $lvl2.value"
    switches1.setLevel(lvl1.value)
    switches2.setLevel(lvl2.value)
    switch1.off()
    theSwitch.off()
}

def offHandler(evt) {
	log.debug "Received off from ${theSwitch}"
}

def initialize() {
	subscribe(theSwitch, "switch.On", onHandler)
	subscribe(theSwitch, "switch.Off", onHandler)
}

Hey @nelemansc, I’ve wanted to update this app we worked on a bit more to also include a function of turning on some on/off light switches in addition to the dimmer switches that we already had it controlling. I tried adjusting the code myself to add this functionality, but it’s not working. Can you take a look at my code below and see if you can figure out how to get it going? Thanks in advance!

definition(
    name: "Virtual Switch Control Lights",
    namespace: "Virtual Switch Control Lights",
    author: "cbd@deyoungproperties.com",
    description: "Set a group of your light switches to specific levels, or turn them off, with the press of a single 'virtual switch'.",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png"
)

preferences {
	section("Select Switch to monitor"){
		input "theSwitch", "capability.switch"
	}
	section("Which light(s) to dim to Level 1:") {
		input "switches1", "capability.switchLevel", multiple: true, required: false
	}
    section("Level 1"){
    	input "lvl1", "number", required: false
    }
	section("Which light(s) to dim to Level 2:") {
		input "switches2", "capability.switchLevel", multiple: true, required: false
	}
    section("Level 2"){
    	input "lvl2", "number", required: false
    }
    section("Turn ON these lights..."){
		input "switch1", "capability.switch", multiple: true, required: false
	}
    section("Turn OFF these lights..."){
		input "switch2", "capability.switch", multiple: true, required: false
	}
}

def installed()
{
	subscribe(app)
        initialize()
}

def updated()
{
	unsubscribe()
	subscribe(app)
        initialize()
}


def appTouch(evt) {
	log.info evt.value
    log.info "lvl1: $lvl1.value"
    log.info "lvl2: $lvl2.value"
    switches1.setLevel(lvl1.value)
	switches2.setLevel(lvl2.value)
    switch1.on()
    switch2.off()

}

def onHandler(evt) {

//
	log.info evt.value
    log.info "lvl1: $lvl1.value"
    log.info "lvl2: $lvl2.value"
    switches1.setLevel(lvl1.value)
    switches2.setLevel(lvl2.value)
    switch1.on()
    switch2.off()
    theSwitch.off()
}

def offHandler(evt) {
	log.debug "Received off from ${theSwitch}"
}

def initialize() {
	subscribe(theSwitch, "switch.On", onHandler)
	subscribe(theSwitch, "switch.Off", onHandler)
}

Hey, I’m not able to test this since I’m at work, will either the virtual switch toggle or the app touch trigger it?

Unfortunately, no. Not with the way I adjusted the code from how I had it in my previous post.

Hey @nelemansc, sorry to bug… just thought I’d check back to see if you had a chance to take a look at this yet. Thanks!

@triggertact Hmm, the virtual switch works on my setup, but no luck with the app touch trigger. Not exactly sure why it isn’t though, I can see you haven’t really altered that portion of the code. Did you set yours so it could only trigger during certain modes?

Hey @nelemansc, I did not have it set to trigger only during certain modes. I just tried installing the app again to see if anything has changed, but unfortunately it still doesn’t work. Neither pressing the app play button nor turning the virtual switch on work to trigger it. Should we tag anyone else that you think might be able to help?

Try this -

definition(
    name: "Virtual Switch Control Lights",
    namespace: "Virtual Switch Control Lights",
    author: "cbd@deyoungproperties.com",
    description: "Set a group of your light switches to specific levels, or turn them off, with the press of a single 'virtual switch'.",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png"
)

preferences {
	section("Select Switch to monitor"){
		input "theSwitch", "capability.switch"
	}
	section("Which light(s) to dim to Level 1:") {
		input "switches1", "capability.switchLevel", multiple: true, required: false
	}
    section("Level 1"){
    	input "lvl1", "number", required: false
    }
	section("Which light(s) to dim to Level 2:") {
		input "switches2", "capability.switchLevel", multiple: true, required: false
	}
    section("Level 2"){
    	input "lvl2", "number", required: false
    }
    section("Turn ON these lights..."){
		input "switch1", "capability.switch", multiple: true, required: false
	}
    section("Turn OFF these lights..."){
		input "switch2", "capability.switch", multiple: true, required: false
	}
}

def installed()
{
	subscribe(app, appTouch)
        initialize()
}

def updated()
{
	unsubscribe()
	subscribe(app, appTouch)
        initialize()
}


def appTouch(evt) {
	log.info evt.value
    log.info "lvl1: $lvl1.value"
    log.info "lvl2: $lvl2.value"
    switches1.setLevel(lvl1.value)
	switches2.setLevel(lvl2.value)
    switch1.on()
    switch2.off()

}

def onHandler(evt) {

	log.info evt.value
    log.info "lvl1: $lvl1.value"
    log.info "lvl2: $lvl2.value"
    switches1.setLevel(lvl1.value)
    switches2.setLevel(lvl2.value)
    switch1.on()
    switch2.off()
    theSwitch.off()
}

def offHandler(evt) {
	log.debug "Received off from ${theSwitch}"
}

def initialize() {
	subscribe(theSwitch, "switch.On", onHandler)
	subscribe(theSwitch, "switch.Off", onHandler)
}

We never subscribed to appTouch, that could have been part of the problem. Now it works for both the virtual switch and the app touch in my environment.

@nelemansc - Oops, I forgot to tag you in this reply… wasn’t sure if you saw it come through.

Dang, unfortunately, it still doesn’t want to work on my end. With either the virtual switch or pressing play on the app. Also, I notice that the virtual switch doesn’t turn itself off after you turn it on. I think the other ones that we setup before did.

With it working right on your end, how should I troubleshoot this? Thanks again for the help!

UPDATE: just got it working… what I found out is that it’s requiring me to use the “dim light(s) to level 1” function. If I don’t input a light and dim value for that first one then it wont allow any of the other functions to work. In other words, if I just wanted the app to “turn off” a light by turning the virtual switch on it wont work. It will require that I add a light to dim to level one in addition to turning the other light off. Can you adjust it so that using the first function isn’t required?

UPDATE 2: I uninstalled the app to try reinstalling and see if the same thing held true. However, this time it required lights and dim values input for both level 1 AND 2 in order to have the “turn on” lights function to work. Lastly, it appears as though the virtual switch did not turn itself off.

Hey @nelemansc, just following up with my last post. Ultimately, it works, but it requires me to use the level 1 and level 2 actions in order for it to work. In other words, I can’t just have the virtual switch turn OFF some lights. Any idea of how to fix this? Thanks

Hey @nelemansc, I really hate to bug but I thought I’d just check back and see if you’ve had a chance to review my last two posts. Thanks again for all the help!

Hey @triggertact, I’ve been moving into a new place and have not had time to hook my SmartThings back up yet. I hope to get around to it sometime this week, then I can look back at it

Awesome thanks @nelemansc! I definitely can relate to the whirlwind that is moving haha. Talk soon…

Hey @nelemansc, hope the move went well! Any luck setting up your hub yet?