Trying to calculate the time between two tag changes

I am trying to calculate and display the time as a numerical label between the start of a process, indicated by a tag boolean, and when the process has reached a specific temperature, indicated by another boolean. However, I’m not sure how to do that. I also thought about showing it via a report but I’m not sure if it’s easier in a main window or a report

You could use 2 tags for this:

  • One DateTime tag for logging when the boolean goes true. In the ValueChange event script of your boolean, if the previousValue.value == False and currentValue.value == True, then write system.date.now() to your datetime tag.
  • Another DateTime tag for logging when the temperature setpoint is reached. You’ll update this value in the ValueChange event of the temperature tag if the currentValue.value >= your setpoint.

Then in your numeric label or report, get the seconds or minutes between those values. You could have this duration be it’s own tag, and include logic to set it to 0 or null if the process isn’t started, or if the temperature hasn’t been reached yet.

How would I ensure that the value stays static even after all the tag conditions are met?

Oh, good point.

You might need another boolean tag for “target temperature reached” or something similar.
You set that tag to False when the process boolean value goes from True to False.
You set it to True when the temperature value first exceeds your setpoint, so that any more increases won’t overwrite your original timestamp.

Finally have that new temperature reached boolean ValueChange event script perform the setting of the temperature datetime tag.

You might find the techniques in this thread helpful (in spite of the title):

Thank you for the reference, unfortunately most went well over my head. Problem ended up being in the oddest place. Why does ignition “molest” contents of tags of Data Type “String”? I ran into saving a time stamp to a string tag end up with that value jumbled enough that, later, it couldn’t be ‘coerced’/recognized as a date.

Set up a memory tag of Data Type “string” named {[default]string_memory_tag} and then run this:

time_now = system.date.now()
system.tag.write("[default]string_memory_tag", time_now )
print "==="
saved = system.tag.read("[default]string_memory_tag")
print "now = %s \nsaved = %s" % (time_now,saved.value)
#duration = system.date.minutesBetween(time_now,saved.value)
#print "difference = %s" % (duration)

script console prints the following:

>>> 
2
===
now = Fri Oct 05 14:44:25 EDT 2018 
saved = 2018-10-05 14:44:25
>>>

I’ve never used a language before where strings saved to a string variable/tag get rearranged like this behind the scenes!!

I’ve since ‘discovered’ that tag can’t be a type “String” but must be “Date”. Change “string_memory_tag” tag to Data Type “Date” and uncomment the last 2 lines and run it again. It now prints:

>>> 
2
===
now = Fri Oct 05 14:37:37 EDT 2018 
saved = Fri Oct 05 14:37:37 EDT 2018
difference = 0
>>>

BTW, can someone tell me why system.tag.write() emits a “2” to the script console output?

Thank you.

P.S. sorry for posting replies under someone else’s question instead of my question. I also didn’t know I could edit posts.

Because “time_now” is not a string. It doesn’t get converted to a string until it is written into the tag on the gateway. The gateway’s locale and date=>string conversion defaults can be (are) different from your script console. Printing time_now on your console performs a string conversion during print that uses your client locale. Printing saved.value doesn’t perform a string conversion–it’s from a string tag–so it prints what came from the gateway.

Jython is helping you print out objects that aren’t strings, because most everything has a default way to show itself as such, but those methods are unreliable for general use.

1 Like

Strings are not dates, and should not be used as storage of dates and times.

In your first example - you're getting a Java Date from system.date.now(), then writing it to a string tag. The string tag accepts it, because the date object has a naive toString() method that will convert it to a string - specifically, the literal '2018-10-05 14:44:25' you see on the tag. system.date.minutesBetween fails to compare between the value of that string tag and now() because they are different types of objects.

Always store dates using native date types - they are easier to manipulate, and infinitely less prone to failure upon edge cases.

A return value of '2' means the write is pending: see system.tag.write in the documentation.

1 Like