Session Custom Property

Is it possible to pass a session custom property from a URL? I see how it is done from the view param but was wondering if it could be done for the session.

Could you provide an example of what you’re trying to accomplish? Are you asking how to set a session property based off of the value supplied in a url?

That is exactly what I am trying to do, but I can only get it to pass it to the view property.

Place an onChange script on the View param which then sets the session property to the new value.

1 Like

Considering you’d have to do this for multiple views probably, I could see it being a bit obnoxious. I am not sure if it’s a limitation of the web environment, but it would be nice if you could do this at the project level.

For instance if /data/client/projectname/pagename/param works for a view parameter, it would be nice if /data/client/projectname/param/pagename could work for a session parameter. But I would assume this is probably so much more complex and difficult than it sounds. As how would the url distinguish between a param and a page name?

I am trying to use a custom session property to bind all of the tags in my project to. I have 16 Chemical reactors that use the same screen, I would like to use a custom session property as a client override like I used in vision. I assume that with the session it would be persistent for this instance and I wouldn’t have to worry about disconnects resetting to a empty attribute.

I do a similar thing with remote locations and session props, when the user selects the location they want on a map, then it sets the custom property and all of the following pages match that property in that session.

One way that this can be fooled though is if they bookmark a page, thinking that its dedicated to one reactor, when in reality it is shared by several and they end up looking at the wrong thing at the wrong time. I am sure there are better ways to avoid this, but I also typically try to put something “bold and identifying” as well to make it more clear what they are looking at in this case, and an easy page to “switch locations” if they do end up looking at the wrong one.

In this case I also try to allow any of my pages to also allow for a parameter in the url, so that if that value is populated then it sets it to the session props, however this also doesnt feel foolproof as it requires a bit of extra page:param management.

Let's use the following project as an example:

  • session.custom.displayed_reactor has a default/fallback/initial value of 1.
  • MyView.params.displayed_reactor has a default/fallback/initial value of 1, and it is Bi-directionally bound to session.custom.displayed_reactor.
  • There is a Page Configuration with a configured URL of /reactors/:displayed_reactor which uses MyView as the Primary View.

Cases:
1a. I navigate to <GatewayAddress>/data/client/perspective/MyProject/reactors/ (note no supplied param value).
1b. Behavior: The View falls back to the default value of 1 and displays info for reactor 1.

2a. I navigate to /data/client/perspective/MyProject/reactors/2`
2b. Behavior: The View displays info for reactor 2.

3a. I navigate to /data/client/perspective/MyProject/reactors/two`
3b. The View probably fails to display much of anything, depending on how you configure the setup.

4a. A user is viewing reactor 7, but their session loses connection for more than 60 seconds or they log out and back in .
4b. A new session is started, which means they will once again be using a value of 1, since that is what the View starts with.

Yes, it will persist for the life of the session. You will not encounter an empty attribute because you've supplied a default value of 1. If you were creating the custom property as part of a View onStartup Event, you could run into NullPointerExceptions, but the setup I recommended will never encounter those if implemented as described.

Is it possible for us to cache certain things like this?

You could get fancy and write the value to a tag, like a Dataset where one column is the User’s username and the other column is the last reactor viewed, but at that point you should use the tag instead of the session property. Using a combo of param/sessionProp/Tag is just inviting undesirable behavior and/or race conditions. You could also write it to a DB. As far as caching goes… no - Perspective does not have a caching concept.

What about using a data set tag with the host ip and displayed_reactor and bind that to the session custom property? Would that result in a more consistency or if i mada another custom session property as an array of key/value pairs and compare to the host ip. I initially tried the bi-directional bind but what i noticed is that on a template project the home screen would load and the first menu choice would load properly but when i went back to the home screen from the menu a blank page would load because the custom session property would be null.

Why even use the session property in this setup? Tags or DB entries should be used for values which should be retained for a user from session to session. Session properties should be used for values which need to be referenced during a session from within more than one View. binding a Session property to a tag only makes the session property redundant.

This should only happen if the value saved for the property is null in the Designer, or if the Session itself writes a null value to the property. Examine your setup to determine where the null is being applied as the property value.

@cmallonee how can a session property default value be set? Do you have to create a binding for it?
What if we want it to be changed in the session, how do you “oneshot” a default value so to speak?

When you create a session property, the value you see when you save your project in the Designer is the default value. If you set the property to be non-persistent, then it will have no value (None/null) until you set the property at runtime; this is the same behavior you would see if the property had never been created in the first place.

Ah gotchya, that makes sense. I think i’ll probably want a dynamic default, such as a date range which would be used for reporting, and would refresh every time a new session is started. So a binding on the session properties, something like this should work?

endDate = now(0)
startDate = addDays(endDate, -3)

While that would work, that also doesn’t seem like something you need for the session as you would only need it in some minor location. Session properties are intended to be used as properties which multiple tabs/Views/Popups/Docked Views could all reference and get the same value.

Thanks, understood.

Is there any way to set a custom session property from the gateway scope dynamically?
I've managed to create a function in a script library which is passed the "session" object, and can set a parameter directly such as:

session.custom.mycustomprop = "Test"

But i would like to get clever and pass it indirectly, something like this:

#-------------------------------------------------------------------
# On a button event script or similar:

# Payload defined in calling function
payload = {"propName":"mycustomprop", "propValue":"Test"}
# Calling custom script
shared.mylibrary.updateSessionProp(session, payload)

#-------------------------------------------------------------------
# shared.mylibrary  
def updateSessionProp(session, payload):
    session.custom.payload["propName"] = payload["propValue"]
# end def
#-------------------------------------------------------------------

I can't get this to work with a dynamic session property path.
I get the following error:

Caused by: org.python.core.PyException: AttributeError: 'com.inductiveautomation.perspective.gateway.script' object has no attribute 'payload'

Any ideas?

  1. You’re setting up those references incorrectly; what you want would be something like
session.custom[payload['propName'] = payload['propValue']

The error you are encountering is because the custom properties don’t contain a payload property.
2. I don’t think we allow for accessing property categories as dictionaries, so it wouldn’t work anyway.