Simultaneous use of state and atomicState

@Jim I’m starting a new thread on this topic, in another thread Bug in Parent Child Devices you had mentioned that it’s discouraged to use state and atomicState in the same app. One should use either state or atomicState throughout the app.

I had mentioned that are some inconsistencies that would need to resolved before that would be practical to enforce and you had requested an example. So to follow up on my promise.

I can/have built apps that only atomicState due to nature of the variables involved. However I cannot avoid the use of state, when the smartApp calls createAccessToken, ST stores the token in the state variable under state.accessToken

This is probably the only and big hurdle that I can think of which would prevent me from not mixing state and atomicState in a single app.

Any thoughts?

That should be ok as long as you’re not updating the accessToken in both state and atomicState. It would be nice if createAccessToken() just returned the token and you can store it how you want, but that would break a lot of existing usages.

1 Like

Well it could return a value and still store it in the state variable going forward. That way new apps using atomicState will be able to redirect the read and future writes.

I think it does currently - I’ve seen apps do atomicState.accessToken = createAccessToken()

2 Likes

So when I do revokeAccessToken() it will pick up from the state and invalidate it I’m assuming. So it shouldn’t be any issue at all unless I’m missing something.

No unfortunately I don’t think revokeAccessToken() removes the access token from state currently. :frowning:

1 Like

It won’t remove but it invalidates the token right? My point being using your example to save the token in atomicState and then reading from it v/s reading the token from the State - what’s the pro’s / con’s in an app that uses only atomicState (since there will be no writes to the State variable to access the token)

Why don’t you test and find out. You might be surprised … or not.

1 Like

Yes it does and I’ll take Jim word for it either way.

1 Like

@Jim would like to point out that the platform is having issues when saving a float variable in state

state.last_check = now() as float

This causing severe issues, it’s caching the value of state even after 10 seconds, ie the code when executed over 10 seconds 10 times reports the same value all 10 times. However

state.last_check = now()

works fine every time.

Not sure if it’s related to this

Any reason you need to cast to float? The state json serialization would handle long which is what now() returns.

I was building a rate limiting algorithm on request from @Aaron and the algorithm called for floating point OPS. I’ve since rewritten the algorithm but in the process found this bug hence reporting it. State should not be caching the float but it does for some reason.

Oops, meant to include this link that documents the data types that will be handled when serializing the state to JSON and back: http://docs.smartthings.com/en/latest/smartapp-developers-guide/state.html#what-can-be-stored-in-state-and-atomic-state

I’m not sure about caching; if values with the data types documented above are being cached somehow than it seems like an issue we need to look into more.

2 Likes

No actually I don’t even see float or double there.

I’m referring to caching. @Aaron has the code with him. Just change the state value to float and see what happens when it changes. When you call the function Ina loop you’ll see what I mean. The trace commands will show that the value doesn’t change when the state variable is storing a type float even after updating it. It caches it. However when it stores a long it works fine.

@Aaron, Bob has confirmed this issue. FYR it’s due to an issue with the way the state stores the float value which causes it to lose precision and hence appear to be cached if the change is very small.
e.g.
state.floatVar = 2.000004

and it changes to
state.floatVar = 2.000005

It doesn’t save it because it converts it to 2.0E+X format. He mentioned it would be fixed, soon hopefully :slight_smile:

1 Like

Yeah that makes sense (from looking at the code, that is). We did document the data types that state/atomicState will support for serialization, so until that change is made and documented, probably safest to stick to the supported types.

2 Likes

Jim that isn’t an option always, often when doing calculation one needs to store decimal points unfortunately. Just hope Bob team is quick to fix this one :slight_smile:

Sure but in the meantime maybe you can get what you need using BigDecimal without having to wait through a change/testing/deploy cycle. long is also accounted for, which is what now() returns, so maybe you could just store it directly? Maybe not, I don’t know your exact use case :wink:

2 Likes