Expression Tag Performance

I have an interesting problem with a gateway and reliability of expression tags.
The gateway is not overloaded running 40-50% CPU with sawtooth RAM use.
I have access to the windows server.
I will try to explain clearly:
Ignition 8.1.17
OS = Windows Server 2016
Tag Provider Group = default 1000mS

I am using an expression tag to calculate seconds of production time in a shift. The tag name is "Shift Production Time Duration", type = integer.
Seperate tags contain a shift name and shift status. For example: Shift = "First" Status = "Production" or Status = "Lunch"
The expression tag named "Shift Production Duration" watches for shift status to equal "Production", if equal increment by one second.
Not important but shift name and shift status are fed from a gateway event script containing shift definition lookup at 1000mS.
I will refer to the above tag as "exp01"

exp01 has a value change script.

exp01 value change script writes to another tag documenting an integer number of seconds a shift status = "Production".
When status changes from Production to Break (or any other status) exp01 turns to 0 and value change script stops executing. As a result tag "Shift Production Time" stops climbing.
When status changes from anything to "Production" the status counter exp01 should increment by 1. The value change script should only trigger once exp01 = 1 (and previousValue = 0)

However, sometimes exp01 will add the none Production status seconds to the total. For example Shift Production Time = 3700 and status will be "Break" for 300 seconds.
When status goes from "Break" to "Production" Shift Production time will change to 4000 when its broken. When it works the next value will be 3701.

I have a copy of the above setup I will call exp02. The only difference is exp02 is working from Reference tags (reference of shift name and shift status). The reference tags point at the same tags exp01 is using.

How can I have 2 identical expressions driven from the same source of truth on the same gateway evaluate differently (sometimes) and other times the same?
I have noticed on gateway startup exp01 is frequently broken. I think it could be related to previousValue being "None"? If the gateway restarts I have to modify and resave exp01 to get it working properly. When exp01 does work it could be for days and randomly stop.

I am looking to understand why the expressions evaluate differently sometimes, and if Ive done something wrong.

I would like to also understand how to handle previousValue use on gateway startup as effective as possible.

Open to criticism on the entire process really.

Here are the other tags:

It would be much cleaner and useful to simply record the timestamp, cycleCount, goodCount, runStatus, product, stopCode, operator, etc. in dedicated table, triggered on runStatus change event and on shiftStart or hourly (or whatever). Make the counters of type "never-resetting" and you can then easily calculate uptime and output between any two timestamps.

4 Likes

Would it be easier to track the start time of a production shift/status with a value change script on the Shift Status that writes the start time to a ProductionStartTime tag, then when the shift status changes to something else like Break, and if the previous value was Production, read the start time, take the difference from now, and add that value onto a production time duration tag?

If you're needing live values, then have an expression tag that sums the production duration time with the difference in seconds between the production start time and now().

This would only cause the production time tag to change at the end of a production run instead of constantly writing to the tag every second, but it seems more straight forward.

1 Like

The only effective way to handle this is look up the last value in history whenever you see initialChange true. Full stop.

Fundamentally, your approach is broken, cause Ignition doesn't even try to make every expression tag execute precisely on schedule. So adding one second to a counter based on executions is utterly bogus.

Record timestamps for your on-off events and use your database's lead() function to compute precise deltas.

2 Likes

Appreciate the suggestions everyone.

I started logging shift status to a database using the timestamps to calculate seconds. So far the process has proved reliable, thank you @pturmel

I should have mentioned in my original post:
The purpose of the counter was not precision. Most important, the counter needs to be consistent. The database solution does seem like the most sensible approach for the application.

My experience with the described counter has lowered my confidence in expressions. I would like to understand why the expression method was not consistent, even if the approach/application was flawed. The expression should behave in a consistent way, and 80% of the time does. I have used countless expressions for all kinds of things where performance was stable.

Any ideas on why the flawed counter expression performance was inconsistent?

Too many complex expressions can bog down the tag expression thread pool. That'd be my first guess.