# Use sendRequest to get project script variable from console

**URL:** <https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012>\
**Category:** Ignition\
**Tags:** ignition81, perspective, scripting\
**Created:** [October 31, 2024, 4:56pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012 "2024-10-31T16:56:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![csjohnson](https://avatars.discourse-cdn.com/v4/letter/c/5f8ce5/32.png) [@csjohnson](https://forum.inductiveautomation.com/u/csjohnson)\
**Post date:** [October 31, 2024, 4:56pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/1 "2024-10-31T16:56:42Z")

</div>

Ignition v8.1.39  
Perspective

The TL;DR  
Is it possible to access the same variable instance as it is defined in an inheritable project top level script from the parent and child designer script console?

I have a dictionary variable `plants` defined in the top level of a project script. It is filled with instances of my own class called `Plant` unconditionally, also in the top level of the script. The project scripts are in an inheritable project, that is inherited by one project.

Access to the `plants` variable is wanted in the script console while in either project designer for testing. If I call `projectScript.getPlant('plantName')`, it does not return the same instance. As I understand it, I cannot access other scopes unless I send a message.  
I created a gateway message handler in the parent project named `getPlant`.  
However, I am unable to get it to work in the parent's or child's script console.  
When I try `sendRequest` from either parent or child's script console, using project name `childProj` the designer disconnects briefly from the gateway, and a popup displays saying `'Waiting For Gateway...'` with exception `No module named Plant`.

```python
# from perspective binding in view on parentProj
# i set the message handler to return projectScript.getPlant
payload = {'plantName': 'Plant1'}
plant = system.util.sendRequest('childProj', 'getPlant', payload = payload)
>>>
<function wrapper at 0x43>

# from parent console
print projectScript.getPlant
>>>
<function wrapper at 0x3>

# from child console
print projectScript.getPlant
>>>
<function wrapper at 0x4>

```

```python
def handleMessage(payload):
# gateway message handler defined in parent project
	plantName = payload.get('plantName')
	if plantName is None:
		plantName = 'Default'

	return projectScript.getPlant(plantName)

```

```python
# defined in parent project script
import threading
lock = threading.Lock()

plants = {}
plantConfigs = {
    'Plant1': {
    'tagProvider': 'p1TagProvider'
    # many other configuration parameters
    }
    'Plant2':{
    'tagProvider': 'p2TagProvider'
    # many other configuration parameters
    }
}

with lock:
    for plantName, plantConfig in plantConfigs.items():
        plant = projectScript.Plant.Plant(name = plantName, config = plantConfig)
      
        # calls system.tag.browse
        machines = projectScript.Tags.getMachineTags(plant.getTagProvider())
        
        for machine in machines:
            machineInst = projectScript.Machine.Machine(name = machine.get('name'), tagProvider = plant.getTagProvider())

        plant.addMachine(machineInst)
        plants.setdefault(plantName, plant)
        

def getPlant(plantName):
	global plants
	return plants.get(plantName)

```

```python
# called from parent/child script console using parentProj name
# fails because inheritable projects cannot execute handler scripts
payload = {'plantName': 'Default'}
plant = system.util.sendRequest('parentProj', 'getPlant', payload = payload)
print plant

[SwingWorker-pool-1-thread-10] ERROR designer.scripting.SystemUtilities -- Error invoking sendRequest from client.
com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Project 'parentProj' is inheritable and cannot execute message handler scripts.

```

```python
# called from parent/child script console
# designer disconnects briefly and gets ImportError: No module named Plant.
payload = {'plantName': 'Default'}
plant = system.util.sendRequest('childProj', 'getPlant', payload = payload)
print plant

10:26:59.668 [DesignerExecEngine-3] WARN com.inductiveautomation.ignition.client.gateway_interface.GatewayConnectionManager -- Connection to Gateway lost, due to exception.
com.inductiveautomation.ignition.client.gateway_interface.GatewayException: ImportError: No module named Plant
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:360)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.getResponse(GatewayInterface.java:556)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.getResponse(GatewayInterface.java:366)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.ping(GatewayInterface.java:1024)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.ping(GatewayInterface.java:1009)
	at com.inductiveautomation.ignition.client.tags.impl.GatewayTagInterface.runPoll(GatewayTagInterface.java:128)
	at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$TrackedTask.run(BasicExecutionEngine.java:593)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: ImportError: No module named Plant
	at org.python.core.Py.ImportError(Py.java:327)
	at org.python.core.imp.import_first(imp.java:1232)
	at org.python.core.imp.import_module_level(imp.java:1363)
	at org.python.core.imp.importName(imp.java:1520)
	at org.python.core.PyType$TypeResolver.readResolve(PyType.java:2674)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at java.base/java.io.ObjectStreamClass.invokeReadResolve(Unknown Source)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.base/java.io.ObjectInputStream$FieldValues.<init>(Unknown Source)
	at java.base/java.io.ObjectInputStream.readSerialData(Unknown Source)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.base/java.io.ObjectInputStream$FieldValues.<init>(Unknown Source)
	at java.base/java.io.ObjectInputStream.readSerialData(Unknown Source)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.base/java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.base/java.io.ObjectInputStream.readObject(Unknown Source)
	at java.base/java.io.ObjectInputStream.readObject(Unknown Source)
	at com.inductiveautomation.ignition.common.Base64.decodeToObjectFragile(Base64.java:985)
	at com.inductiveautomation.ignition.common.Base64.decodeToObjectFragile(Base64.java:959)
	at com.inductiveautomation.ignition.client.gateway_interface.ResponseParser.endElement(ResponseParser.java:165)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.getResponse(GatewayInterface.java:498)
	... 11 common frames omitted
10:26:59.685 [DesignerExecEngine-4] INFO tags.subscriptions -- Changing connected quality to 'Bad_Stale'
10:26:59.685 [DesignerExecEngine-3] INFO Scripting.ScriptManager.childProj -- Pausing scripts...
10:26:59.685 [DesignerExecEngine-3] INFO com.inductiveautomation.ignition.client.gateway_interface.GatewayConnectionManager -- Starting reconnect thread.
10:26:59.785 [GatewayConnection-1] INFO tags.subscriptions -- Changing connected quality to 'Good'
10:26:59.786 [GatewayConnection-1] INFO Scripting.ScriptManager.childProj -- Resuming scripts...
10:26:59.858 [GatewayConnection-1] INFO com.inductiveautomation.ignition.client.gateway_interface.GatewayConnectionManager -- Stopping reconnect thread.
10:27:59.561 [SwingWorker-pool-1-thread-9] ERROR designer.scripting.SystemUtilities -- Error invoking sendRequest from client.
com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Results for asynchronous rpc call were not received within the specified amount of time [60000 ms] for task '16043852-3e0d-4d2b-aeef-ef65212a3138'
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:360)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:330)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:287)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.invoke(GatewayInterface.java:967)
	at com.inductiveautomation.ignition.client.script.DesignerSystemUtilities$SendRequestManager.invokeRequest(DesignerSystemUtilities.java:388)
	at com.inductiveautomation.ignition.client.script.DesignerSystemUtilities.sendRequestInternal(DesignerSystemUtilities.java:217)
	at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.sendRequestInternal(SystemUtilities.java:907)
	at com.inductiveautomation.ignition.common.script.builtin.SystemUtilities.sendRequest(SystemUtilities.java:828)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
	at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:553)
	at org.python.core.PyObject. __call__ (PyObject.java:400)
	at org.python.pycode._pyx172.f$0(<input>:10)
	at org.python.pycode._pyx172.call_function(<input>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1703)
	at org.python.core.Py.exec(Py.java:1747)
	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:277)
	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:130)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:628)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:616)
	at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.desktop/javax.swing.SwingWorker.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.util.concurrent.TimeoutException: Results for asynchronous rpc call were not received within the specified amount of time [60000 ms] for task '16043852-3e0d-4d2b-aeef-ef65212a3138'
	at com.inductiveautomation.ignition.client.util.gui.progress.ClientProgressManager$RunningTask.waitForResult(ClientProgressManager.java:453)
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:314)
	... 29 common frames omitted

```

---

<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:** [October 31, 2024, 5:02pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/2 "2024-10-31T17:02:21Z")

</div>

You cannot send arbitrary objects through Remote Procedure Calls. Certainly not any jython class instances. The designer (and therefore its script console) is a completely different JVM process from the gateway, even when running on the same machine.

---

<div class="post-metadata">

**Author:** ![csjohnson](https://avatars.discourse-cdn.com/v4/letter/c/5f8ce5/32.png) [@csjohnson](https://forum.inductiveautomation.com/u/csjohnson)\
**Post date:** [October 31, 2024, 6:16pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/3 "2024-10-31T18:16:57Z")

</div>

Thanks, Phil.  
So testing in script console will have to be its own instance.

Just for kicks, I changed the message handler and tested it within a perspective binding on a view in the parent. It does return the class instance.

```python
def handleMessage(payload):
	plantName = payload.get('plantName')
	if plantName is None:
		plantName = 'CGV'
    # get value directly from global variable
	return projectScript.plants.get(plantName)

```

```python
def transform(self, value, quality, timestamp):
	payload = {'plantName': 'Plant1'}
	plant = system.util.sendRequest('childProj', 'getPlant', payload = payload)
	return plant.getMachine('Machine1').getLastEvent()

```

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/d/6daf2261afce227ef7f81d4568f4f8ff08c100e7.png)

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/7/3/73690d4c801665e777ac5cf42b3b365146281f1f.png)

---

<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:** [October 31, 2024, 6:23pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/4 "2024-10-31T18:23:24Z")

</div>

> [@csjohnson](#):
>
> So testing in script console

Any testing of scripts intended to be used with Perspective is ill fated. The script console executes its scripts in a modified 'Vision Client Scope' which leads to all kinds of unexpected results.

For testing perspective scripts of any kind you need a way to delegate that execution scope to the gateway.

---

<div class="post-metadata">

**Author:** ![csjohnson](https://avatars.discourse-cdn.com/v4/letter/c/5f8ce5/32.png) [@csjohnson](https://forum.inductiveautomation.com/u/csjohnson)\
**Post date:** [October 31, 2024, 6:50pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/5 "2024-10-31T18:50:52Z")

</div>

Perhaps `system.util.runInGateway`?

---

<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:** [October 31, 2024, 6:51pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/6 "2024-10-31T18:51:54Z")

</div>

Sure, if you have Phil's module, that is the task that decorator was created for (delegating a function to run in Gateway Scope).

However, I would caution you to read the documentation, there are caveats to its use.

---

<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:** [October 31, 2024, 6:54pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/7 "2024-10-31T18:54:18Z")

</div>

My `runInGateway` decorator still does RPC from the designer script console, so is no help for this case.

Test with an event action script on a Perspective button in a test view.

---

<div class="post-metadata">

**Author:** ![csjohnson](https://avatars.discourse-cdn.com/v4/letter/c/5f8ce5/32.png) [@csjohnson](https://forum.inductiveautomation.com/u/csjohnson)\
**Post date:** [October 31, 2024, 7:01pm UTC](https://forum.inductiveautomation.com/t/use-sendrequest-to-get-project-script-variable-from-console/98012/8 "2024-10-31T19:01:41Z")

</div>

Thanks for the guidance, guys.
