# Calculate consumption from tag history

**URL:** <https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664>\
**Category:** Ignition\
**Created:** [January 30, 2026, 5:06pm UTC](https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664 "2026-01-30T17:06:02Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![d3h637](https://avatars.discourse-cdn.com/v4/letter/d/13edae/32.png) [@d3h637](https://forum.inductiveautomation.com/u/d3h637)\
**Post date:** [January 30, 2026, 5:06pm UTC](https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664/1 "2026-01-30T17:06:02Z")

</div>

Is there a way to determine the timestamp in scripting for the maximum value in a tag history query? I have a tank with a level measurement, and I would like to calculate current consumption rate. I know that I can use the minmax function in the system.tag.queryTagCalculations to get the minimum and maximum, and that works if the tank has not been refilled during that time period. If I could get the timestamp from the maximum value, then I can just subtract the current value from the maximum and divide by the difference in time.

---

<div class="post-metadata">

**Author:** ![Bushmatic](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bushmatic/32/87014_2.png) [@Bushmatic](https://forum.inductiveautomation.com/u/Bushmatic)\
**Post date:** [January 30, 2026, 6:02pm UTC](https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664/2 "2026-01-30T18:02:45Z")

</div>

```python
rows = [
    (historyDataset.getValueAt(r, 1), historyDataset.getValueAt(r, 0))
    for r in range(historyDataset.getRowCount())
    if historyDataset.getValueAt(r, 1) is not None
]

maxValue, maxTimestamp = max(rows)

```

If I’m understanding correctly and you’re in a script already anyway, the above might help.

---

<div class="post-metadata">

**Author:** ![d3h637](https://avatars.discourse-cdn.com/v4/letter/d/13edae/32.png) [@d3h637](https://forum.inductiveautomation.com/u/d3h637)\
**Post date:** [January 30, 2026, 7:01pm UTC](https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664/3 "2026-01-30T19:01:33Z")

</div>

> [@Bushmatic](#):
>
> ```python
> rows = [
> (historyDataset.getValueAt(r, 1), historyDataset.getValueAt(r, 0))
> for r in range(historyDataset.getRowCount())
> if historyDataset.getValueAt(r, 1) is not None
> ]
> 
> maxValue, maxTimestamp = max(rows)
> 
> ```

Thanks for the help. I had thought about iterating through myself, but I was hoping there was a built in solution. Your algorithm is more efficient than mine, so I went ahead and used it.

---

<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:** [January 30, 2026, 7:23pm UTC](https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664/4 "2026-01-30T19:23:24Z")

</div>

Untested, but this or something like it should be a little bit more efficient:

```python
maxValue, maxTimestamp = max(system.dataset.toPyDataSet(historyDataset), key=lambda row: row[1])

```

The other approach is creating an extra copy of all the values in a list (which is not free) and iterating through them all twice. If you're on 8.3 you can drop the `toPyDataSet` call.

---

<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:** [January 31, 2026, 11:41pm UTC](https://forum.inductiveautomation.com/t/calculate-consumption-from-tag-history/113664/5 "2026-01-31T23:41:46Z")

</div>

I would use my toolkit's `orderBy()` function (expression or scripting) to get the dataset in descending order by value, then the entire first row is easily accessible. (FWIW. the toolkit's `asMap()` function turns the first row of any dataset into a dictionary, which makes it really handy in Perspective.)
