Making a gateway timer script dynamic

I have a gateway timer script that I want to make dynamic. I have 219 lines in the script that I want to shrink down. I use the same script below for each piece of equipment. What is the best way to go about it.

#Equipment 10891
		if system.tag.read("[default]Moblie/Downtime10891State").value == 1:
			system.tag.write("[default]Moblie/Downtime10891State", 0)
			system.tag.write("[default]Moblie/Downtime10891", 0)
			system.tag.write("[default]Moblie/Downtime10891Timer", 0)
			system.tag.write("[default]Moblie/Downtime10891State", 1)
		else:
			system.tag.write("[default]Moblie/Downtime10891", 0)
			system.tag.write("[default]Moblie/Downtime10891Timer", 0)

Is the 10891 the only thing that changes, if so what is the range?

Assuming it is you can do something like:

#Equipment 10891
      for x in range(10891, 10895):
		if system.tag.read("[default]Moblie/Downtime"+x+"State").value == 1:
			system.tag.write("[default]Moblie/Downtime"+x+"State", 0)

I see what you are saying, but the numbers are not in order. They skip around. I have 1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891.

You could always just provide an ordered list of equipments.

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]

for x in myEquipment:
    if system.tag.read("[default]Moblie/Downtime"+x+"State").value == 1:
        system.tag.write("[default]Moblie/Downtime"+x+"State", 0)

One comment though, depending on your version, system.tag.read/write are deprecated and you should be using system.tag.readBlocking/writeBlocking for this use-case.

That will also take a list of tags, so you could technically make this more performance (but maybe harder to read) with the following:

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]

# Create a list of all the equipment with a list comprehension
tagPaths = ["[default]Moblie/Downtime%sState" % equipment for equipment in myEquipment]

# Read all of the states at once
states = system.tag.readBlocking(tagPaths)

# Create a list of tagpaths for each one that has a matching state of 1
validEquipment = [tagPath for tagPath, state in zip(tagPaths, states) if state.value == 1]

# write all of those tags to 0, with a list comprehension to create a list of 0s the same length as validEquipment
system.tag.writeBlocking(validEquipment, [0 for _ in validEquipment])

EDIT: I don't know why, but the syntax highlighting in these snippets is broken for me, so maybe for you too. If so here is a code-snap

3 Likes

when I try this it gives me a error ( no viable alternative at input 'system') I assume it has something to do with the else statement

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]
		
		for x in myEquipment:
			if system.tag.read("[default]Moblie/Downtime"+x+"State").value == 1:
				system.tag.write("[default]Moblie/Downtime"+x+"State", 0)
				system.tag.write("[default]Moblie/Downtime"+x+", 0)
				system.tag.write("[default]Moblie/Downtime"+x+"Timer", 0)
				system.tag.write("[default]Moblie/Downtime"+x+"State", 1)
			else:
				system.tag.write("[default]Moblie/Downtime"+x+", 0)
				system.tag.write("[default]Moblie/Downtime"+x+"Timer", 0)

Remove the +" after the x in the 3rd line of your if statement and in the 1st line of your else statement

I get the same error

There's another of the same error in the first line after "else:"

Also make sure your tabs/indentation are all correct. Not sure if the extras are from pasting to the forum or are really present in your script.

If it still doesn't work show us the newly edited script and the full error, which should include some hint as to what line it's occurring on.

You can test your code in the Script Console by making a few modifications.

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]
value = 1
for x in myEquipment:
	if value == 1:
		print("[default]Moblie/Downtime" + x + "State", 0)
		print("[default]Moblie/Downtime" + x + ", 0)
		print("[default]Moblie/Downtime" + x + "Timer", 0)
		print("[default]Moblie/Downtime" + x + "State", 1)
	else:
		print("[default]Moblie/Downtime" + x + ", 0)
		print("[default]Moblie/Downtime" + x + "Timer", 0)

This gives error SyntaxError: no viable alternative at input 'print' (<input>, line 9)

Fixing the + " problems gives you this:

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]
value = 1
for x in myEquipment:
	if value == 1:
		print("[default]Moblie/Downtime" + x + "State", 0)
		print("[default]Moblie/Downtime" + x, 0)
		print("[default]Moblie/Downtime" + x + "Timer", 0)
		print("[default]Moblie/Downtime" + x + "State", 1)
	else:
		print("[default]Moblie/Downtime" + x, 0)
		print("[default] bMoblie/Downtime" + x + "Timer", 0)

which generates the error, Traceback (most recent call last): File "<input>", line 7, in <module> TypeError: cannot concatenate 'str' and 'int' objects

This, in turn, can be fixed by converting x to a string.

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]
value = 1
for x in myEquipment:
	if value == 1:
		print("[default]Moblie/Downtime" + str(x) + "State", 0)
		print("[default]Moblie/Downtime" + str(x), 0)
		print("[default]Moblie/Downtime" + str(x) + "Timer", 0)
		print("[default]Moblie/Downtime" + str(x) + "State", 1)
	else:
		print("[default]Moblie/Downtime" + str(x), 0)
		print("[default]Moblie/Downtime" + str(x) + "Timer", 0)
1 Like
myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]
		
		for x in myEquipment:
			if system.tag.read("[default]Moblie/Downtime"+x+"State").value == 1:
				system.tag.write("[default]Moblie/Downtime"+x+"State", 0)
				system.tag.write("[default]Moblie/Downtime"+x+", 0)
				system.tag.write("[default]Moblie/Downtime"+x+"Timer", 0)
error on this line>	system.tag.write("[default]Moblie/Downtime"+x+"State", 1)
			else:
				system.tag.write("[default]Moblie/Downtime"+x+", 0)
				system.tag.write("[default]Moblie/Downtime"+x+"Timer", 0)

You still have a stray quote on one of the lines in the if block.

I tried to remove it but the error keeps moving around

Break every string concatenation operation into multiple parts on separate lines to help make it obvious where your problems are. Or use string interpolation/formatting operations to avoid concatenation.

If you're really desperate, paste from an external editor into Ignition's editor one line at a time, paying attention to the red margin markers for syntax errors.

Or go home, have a beer/beverage of choice, and try again after the frustration dissipates.

2 Likes

system.tag.write("[default]Moblie/Downtime"+x+", 0)
should be this:
system.tag.write("[default]Moblie/Downtime"+x, 0)

I can recreate the problem and fix it by deleting the +"

image

It really does go away when I delete the +" from those two lines

1 Like

You're writing 1 to the State tag, then 0 immediately after. Why ?

The only difference between the 2 branches is that the DowntimeXTimer and DowntimeX writes are surrounded by this state change. What is it supposed to do ?

This setup keeps track of the downtime for mobile equipment for each month and the data gets reset at the end of the mouth but If the state 1(meaning down) then the state 1 gets set again to continue to add up the time for the next month.

Here is a screen shot of the setup. There are 4 tags for each piece of equipment. Downtime1793(this is stored in a database for each hour the equipment is down), Downtime1793Display(this is your display time in hours,minutes,seconds), Downtime1793State(this is the multistate indicator for status, Downtime1793Timer(this keeps the time). There scripts involved as well like the one I am trying to make better by stream lining it.
image

Did you ever get your code working?

Transitor's post walks you through exactly what you need to do:

  • fix the two stray quotes
  • convert x to a string in your tag writes
1 Like

I believe this will work if I am understanding it correctly

myEquipment = [1744, 1767, 1790, 1792, 1802, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1846, 1848, 1850, 1851, 1855, 10888, 10891]

	for x in myEquipment:
		if system.tag.read("[default]Moblie/Downtime" + str(x) + "State").value == 1:
			system.tag.write("[default]Moblie/Downtime" + str(x) + "State", 0)
			system.tag.write("[default]Moblie/Downtime" + str(x), 0)
			system.tag.write("[default]Moblie/Downtime" + str(x) + "Timer", 0)
			system.tag.write("[default]Moblie/Downtime" + str(x) + "State", 1)
		else:
			system.tag.write("[default]Moblie/Downtime" + str(x), 0)
			system.tag.write("[default]Moblie/Downtime" + str(x) + "Timer", 0)