Perspective run script after inactivity timer elapses

I need to run a script to turn off some boolean values in a few page custom properties if there are 2mins of inactivity on the client. How would I do this?

1 Like

I also need this

In an upcoming release, we’re planning to add a lastActivity session prop, which would allow you to drive whatever logic you want via a property change script.

5 Likes

I haven’t experimented with this yet, but I’m wondering if you could set up your project (In Project>Project Properties>Inactivity) to enable an inactivity timer of 2 minutes which would generate a message to the user. Then create a Session Message Event script that would fire when this message comes through in which you can set your booleans as desired.
Optionally, you can configure the project to have a longer grace period if you don’t want to actually log them out or close the session after 2 minutes.
The lastActivity session prop would definitely be a preferred solution though.

This would all be achievable and fully customisable with the lastActivity session prop :slight_smile:

Just bumping this old post now that lastActivity is available in the designer post 8.1.8. Thanks guys!

What’s the most efficient use of it? I’d like to navigate to another view if no activity occurs for ‘x’ seconds. I’m thinking of creating a custom property that houses the current datetime, then put a property change script on that tag that if it’s been longer than ‘x’ seconds, then fire a navigation event. Is there a more efficient way to do this though?

Thanks again!

Is there any work around to implement this functionality in version 8.1.7?

No. Upgrade.

You don’t have the ability to author your own code that runs on the browser in Perspective, very deliberately.

1 Like

@PGriffith , is lastActivity supposed to update when Perspective Automatically Detects Inactivity?

Using these settings, my lastActivity timestamp doesn't change at Logout.
image

Goal is to close a dock when user is auto logged out.

That's not how it works.
lastActivity is a datetime that's automatically updated the last time the user does do something. If you want to react to that change, it's up to you. So, if you want to close a dock, then start a thread after the property changes that waits 60 seconds, checks if the last activity still hasn't changed from the value it was last set to, and then kicks off whatever action you want.

1 Like

I am facing an issue with lastActivity status tag when using it inside the script. The purpose of the script is to do auto-logout after an ideal time. The issue is lastActivity value is not updating in script when client is running. I have written a script in Session Probs > SESSION CUSTOM > Expression Structure and below is my script. Kindly support me to resolve this issue.

 

def transform(self, value, quality, timestamp):
lt01 = value['LA']
ct01 = value['CT']
idTime = value['IdealTime']
if lt01:
diff = system.date.minutesBetween(ct01, lt01)
if diff >= idTime:
system.perspective.logout()
return value

 

 

Let's clarify some terminology. It may help solve your issue.

lastActivity isn't a tag - it's a session property.

  1. Typo. It's SESSION PROPS, as in "properties".
  2. SESSION CUSTOM isn't a child of SESSION PROPS. It sits alongside them.

What is "Expression Structure"? It can't be a custom prop if it has a space in the name.
How is the script you provided related to lastActivity?

  1. This script should not be in a script transform - a script transform is for driving the value returned for a prop, not for executing arbitrary code. This belongs inside of a value change event (right click on the "AutoLogoff" prop and click "Add Change Script...").

  2. That's a strange way, to me, to derive the values of the keys under AutoLogoff, by using an expression structure. I normally use an expression structure to monitor the values of multiple things which should all trigger the binding to change. I would be moving those expressions into individual bindings on the keys instead.

2 Likes
  1. In SESSION CUSTOM create a value property "idleTimeout".
  2. On idleTimeout create an expression binding.
    (now() - {this.props.lastActivity}) > 5000 // 5 s
    The 5 s timeout is just to enable you to test it quickly. Point this at some other variable if you want. You seem to be using a tag in your example but tags are common to all projects so it doesn't seem appropriate.
  3. Right-click on custom.idleTimeout and select Add Change Script ...
    Put one line in there:
    system.perspective.logout()

Be aware that Perspective has Perspective Project Properties | Ignition User Manual which includes the session timeout. If you're going to do your own custom auto-logout then you need to set the project's auto-timeout to a value longer than your timout.

1 Like

I actually don't know if this works from the session prop change script. I looked at what I did and I sent a message from my session prop and had a message handler in my navigation dock which did the logout... it was a long time ago I did it, but I wouldn't have gone such a bizarre route if I could get it working from the session on change script... there are definitely some peculiarities that I haven't yet worked out with targetting sessions from different places.
I was about to test this all out, but it was very late at night...

After I implement the script in "Add Change Script". I am getting below error message.
com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
File "function:valueChanged", line 2, in valueChanged
NameError: global name 'now' is not defined

at org.python.core.Py.NameError(Py.java:259)
at org.python.core.PyFrame.getglobal(PyFrame.java:265)
at org.python.pycode._pyx524.valueChanged$1(<function:valueChanged>:3)
at org.python.pycode._pyx524.call_function(<function:valueChanged>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
at org.python.core.PyFunction.function___call__(PyFunction.java:474)
at org.python.core.PyFunction.__call__(PyFunction.java:469)
at org.python.core.PyFunction.__call__(PyFunction.java:464)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:847)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:829)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:868)
at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1010)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:950)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:161)
at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:98)
at com.inductiveautomation.perspective.gateway.model.PropertyChangeScript.access$001(PropertyChangeScript.java:31)
at com.inductiveautomation.perspective.gateway.model.PropertyChangeScript$ScriptSequencer.run(PropertyChangeScript.java:162)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
at java.base/java.lang.Thread.run(Unknown Source)

Caused by: org.python.core.PyException
Traceback (most recent call last):
File "function:valueChanged", line 2, in valueChanged
NameError: global name 'now' is not defined

... 24 more

Ignition v8.1.35 (b2023120517)
Java: Azul Systems, Inc. 17.0.8

We can't possibly help you without seeing the script as your original script doesn't have now in it I can only deduce that you're not using it. If you're looking at Transistor's reply, he mentions using now() inside of an expression binding. The scripting environment doesn't have a now() function, it has a system.date.now(), but you most likely don't want to be using that inside of your script in this instance

1 Like

The above error log is for Transistor Script wrote in Chage Script property. I also wrote my own script in Chage Script property. For this code error is not raising but Auto log-out function not happening after ideal time. Below is original code.

Please explain why you can't use Project | Project Properties | Perspective | General | Session Timeout.

What is special about your application?