Perspective Script Execution

I am creating a component in Perspective which looks like this.

When I click the button, it turns a different color according to this script, which is for the onClick Mouse Event.

def runAction(self, event):
	if self.view.custom.State == 3:
		self.view.custom.State = 1
	elif self.view.custom.State == 1:
		self.view.custom.State = 3
		then = system.date.now()
		seconds = self.view.params.ackTime
		while True:
			sec_between =  system.date.secondsBetween(then, system.date.now())
			if sec_between > seconds:
				break
		self.view.custom.State = 1

The button stays that color for self.view.params.ackTime property. The button's color is bound to the self.view.custom.State property and when it changes from 1 to 3, the color of the button changes accordingly.

The problem is that if the button is already in color 3, and I press the button again, the scripts queue up for execution. For example, if the self.view.params.ackTime is set to 3 seconds, and I click the button once, it turns to color 3. But, if I click the button again while it is in color 3, it will extend the total time to 6 seconds. I want it to stop at 3 seconds or just turn the button back to color 1 when it is clicked while the onClick event script is already running. How can I achieve this?

Timers and while loops in scripts have been discussed many times on the forum and are generally considered to be a-very-bad-idea.

If you wish to persist in this approach you could create a boolean session variable to keep track of whether or not a timer is running and then handle that in code. Reset the session variable when the timer is complete.

In general, it would be much safer to have Ignition start the process in question and have the PLC reset the process at timeout. The button status colour would be based off feedback from the PLC and the process will stop even if the browser locks up, is closed, or comms fail.

If you describe what your actual application is (rather than your solution) you may get some better ideas.

2 Likes

I think you misspelled sleep

2 Likes

I understand that it is a bad idea. I tried using your approach of creating a boolean session variable like this

def runAction(self, event):
    if self.view.custom.State == 3:
        self.view.custom.State = 1
    elif self.view.custom.State == 1:
        # Check if script is already running
        if self.session.custom.buttonScriptRunning:
            return  # Exit the function if script is running
        else:
            self.session.custom.buttonScriptRunning = True  # Set the session variable to indicate script is running
            self.view.custom.State = 3
            then = system.date.now()
            seconds = self.view.params.ackTime
            while True:
                sec_between = system.date.secondsBetween(then, system.date.now())
                if sec_between > seconds:
                    break
            # Resume rest of script after values return to 0 and False
            self.view.custom.State = 1
            self.session.custom.buttonScriptRunning = False  # Reset the session variable after script execution

However, it still doesn't work. The variable changes to True, but for some reason, it does not stop the newer events from running.

Oh, no, that wasn't a misspelled sleep. That was a cpu-hogging denial-of-service attack.

1 Like

From your deleted post, change,
if self.session.custom.buttonScriptRunning:
to
if self.session.custom.buttonScriptRunning.value:

self.session.custom.buttonScriptRunning returns
[true, Good, Mon Jun 05 15:37:36 BST 2023 (....)]
You just want the value.

You still didn't tell us what the funtion of this button is.

basically, that button needs to flash with color 3 when there's a problem, and then temporarily shelve the alarm for the set amount of time by clicking on it and changing its color to color 2 (color 1 is default). The problem occurs when you click it while it is in color 3 state

The generally-accepted method is to disable the button while you don't want additional executions.

Bind the enabled property (and maybe it's style class too if you want it to flash) to whatever tells you there's an issue.