Timer to Close Vision Popup Window

How do you create a timer to close a popup after it has been open for more then a set time.
I want to close control screens after 15 seconds to stop people from leaving them open.

I would ask why these pop-ups keep getting left open - does your system open multiple popups and perhaps some are getting lost behind main windows?

Either way, I think probably the easiest catchall way to do this would be on a Client Timer script, set to run every 30 seconds. Use (system.util.getInactivitySeconds - Ignition User Manual 8.0 - Ignition Documentation) to see how long since the keyboard or mouse was last touch. If it’s been more than 15 seconds.

Then use system.gui.getOpenedWindows - Ignition User Manual 8.1 - Ignition Documentation to get all the opened windows. Assuming you have some naming convention that differentiates a popup window from a main window, such as a Pop_ prefix or a folder where all the popups are, the psuedocode for the client event timer script would look like

You will also need system.nav.closeWindow - Ignition User Manual 8.0 - Ignition Documentation

inactiveSeconds = system.util.getInactivitySeconds()
if inactiveSeconds > 15:
    for window in system.gui.getOpenedWindows():
        windowName = window.getPath()
        # some logic to determine if popup
        ispopup = ? (depends on your system)
        if ispopup:
            system.nav.closeWindow(window)

An alternative to inactivity seconds could be adding a custom property to the window that would hold the open time. Then you could use an expression binding to fire a property change event where your close the window.

secondsBetween({Root Container.openTime},now()) > 15
1 Like

This was my initial idea, the only issue I have with it is I would then have to add it to every window, whereas the client timer method works with implementing it one place.

However, if your project does not have a nice naming convention or some way to tell if a window is a popup (maybe there’s some underlying java method to do this but I don’t know it off hand), then this way would be more appropriate than mine.

1 Like

I do prefer the secondsBetween option.
Is there a list of available functions and properties for stuff like the ‘Root Container’?
Like where do you find the .openTime property even exists?

Would my end goal be an expression binding on some object on the page that does the following?:

if secondsBetween({Root Container.openTime>,now()) > 15:
	system.nav.closeWindow({Root Container})

openTime is a custom property that I created on the root container. Right click on the RC and select Customizers then Custom Properties (ctrl + u). Here you can add and name custom properties yourself. You can add one called openTime of type date, which can be added to your open popup script.

window = system.nav.openWindow('Popups/messenger', {'openTime' : system.date.now()})
system.nav.centerWindow(window)

You would also have another custom property on the root container that could be named expired of type boolean with the expression

secondsBetween({Root Container.openTime},now()) > 15

Then in root container’s property change event

if event.propertyName == 'expired':
	if event.newValue:
		system.nav.closeParentWindow(event)

I would probably make this

if event.propertyName == 'expired':
	if event.newValue:
		system.nav.closeParentWindow(event)
if event.propertyName == 'expired' and event.newValue:
	system.nav.closeParentWindow(event)

but that’s super minor.

However, this is what I meant regarding a lot more engineering to use this method. You have to modify

  1. The system.nav.openWindow
  2. Add two custom root container properties
  3. Add a property change script
    multipled by however many popup containers you have (and you will probably need to do a Control+F to find all your system.nav.openWindows type scripts)

So if you have 15 popup windows you’re looking at 45 changes you have to make, versus 1 client timer script to write if you have some way to figure out by name if the window is a popup window. It is for this type of reason I highly recommend using naming conventions not only on tags, but on windows, custom properties, etc, in case you ever need extra information you want to imbue via naming.

I see your point, but the popup I used this on is in an inherited global project, so I only have a single window I needed to configure this way.

1 Like

Also, the timer script could take up to 45 seconds to close the popup instead of 15 seconds, where the custom property will always close after exactly 15 seconds

Oh that makes sense. I haven’t had the chance to work with projects that have inherited properties, but in that case, them yes the workload is equal and it’s just a matter of taste - would probably do your way tbh so the closing logic of the window is on the window instead of hidden away in a client timer script.

Point stands if you are using an older version of Ignition without inherited projects or don’t have an inherited popup window like that.

1 Like

I get where you are both coming from with the differences between the two solutions yeah.
I am still in the templating stage for my popup control window, the only issue i have is that i cannot make it dynamically update between the different switches being controlled as my data coming in is a DNP3 map and the tags cannot be named in a way that will allow me to completely dynamically assign the tags.

I think the solution by @dkhayes117 will work perfectly for me as once i make the template popup i will just need to copy it a handful of times and manually change a bunch of items on them anyways (unfortunately).

I would love to make the one screen dynamically update but alas that isnt possible with my tag map coming from my SCADA RTU.

One thing though - won’t this always just trigger 15 seconds after window opens regardless of if the user is using the window or not? I think the propertyChange logic needs to incorporate inactivity.

Imagine too though we do incorporate inactivity right -

if event.propertyName == 'expired' and event.newValue:
    if system.util.getInactivitySeconds() > 15:
        system.nav.closeParentWindow(event)

say they were active, and this doesn’t go off, then the boolean value is just stuck on true, and it won’t try to close the window again right? It tries once after 15 seconds, but that is it. Which I don’t think is OP’s intent.

Edit: Per clarification, it should be

if event.propertyName == 'expired' and event.newValue:
    system.nav.closeParentWindow(event)

to close after 15 seconds no matte user usage.

Yes, that is true. If you want 15 seconds of inactivity then you would need to add that inactivity check to the script.

This throws a bit of a wrench in it as well, since after 15 seconds, that change script would fire every second after the initial 15 seconds

I think this would work to keep it checking every so often -

if event.propertyName == 'expired' and event.newValue:
    if system.util.getInactivitySeconds() > 15:
        system.nav.closeParentWindow(event)
    else:
        event.source.openTime = system.date.now()

to reset expired to false, and so this thing triggers again.

Though I would probably make
the 15 in
system.util.getInactivitySeconds() > 15 a number less than the 15 in secondsBetween({Root Container.openTime},now()) > 15 for better catching of inactivity.

This throws a bit of a wrench in it as well, since after 15 seconds, that change script would fire every second after the initial 15 seconds

My impression is that changing from True to True wouldn’t create another property change event.

1 Like

I actually want the window to close regardless of if they are using it or not.
This is being used for a breaker control in an Electrical Substation, so if they open the breaker control screen I don’t want them being able to leave it open.

1 Like

Disregard everything I’ve said then. Follow @dkhayes117 first recommendation.

Ah, yes. I missed that, good point.

No worries, I appreciate all the discussion of options though, thanks.
I’m sure the other options will come in handy for some of the other screens i need to make for this system as well, and i have gained a much better understanding of how to use some of the backend of Ignition Scripting.

2 Likes