The machine-name string tag in this UDT never lost its value. The historian stopped returning a row for it. A value that never changes is stored once on change, and that single row eventually falls outside every query window or gets pruned. The live tag, the UDT parameter, and the Tag Browser all still show the machine name. The historian trend and the CSV export built from history show blank. Writing a different value and then the original value "fixes" it because those two writes create fresh history rows, and the problem returns weeks later.
What is actually blank: the tag, the binding, or the history?
"Blank" means something different on each screen. Map the operator's view to the layer that produced it before changing anything.
| Where the operator looks | What it shows | Layer it points to |
|---|---|---|
| UDT instance parameter (instance editor) | Machine name present | Parameter is intact |
| Tag Browser, member string tag | Machine name, Good quality | Tag and binding are healthy |
| Tag Browser, member string tag | Empty string, Good quality | Binding fault or something writing to the tag |
| Tag Browser, member string tag | Bad or config-error quality | Binding fault, such as an unresolved parameter reference |
| History trend / history query / CSV built from history | No value for the window | History storage or query fault |
This case has a live value that is present and a history result that is empty. That is a history fault. Confirm it with the checks below instead of rebuilding the UDT.
Is the member tag still holding the parameter value?
Separate tag faults from binding faults first. A binding fault shows up live. A history fault shows up only in queries.
- Open the UDT instance in the Tag Browser. Read the string member's value, quality, and timestamp. A Good-quality machine name with an old timestamp is expected for a static tag.
- Open the member tag's properties on the instance. Confirm the value still references the instance parameter in curly-brace form and is not an instance override. An override on the member replaces the parameter reference with a fixed value. From that point, changes to the definition or parameter no longer flow through.
- Add a Tag Change script to the member in the UDT definition. Every instance then inherits it. Log previous value, new value, quality, and timestamp to the gateway log. This catches any client, script, or transaction group that writes an empty string to the tag.
- Leave the script running through at least one period in which the historian goes blank.
Check: The gateway log shows no change events, and the Tag Browser still shows the machine name while the history query returns blank. The tag and binding are cleared. Move to the history layer.
Why does history return nothing for a value that never changed?
Most historized tags use an on-change sample mode. For a string, any difference counts as a change. A machine name set once produces one stored row, usually when history was enabled or the instance was created. Nothing else is written, because nothing changes.
A history query returns the rows inside the requested window, plus a seed or last-known value from before the window start if the historian can reach that earlier row. Two things take that single row away:
- Window reach. The historian stores data in time partitions. The seed-value lookback does not scan back indefinitely. Once the only row is old enough, a query over the last day or week finds no row in range and no reachable seed. The result is blank.
- Pruning. If data pruning is enabled on the history provider, the partition holding the only row is deleted when it passes the pruning age. The value is then gone from history entirely.
Either mechanism fits the timeline: the export works for weeks or months, then goes blank on a day with no change to the tag. The write-and-restore workaround resets the clock by inserting two new rows, which is why it works only temporarily.
Check: Query the tag's history over a long range that covers the instance creation date. One or two rows far in the past, and nothing after them, confirms the mechanism. Also read the provider's partition length and pruning age in the gateway history provider settings, and compare them to the age of that row.
How do I configure history so the machine name keeps landing in the store?
Make the change on the member tag in the UDT definition so every instance picks it up. Do not make it instance by instance.
| Setting | Location | Effect |
|---|---|---|
| History enabled | Member tag, History section (UDT definition) | Tag is historized on every instance |
| Storage provider | Same | Must match the provider the CSV export queries |
| Sample mode: on change | Same | Records any rename of the machine immediately |
| Maximum time between samples (forced periodic insert) | Same | Writes the current value even with no change; set it shorter than your query window and your pruning age |
| Pruning age | Gateway history provider settings | Must be longer than the forced-sample interval |
Size the forced interval from the export. A weekly forced sample, as sometimes suggested, only works for queries spanning a week or more.
An alternative that needs no storage change is to switch the history query to return the last known value regardless of window. That still fails once pruning deletes the only row, so pair it with the forced sample.
Check: After saving the definition, wait one forced interval. Query the tag's history for that interval. A row with the machine name and a recent timestamp should appear on every instance.
Should the CSV export read history or the live tag?
Both configurations work. For static metadata, prefer reading the live value.
- Live read (preferred for a static name): The export script reads the member tag, or the instance parameter, at export time. It writes the name as a column next to the historized process values. It cannot age out, costs no storage, and avoids historizing a tag whose only purpose is a label.
- Historized with forced sampling: Use this only when the export must show the name as it was at a past timestamp, for example if machines get renamed and old records must keep the old name.
If the export stays history-based, confirm its query uses the same provider and a window no longer than the forced-sample interval.
Check: Run the export for a window that starts after the last manual write-and-restore. The machine-name column is populated on every row.
How do I prove the fix holds end to end?
- Remove any instance overrides found on the member tag, and confirm the Tag Browser shows the parameter-driven name with Good quality.
- Leave the Tag Change logging script in place. Confirm the gateway log stays silent, meaning no stray writes.
- Do not use the write-and-restore workaround. Let the system run past at least one full partition boundary and past the old failure interval.
- Query history for the most recent export window. Confirm at least one row per forced interval, or confirm that the live-read column is populated.
- Open the CSV produced after that boundary. Confirm the machine-name column is filled for every instance on every row.
FAQ
Does Ignition historian store a tag value that never changes?
With on-change sampling, it stores the value once, when the value is first recorded, and nothing afterward. To get periodic rows for a static value, set a maximum time between samples on the tag's history configuration that is shorter than your query window.
Can I fix a blank historian value by writing a different value and then the original back?
Only temporarily. The two writes create fresh change rows, so queries return data again until those rows age out of the query window or get pruned. A forced periodic sample, or a live read in the export, is the permanent fix.
Can a UDT instance override break the parameter reference on a member tag?
Yes. An override on the member's value replaces the curly-brace parameter reference with a fixed value, so parameter or definition changes stop flowing to that instance. Remove the override in the instance's tag properties to restore inheritance, then confirm the Tag Browser shows the parameter value.