Delay multiple events in button component script-editor


Is there any possibilities to make a time delay between multiple events for button handlers?
In the example below, I need the event in line 8 run a few milliseconds after line 7.

Also interested to know other possibilities for setting different Properties to certain values in a form off sequence.

Andreas S,

Probably the simplest method would be to utilize the invokeLater function.


def setStatus(comp = event.source.parent, newValue = value):
    comp.Parameters.STATUS.VALUE = value

delay = 200 #delay in ms

Thanks Irose!

Is it possible to define a value to be the inverse of a property parameter?
Referring to the example below, could value3 be set to be the inverse of “Parameter.STATUS.VALUE”?

Andreas S,

Of course! Just use the not keyword

value3 = not event.source.parameter.STATUS.VALUE

Though I would probably refactor you code to make it a bit more readable.

parent = event.source.parent

#You can use True and False in place of 0 and 1 to set boolean values
parent.Parameter.STATUS.SELECTED = True 

def setManMode(comp = parent,value = True):
    comp.Parameter.STATUS.MAN_MODE = value

#You can use the keyword Not to invert a boolean value.
def setStatus(comp=parent, value = not parent.STATUS.VALUE):
    comp.Parameter.STATUS.VALUE = value

def resetManMode(comp=parent,value=False):
    comp.Parameter.STATUS.VALUE = value

def resetSelected(comp=parent,value=False):
    comp.Parameter.STATUS.SELECTED = False

delay1 = 250
delay2 = 500
delay3 = 750
delay4 = 1000

system.util.invokeLater(resetManMode, delay3)

On a side note, I’m not sure what it is that you are trying to accomplish, but it seems to me that this is an awful lot of hoops to jump through. I would be asking if it’s really needed to work all of this complexity into a button click. Would it perhaps be better handled by what ever controller is attached to this process? Generally sequences like what this one appears to be are better handled at the device level, in my opinion. Of course there is a lot of this picture I’m not seeing.

Concur. If it really needs a sequence that has to be in Ignition, then a state machine driven by a gateway timer script is the reliable choice.

1 Like

Yes, this sequence is needed to be handled by Ignition.
The background for this project is replacing a old ABB Advant scada system that has all these special sequences build-in or handled in other ways.

Pturmel, do you have an example for what you are suggesting?

Your state machine logic would look something like this, in a script module:

# Boolean, Integer, Boolean, Date
myTagPaths = ['[default]Some/Tag/Folder/'+x for x in ['SomeInput', 'State', 'SomeOutput', 'SomeTimestamp']]

def myStateMachine():
	# Get current values
	inp, state, outp, ts = [x.value for x in system.tag.readBlocking(myTagPaths)]
	now =

	# Milliseconds:
	elapsed = now.time - ts.time

	# Python has no switch statement--use if/elif/else instead
	if state == 0:
		# Idle state, perhaps.  Start when input is true
		if inp:
			# Start pulse 1
			system.tag.writeBlocking(myTagPaths[1:], [1, True, now])
	elif state == 1:
		if elapsed > 500:
			# End pulse 1
			system.tag.writeBlocking(myTagPaths[1:3], [2, False])
	elif state == 2:
		if elapsed > 750:
			# Start pulse 2
			system.tag.writeBlocking(myTagPaths[1:3], [3, True])
	elif state == 3:
		if elapsed > 1250:
			# End pulse 2
			system.tag.writeBlocking(myTagPaths[1:3], [4, False])
		# reset when both done pulsing and input returns to false
		if not inp:
			system.tag.writeBlocking(myTagPaths[1:3], [0, False])

The above generates two half-second output pulses a quarter second apart when an input turns on.
Call it from a gateway timer script that executes every quarter second.

Naturally, if you do much of this (as you indicate), you’ll want to place the patterns in a constant array and pass parameters to the function to select various collections of tag paths. A single timer script could call such a function for multiple combinations and patterns.

I personally would use the SFC module for this.