# Calculating the average for tags

**URL:** <https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [June 7, 2023, 12:03pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693 "2023-06-07T12:03:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michal\_Goralczyk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/michal_goralczyk/32/55564_2.png) [@Michal\_Goralczyk](https://forum.inductiveautomation.com/u/Michal_Goralczyk)\
**Post date:** [June 7, 2023, 12:03pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693/1 "2023-06-07T12:03:51Z")

</div>

Hello,

I have a question how to count the average for several tags. Suppose I have 10 measurement sensors. I would like to count the average from them with the exclusion conditions if, for example, the value is unreasonable or there is no comminkation, i.e. Quality tag is "Bad". So far I only have readings of many devices, but no idea how to make an easy average and exclude bad readings according to the conditions ( too small or too large) so that they are not taken into the average.

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

Greetings,  
Michał

---

<div class="post-metadata">

**Author:** ![Hayden\_Watson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hayden_watson/32/48792_2.png) [@Hayden\_Watson](https://forum.inductiveautomation.com/u/Hayden_Watson)\
**Post date:** [June 7, 2023, 1:01pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693/2 "2023-06-07T13:01:29Z")

</div>

You might get a load of recommendations on how to do this with fancy expression tags later. But I would just put a script into the gateway tag events, either timer or tag change. Something like:

```auto
avg = 0
cnt = 0
results = system.tag.browse(path = YourPath, filter = {'tagType':'AtomicTag'})
for result in results.getResults():
    if result["value"].quality == "Good" and otherConditions:
        avg = avg + result['value'].value
        cnt += 1
    else:
        pass
yourAverage = avg / cnt

```

You could then use system.tag.writeBlocking to write to a tag. Have a play around with it and see what works

---

<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:** [June 7, 2023, 1:02pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693/3 "2023-06-07T13:02:56Z")

</div>

```python
def check(qval):
    return qval.good and qval.value >= SOME_MIN_VALUE and qval.value <= SOME_MAX_VALUE
values = [qval.value for qval in system.tag.readBlocking(your_tags_paths) if check(qval)]
return sum(values) / len(values)

```

Note that the `check` function is not necessary. You could just replace the call with what's in its return.  
I did it that way to clearly separate what needs to be changed and what doesn't.

---

<div class="post-metadata">

**Author:** ![zbinder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zbinder/32/28918_2.png) [@zbinder](https://forum.inductiveautomation.com/u/zbinder)\
**Post date:** [June 7, 2023, 2:02pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693/4 "2023-06-07T14:02:56Z")

</div>

You could do some basic checking within expression tags too. Probably doable if you have one instance of 10 tags, but might get a bit unwieldy or inefficient if you have a lot more to do this with.

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

```auto
(
	if({[.]Tag 1} >= {[.]Min} && {[.]Tag 1} <= {[.]Max}, {[.]Tag 1}, 0)
	+ if({[.]Tag 2} >= {[.]Min} && {[.]Tag 2} <= {[.]Max}, {[.]Tag 2}, 0)
	+ if({[.]Tag 3} >= {[.]Min} && {[.]Tag 3} <= {[.]Max}, {[.]Tag 3}, 0)
)

/ (
	if({[.]Tag 1} >= {[.]Min} && {[.]Tag 1} <= {[.]Max}, 1, 0)
	+ if({[.]Tag 2} >= {[.]Min} && {[.]Tag 2} <= {[.]Max}, 1, 0)
	+ if({[.]Tag 3} >= {[.]Min} && {[.]Tag 3} <= {[.]Max}, 1, 0)
)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 7, 2023, 3:32pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693/5 "2023-06-07T15:32:25Z")

</div>

```auto
mean(
	if(isGood({[.]Tag 1}), {[.]Tag 1}, null),
	if(isGood({[.]Tag 2}), {[.]Tag 2}, null),
	if(isGood({[.]Tag 3}), {[.]Tag 3}, null),
	if(isGood({[.]Tag 4}), {[.]Tag 4}, null)
)

```

---

<div class="post-metadata">

**Author:** ![Tim\_Carlton](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tim_carlton/32/52835_2.png) [@Tim\_Carlton](https://forum.inductiveautomation.com/u/Tim_Carlton)\
**Post date:** [June 7, 2023, 4:25pm UTC](https://forum.inductiveautomation.com/t/calculating-the-average-for-tags/74693/6 "2023-06-07T16:25:34Z")

</div>

If you want to do your own range check, you can add a couple of memory tags '''InstrumentHigh''' and '''InstrumentLow'''.

```auto
mean(
	if(isGood(if ({[.]1}>{[.]InstrumentHigh}||{[.]1}<{[.]InstrumentLow},qualifiedValue({[.]1},'bad',524,'Out of instrument range'),{[.]1})), {[.]1}, null),
	if(isGood(if ({[.]2}>{[.]InstrumentHigh}||{[.]2}<{[.]InstrumentLow},qualifiedValue({[.]2},'bad',524,'Out of instrument range'),{[.]2})), {[.]2}, null),
	if(isGood(if ({[.]3}>{[.]InstrumentHigh}||{[.]3}<{[.]InstrumentLow},qualifiedValue({[.]3},'bad',524,'Out of instrument range'),{[.]3})), {[.]3}, null),
	if(isGood(if ({[.]4}>{[.]InstrumentHigh}||{[.]4}<{[.]InstrumentLow},qualifiedValue({[.]4},'bad',524,'Out of instrument range'),{[.]4})), {[.]4}, null),
	if(isGood(if ({[.]5}>{[.]InstrumentHigh}||{[.]5}<{[.]InstrumentLow},qualifiedValue({[.]5},'bad',524,'Out of instrument range'),{[.]5})), {[.]5}, null),
	if(isGood(if ({[.]6}>{[.]InstrumentHigh}||{[.]6}<{[.]InstrumentLow},qualifiedValue({[.]6},'bad',524,'Out of instrument range'),{[.]6})), {[.]6}, null),
	if(isGood(if ({[.]7}>{[.]InstrumentHigh}||{[.]7}<{[.]InstrumentLow},qualifiedValue({[.]7},'bad',524,'Out of instrument range'),{[.]7})), {[.]7}, null),
	if(isGood(if ({[.]8}>{[.]InstrumentHigh}||{[.]8}<{[.]InstrumentLow},qualifiedValue({[.]8},'bad',524,'Out of instrument range'),{[.]8})), {[.]8}, null),
	if(isGood(if ({[.]9}>{[.]InstrumentHigh}||{[.]9}<{[.]InstrumentLow},qualifiedValue({[.]9},'bad',524,'Out of instrument range'),{[.]9})), {[.]9}, null),
	if(isGood(if ({[.]10}>{[.]InstrumentHigh}||{[.]10}<{[.]InstrumentLow},qualifiedValue({[.]10},'bad',524,'Out of instrument range'),{[.]10})), {[.]10}, null)
)

```

If those instrument high/low limits are real, then you probably want those applied to all uses of the tag rather than just in calculating the mean.  
If so, you could add a second set of derived tags '''Validated1''' etc, with an expression

```auto
if ({[.]1}>{[.]InstrumentHigh}||{[.]1}<{[.]InstrumentLow},qualifiedValue({[.]1},'bad',524,'Out of instrument range'),{[.]1})

```

If you reference `Validated1` instead of `1` then you get the benefit of quality in displays and all calculations.
