# Function Working in Script Console and Not in Gateway Event Console

**URL:** <https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089>\
**Category:** Ignition\
**Tags:** scripting, perspective\
**Created:** [August 23, 2024, 4:23pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089 "2024-08-23T16:23:36Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![VerminProgrammer](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/verminprogrammer/32/65954_2.png) [@VerminProgrammer](https://forum.inductiveautomation.com/u/VerminProgrammer)\
**Post date:** [August 23, 2024, 4:23pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/1 "2024-08-23T16:23:36Z")

</div>

Title pretty much as follows. The code is as follows:

```python
vfds = ["Pmp1","Pmp2","Pmp3"]

# Define the paths to the run hours memory tags for each VFD
run_hour_tags = ["[default]Simulation/Index Test/Pmp{}".format(i+1) for i in range(3)]

# Define the paths to the index tags for each VFD (these should store the index values)
index_tags = ["[default]Simulation/Index Test/Pmp{}Index".format(i+1) for i in range(3)]

# Function to retrieve run hours for each VFD
def get_vfd_run_hours():
    run_hours = {}
    
    for i, vfd in enumerate(vfds):
        # Read the run hours from the tag
	    run_hours_value = system.tag.readBlocking([run_hour_tags[i]])[0].value
	    run_hours[vfd] = run_hours_value
    
    return run_hours

# Function to assign VFDs to unique indices based on their run hours
def assign_vfd_indices():
    # Get run hours for all VFDs
    run_hours = get_vfd_run_hours()

    # Sort the VFDs by their run hours in descending order (most run hours last)
    sorted_vfds = sorted(run_hours.keys(), key=lambda vfd: run_hours[vfd], reverse=False)

    # Assign indices, starting at 1
    vfd_indices = {}
    for index, vfd in enumerate(sorted_vfds, start=1):
        vfd_indices[vfd] = index
    
    return vfd_indices

def write_vfd_indices_to_tags(vfd_indices):
    for i, vfd in enumerate(vfds):
        # Get the index for the current VFD
        index_value = vfd_indices.get(vfd)
        
        # Write the index value to the corresponding index tag
        system.tag.writeBlocking([index_tags[i]], [index_value])

# Print the indices for each VFD 
for vfd, index in vfd_indices.items():
   print({vfd},"is assigned to index", {index})

# Example usage
vfd_indices = assign_vfd_indices()

# Write the indices to the index tags
write_vfd_indices_to_tags(vfd_indices)

```

And I get the following error:

```python
Traceback (most recent call last):
  File "<TimerScript:APLD/Index @5,000ms >", line 47, in <module>
NameError: name 'vfd_indices' is not defined

8.1.42 (b2024061810)
Azul Systems, Inc. 17.0.11

```

But this script works in the script console, but not in the gateway. I'm unsure of what the problem and the difference are? Same exact copy and paste between gateway and console. And yes I plan to when the gateway script works I will flush it out to the project library and just call on the functions 🙂

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [August 23, 2024, 4:28pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/2 "2024-08-23T16:28:21Z")

</div>

It looks like you are referencing vfd\_indices:

`for vfd, index in vfd_indices.items():`

before declaring it:

`vfd_indices = assign_vfd_indices()`

so I wouldn't expect this to work in either context.

---

<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:** [August 23, 2024, 4:54pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/3 "2024-08-23T16:54:04Z")

</div>

Many `system.*` functions work differently, or require different arguments, based on what scope they are called from.

The Designer Script Console is a derivative of Vision Scope, while Perspective events run in a derivative of Gateway Project Scope. Look at the documentation for differences in the functions you use.

(The designer script console is almost never the right tool for testing Perspective scripts. It **is** the right tool for testing Vision scripts.)

---

<div class="post-metadata">

**Author:** ![VerminProgrammer](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/verminprogrammer/32/65954_2.png) [@VerminProgrammer](https://forum.inductiveautomation.com/u/VerminProgrammer)\
**Post date:** [August 23, 2024, 5:33pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/4 "2024-08-23T17:33:26Z")

</div>

I suppose I didn't know the difference between the two. Would you have any suggestions for this code then? I am running into a writer's block here

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [August 23, 2024, 5:42pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/5 "2024-08-23T17:42:19Z")

</div>

I think you need to indent properly:

```python
def write_vfd_indices_to_tags(vfd_indices):
	for i, vfd in enumerate(vfds):
		# Get the index for the current VFD
		index_value = vfd_indices.get(vfd)

		# Write the index value to the corresponding index tag
		system.tag.writeBlocking([index_tags[i]], [index_value])

	# Print the indices for each VFD 
	for vfd, index in vfd_indices.items():
		print({vfd},"is assigned to index", {index})

```

When I copied your code it was all spaces, not tabs...

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [August 23, 2024, 5:52pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/6 "2024-08-23T17:52:26Z")

</div>

Spaces for indentation is ok, you just can't mix tab indents with space indents.

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [August 23, 2024, 5:56pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/7 "2024-08-23T17:56:31Z")

</div>

Really? So does one space equal one tab when Python measures indentation?

Either way, there's no space before:

```python
for vfd, index in vfd_indices.items():

```

so it's evaluating before `vfd_indices` gets declared.

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [August 23, 2024, 6:00pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/8 "2024-08-23T18:00:35Z")

</div>

The 'pythonic way' (per PEP8, if anyone wants to read it) is to indent with four spaces.

I always just use a single tab

But what you cannot do is indent 4 spaces on one line and use a tab on the next.

Whichever you decide to use, make it a habit to always use the same thing. 😉

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [August 23, 2024, 6:12pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/9 "2024-08-23T18:12:57Z")

</div>

That said, you are right in that the print loop is in the wrong spot. Probably the assign\_vfd\_indices() function is the best place for it.

The reason it probably worked in the Script Console is that it does not clear values every time you run the script.

---

<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 23, 2024, 8:50pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/10 "2024-08-23T20:50:04Z")

</div>

You sort of can, for different scopes. But maybe we shouldn't be telling people this.

So, it's been a while since I've refactored something, and that first post kinda awakened the itch. I believe this should do the same thing, assuming I understood what's going on.

```python
from operator import itemgetter

vfds = ["Pmp1", "Pmp2", "Pmp3"]
run_hours_tags = ["[default]Simulation/Index Test/{}".format(vfd) for vfd in vfds]

vfds = sorted(
	(
		{
			'name': vfd,
			'hours': qval.value
		} for vfd, qval in zip(vfds, system.tag.readBlocking(run_hours_tags))
	),
	key = itemgetter('hours')
)

index_tags = ["[default]Simulation/Index Test/{}Index".format(vfd['name']) for vfd in vfds]
system.tag.writeBlocking(index_tags, range(1, len(vfds)+1))

```

Side note:

> [@VerminProgrammer](#):
>
> ```python
> print({vfd},"is assigned to index", {index})
> 
> ```

`{}` in python means `set` or `dict`, depending on what you put inside. here are some examples of how you could print that instead:

```python
print (vfd, "is assigned to index", index)
print "{} is assigned to {}".format(vfd, index)
print "{vfd} is assigned to {index}".format(vfd=vfd, index=index)
print vfd + " is assigned to " + index
print "%s is assigned to %d" % (vfd, index)

```

Side note 2:  
I'd recommend not putting spaces in your tags names. Stick to valid python identifiers, basically alphanumerical values + underscores.  
I'd even push it to anything that's not meant for the eye of your application's users: view names, components, db columns, everything.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [August 25, 2024, 3:50pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/11 "2024-08-25T15:50:35Z")

</div>

> [@JordanCClark](#):
>
> it does not clear values every time you run the script.

This quirk of the script console has caused headaches for me on more than one occasion.

---

<div class="post-metadata">

**Author:** ![VerminProgrammer](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/verminprogrammer/32/65954_2.png) [@VerminProgrammer](https://forum.inductiveautomation.com/u/VerminProgrammer)\
**Post date:** [August 26, 2024, 12:28pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/12 "2024-08-26T12:28:42Z")

</div>

I really appreciate everyone's input here. It looks like @pascal.fragnoud's genius is yet again unmatched and it works right out of the gate. I am taking scrupulous notes on your work from now on haha.

I was hoping the script console was going to be more useful for troubleshooting scripts so I wouldn't have to make edits to a script, then save, then wait for the script to run, then see if it fails and repeat as needed. Unless there is a way to clear values? But then it still doesn't have the same scope as a gateway event, right?

---

<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 26, 2024, 12:33pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/13 "2024-08-26T12:33:23Z")

</div>

> [@VerminProgrammer](#):
>
> Unless there is a way to clear values?

There is, on the right of the script console:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/3/f3e830aa9177986b78dc59fe1667dbc326eca28e.png)

> [@VerminProgrammer](#):
>
> But then it still doesn't have the same scope as a gateway event, right?

Nope, but nothing in this script uses "scope restricted" functions.  
When you run into something that does have different behavior for different scopes, you can put the script in your library and call it from a button or something in your browser.  
Use `system.perspective.print` to print to the dev tools console.

Or I believe you can call that script from a gateway event message handler, and send a message with `system.util.sendMessage` from the script console.

---

<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:** [August 26, 2024, 12:35pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/14 "2024-08-26T12:35:33Z")

</div>

> [@pascal.fragnoud](#):
>
> Or I believe you can call that script from a gateway event message handler, and send a message with `system.util.sendMessage` from the script console.

_Pssst!_

Or use my Integration Toolkit's [@system.util.runInGateway](https://www.automation-pros.com/toolkit/doc/utility.html#runingateway) decorator. 😁

---

<div class="post-metadata">

**Author:** ![VerminProgrammer](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/verminprogrammer/32/65954_2.png) [@VerminProgrammer](https://forum.inductiveautomation.com/u/VerminProgrammer)\
**Post date:** [August 26, 2024, 1:09pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/15 "2024-08-26T13:09:31Z")

</div>

> [@pascal.fragnoud](#):
>
> There is, on the right of the script console:  
> ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/3/f3e830aa9177986b78dc59fe1667dbc326eca28e.png)

I didn't think that button actually reset the values as well I figured it only reset the output screen or right side results for some reason. I suppose it still sort of makes sense my script above didn't work because it wasn't getting the proper defining it needed. I think I need to rewatch the python course again or find new material.

> [@pturmel](#):
>
> _Pssst!_
> 
> Or use my Integration Toolkit's [@system.util.runInGateway](https://www.automation-pros.com/toolkit/doc/utility.html#runingateway) decorator.

I'm gonna bring this up to my team they have been looking for some things like what's mentioned on the site there. Thanks!

---

<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 26, 2024, 1:16pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/16 "2024-08-26T13:16:30Z")

</div>

The eraser button clears the screen, the reset button... resets the whole interpreter.

---

<div class="post-metadata">

**Author:** ![VerminProgrammer](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/verminprogrammer/32/65954_2.png) [@VerminProgrammer](https://forum.inductiveautomation.com/u/VerminProgrammer)\
**Post date:** [August 26, 2024, 1:18pm UTC](https://forum.inductiveautomation.com/t/function-working-in-script-console-and-not-in-gateway-event-console/95089/17 "2024-08-26T13:18:56Z")

</div>

I suppose some things should be obvious lol
