Reset Application State?


(Patrick Stuart [@pstuart]) #1

Ok, after discovering you can use state[varname] = varname to store variable values during smartapp running, and check the values in the ide hub -> smartthings -> application state list, I’ve run into a bit of an issue.

I’ve tried resetting state using state.clear() and state = [:] and nothing clears application state.

Is there a way, besides removing the smartapp and reinstalling it to reset application state?


(swanny) #2

What if you put the debug info in a map that’s not at the base level of state? Like state.debug = [:]. Maybe there is some kind of restriction with clearing the whole state as there may be some system level data stored there too?


(Patrick Stuart [@pstuart]) #3

Good idea. I’ll try that…


(The fish is still dead.) #4

I realize this is an old thread, but did you ever find a way to actually reset the application state? I wasn’t able to find anything in the docs.

Maybe this is a good place to tag @Jim? =)


(Jim Anderson) #5

Good timing (and thanks for tagging me. While I may not be able to answer every question or update all the docs immediately, I am watching the forums :slight_smile: ).

We recently updated the State documentation: http://docs.smartthings.com/en/latest/smartapp-developers-guide/state.html

Does that help at all? If you do state.clear() does that not clear the state var?


(Eric) #6

so state.var.clear() and atomicState.var.clear() does not work. No error message, but no removing of the variable.

It seems to me you would want us to unset unused state or atomicState variables to save db load…

Can you give us an update on this? The docs are silent on clearing/removing state variables at run time


(The fish is still dead.) #7

There’s no way to do it.

Though if you wait long enough, the platform will clobber your application’s state for you.


(Eric) #8

Seems like a problem. Garbage collection does not seem to work, and there is no .delete() or .finalize() operating method…

@slagle @jody.albritton @Jim can we get a method to remove state or atomicState variables that we don’t need. The remove the SmartApp / device is very painful, especially in parent / child apps.


(Jim Anderson) #9

For state, you can use clear():

state.key1 = 'val 1'
log.debug "state: $state"
state.clear()
log.debug "state: $state"

For atomicState, there is no way to clear everything from what I can tell right now. You could set each value you want to remove to null; that won’t remove the key but it will set the value to null.

I’ll follow up if I find out or hear otherwise.


(Eric) #10

thanks

Is there a clear of an single variable for state, or is it all or nothing?


(Jim Anderson) #11

state.remove('your_key') should work. That will remove the entry from state once the app is finished executing.

And actually, I think state.clear() will clear atomicState too (once the app is done executing). But I don’t know of a way off-hand to remove individual entries from atomicState.


(Mike Maxwell) #12

state.clear() indeed works, state.remove(“varName”) does not.

definition(
    name: "demo",
    singleInstance: true,
    namespace: "MikeMaxwell",
    author: "Mike Maxwell",
    description: "device selection",
    category: "My Apps",
  	iconUrl: "https://s3.amazonaws.com/smartapp-icons/ModeMagic/Cat-ModeMagic.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/ModeMagic/Cat-ModeMagic@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/ModeMagic/Cat-ModeMagic@3x.png"
)

preferences {
    page(name: "main")
}

def main(){
	dynamicPage(name: "main", title: "main", uninstall: true, install: true) {
        section(){
        	 input(
            	name			: "devices"
                ,title			: "select contacts"
                ,multiple		: true
                ,required		: true
                ,type			: "capability.contactSensor"
                ,submitOnChange	: true
            )	
            if (settings.devices){
            	paragraph("contacts are open? ${contactOpenList()}")
            }
        }
    }

}

def contactOpenList(){
	def result = settings.devices.currentValue("contact").contains("open")
    devices.each{ device ->
    	state."${device.id}" = device.displayName
    }
	return result
}

def installed() {
   
}

def updated() {
	log.info "before state: ${state}"
    //state.remove('your_key')
    devices.each{ device ->
    	state.remove("${device.id}")
        log.info "removed ${device.id}?? ${state}"
    }
    //state.clear()
    //log.info "anything left? ${state}"
    
}

I checked application state in the IDE for this app, the state vars are still there after the app finishes executing (multiple refresh attempts.


(Jim Anderson) #13

Interesting. It worked in my attempt else I wouldn’t have put that down, but maybe my quick test missed something. When my app executed again and logged the contents of state, the removed key was gone.


(Mike Maxwell) #14

interesting, post up your demo, I’ll run it and see what happens…


(Eric) #15

It also clears out atomicState (state.clear), and settings to atomicState after state.clear() in the same execution are lost


(Eric) #16

I’ve found it does work (state.remove(‘var’))

The app has to exit

I found for my case I had to cancel subscriptions, schedules, do the state.remove), let things exit, then go again.

Practically speaking it requires user intervention. It would be great if state.remove(‘var’) worked at run time.

I found I could not use “var”…or “var${iterator}”


(Jim Anderson) #17
/**
 *  state example
 *
 *  Copyright 2015 james anderson
 *
 *  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: "state example",
    namespace: "",
    author: "james anderson",
    description: "state",
    category: "",
    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("Title") {
		// TODO: put inputs here
	}
}

def installed() {
    log.debug "Installed with settings: ${settings}"
    initialize()
}

def updated() {
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    initialize()
}

def initialize() {
    state.clear()
    log.debug "in initialize, state is: $state"
    runIn(20, addStuff)
    runIn(40, testClearSingle)
    
    // scheduled execution to show final state
    runIn(60, logIt)
}

def addStuff() {
    state.s1 = "test"
    state.s2 = "test again"
    logIt()
}

def testClearSingle() {
    log.debug "testClearSingle, state: $state"

    // remove single item, will be gone from state next execution
    state.remove("s1") 
    logIt()
}

def logIt() {
    log.debug "STATE: $state"
}

(Mike Maxwell) #18

works!, well SOB, thanks for that!