Just curious to see if there's a better way of doing this. But currently I need to pull information for a couple of machines via Kepware and Modbus. The information comes in very quickly but can very from machine some as quick as 120 boxes per minute while others come in at 45 boxes per minute. So some machines I'm scanning at 250 ms while the others I have them at 150 ms. I have historian turned on and am capturing everything correctly however when I go to pull the information and put it in a CSV file using system.tag.querytaghistory I have to set the result to a big number just to get all the information because if I set it to 0 or -1 then I get missing information since for example the name of the machine doesn't change or the product it's running doesn't change so it may show up once and never again. So I have to set the start and end time in this case I have it as a static 8 hours and then I divide that into how many points would be 250 ms and then grab the information that way then remove any duplicates and get my scv results. Just wondering if there's an easier way to grab all my information since I'm in ms sometimes one value will change before another so it's gets kind of tricky to capture everything accurately
If only Modbus, skip kepware, use Ign native driver or phils modbus driver.
For fastest reads, don't poll the data using tags, instead builk script read with
Reading 8 hours of data and dividing that by 250mS blocks and expecting repeatable results is asking for trouble.
I would script the bulk read, and insert into SQL, then use SQL to count quantity in 8 hours, then do your post processing to CSV as a separate exercise.
It's Modbus to Kepware to Ignition. It has to be this way since it's being used in other places too.
Do you have an example of how this would work.
Let's say I need, MachineName, Machinedescription, Product running, totalCount, badCount, goodCount. And I need each totalCount to show up with all this information in consecutive order. Would this work?
Create a SQL column for each, on each OPC read values pull the latest info and insert into a new row.
If totalCount can be relied on, use that as your trigger for opcReads. Monitor totalCount super fast and when it changes, do a readValues of everything and insert to SQL.
Use GateWay scripts, do not put this scripting into tags script section.
Search the forum, you will find similar topics on OPC reading fast to get you started.
Wow this is true! I don't know how I didn't think of that! Would this work using transaction groups? Also how do I compensate if tags change delays. For instance totalCount changes then underweight changes like 2 ms after?
Your best bet is probably transaction groups with a trigger, but in the database, I think storing the Metadata like machine description as part of the transaction group data is a bad idea. Put any extra data like this that's static in a separate table that you can join with the transaction group data in queries and only store the unique identifier of the machine with the counts you need stored. If the total ALWAYS matches the sum of the other tags you don't need to save it either, but can use it as your trigger to read the other values.
Be aware though, that while transaction groups are easier to implement and get running quickly, they have their limitations - discussed on the forum. Therefore, my advice is; if you can script it, then script it.
Yea that would be great! But one of the main requirements is to use this Kepware setup. Now when it comes to collecting I should be fine just using the transaction group? My only fear which I had in the beginning is sometimes totalCount gets updated before bad or good counts does. Like milliseconds sometimes. Is there anyway I can compensate for this?
Not really, you need a state machine that can lock based on a monitored condition, if things change outside of that, it's poor data management in the OEM kit.
All those are there and working properly. Using tag historian I'm grabbing all the information and not missing it. However, my worry is if while running the tag change script another change happens will I miss one of those? In the event that it still in the writing tag to the database part or hanging for whatever reason. The issue is I can't miss a single value going in.
If you are getting it, and not missing data, using the tag historian, then OpcReadValues is going to be much quicker.
Put some completion time code into your script that executes on totalCount changing that does the write to DB.
You should be able to do this (script) in single-digit milliseconds.
If you do miss events you may consider putting a PLC to poll the end hardware on modbus, and store events in a buffer. Then, get SCADA to pull them out of the buffer with appropriate handshaking.
Sorry to ask so many questions but I have one more. If some of these are memory tags as in I pull the value of a Modbus tag and then retain it as it clears when they don't want it to would it better to use system.tag.read instead? And if so would it still run at the same speed?
Pull via OpcRead and if you still want it in a memory tag, use system.tagWrite(blocking) to write to memory tags at the same time as inserting to your DB.
Tag reads do not go out on the wire to get fresh data. They just retrieve the value last delivered by the subscription. If you work on a trigger on a tag, then read from other tags, those other tags may not have the latest value. That is the point of system.opc.read* -- it gets fresh values from the endpoint. Ideally, when you use system.opc.read*(), you do not make Ignition tags for them. Or if you must, make memory tags as Matrix suggests.
There is some good data in this thread regarding high-speed data collection. Glad you were able to achieve desired results with your advertised architecture.
If you are happy with the data is stored in your original architecture, and still wish to utilize Ignition's Historian (w/ the analog compression & value-change events it awards), is it an option to system.opc.readValues() for all tags in the system.tag.queryTagHistory() to get a 'current value' for each and display that data in your report without duplicating data in your historian? If you opt to leave your existing polling architecture alone, but still wish to insert data periodically, you can also add a 'maximum time between samples' to each of your tags which are not expected to change.
No, tag reads would simply get the most recent polled value instead of the most recent subscription delivery. No gain for a very substantial increase in workload/traffic.