# Delay between lines of code

**URL:** <https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301>\
**Category:** Ignition\
**Tags:** ignition81, scripting\
**Created:** [August 2, 2023, 6:31pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301 "2023-08-02T18:31:39Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 3, 2023, 8:21pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/22 "2023-08-03T20:21:47Z")

</div>

You can generate your tag list like this:

```python
tags1= ['[Kenmex]Kenmex/{}/{}'.format(a,b) 
		for a in ('Axle CV1',
				  'CV 2',
				  'CV 3',
				  'CV5',
				  'CV 6',
				  'CV 7'
		) 
		for b in ('stopcond/Matutino/TEO_TP/TEOTOTALMIN',
				  'stopcond/Matutino/TEO_TP/TPTOTALMIN',
				  'stopcond/Vespertino/TEO_TP/TPTOTALMIN',
				  'stopcond/Vespertino/TEO_TP/TEOTOTALMIN',
				  'stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN',
				  'soppcond/TEO_TP_TOTALTURNO/TPTOTALMIN'
				  )]
tags += ["[Kenmex]Kenmex/Kenmex Monitoreo/Kenmex Monitoreo Totales/TEO_TOTALMIN",
          "[Kenmex]Kenmex/Kenmex Monitoreo/Kenmex Monitoreo Totales/TP_TOTALMIN"]

```

This means that if you ever need to add/or remove a stop condition it will be relatively painless, and you don't need to dig through a huge block of strings to do it.

Since you are using the values in the query in the same order that they are being read, then you can just generate the list of values, no need to first extract the values into variables that are never used again. This will also give you the ability to construct the query more dynamically.

```auto
tagValues = [qv.value for qv in system.tag.readBlocking(tags)]

CONSULTA = """INSERT INTO assy_kenmex_monitoreo_click 
		(t_stamp,
		CV1_M_TEO,CV1_M_TP,CV1_V_TEO,CV1_V_TP,CV1_TEO_TOTAL,CV1_TP_TOTAL,
		CV2_M_TEO,CV2_M_TP,CV2_V_TEO,CV2_V_TP,CV2_TEO_TOTAL,CV2_TP_TOTAL,
		CV3_M_TEO,CV3_M_TP,CV3_V_TEO,CV3_V_TP,CV3_TEO_TOTAL,CV3_TP_TOTAL,
		CV5_M_TEO,CV5_M_TP,CV5_V_TEO,CV5_V_TP,CV5_TEO_TOTAL,CV5_TP_TOTAL,
		CV6_M_TEO,CV6_M_TP,CV6_V_TEO,CV6_V_TP,CV6_TEO_TOTAL,CV6_TP_TOTAL,
		CV7_M_TEO,CV7_M_TP,CV7_V_TEO,CV7_V_TP,CV7_TEO_TOTAL,CV7_TP_TOTAL,
		KENMEX_TEO_TOTAL,KENMEX_TP_TOTAL) 
		VALUES ({})""".format(','.join(['?']*len(tagValues)))

FILAS_INSERTADA = system.db.runPrepUpdate(CONSULTA,[system.date.now()] + tagValues)

```

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 3, 2023, 9:06pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/23 "2023-08-03T21:06:35Z")

</div>

I took the liberty of refactoring this script a bit.  
Assuming you showed us the whole thing, it shouldn't change anything about its functionality, it's mostly a readability" (except for batching tag reads, which does improve performances noticeably).  
I also assumed the indentation was boinked up, as it doesn't make much sense otherwise.

I changed the names of variables. It's not something that's set in stone, but a good naming convention makes things easier. Here are a few rules I use, and which are I believe quite common:

- Variables names don't start with a capital, that's for classes
- Full caps variable names are for constants
- Once you pick a style, stick with it
- Names in English, makes things easier for everyone when you're sharing code with people who don't speak your language (I'm guessing 'consulta' means 'query' from context, but guessing is not something to do when it comes to code)

Aside from that:

- Might as well check the 4 elements at once:

```python
event.path[0] == 0 and event.path[1] == 6 and event.path[2] == 1 and event.path[3] == 0

# becomes
event.path[:3] == [0, 6, 1, 0]

```

- don't compare booleans to `True` or `False`:

```python
if Paso == True:

# becomes
if paso:

```

Though those conditions can be removed:  
you're setting `paso`'s to `True` or `False` based on another condition. Might as well used that condition directly:

```python
FILAS_INSERTADAS = system.db.runPrepUpdate(CONSULTA, VALORES)       
if FILAS_INSERTADAS > 0:
    Paso = True
else:
    Paso = False
if Paso == True:
    # code

# becomes
if system.db.runPrepUpdate(query, [t_stamp]+values) > 0:
    # code

```

You're setting up another boolean variable (`Paso1`) in a `if` block, then checking that out of the if's scope.  
Two things here: If the first block is not executed, `Paso1` does not exist and an error will be raised.  
And it's not necessary anyway, you can just put that 2nd if's block in the first one.  
Also, the inner functions don't serve any purpose here. Just put their code directly where the function is called.

Adding all this together:

```python
def runAction(self, event):
	if event.path[:3] == [0, 6, 1, 0]:
		t_stamp = system.date.now()
		tag_paths = [
			"[Kenmex]Kenmex/Axle CV1/stopcond/Matutino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/Axle CV1/stopcond/Matutino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/Axle CV1/stopcond/Vespertino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/Axle CV1/stopcond/Vespertino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/Axle CV1/stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN",
			"[Kenmex]Kenmex/Axle CV1/stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 2/stopcond/Matutino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 2/stopcond/Matutino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 2/stopcond/Vespertino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 2/stopcond/Vespertino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 2/stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 2/stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 3/stopcond/Matutino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 3/stopcond/Matutino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 3/stopcond/Vespertino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 3/stopcond/Vespertino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 3/stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 3/stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN",
			"[Kenmex]Kenmex/CV5/stopcond/Matutino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV5/stopcond/Matutino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV5/stopcond/Vespertino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV5/stopcond/Vespertino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV5/stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV5/stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 6/stopcond/Matutino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 6/stopcond/Matutino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 6/stopcond/Vespertino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 6/stopcond/Vespertino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 6/stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 6/stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 7/stopcond/Matutino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 7/stopcond/Matutino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 7/stopcond/Vespertino/TEO_TP/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 7/stopcond/Vespertino/TEO_TP/TPTOTALMIN",
			"[Kenmex]Kenmex/CV 7/stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN",
			"[Kenmex]Kenmex/CV 7/stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN",
			"[Kenmex]Kenmex/Kenmex Monitoreo/Kenmex Monitoreo Totales/TEO_TOTALMIN",
			"[Kenmex]Kenmex/Kenmex Monitoreo/Kenmex Monitoreo Totales/TP_TOTALMIN"
		]
		values = [t_stamp] + [qval.value for qval in system.tag.readBlocking(tag_paths)]
		query = "INSERT INTO assy_kenmex_monitoreo_click (t_stamp,CV1_M_TEO,CV1_M_TP,CV1_V_TEO,CV1_V_TP,CV1_TEO_TOTAL,CV1_TP_TOTAL,CV2_M_TEO,CV2_M_TP,CV2_V_TEO,CV2_V_TP,CV2_TEO_TOTAL,CV2_TP_TOTAL,CV3_M_TEO,CV3_M_TP,CV3_V_TEO,CV3_V_TP,CV3_TEO_TOTAL,CV3_TP_TOTAL,CV5_M_TEO,CV5_M_TP,CV5_V_TEO,CV5_V_TP,CV5_TEO_TOTAL,CV5_TP_TOTAL,CV6_M_TEO,CV6_M_TP,CV6_V_TEO,CV6_V_TP,CV6_TEO_TOTAL,CV6_TP_TOTAL,CV7_M_TEO,CV7_M_TP,CV7_V_TEO,CV7_V_TP,CV7_TEO_TOTAL,CV7_TP_TOTAL,KENMEX_TEO_TOTAL,KENMEX_TP_TOTAL) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"

		if system.db.runPrepUpdate(query, values) > 0:
			data = system.report.executeReport("assy_kenmex/Kenmex Monitoreo/Kenmex Monitoreo_Click", fileType="pdf")
			system.perspective.download("Kenmex Monitoreo_{}.pdf".format(system.date.format(t_stamp, "MM-dd-yy_hh-mm a")), data)
			system.db.runPrepUpdate("DELETE FROM assy_kenmex_monitoreo_click; TRUNCATE TABLE assy_kenmex_monitoreo_click")

```

---

<div class="post-metadata">

**Author:** ![Josue\_Cuadras](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/josue_cuadras/32/59915_2.png) [@Josue\_Cuadras](https://forum.inductiveautomation.com/u/Josue_Cuadras)\
**Post date:** [August 3, 2023, 9:55pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/24 "2023-08-03T21:55:34Z")

</div>

Thanks to all who have commented on the post, you are all pretty good at coding, in this short period working with Ignition has been a great challenge and a great learning experience for me, in this short period I have learned about SQL, CSS, HTML , Python, etc. I hope to continue improving my knowledge in these programming languages ​​and improve my way of writing code and above all I would like to continue learning from you! Thank you all!

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [August 4, 2023, 2:18am UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/25 "2023-08-04T02:18:26Z")

</div>

> [@pascal.fragnoud](#):
>
> - Variables names don't start with a capital, that's for classes
> - Full caps variable names are for constants
> - Once you pick a style, stick with it
> - Names in English, makes things easier for everyone when you're sharing code with people who don't speak your language (I'm guessing 'consulta' means 'query' from context, but guessing is not something to do when it comes to code)

I'd also add, pick a naming convention for tag names as well. The current convention is all over the place in this example `"[Kenmex]Kenmex/Axle CV1/stopcond/Matutino/TEO_TP/TEOTOTALMIN"`  
You've got:

- Title Case
- lower case
- using spaces
- SUBSTITUTING\_SPACES\_FOR\_UNDERSCORES
- UPPER CASE

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 7:16am UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/26 "2023-08-04T07:16:29Z")

</div>

Don't hesitate to show some code and ask how it could be done differently. As long as you actually put some effort in, we're always happy to help make things better.  
But DO put some effort in, or you won't learn much: seeing how people rewrite what you spent a good amount of brain power on is (for me) the best way to make things click.

Also note that ignition is a vast and complex machinery. More often than not you'll find that fixing code is a good first step, but that there's a better solution that involves built-in mechanisms and that is what you should strive for - and what we'll happily try to help with if the problem is described well enough.  
Here's a link to a page that everyone using the community's help for technical environments should read:

> **[The XY Problem](https://xyproblem.info/)**
>
> Asking about your attempted solution rather than your actual problem

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 3:48pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/28 "2023-08-04T15:48:51Z")

</div>

Do you get an error ? If so, what is it ?

---

<div class="post-metadata">

**Author:** ![Josue\_Cuadras](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/josue_cuadras/32/59915_2.png) [@Josue\_Cuadras](https://forum.inductiveautomation.com/u/Josue_Cuadras)\
**Post date:** [August 4, 2023, 3:51pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/29 "2023-08-04T15:51:09Z")

</div>

It does not show an error simply when I click the button it doesn’t trigger the script.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [August 4, 2023, 4:14pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/30 "2023-08-04T16:14:47Z")

</div>

Check your gateway logs, an error would appear there.

---

<div class="post-metadata">

**Author:** ![Josue\_Cuadras](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/josue_cuadras/32/59915_2.png) [@Josue\_Cuadras](https://forum.inductiveautomation.com/u/Josue_Cuadras)\
**Post date:** [August 4, 2023, 4:17pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/31 "2023-08-04T16:17:11Z")

</div>

I'm going to check, other than that heres new version fo the code implementing some of the features you showed me:

```auto
def runAction(self, event):

    #If the button is clicked:
    if event.path[0] == 0 and event.path[1] == 6 and event.path[2] == 1 and event.path[3] == 0:

        t_stamp = system.date.now()

        # These are the routes of the tags.
        tags1 = ['[Kenmex]Kenmex/{}/{}'.format(a,b) 
                 for a in ('Axle CV1',
                           'CV 2',
                           'CV 3',
                           'CV5',
                           'CV 6',
                           'CV 7')
                 for b in ('stopcond/Matutino/TEO_TP/TEOTOTALMIN',
                           'stopcond/Matutino/TEO_TP/TPTOTALMIN',
                           'stopcond/Vespertino/TEO_TP/TEOTOTALMIN',
                           'stopcond/Vespertino/TEO_TP/TPTOTALMIN',
                           'stopcond/TEO_TP_TOTALTURNO/TEOTOTALMIN',
                           'stopcond/TEO_TP_TOTALTURNO/TPTOTALMIN')]

        tags2 = ["[Kenmex]Kenmex/Kenmex Monitoreo/Kenmex Monitoreo Totales/TEO_TOTALMIN",
                 "[Kenmex]Kenmex/Kenmex Monitoreo/Kenmex Monitoreo Totales/TP_TOTALMIN",
                 "[Kenmex]Kenmex/CV 6/stopcond/MIN_TIEMPO_MUERTO"]

        tags = tags1 + tags2

        # These are the values of the tags.
        tag_values = [t_stamp] + [qval.value for qval in system.tag.readBlocking(tags)]

        # These are the names of the tags.
        names1 = ['t_stamp'] + ['{}_{}'.format(a, b) 
                              for a in ['CV{}'.format(i) for i in range(1, 8) if i != 4]
                              for b in ('M_TEO', 'M_TP', 'V_TEO', 'V_TP', 'TEO_TOTAL', 'TP_TOTAL')]
                              
        names2 = ["KENMEX_TEO_TOTAL","KENMEX_TP_TOTAL","CV6_TIEMPO_MUERTO"]
        names = names1 + names2

        # This is the combination format between tag names and tag paths to perform an update to the query.
        combine = ', '.join("{} = ?".format(column) for column in names)

        # Commands to update the SQL table.
        update_query = """
            UPDATE assy_kenmex_monitoreo_click
            SET {}
            WHERE assy_kenmex_monitoreo_click_id = ?
        """.format(combine)

        # Value of the ID.
        id_value = 1
        tag_values.append(id_value)

        # Create or generate the report.
        if system.db.runPrepUpdate(update_query, tag_values) > 0:
            data = system.report.executeReport("assy_kenmex/Kenmex Monitoreo/Kenmex Monitoreo_Click", fileType="pdf")
            system.perspective.download("Kenmex Monitoreo_{}.pdf".format(system.date.format(t_stamp, "MM-dd-yy_hh-mm a")), data)

```

---

<div class="post-metadata">

**Author:** ![Josue\_Cuadras](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/josue_cuadras/32/59915_2.png) [@Josue\_Cuadras](https://forum.inductiveautomation.com/u/Josue_Cuadras)\
**Post date:** [August 4, 2023, 4:29pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/32 "2023-08-04T16:29:38Z")

</div>

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 2, in runAction IndexError: index out of range: 3

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [August 4, 2023, 4:39pm UTC](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301/33 "2023-08-04T16:39:50Z")

</div>

Then I suspect you typed `event.path[3]` instead of `event.path[:3]`.  
Slicing like this doesn't raise `IndexError`.

[Previous page](https://forum.inductiveautomation.com/t/delay-between-lines-of-code/77301.md?page=1)
