# Average value of a tag over last 20s

**URL:** <https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306>\
**Category:** Ignition\
**Created:** [July 13, 2023, 8:51am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306 "2023-07-13T08:51:30Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![JJZZ](https://avatars.discourse-cdn.com/v4/letter/j/f475e1/32.png) [@JJZZ](https://forum.inductiveautomation.com/u/JJZZ)\
**Post date:** [July 13, 2023, 8:51am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/1 "2023-07-13T08:51:30Z")

</div>

I want to calculate the average value of my OPC tag in Ignition for the last 20 seconds.  
I tried using an Expression Tag and the following code:

` avg(toMillis(now()) - toMillis(tag("OPC TAG PATH)), -20000, now())`

Is there any error or issue you encountered with this code? could you please help 🙂

I tried

` toMillis(tag("OPC TAG PATH)`  
und couldent get any value. I got Just Erro\_Configuration

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [July 13, 2023, 9:11am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/2 "2023-07-13T09:11:56Z")

</div>

A few things wrong here:

- the expression function for averaging values is `mean`
- what is the value of your "OPC TAG PATH"?
- is the opc tag path the path to the tag in the ignition tag browser? or is it the opc item path from the opc tag browser? (you should be using the ignition tag browser tag)
- what you have now, assuming it was syntactically correct, would average 3 values: the difference in milliseconds between now and your tag, -20000, and the datetime now. This is definitely not what you're after, I assume

How do you want to calculate the average? Do you just want it using two data points, at -20s and now? or do you want a time-weighted avg using multiple data points over the 20s period?

The most likely answer will be to use [`system.tag.queryTagCalculations(...)`](https://docs.inductiveautomation.com/display/DOC81/system.tag.queryTagCalculations) with `calculations='Average'` in which case you'll need to enable history on the tag

---

<div class="post-metadata">

**Author:** ![JJZZ](https://avatars.discourse-cdn.com/v4/letter/j/f475e1/32.png) [@JJZZ](https://forum.inductiveautomation.com/u/JJZZ)\
**Post date:** [July 13, 2023, 9:25am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/3 "2023-07-13T09:25:20Z")

</div>

Thanks for your reply 🙂

> [@nminchin](#):
>
> - what is the value of your "OPC TAG PATH"?

the value of my OPC TAG PATH is the speed in meters per minute. I want to display the average value of the past 20 seconds with an expression tag.  
I am using the ignition tag browser tag  
I would like to take into calculation all the values

> [@nminchin](#):
>
> The most likely answer will be to use [`system.tag.queryTagCalculations(...)`](https://docs.inductiveautomation.com/display/DOC81/system.tag.queryTagCalculations) with `calculations='Average'` in which case you'll need to enable history on the tag

I will take a look on this

---

<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 13, 2023, 10:41am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/4 "2023-07-13T10:41:17Z")

</div>

More problems:

1. Where is the speed from 20 seconds ago stored? You can't just read an OPC tag and subtract time from it. You have to build a shift register in the PLC (best) or in Ignition and calculate from that.
2. Getting the average of speed now and speed 20 s ago only works if the the speed is constant or accelerating at a constant rate. If the rate changes then you haven't got it!

You should be recording **distances** or positions and then the average speed becomes  
vavg = (s1 - s0) / (t1 - t0)  
This will give the true average speed no matter what the speed profile is.

* * *

Tip: Use code formatting for code, not \> quote which indicates that you are quoting someone else's post.

![Formatted code](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/1/e11cdbb3b8348c74916b62652bdd100dd77082cf.png)

---

<div class="post-metadata">

**Author:** ![JJZZ](https://avatars.discourse-cdn.com/v4/letter/j/f475e1/32.png) [@JJZZ](https://forum.inductiveautomation.com/u/JJZZ)\
**Post date:** [July 13, 2023, 10:43am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/5 "2023-07-13T10:43:40Z")

</div>

> [@Transistor](#):
>
> - Where is the speed from 20 seconds ago stored? You can't just read an OPC tag and subtract time from it. You have to build a shift register in the PLC (best) or in Ignition and calculate from that.

Maybe from the History Tag of Speed?

---

<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 13, 2023, 10:45am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/6 "2023-07-13T10:45:28Z")

</div>

> [@JJZZ](#):
>
> Maybe from the history tag of speed?

Then you are goint to have to consider the size of your history table and the speed of your history queries.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [July 13, 2023, 11:08am UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/7 "2023-07-13T11:08:31Z")

</div>

Yes, it's by no means going to be terribly efficient to calc the avg of a tag all the time. 20s is very short though so I can't imagine it being that bad. I would try to limit calcing the avg to only when you want to see it. And I also wouldn't go crazy doing this for 100s of tags

---

<div class="post-metadata">

**Author:** ![MMaynard](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mmaynard/32/3366_2.png) [@MMaynard](https://forum.inductiveautomation.com/u/MMaynard)\
**Post date:** [July 13, 2023, 12:51pm UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/8 "2023-07-13T12:51:08Z")

</div>

For simple displays you can just use a timer control with a dataset.  
Create a custom property of dataset type on the root container.  
Add a timer control to the window and put this code in it.

```auto
from random import randint
sDS = event.source.parent.avgDS
#Create a custom property on the root container called avgDS of dataset type.
#Check for a blank dataset or a dataset larger than 20
# Blank the dataset and create a single INT record to set the datatype of the column
if sDS.getRowCount()>=21 or sDS.getRowCount() < 0:
	hdr=['value']
	blankDS = [[1]]
	event.source.parent.avgDS=system.dataset.toDataSet(hdr,blankDS)
	event.source.parent.avgDS = system.dataset.deleteRow(event.source.parent.avgDS,0)

#grab the current value, add it to the dataset at row 0
sDS = event.source.parent.avgDS
#Replace randint with the tag value you want to average
val = randint(1,450)
nDS = system.dataset.addRow(sDS, 0,[int(val)])
event.source.parent.avgDS = nDS
#delete the oldest row in the dataset
if sDS.getRowCount()>19:
	nDS = system.dataset.deleteRow(nDS,20)
	event.source.parent.avgDS = nDS

```

Then you can add a label or text box to the window and do an expression of  
`mean({Root Container.avgDS},0)`

Take this with a big grain of salt, this is for a simple window with a simple calculation needed for display.  
I would not be doing this for more than a few things.

---

<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:** [July 13, 2023, 1:33pm UTC](https://forum.inductiveautomation.com/t/average-value-of-a-tag-over-last-20s/76306/9 "2023-07-13T13:33:30Z")

</div>

My `recorder()` expression function (from Simulation Aids) can maintain this kind of very short term history in a dataset. But if possible, I'd record positions instead of speed, as @Transistor pointed out. Much more precise.
