# 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:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [June 3, 2024, 4:50pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/1 "2024-06-03T16:50:16Z")

</div>

Hello,  
I'm trying to figure out how to create an expression for a runtime counter.  
I found this script that works:

```python
if({[~]P_1_RI.value},
if(IsGood({[~]P1_RT.value}),{[~]P1_RT.value},0)+1,
if(IsGood({[~]P1_RT.value}),{[~]P1_RT.value},0))

```

However, I'm trying to figure out how I can add a 'reset' function that will allow the operator to reset the runtime counter to 0 if the button is pushed.

Additionally, sometimes the operator will need to manually update the runtime counter and then the system will continue to count up from that number.  
Can anyone point me in the right direction?

---

<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 4, 2024, 7:35am UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/2 "2024-06-04T07:35:23Z")

</div>

I'm having a hard time figuring out what exactly this counter does...

Anyway, you can write to tags with the `system.tag.write*` functions:

```python
def reset_counter():
    system.tag.writeBlocking(["[~]P1_RT"], [0])

```

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [June 4, 2024, 5:11pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/3 "2024-06-04T17:11:35Z")

</div>

This particular request was a runtime counter for a motor. The client is used to being able to reset the counter at will. It scans at a fixed 1,000 ms rate.

This is the way I did it:

```python
if ({[~]P1_RT_Reset.value}, 0,
    if ({[~]P1_RI.value},
        {[~]P1_RT.value} + 1,
        {[~]P1_RT.value}))

```

It'll just increment the runtime (RT) counter (displayed in hours) every 1 second that the run indicator (RI) is turned on.

---

<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}
)

```

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 6:58pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/5 "2024-09-13T18:58:16Z")

</div>

Hello,

I'm now getting errors that readBlocking, , .after, and .time are not valid attributes. I put this script into the tag editor \> value changed script editor. Is this correct?

---

<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:** [September 13, 2024, 7:00pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/6 "2024-09-13T19:00:18Z")

</div>

"readBlocking" should be `system.tag.readBlocking` in that sample.

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:07pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/8 "2024-09-13T19:07:34Z")

</div>

```python
def valueChange(....):
	prior, onTS, offTS = [x.value for x in system.tag.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]])

```

I am now getting no error in the tag diagnostics, however, the OnTimestamp and OffTimestamp are not being written to at all.

---

<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:** [September 13, 2024, 7:09pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/9 "2024-09-13T19:09:38Z")

</div>

Did you create those memory tags with the right data types, and set a non-null initial value?

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:11pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/10 "2024-09-13T19:11:34Z")

</div>

OnTimestamp = 2024-09-13 2:05:00 PM  
OffTimestamp = 2024-09-13 2:00:00 PM  
PriorSeconds = 5

These were manually set to test

---

<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:** [September 13, 2024, 7:12pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/11 "2024-09-13T19:12:40Z")

</div>

Add some logging after the readBlocking and see if you are getting expected values in the gateway log.

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:13pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/12 "2024-09-13T19:13:08Z")

</div>

Can you advise how to add the logging after the read blocking?

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [September 13, 2024, 7:17pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/13 "2024-09-13T19:17:08Z")

</div>

```python
logger = system.util.getLogger('someName')
value = 2
logMsg= 'Value: {}'.format(value)
logger.infof(logMsg)

```

---

<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:** [September 13, 2024, 7:17pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/14 "2024-09-13T19:17:15Z")

</div>

Something like this:

```python
	logger = system.util.getLogger("Austin")
	logger.infof("prior=%s, onTS=%s, offTS=%s", prior, onTS, offTS)

```

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:22pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/15 "2024-09-13T19:22:28Z")

</div>

In the gateway log I received:

prior=5.0, onTS=Fri Sep 13 14:05:00 CDT 2024, offTS=Fri Sep 13 14:00:00 CDT 2024

---

<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:** [September 13, 2024, 7:25pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/16 "2024-09-13T19:25:16Z")

</div>

That's it? Nothing more when you toggle the boolean?

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:26pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/17 "2024-09-13T19:26:37Z")

</div>

See screenshot for what is coming in whenever bool is toggled on and off

 ![Untitled](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/d/6df43b9fbeb34d391fc1743d28b2c3dfa28fae4f.jpeg)

---

<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:** [September 13, 2024, 7:31pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/18 "2024-09-13T19:31:28Z")

</div>

Hmmm. Alter the logging like so:

```python
	logger = system.util.getLogger("Austin")
	logger.infof("current=%s, prior=%s, onTS=%s, offTS=%s", currentValue, prior, onTS, offTS)

```

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:34pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/19 "2024-09-13T19:34:02Z")

</div>

The error message only occurred on the first toggle, does not happen again

 ![Untitled2](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/8/38a371db111a1759c21ed5c2f12d8739ee9b5f9e.jpeg)

Script:

 ![script](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/1/e1a5b448b094785b610d62877327c6edab841e2a.jpeg)

---

<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:** [September 13, 2024, 7:39pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/20 "2024-09-13T19:39:56Z")

</div>

Make sure your Prior tag is an ~~integer long integer, int8, not a string or float~~ a float (4 or 8).

---

<div class="post-metadata">

**Author:** ![Austin\_Allen](https://avatars.discourse-cdn.com/v4/letter/a/f0a364/32.png) [@Austin\_Allen](https://forum.inductiveautomation.com/u/Austin_Allen)\
**Post date:** [September 13, 2024, 7:44pm UTC](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299/21 "2024-09-13T19:44:19Z")

</div>

Its currently set to a double, i changed it to float and still not working.

[Next page](https://forum.inductiveautomation.com/t/resettable-runtime-counter/91299.md?page=2)
