# Gateway scripts or expression

**URL:** <https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077>\
**Category:** Ignition\
**Tags:** ignition81, vision\
**Created:** [December 13, 2023, 12:21pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077 "2023-12-13T12:21:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 13, 2023, 12:21pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/1 "2023-12-13T12:21:09Z")

</div>

I just read a forum topic about expressions and got the question when should you use an expression and when a gateway script. I have for example an operator screen in my project that has to show certain information that contains tags and strings. I made it with the use of expression but find it a bit slow when tag values change.  
The information that is displayed by the operator screen is made as follows:

```auto
if ({Root Container.Label.Prompt} = 2,"<html>Huidige dosering:"+" "+ {Root Container.Label.MateriaalNaam}+
"<BR>Setpunt is" +" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+ 
"<BR>Actual is"+" "+ {Root Container.Label.actual} + {Root Container.Label.engunit}+ 
"<BR>Tolerantie - / + :" +" "+ {Root Container.Label.tolMin}+"/"+{Root Container.Label.tolPlus}+{Root Container.Label.engunit},

if ({Root Container.Label.Prompt} = 3, "<html>Recept totaal is groter dan de maximale inhoud van de tank."+
"<BR>Maximale inhoud is"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+
"<BR>Recept grote is"+" "+ {Root Container.Label.actual} + {Root Container.Label.engunit},

if ({Root Container.Label.Prompt} = 4, "<html>Tank is momenteel vervuild."+
"<BR>Deze moet eerst gereinigd worden en dit moet bevestigd worden"+
"<BR>voordat we teruggaan naar standby.",

if ({Root Container.Label.Prompt} =5, "<html>Tappunt is momenteel vervuild."+
"<BR>Deze moet eerst gereinigd worden en dit moet bevestigd worden"+
"<BR>voordat we teruggaan naar standby.",

if ({Root Container.Label.Prompt} =6, "<html>Recept in tappunt bunker komt niet overeen"+
"<BR>met receptnummer in voordeegtank.",

if ({Root Container.Label.Prompt} =7, "<html>Temperatuur is niet gehaald binnen de ingestelde tijd!"+
"<BR>Setpunt is"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+ 
"<BR>Process waarde is"+" "+{Root Container.Label.actual}+ {Root Container.Label.engunit},

if ({Root Container.Label.Prompt} =8, "<html>Voeg schoonmaak componenten toe!"+
"<BR>Druk hierna op bevestigen",

if ({Root Container.Label.Prompt} =9, "<html>RunID:"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+  
" "+"BatchID:"+" "+{Root Container.Label.actual}+ {Root Container.Label.engunit}+  
" "+"Productnummer:"+" "+{[Test SCADA Ignition]Action/Action0/hmi/materialCode}+ {Root Container.Label.engunit}+
"<BR>Productnaam:"+
"<BR>Reden : ",

if ({Root Container.Label.Prompt} =10, "<html>RunID:"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+  
"<BR>Productnummer:"+" "+{[Test SCADA Ignition]Action/Action0/hmi/materialCode}+ {Root Container.Label.engunit}+
"<BR>Productnaam: ",
if ({Root Container.Label.Prompt} =11, "<html>Plaats een lege kuip onder het tappunt en bevestig dit erna.",
if ({Root Container.Label.Prompt} =12,	"<html>Batch is gereed verwijder kuip onder tappunt en"+
"<BR>plaats deze in een menger bevestig dit erna!",
if ({Root Container.Label.Prompt} =13,	"<html>Is het deksel van de aanmaaktank goed gesloten?"+
"<BR>Draai deze stevig vast en bevestig dit!",
if ({Root Container.Label.Prompt} =14,	"<html>Wil je de weegbunker in de koelcel meespoelen?"+
"<BR>Dit betekent dat het resterende voordeeg eruit wordt getapt!",
if ({Root Container.Label.Prompt} =15,	"<html>Voeg" +" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+" "+ "van<BR>"+
{Root Container.Label.MateriaalNaam}+" "+ "toe.",
if ({Root Container.Label.Prompt} =16, "<html>Plaats een lege bak op de weegschaal en bevestig dit",
if ({Root Container.Label.Prompt} =17,	"<html>Voeg"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+"van"+
"toe."+
"<BR>Gedoseerd :"+" "+{Root Container.Label.actual}+ {Root Container.Label.engunit},   
if ({Root Container.Label.Prompt} =18, "<html>Leeg de bak met componenten in de kuip.",
if ({Root Container.Label.Prompt} =19,	"<html>Leeg de bak met componenten in de aanmaaktank."+
"<BR>Bevestig dit hierna.",
if ({Root Container.Label.Prompt} =20,	"<html>Plaats lege kuip/bak onder de afvoer van de AMT."+
"<BR>Bevestig dit! Hierna zal de aanmaaktank beginnen met lossen!",
if ({Root Container.Label.Prompt} =21,	"<html>Gevraagde materiaalcode komt niet overeen met aanwezig product."+
"<BR>Voordeegbunker :"+" "+{Root Container.Label.actual}+ "/Gevraagd :"+" "+{Root Container.Label.setpoint}, 
if ({Root Container.Label.Prompt} =22,	"<html>Plaats bak onder stofafzuiging en laat het deksel zakken."+
"<BR>Deze melding verdwijnt automatisch.",
if ({Root Container.Label.Prompt} =23,	"<html>Stofafzuiging is niet ingeschakeld of heeft storing."+
"<BR>Klik op bevestigen om door te gaan zonder stofafzuiging.",
if ({Root Container.Label.Prompt} =24,	"<html>Controleer gist voorraad!"+
"<BR>Melder ziet geen product!"+
"<BR>Deze melding verdwijnt automatisch.",
if ({Root Container.Label.Prompt} =25, "<html>Geen voordeeg gereed voor productie!",
if ({Root Container.Label.Prompt} =26,	"<html>Sluit 1 zijde van de slang aan op het tappunt bij"+
"<BR>de voordeeg uitvoer en de andere kant op het riool."+
"<BR>Bevestig dit als het aangesloten is!",
if ({Root Container.Label.Prompt} =27,	"<html>Seal lekkage bij dispergeerpomp gedetecteerd!"+
"<BR>Controleer seal spoeling!",
if ({Root Container.Label.Prompt} =28,	"<html>laagniveau sensor laag."+
"<BR>Nogmaals wankelen of leegmelden?",
if ({Root Container.Label.Prompt} =29,	"<html>Lossen naar afvalbak is actief!"+
"<BR>Druk de drukknop bij de bak in om de klep te openen."+
"<BR>Let op! Zolang als deze melding hier actief is"+
"<BR>kan het riool niet gebruikt worden!",
if ({Root Container.Label.Prompt} =30,	"<html>Bevestig het schoonmaak koppelstuk"+
"<BR>om de menger te reinigen",
if ({Root Container.Label.Prompt} =59, "<html>Plaats een slang van gistaansluiting naar riool en bevestig dit.",
if ({Root Container.Label.Prompt} =60, "<html>Verwijder de slang tussen gistaansluiting en riool en bevestig dit."+
"<BR>Let op! Na bevestigen draait het carrousel automatisch.",
if ({Root Container.Label.Prompt} =200, "<html>Deeg temperatuur is te laag."+
"<BR>Gewenste temperatuur :"+{Root Container.Label.setpoint} +"°C"+
"<BR>Actuele temperatuur :"+ {Root Container.Label.actual} +"°C",
if ({Root Container.Label.Prompt} =207, "<html>Carrousel kan niet veilig draaien door"+ {Root Container.Label.L4_ID_Unit}+
"<BR>Controleer dat de tangen open staan.",
if ({Root Container.Label.Prompt} =205, "<html>Kuip in hefkieper bevat laatste batch van recept"+"<BR>Graag bevestigen dat hefkieper is schoongemaakt.",
if ({Root Container.Label.Prompt} =183, "<html>Het caroussel kan niet veilig draaien doordat de kop of klemming van kneder 1 niet veilig open staat. Controleer de positiesensoren van kneder 1.","")))))))))))))))))))))))))))))))))))

```

The prompt parameter here is different based on the tag value of 'operatorIndex'  
I made it in such a way that the operatorindex is passed into a tag path of the prompt tag. the prompt tags are different in the name based on a value like so:

```auto
[Test SCADA Ignition]Action/Action1/hmi/prompt

```

this is one of the prompt tag tag paths. There are more of these tags but with a different number then 1. It also could point to:

```auto
[Test SCADA Ignition]Action/Action4/hmi/prompt

```

So I made it like this:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/7/f7cedc215308ce323e237f712b8237334140f867.png)

But now my question. Is it better to make this in a gateway script so that my project stays quicker or is it not that bad to leave it like this.  
Like I said at the beginning, If operatorIndex changes it changes the prompt value and the text that it displays, but there is a delay for like a second or two.

Is it better to make gateway scripts overall instead of expressions? and what are great examples of when you use a gateway script and when an expression.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [December 13, 2023, 12:35pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/2 "2023-12-13T12:35:02Z")

</div>

Vau... how many ifs are there... 🤪

Why not use the [case](https://docs.inductiveautomation.com/display/DOC81/case) instead?

---

<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:** [December 13, 2023, 12:36pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/4 "2023-12-13T12:36:48Z")

</div>

> [@Stef\_Velers](#):
>
> that doesn't work

[https://docs.inductiveautomation.com/display/DOC81/case](https://docs.inductiveautomation.com/display/DOC81/case)

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 13, 2023, 12:38pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/5 "2023-12-13T12:38:19Z")

</div>

But before I try to change everything isn't it better to find a way in gateway script?  
or is case already much more sufficient?

---

<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:** [December 13, 2023, 12:48pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/6 "2023-12-13T12:48:55Z")

</div>

Short version, if you can use an expression you absolutely should.

Slightly longer version:

If the result is non-specific to the client and/or should be executed independent of running clients, then you can use a gateway script.

If the result is client specific, the operation must be executed in a client scope, in that case a properly structured (maybe even an improperly structured one) will always be more performant.

If the result does not need to be executed independent of running clients then a gateway script might not be the correct tool for the job.

In this case it appears that the result is client specific so it must be executed per client. So, I think you'll find that an expression is much more performant.

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 13, 2023, 12:54pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/7 "2023-12-13T12:54:07Z")

</div>

Okay, thanks for your answer!!

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 13, 2023, 12:59pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/8 "2023-12-13T12:59:28Z")

</div>

> **The \`case()\` version.**
>
> ```auto
> case {Root Container.Label.Prompt},
> 2,"<html>Huidige dosering:"+" "+ {Root Container.Label.MateriaalNaam}+
> "<BR>Setpunt is" +" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+ 
> "<BR>Actual is"+" "+ {Root Container.Label.actual} + {Root Container.Label.engunit}+ 
> "<BR>Tolerantie - / + :" +" "+ {Root Container.Label.tolMin}+"/"+{Root Container.Label.tolPlus}+{Root Container.Label.engunit},
> 3, "<html>Recept totaal is groter dan de maximale inhoud van de tank."+
> "<BR>Maximale inhoud is"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+
> "<BR>Recept grote is"+" "+ {Root Container.Label.actual} + {Root Container.Label.engunit},
> 4, "<html>Tank is momenteel vervuild."+
> "<BR>Deze moet eerst gereinigd worden en dit moet bevestigd worden"+
> "<BR>voordat we teruggaan naar standby.",
> 5, "<html>Tappunt is momenteel vervuild."+
> "<BR>Deze moet eerst gereinigd worden en dit moet bevestigd worden"+
> "<BR>voordat we teruggaan naar standby.",
> 6, "<html>Recept in tappunt bunker komt niet overeen"+
> "<BR>met receptnummer in voordeegtank.",
> 7, "<html>Temperatuur is niet gehaald binnen de ingestelde tijd!"+
> "<BR>Setpunt is"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+ 
> "<BR>Process waarde is"+" "+{Root Container.Label.actual}+ {Root Container.Label.engunit},
> 8, "<html>Voeg schoonmaak componenten toe!"+
> "<BR>Druk hierna op bevestigen",
> 9, "<html>RunID:"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+  
> " "+"BatchID:"+" "+{Root Container.Label.actual}+ {Root Container.Label.engunit}+  
> " "+"Productnummer:"+" "+{[Test SCADA Ignition]Action/Action0/hmi/materialCode}+ {Root Container.Label.engunit}+
> "<BR>Productnaam:"+
> "<BR>Reden : ",
> 10, "<html>RunID:"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+  
> "<BR>Productnummer:"+" "+{[Test SCADA Ignition]Action/Action0/hmi/materialCode}+ {Root Container.Label.engunit}+
> "<BR>Productnaam: ",
> 11, "<html>Plaats een lege kuip onder het tappunt en bevestig dit erna.",
> 12,	"<html>Batch is gereed verwijder kuip onder tappunt en"+
> "<BR>plaats deze in een menger bevestig dit erna!",
> 13,	"<html>Is het deksel van de aanmaaktank goed gesloten?"+
> "<BR>Draai deze stevig vast en bevestig dit!",
> 14,	"<html>Wil je de weegbunker in de koelcel meespoelen?"+
> "<BR>Dit betekent dat het resterende voordeeg eruit wordt getapt!",
> 15,	"<html>Voeg" +" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+" "+ "van<BR>"+
> {Root Container.Label.MateriaalNaam}+" "+ "toe.",
> 16, "<html>Plaats een lege bak op de weegschaal en bevestig dit",
> 17,	"<html>Voeg"+" "+{Root Container.Label.setpoint}+ {Root Container.Label.engunit}+"van"+
> "toe."+
> "<BR>Gedoseerd :"+" "+{Root Container.Label.actual}+ {Root Container.Label.engunit},   
> 18, "<html>Leeg de bak met componenten in de kuip.",
> 19,	"<html>Leeg de bak met componenten in de aanmaaktank."+
> "<BR>Bevestig dit hierna.",
> 20,	"<html>Plaats lege kuip/bak onder de afvoer van de AMT."+
> "<BR>Bevestig dit! Hierna zal de aanmaaktank beginnen met lossen!",
> 21,	"<html>Gevraagde materiaalcode komt niet overeen met aanwezig product."+
> "<BR>Voordeegbunker :"+" "+{Root Container.Label.actual}+ "/Gevraagd :"+" "+{Root Container.Label.setpoint}, 
> 22,	"<html>Plaats bak onder stofafzuiging en laat het deksel zakken."+
> "<BR>Deze melding verdwijnt automatisch.",
> 23,	"<html>Stofafzuiging is niet ingeschakeld of heeft storing."+
> "<BR>Klik op bevestigen om door te gaan zonder stofafzuiging.",
> 24,	"<html>Controleer gist voorraad!"+
> "<BR>Melder ziet geen product!"+
> "<BR>Deze melding verdwijnt automatisch.",
> 25, "<html>Geen voordeeg gereed voor productie!",
> 26,	"<html>Sluit 1 zijde van de slang aan op het tappunt bij"+
> "<BR>de voordeeg uitvoer en de andere kant op het riool."+
> "<BR>Bevestig dit als het aangesloten is!",
> 27,	"<html>Seal lekkage bij dispergeerpomp gedetecteerd!"+
> "<BR>Controleer seal spoeling!",
> 28,	"<html>laagniveau sensor laag."+
> "<BR>Nogmaals wankelen of leegmelden?",
> 29,	"<html>Lossen naar afvalbak is actief!"+
> "<BR>Druk de drukknop bij de bak in om de klep te openen."+
> "<BR>Let op! Zolang als deze melding hier actief is"+
> "<BR>kan het riool niet gebruikt worden!",
> 30,	"<html>Bevestig het schoonmaak koppelstuk"+
> "<BR>om de menger te reinigen",
> 59, "<html>Plaats een slang van gistaansluiting naar riool en bevestig dit.",
> 60, "<html>Verwijder de slang tussen gistaansluiting en riool en bevestig dit."+
> "<BR>Let op! Na bevestigen draait het carrousel automatisch.",
> 200, "<html>Deeg temperatuur is te laag."+
> "<BR>Gewenste temperatuur :"+{Root Container.Label.setpoint} +"°C"+
> "<BR>Actuele temperatuur :"+ {Root Container.Label.actual} +"°C",
> 207, "<html>Carrousel kan niet veilig draaien door"+ {Root Container.Label.L4_ID_Unit}+
> "<BR>Controleer dat de tangen open staan.",
> 205, "<html>Kuip in hefkieper bevat laatste batch van recept"+"<BR>Graag bevestigen dat hefkieper is schoongemaakt.",
> 183, "<html>Het caroussel kan niet veilig draaien doordat de kop of klemming van kneder 1 niet veilig open staat. Controleer de positiesensoren van kneder 1."
> )
> 
> ```

The speed advantage will be checking `{Root Container.Label.Prompt}` just once and jumping straight to the relevant line. Your nested if check over and over until it finds a match - or doesn't!

Oh - and it is readable!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [December 13, 2023, 1:08pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/9 "2023-12-13T13:08:01Z")

</div>

Pssst! Use [lookup()](https://docs.inductiveautomation.com/display/DOC81/lookup) with a constant dataset of value-string combinations tucked away in a memory tag.

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 13, 2023, 1:24pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/10 "2023-12-13T13:24:53Z")

</div>

you're saying that instead of the strings typed in the expression and added the tag values after them, put them into a dataset? But how can I set tag paths or parameters in the a dataset with strings in it?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 13, 2023, 1:37pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/11 "2023-12-13T13:37:45Z")

</div>

> [@pturmel](#):
>
> with a **constant** dataset

You can't with your dynamic HTML.

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 13, 2023, 1:40pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/12 "2023-12-13T13:40:26Z")

</div>

and there is no work around? or maybe just without html

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [December 13, 2023, 1:53pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/13 "2023-12-13T13:53:23Z")

</div>

Ah, that's a little more tricky.  
Provide the dataset with strings that have `printf`-style placeholders with numbered arguments. Wrap the `lookup()` inside of `stringFormat()`, and provide all possible arguments to `stringFormat()`. It would look something like this:

```auto
stringFormat(
	lookup(
		{Root Container.Label.strings},
		{Root Container.Label.Prompt},
		"<html>Unknown Prompt Code!",
		'Prompt',
		'Pattern'
	),
	{Root Container.Label.setpoint},
	{Root Container.Label.actual},
	{Root Container.Label.engunit}
)

```

The dataset I tested had this content:

```auto
"#NAMES"
"Prompt","Pattern"
"#TYPES"
"I","str"
"#ROWS","2"
"7","<html>Temperatuur is niet gehaald binnen de ingestelde tijd!<BR>Setpunt is %1$.1f%3$s<BR>Process waarde is %2$.1f%3$s"
"8","<html>Dummy"

```

Prompt #7 looked like this:  
 ![stringFormat-Numbered-Placeholders](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/6/26f493d9605404a5ff60f164bb21cc3033bf36a6.png)

The numbered placeholders work because Ignition's `stringFormat()` is a thin wrapper around Java's [String.format()](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#format(java.lang.String,java.lang.Object...)) method, which delegates the hard work to java's [Formatter](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Formatter.html) class.

If you need any other arguments, simply include them, and reference them by number. Unused arguments will be ignored. Since you reference them by number, you do not need to use them in the string in the order provided, and can use them multiple times.

(For testing, I just put the dataset in a custom property. In production, I'd use a Vision Client Tag, and I'd arrange for the strings to be swapped in that client tag based on the client's chosen runtime language.)

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 13, 2023, 2:20pm UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/14 "2023-12-13T14:20:17Z")

</div>

Okay thanks, I will try your suggestion and see if I can make it work.

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 14, 2023, 7:46am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/16 "2023-12-14T07:46:24Z")

</div>

nevermind I found what the problem was

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 14, 2023, 9:58am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/17 "2023-12-14T09:58:19Z")

</div>

Thanks Pturmel!! It works!! This is exactly like I want it to be.

There is one thing though, maybe someone knows a solution to it.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/6/a6139d69ce1027af2a02500ee72520414eed665a.png)  
The picture above is my operator screen and the buttons on the side make it possible to see the other alarm in the operator screen. I made this with the following script for the buttons:

```auto
def find_activeAlarm_tags():
        # Initialize an empty list to store matching tag paths
        Alarm_tags = []
    
        # Define the range of tag names
        for i in range(24):
            action_tag = "Action" + str(i)
    
            # Create a tag path for the current tag
            tag_path = "[Test SCADA Ignition]Action/{}/hmi/prompt".format(action_tag)
            tag_Nrpath = "[Test SCADA Ignition]Action/{}/obj/nr".format(action_tag)
    
            # Get the tag value
            tag_values = system.tag.readBlocking([tag_path])
            tag_Nr = system.tag.readBlocking([tag_Nrpath])
    
            # Check if the prompt value is greater than 0
            if tag_values[0].value > 0:
                # Add the tag path to the list if the condition is met
                Alarm_tags.append(tag_Nr)
    
        # Return the list of matching tag paths
        
        return Alarm_tags

```

This script simply searches through my Prompt tags and filters the ones that are higher then 0 ( The alarms that are on). But when I press the button it has a delay for like 2 seconds before my other alarm information is being displayed on my operator screen.

If it is not clear what I mean I can try to explane better but If it is clear, maybe someone know a solution to make it react quicker?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 14, 2023, 10:23am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/18 "2023-12-14T10:23:06Z")

</div>

You have 48 `readBlocking` events in that script.

This has two.

```auto
def find_activeAlarm_tags():
    # Initialize an empty list to store matching tag paths
    tagPaths = []
    tagNrPaths = []
    Alarm_tags = []

    # Define the range of tag names
    for i in range(24):
        action_tag = "Action" + str(i)
        # Create a tag path for the current tag
        tagPaths.append("[Test SCADA Ignition]Action/{}/hmi/prompt".format(action_tag))
        tagNrPaths.append("[Test SCADA Ignition]Action/{}/obj/nr".format(action_tag)
    
    # Get the tag values
    tag_values = system.tag.readBlocking(tagPaths)
    tag_Nrs = system.tag.readBlocking(tagNrPaths)

    for i in range(24):
        # Check if the prompt value is greater than 0
        if tag_values[i].value:
            # Add the tag path to the list if the condition is met
            Alarm_tags.append(i)

    # Return the list of matching tag paths
    return Alarm_tags

```

See if that makes a difference.  
Then see if you can reduce it to one `readBlocking`.

* * *

Tip: you have three different font sizes and two different styles (normal and bold) on that screenshot as well as buttons breaking into the text area. It is not nice and visually very distracting! Have a look at some visual style guides to get some ideas for better layout.

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 14, 2023, 10:53am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/19 "2023-12-14T10:53:40Z")

</div>

It give me a error saying that the following

```auto
Traceback (most recent call last):
  File "<event:actionPerformed>", line 1, in <module>
  File "<module:find_activeAlarm_tags>", line 16, in find_activeAlarm_tags
TypeError: expected a str

```

---

<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:** [December 14, 2023, 10:56am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/20 "2023-12-14T10:56:11Z")

</div>

> [@Transistor](#):
>
> ```auto
> tag_Nrs = system.tag.readBlocking([tagNrPaths])
> 
> ```

I believe this should be `system.tag.readBlocking(tagNrPaths)`.

Single read version:

```python
from itertools import chain

tags_paths = list(chain.from_iterable(
	(
		"[Test SCADA Ignition]Action/Action{}/hmi/prompt".format(n),
		"[Test SCADA Ignition]Action/Action{}/obj/nr".format(n)
	) for n in xrange(24)
))

qvals = system.tag.readBlocking(tags_paths)
tags_values = [qval for qval in qvals[::2]]
tags_nrs = [qval for qval in qvals[1::2]]

return [nr for val, nr in zip(tags_values, tags_nrs) if val > 0]

```

Could be made more unreadable with some chunking if you're interested in making ennemies.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [December 14, 2023, 11:02am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/21 "2023-12-14T11:02:38Z")

</div>

> [@pascal.fragnoud](#):
>
> I believe this should be `system.tag.readBlocking(tagNrPaths)`.

Correct, and fixed. Thanks.

@Stef_Velers, my original script failed because I had created a list of tags, `["tag1", "tag2", ...]` and then enclosed that in `[]` which made it into `[["tag1", "tag2", ...]]` (which won't work).

---

<div class="post-metadata">

**Author:** ![Stef\_Velers](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@Stef\_Velers](https://forum.inductiveautomation.com/u/Stef_Velers)\
**Post date:** [December 14, 2023, 11:13am UTC](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077/22 "2023-12-14T11:13:20Z")

</div>

correct I saw that.  
But the script returns nothing sad enough. Not sure why cause it looks right to me. But I'm not a coding expert 🙂

[Next page](https://forum.inductiveautomation.com/t/gateway-scripts-or-expression/83077.md?page=2)
