Tag History binding includes current timestamp in result

When I configure a Tag History binding in Perspective with a historical time range that has a fixed end date, the result set unexpectedly includes an additional row. This row represents the current timestamp and the values that are currently on the tag. However, this is problematic because the current timestamp falls outside the specified historical range.

Here's an example using the AsStored query mode. As a workaround I could either add a filter on the quality code to remove any rows with quality code 200, or always remove the last row. Although that doesn't change the fact that the binding is returning data which falls outside of the requested range.

Another thing to note for this particular example, is that we don't have a historized value for today (21/11/2023) yet. I'm working with a tag for which values are entered manually and stored in the historian using system.tag.storeTagHistory(...). That means these are discrete values, not a continuous signal, and I only want to work with the values that are actually in the database.

Combine this with the issue above, and we run into problems again when using a Periodic (1 day) historical query, where the range includes today (21/11/2023):

While the timestamp of the last row is located in the requested time range, it's values are not what I expected. Since there is no value in the database for today, I would have expected 0, similar to the values for 18/11/2023 and 19/11/2023, which don't have a value either.

In this case I can't use the earlier workaround either of removing the rows with quality code 200, since the row for yesterday also has that quality code. Nor can I simply remove the last row, because it is possible that a value exists for today in the database, in which case I do want to show it.

I know Ignition is mostly tailored for working with continuous signals, but these behaviors don't feel like they are correct. Anybody who can help with this?

I've already looked through the forum and found multiple similar reports, unfortunately none of them had any replies:

Use "As Stored" query mode and post-process with a transform if necessary.

Hi @pturmel , the first example is using the "AsStored" query mode, but is returning (A) a row outside of the requested range, and (B) a value that is not actually stored in the database.

Are the values floating point with deadband style "Auto" ? This would yield deadband style "Analog", which needs interpolation points. Ensure you are using deadband style "Discrete".

That seems to be the case yes. I'll try it out, thanks.

For future reference, I'm also talking with support to look into this issue.

@pturmel's advice is legit for normal tags which receive regular tag changes. Setting the deadband style to discrete, combined with an AsStored tag history binding will result in the Raw result set from the historian, without an extra row with the realtime value, as documented here: Configuring Tag History - Ignition User Manual 8.1 - Ignition Documentation .

However, I'm in a special case where I have tags that will only get historical value updates by a script using system.tag.writeAsync(...) and system.tag.storeTagHistory(...). And unfortunately, using the storeTagHistory function has some caveats, as explained by support:

So the function system.tag.storeTagHistory function has a different purpose when it comes to storing tag history data. If you want to store data using this function then you must meet bunch of criteria in order to not run into issues such as the tag you are trying to store data using this function must be already storing history through the tag changes, only use this function to fill data points that you missed such as quarantined data, and cannot store values outside of the creation or retired date of the tag. If we don't meet these criteria then this function starts acting weird and starts causing issue such as creating 2 new entries in the sqlth_te table as we saw.

In my case, using it will always create a second tag definition in the sqlth_te table with the analog deadband mode, instead of using the existing tag definition with the discrete deadband mode.

1 Like

Eww! Sounds like you should be using custom tables, not the historian.

What do you mean exactly with custom tables? The reason we are (ab)using tags & the historian for this, is that we wanted to use the data in the same way as everything else. So for example: easy tag (history) bindings with aggregations, alongside the other tags that are connected to a real time sensor.