Project Library Message Handler

I have created a Project library script that i want to send out a message to be received by a popup. I know the script is being executed exactly where i have placed this messageSender because i have written to a tag directly before it. My question is whethere it is possible to send a message from the script and if so what scope should it be and what scope should the handler from the popup be?

Using system.perspective.sendMessage(), by default, depends on being called from a Perspective scope. The project library doesn't have a scope of its own, but runs in the scope of whatever event calls the library function.

If you call into the library from a Perspective event, the library will use the scope of that event for the information needed by system.perspective.sendMessage(). If you call your library script from something other than a Perspective event, you will need to provide the session and page IDs in the system.perspective.sendMessage() call.

Edit: a little birdie let me know of a typo....

Ok sorry trying to understand. The script is being called from a startup event on the popup. So i should use the system.util.sendMessage() instead of the perspective.sendMessage?

I am calling the project library script from the popup onStartup event in the script this is how I am calling it:

system.perspective.sendMessage('ClosePopup')

Then I have a messge handler setup on the same popup that looks like this:

Both the variable in this script and the closePopup arent working.

Please show your actual popup startup event. You'll have to show your library script, too.

A timer object is not a project library object, and its function will never have Perspective scope, since it runs in a different thread.

(You should avoid jython stdlib objects, and especially avoid sleeping or timing in events.)

Sorry Timer is the library that i created and it is working. Here is the code from my script called Timer:

import threading
import time

class ResettableTimer:
    def __init__(self, interval, function, args=None, kwargs=None):
        self.interval = interval
        self.function = function
        self.args = args if args is not None else []
        self.kwargs = kwargs if kwargs is not None else {}
        self.timer = None
        self.is_running = False

    def _run(self):
        self.is_running = False
#        path = '[default]ClosePopup'
#        system.tag.writeBlocking(path, True)
        system.perspective.sendMessage('ClosePopup') # <-- Here is where I am calling the sendMessage
        self.function(*self.args, **self.kwargs)


    def start(self):
        if not self.is_running:
            self.timer = threading.Timer(self.interval, self._run)
            self.timer.start()
            self.is_running = True
            #path = '[default]ClosePopup'
            #system.tag.writeBlocking(path, True)

    def reset(self):
        if self.is_running:
            self.timer.cancel()
        self.start()

    def cancel(self):
         if self.is_running:
            self.timer.cancel()
            self.is_running = False

If I uncomment the two lines under def_run then it writes to that tag five seconds after the popup opens so i know the code is being called.

You are using threading.Timer to run your function. It will never have Perspective scope. Don't use threading.Timer.

Can i use any timer in this script that will have perspective scope? Or is there a better way to accomplish what I am trying to do which is close the popup after a certain amount of time unless i set the reset timer funciton?

Use a couple view custom properties. Have the first bound to the expression now(0). Have the second bound to just now(). Then use a change script on the latter to compute the time between the two, and if greater than desired, the script can close the popup.

To reset the timer, write a new start timestamp (from system.date.now(), typically) to the start timestamp property.

Note, this topic is an example of a classic "XY" problem, where you ask for help on a task that you've decided will solve your real problem, instead of asking for help solving your real problem.

In the Ignition platform, uses of jython timers, or any kind of .sleep(), or any kind of unbounded loops, are all big red flags that your approach to your problem is flawed.

1 Like

Thanks for the help