# URCAP Limitations access feasibility

**URL:** <https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937>\
**Category:** URScript\
**Created:** [August 25, 2025, 8:55am UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937 "2025-08-25T08:55:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![manigandan.g](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@manigandan.g](https://forum.universal-robots.com/u/manigandan.g)\
**Post date:** [August 25, 2025, 8:55am UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/1 "2025-08-25T08:55:32Z")

</div>

We are currently developing a URCap and have encountered some limitations regarding live input status updates on the Java (UI) side of the URCap. As per our understanding:

- URCap has two parts:

- Live input status (e.g., Configurable Digital Inputs) is only accessible inside the robot script using:  
get\_configurable\_digital\_in(x)

- The Java side does not have direct access to this real-time data, which means that input ON/OFF status cannot be shown in the UI by default.

Because of this limitation, we are unable to implement the following features in our URCap screen:

1. Cycle count reading and store those values

2. Display of PCB ON/OFF status

3. Live status message. Clamping / unclamp

4. Clamp done / Unclamp done status to be shown

5. Pause option outside the URCap (since it stops the entire robot program and prevents output control until resumed)

We have tried using the **Realtime Client (port 30003)** as a workaround to fetch live robot data, but this has not shown positive results for our application.

Could you kindly advise us on:

- Whether there is an official or recommended method to fetch and display live input/output status on the URCap UI?

- If **Realtime Client** is not suitable, are there alternative supported approaches (e.g., Secondary Client, XML-RPC, or other communication methods)?

Your guidance will help us move forward with providing a better user experience in our URCap.

Thank you for your time and support. We look forward to your valuable suggestions.

---

<div class="post-metadata">

**Author:** ![dmytro.kharchenko](https://avatars.discourse-cdn.com/v4/letter/d/54ee81/32.png) [@dmytro.kharchenko](https://forum.universal-robots.com/u/dmytro.kharchenko)\
**Post date:** [August 25, 2025, 10:06am UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/2 "2025-08-25T10:06:42Z")

</div>

I never needed it myself, but I would start with

api.getInstallationAPIProvider().getInstallationAPI().getIOModel().getIOs(DigitalIO.class);

digitalIO.getValue();

> **[api 1.12.0 API](https://www.universal-robots.com/apidoc/105569/index.html?com%2Fur%2Furcap%2Fapi%2Fdomain%2Fio%2FIO.html)**

there are workarounds if this does not work

---

<div class="post-metadata">

**Author:** ![manigandan.g](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@manigandan.g](https://forum.universal-robots.com/u/manigandan.g)\
**Post date:** [August 26, 2025, 2:12pm UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/3 "2025-08-26T14:12:24Z")

</div>

we tried it many options, we really want below confirmation.

Could you kindly advise us on:

- Whether there is an official or recommended method to fetch and display live input/output status on the URCap UI?

- If **Realtime Client** is not suitable, are there alternative supported approaches (e.g., Secondary Client, XML-RPC, or other communication methods)?

---

<div class="post-metadata">

**Author:** ![eric.feldmann](https://avatars.discourse-cdn.com/v4/letter/e/94ad74/32.png) [@eric.feldmann](https://forum.universal-robots.com/u/eric.feldmann)\
**Post date:** [August 26, 2025, 7:31pm UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/4 "2025-08-26T19:31:13Z")

</div>

```auto
package com.yourcompany.yourproject;

import java.util.Collection;
import java.util.Iterator;

import com.ur.urcap.api.domain.io.DigitalIO;
import com.ur.urcap.api.domain.io.IO;
import com.ur.urcap.api.domain.io.IOModel;
import com.ur.urcap.api.domain.io.ModbusIO;

/*
 * A library class for getting the IO on the robot
 */

public class IOHelper {

	private final IOModel ioModel;

	public IOHelper(final IOModel ioModel) {
		this.ioModel = ioModel;
	}

	public DigitalIO[] getDigitalInputs() {
		final Collection<DigitalIO> ioCollection = ioModel.getIOs(DigitalIO.class);
		ioCollection.removeIf(n -> !n.isInput());
		final int inputSize = ioCollection.size();
		final Iterator<DigitalIO> itr = ioCollection.iterator();
		final DigitalIO[] inputList = new DigitalIO[inputSize];

		for (int i = 0; i < inputSize; i++) {
			inputList[i] = itr.next();
		}
		return inputList;
	}
	
	
	
	public DigitalIO[] getDigitalOutputs() {
		final Collection<DigitalIO> ioCollection = ioModel.getIOs(DigitalIO.class);
		ioCollection.removeIf(DigitalIO::isInput);
		final int outputSize = ioCollection.size();
		final Iterator<DigitalIO> itr = ioCollection.iterator();
		final DigitalIO[] outputList = new DigitalIO[outputSize];

		for (int i = 0; i < outputSize; i++) {
			outputList[i] = itr.next();
		}
		return outputList;
	}

	public ModbusIO[] getModBusInputs() {
		final Collection<ModbusIO> ioCollection = ioModel.getIOs(ModbusIO.class);
		ioCollection.removeIf(n -> !n.isInput());
		final int inputSize = ioCollection.size();
		final Iterator<ModbusIO> itr = ioCollection.iterator();
		final ModbusIO[] inputList = new ModbusIO[inputSize];

		for (int i = 0; i < inputSize; i++) {
			inputList[i] = itr.next();
		}
		return inputList;
	}

	public ModbusIO[] getModBusOutputs() {
		final Collection<ModbusIO> ioCollection = ioModel.getIOs(ModbusIO.class);
		ioCollection.removeIf(ModbusIO::isInput);
		final int outputSize = ioCollection.size();
		final Iterator<ModbusIO> itr = ioCollection.iterator();
		final ModbusIO[] outputList = new ModbusIO[outputSize];

		for (int i = 0; i < outputSize; i++) {
			outputList[i] = itr.next();
		}
		return outputList;
	}

	public DigitalIO getSpecificDigitalIO(final String defaultName) {
		final Collection<DigitalIO> ioCollection = ioModel.getIOs(DigitalIO.class);
		final int ioCount = ioCollection.size();

		if (ioCount > 0) {
			final Iterator<DigitalIO> ioItr = ioCollection.iterator();
			while (ioItr.hasNext()) {
				final DigitalIO thisIO = ioItr.next();
				final String thisDefaultName = thisIO.getDefaultName();
				if (thisDefaultName.equals(defaultName)) {
					return thisIO;
				}
			}
		}
		return null;
	}
	
	public IO getSpecificGPIO(final String defaultName) {
		final Collection<IO> ioCollection = ioModel.getIOs();
		final int ioCount = ioCollection.size();

		if (ioCount > 0) {
			final Iterator<IO> ioItr = ioCollection.iterator();
			while (ioItr.hasNext()) {
				final IO thisIO = ioItr.next();
				final String thisDefaultName = thisIO.getDefaultName();
				if (thisDefaultName.equals(defaultName)) {
					return thisIO;
				}
			}
		}
		return null;
	}
	
	

	public ModbusIO getSpecificModBusIO(final String signalName) {
		final Collection<ModbusIO> ioCollection = ioModel.getIOs(ModbusIO.class);
		final int ioCount = ioCollection.size();
		if (ioCount > 0) {
			final Iterator<ModbusIO> ioItr = ioCollection.iterator();
			while (ioItr.hasNext()) {
				final ModbusIO thisIO = ioItr.next();
				final String thisSignalAddress = thisIO.getName();
				if (thisSignalAddress.equals(signalName)) {
					return thisIO;
				}
			}
		}
		return null;
	}

}

```

Above is a class I’ve found on the forum…somewhere which allows you to get the digitalIO IN JAVA. You can call .setValue and .getValue to change and read the variable state FROM THE UI.  
Note if you’re trying to read states in realtime, it is on you to employ a thread to call the .getValue() method and take some action accordingly

```auto
//Instantiate an instance of the helper by passing it a reference to the IOModel. This example is from the toolbar.
ioHelper = new IOHelper(context.getAPIProvider().getApplicationAPI().getIOModel());

```

```auto
//Assign digital_out[1] to the java variable "yourOutput". It is of type DigitalIO
yourOutput = ioHelper.getSpecificDigitalIO("digital_out[1]");

```

I reference the below post for which string to feed into the “getSpecificDigitalIO()” method:

> [@How to obtain a list of ALL the IOs on the robot using the URCap Java API](https://forum.universal-robots.com/t/how-to-obtain-a-list-of-all-the-ios-on-the-robot-using-the-urcap-java-api/8075/3):
>
> I created the function below. I could list all IOs into one collection. private ArrayList\<IO\> getAllIOs(URCapAPI api) { IOModel ioModel = api.getInstallationAPIProvider().getInstallationAPI().getIOModel(); Collection\<AnalogIO\> AnalogIOs = ioModel.getIOs(AnalogIO.class); Collection\<DigitalIO\> DigitalIOs = ioModel.getIOs(DigitalIO.class); Collection\<ModbusIO\> ModbusIOs = ioModel.getIOs(ModbusIO.class); Collection\<BooleanRegister\> BooleanRegisters = ioModel.getIOs(Boolea…

---

<div class="post-metadata">

**Author:** ![manigandan.g](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@manigandan.g](https://forum.universal-robots.com/u/manigandan.g)\
**Post date:** [August 28, 2025, 5:39pm UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/5 "2025-08-28T17:39:53Z")

</div>

Thank you. We will check and get back to you.

---

<div class="post-metadata">

**Author:** ![manigandan.g](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@manigandan.g](https://forum.universal-robots.com/u/manigandan.g)\
**Post date:** [September 2, 2025, 12:36pm UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/6 "2025-09-02T12:36:18Z")

</div>

![image](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/4/4731e59f1c4c98b3c7d853f9e5cf41f3b83b1b70.png)

 ![WhatsApp Image 2025-09-02 at 16.26.51_3463412f](https://us1.discourse-cdn.com/flex020/uploads/universal_robots/original/2X/f/fd65c06b44d1acdb78c406d724ffb3bb505a3341.jpeg)

We found the above errors while compile the file from JAVA. Please advise is there any other alternative option or else what we could follow to show the external inputs in the teach pendant display.

---

<div class="post-metadata">

**Author:** ![eric.feldmann](https://avatars.discourse-cdn.com/v4/letter/e/94ad74/32.png) [@eric.feldmann](https://forum.universal-robots.com/u/eric.feldmann)\
**Post date:** [September 2, 2025, 1:52pm UTC](https://forum.universal-robots.com/t/urcap-limitations-access-feasibility/40937/7 "2025-09-02T13:52:08Z")

</div>

It’s telling you right there both what the problem is, and how to fix it. In your Timer.fireActionPerformed() on line 313 you’re either modifying the Program Tree via node insertion/deletion or you’re storing some value to the datamodel. In order to modify the tree or the data model, you have to do so in an UndoRedoManager. You’ll see this everywhere in the URCAP samples. In this case, the error has nothing to do with specifically trying to use the IO

```auto
undoRedoManager.recordChanges(() -> {
    //Your code goes here
});

```

And you should have an instantiation of the undoRedoManager in the constructor of your node:

```auto
UndoRedoManager undoRedoManager = apiProvider.getProgramAPI().getUndoRedoManager();

```

For whatever reason, the Installation Nodes don’t use the UndoRedoManager. Just a little tip that’s tripped me up in the past when I find myself copy/pasting things to/from the Installation
