When I write to a tag, can I set the timestamp as well somehow?
I am collecting history for a tag from the response from an API call and storing it to the tag, but I also want to set the current value to the latest value in the history with its associated timestamp intact. Possible?
#example only
from com.inductiveautomation.ignition.common.model.values import BasicQualifiedValue, QualityCode
BasicQualifiedValue(14, QualityCode.Good, system.date.now())
Hmm, just trying this again for something else, I actually don’t know if it is working… as a test I created a new memory tag with history enabled with no min capture rate (max time between samples), and to capture all records.
from com.inductiveautomation.ignition.common.model.values import BasicQualifiedValue as qval, QualityCode as qc
tagPath = '[default]Testing/New Folder 1/Test'
now = system.date.now()
now = system.date.setTime(now, 0,0,0)
values = []
value = qval(50, qc.Good, system.date.addHours(now, 3))
values.append(value)
value = qval(50, qc.Good, system.date.addHours(now, 5))
values.append(value)
system.tag.writeBlocking([tagPath]*len(values), values)
system.tag.queryTagHistory([tagPath], now, system.date.setTime(now, 3,1,0), returnSize=-1)
If I run this at 1707, I see a single historical entry added at 1707, not at 0300 and another at 0500 Even if I try to write a single value, the result is the same - the timestamp is always the time of the write and not the time that I’m supplying.
@PGriffith should this work? Or how else can I write a value with timestamp to a tag? And will this write that timetstamp into the history as well if the tag is historised?
Essentially, we have a 3rd party system which stores history for some things. We’re pulling in this history via API calls every 10 mins and we might get a handful of historic points in that time. I want to:
store that history into the Ignition database for corresponding Ignition tags
write the latest value with timestamp to the corresponding Ignition tags
I’m guessing the timestamp of the tag is not what the historian uses to store data: Your tag timestamp will be set to whatever you provide, but then some other mechanism determines the timestamp for the historized data.
You can try system.tag.storeTagHistory, which should allow you to provide your own timestamp to the historian, but you’ll need to un-historize your tag or you’ll get 2 entries for the same data point, with 2 different timestamps.
The tag history system filters out tag changes with timestamps going backwards in order to avoid problems with OPC servers that sometimes deliver updates out of order.
IIRC, there’s a setting to disable that behavior. I don’t recall where.
FWIW, the proper way to populate past history is with the storeTagHistory function. (Whoops, just noticed pascal mentioned that.)
This is actually what I have been using, but I also wanted to write the latest historical value to the value of the tag, keeping the timestamp of the historical record. If I write all historic records using storeTagHistory and also write the tag value, I would then get two entries in the database (well actually I believe I'm getting duplicate id errors stacking up in my s+f quarantine log due to exactly this). So then I thought that maybe I could just use tag.write* to write all of the historical records using qualified values to the same tag in the one tag write function. Maybe this would bring other complications, but I was curious to see if it would work.
I think i'll just go back to what I originally planned and write all but the latest record using storeTagHistory, then write the latest record via tag.write*.
The gateway I actually tested this on does not have this option checked, however the gateway I'm actually using this for does since we are predominately talking to MQTT devices. This probably explains why I was seeing it working when I first posted, but then wasn't seeing it working yesterday on the other gateway. It's all very complicated...
So I’ve just tested this finally and have an issue.
To recap, I retrieve a list of history for a point from an API and want to write this into Ignition’s history. I want to set the current value of the tag to the value of the latest historic record from the API with the timestamp of the value taken from the historic timestamp.
When I “allow back-fill of data” for the tag provider, I can use system.tag.write* to store history for the tag by supplying BasicQualifiedValues, however the current value will never be written to now since all values in the past are not written to the current value, and it would be incredibly rare for the api to return a historic value with now() as the timestamp.
If I disable back-filling, then I can write to the history using storeTagHistory and I can write to the current value using tag.write, but then I lose the ability to write the timestamp of the current value…
Is there any work around?
I’d probably use the second method, write everything to the historian with storeTagHistory, including the last one, then do a write* for the last value, which shouldn’t be historized since this value is already the last one in the history. If you need this tag to have its original timestamp, it shouldn’t be a problem, you can write the timestamp you like on it, it just wouldn’t be historized with it, but it’s not a problem if it has already been historized.
I did test this and this isn't correct. It is based on the last value of the tag, not the last value in the history. storyTagHistory doesn't write to the tag value.
I have tried writing a BasicQualifiedValue to a tag using tag.write* but this just sets the timestamp to the time you wrote to it, not to the timestamp that you provide.
To work around the issue, I ended up setting the historical deadband value to something stupidly high (9999999999) so that tag.write will never write history to the tags, only storeTagHistory will. It doesn't solve the timestamp on the tag value itself, but I can live with that
Because I still want to record and display history. History just isn't collected for these particular tags in the usual way. History is literally being returned from a restAPI call and then being stored into the tags' history. If I turn off history, then I have no tag to store it against (although the storeTagHistory function does accept tags and providers that don't exist) and no way to view it (maybe this is incorrect due to previous bracket comment). But I guess more generally, it's nice to know which tags are collecting history from the configuration of the tag, rather than turning it off and having to rely on knowledge of the system to know they're actually being trended
Maybe I just didn't hit the enter key in the right spot?
But then someone seeing 999999 as the deadband might think that it will never historize anything (or worse, think it's misconfigured and change that value), and wonder where the history comes from. They'll have to have that knowledge anyway.
If the benefit is having data in the historian, I believe storeTagHistory does that as well.
But that’s not very important, the difference is small enough that it’s not worth spending time on it.
For future reference, and/or other visitors stumbling upon this topic. Even without enabling the "Allow Back-fill data" option of the realtime tag provider, I'm able to update the value of a tag including timestamp using a BasicQualifiedValue as demonstrated by @nminchin earlier in this topic.