# Resettable runtime counter

**URL:** <https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [June 3, 2024, 4:50pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299 "2024-06-03T16:50:16Z")\
**Posts on this page:** 1\
**Showing post:** 4

<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:** [June 4, 2024, 5:34pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/4 "2024-06-04T17:34:28Z")

</div>

> [@Austin\_Allen](#):
>
> every 1 second

Well, no. Not accurately. Tag execution intervals are approximate, and heavy load on the gateway will add to the inaccuracy.

Plus, your expression's use of itself makes a circular reference that will almost certainly choke on gateway restart.

The reliable way to have such a timer is to use a **single** datetime **memory** tag that holds the timestamp of the most recent reset.

Wherever you need to **display** the seconds since that timestamp, use:

```python
dateDiff({[provider]path/to/memory/tag}, now(), 'second')

```

Whatever script you are using to write to your reset tag, change to simply write the current timestamp (from `system.date.now()`) to the memory tag.

Precise, zero gateway workload, simple reset. Even "counts" during gateway restarts.

Edit: Hmmm. The above doesn't handle the run indicator. A more complicated solution is needed for accuracy and robustness for such:

- A memory tag of type double to hold "Prior Runtime Seconds"

- Two memory tags of type datetime to hold the last "On" and "Off" timestamps of the run indicator.

- A valueChange event script on the run indicator tag to intelligently update those memory tags (presumably all in the same tag folder). Something like this:

```python
def valueChange(....):
	prior, onTS, offTS = [x.value for x in readBlocking(['[.]PriorSeconds', '[.]OnTimestamp', '[.]OffTimestamp'])]
	if currentValue.value:
		# Run Indicator is ON
		if offTS.after(onTS):
			# Really is transition to ON
			system.tag.writeBlocking(['[.]OnTimestamp'], [system.date.now()])
	else:
		# Run Indicator is OFF
		if not offTS.after(onTS):
			# Really is transition to OFF
			now = system.date.now()
			interval = 0.001 * (now.time - onTS.time)
			system.tag.writeBlocking([['[.]PriorSeconds', '[.]OffTimestamp'], [prior + interval, now])

```

- Your reset operation simultaneously writes now() to the OnTimestamp and 0.0 to the PriorSeconds tags.

- Your display expression becomes:

```python
if(
	{[provider]path/to/run/indicator},
	{[provider]path/to/PriorSeconds} + dateDiff({[provider]path/to/OnTimestamp}, now(), 'second'),
	{[provider]path/to/PriorSeconds}
)

```

---

_[View the full topic](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299)._
