# Best practice for modifying the value of an OPC tag

**URL:** <https://forum.inductiveautomation.com/t/best-practice-for-modifying-the-value-of-an-opc-tag/108661>\
**Category:** Ignition\
**Created:** [July 18, 2025, 10:22am UTC](https://forum.inductiveautomation.com/t/best-practice-for-modifying-the-value-of-an-opc-tag/108661 "2025-07-18T10:22:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![karl.fredrik.wirgene](https://avatars.discourse-cdn.com/v4/letter/k/c89c15/32.png) [@karl.fredrik.wirgene](https://forum.inductiveautomation.com/u/karl.fredrik.wirgene)\
**Post date:** [July 18, 2025, 10:22am UTC](https://forum.inductiveautomation.com/t/best-practice-for-modifying-the-value-of-an-opc-tag/108661/1 "2025-07-18T10:22:41Z")

</div>

**Problem description:**

- I am extracting data from an OPC-UA server that only supports read. I have no control over the format of the value from the OPC-UA server.
- The format of the value is a variant array of size 2 (see example in picture). The only way I am able to not get a "TypeConversion" error in Ignition is to use datatype equal to string array for the OPC-tag.
- My goal is to have a tag where the value is only the float inside the first element of the array, while the quality and timestamp is unchanged.  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/5/85fe7a14e093efd7e56e3b16a196e3c121644073.png)

**What I have tried to to:**  
By creating an Expression tag with the expression below, I am able to isolate the value that I am interested in:  
`toFloat(replace(replace({[default]tag_name[0]}, "Variant{value=", ""), "}", ""))`

However, using the expression it also impacts the timestamp, thus I thereby losses the time of sampling of the sensor. It is also very cumbersome as I have to do this for about 1000 sensors.

Any tips on a scalable approach?

---

<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:** [July 18, 2025, 10:45am UTC](https://forum.inductiveautomation.com/t/best-practice-for-modifying-the-value-of-an-opc-tag/108661/2 "2025-07-18T10:45:35Z")

</div>

That looks to be a painful problem.

- What's the brand of OPC-UA server?
- What does the OPC Item Path look like?

Unfortunately, the `replace()` expression doesn't support regex. (The `split()` function does.)  
A simpler expression that seems to work is  
`toFloat(substring({this.custom.variant}, 14))`

You could create a UDT with two internal tags and a tagpath parameter. The first tag would get your Array[2] using the tagpath parameter and the second one would return the float.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 18, 2025, 11:00am UTC](https://forum.inductiveautomation.com/t/best-practice-for-modifying-the-value-of-an-opc-tag/108661/3 "2025-07-18T11:00:51Z")

</div>

This will be a bit ugly because Variant (and Variant array) is basically an unsupported type in Ignition. I think it'll be a little better in 8.3, but still not great.

Create a UDT. Create 3 tags:

- OpcVariantArray
- V0
- V1

In the OpcVariantArray, add a value changed event script:

```python
	import re
	from com.inductiveautomation.ignition.common.model.values import BasicQualifiedValue
	from com.inductiveautomation.ignition.common.model.values import QualityCode
	
	ts = currentValue.timestamp
	v0 = currentValue.value[0]
	v1 = currentValue.value[1]
	
	match0 = re.search(r'value=([^}]+)', v0)
	match1 = re.search(r'value=([^}]+)', v1)
	
	if match0:
		value = BasicQualifiedValue(match0.group(1), QualityCode.Good, ts)
		system.tag.writeBlocking(["[.]V0"], [value])

	if match1:
		value = BasicQualifiedValue(match1.group(1), QualityCode.Good, ts)
		system.tag.writeBlocking(["[.]V1"], [value])

```

you'll probably need to do some casting to int/float on the desired type on the values you pull out of the regex (`match0.group(1)` etc...) and generally clean this script up a but, but the basic idea is there...

Parameterize the UDT as needed so that you just instantiate 1000 of them or whatever.

---

<div class="post-metadata">

**Author:** ![karl.fredrik.wirgene](https://avatars.discourse-cdn.com/v4/letter/k/c89c15/32.png) [@karl.fredrik.wirgene](https://forum.inductiveautomation.com/u/karl.fredrik.wirgene)\
**Post date:** [July 18, 2025, 12:16pm UTC](https://forum.inductiveautomation.com/t/best-practice-for-modifying-the-value-of-an-opc-tag/108661/4 "2025-07-18T12:16:27Z")

</div>

> [@Kevin.Herron](#):
>
> his will be a bit ugly because Variant (and Variant array) is basically an unsupported type in Ignition. I think it'll be a little better in 8.3, but still not great.
> 
> Create a UDT. Create 3 tags:
> 
> - OpcVariantArray
> - V0
> - V1
> 
> In the OpcVaria

Thanks for the approach, this works. Information to other beginners:

- For v0, v1 I used Memory tags.
- To understand UDT's I recommend: [Understanding UDTs Video at Inductive University](https://inductiveuniversity.com/videos/understanding-udts/8.1)
