You can help by commenting or suggesting your edit directly into the transcript. We'll review any changes before posting them. All comments are completely anonymous. For any comments that need a reply, consider emailing email@example.com.
Reading and Writing Tags
Learn how to read from and write to Tags from a script.
Video recorded using: Ignition 8.1
Transcript(open in window)
[00:00] In this lesson, we're going to learn how to read from and write to tags in Ignition using component event scripts. Before we get started on that, here are some initial considerations we might wanna ask ourselves. What are the specific tags we wanna read and write? Are there one or many such tags? And do we have all the needed tag paths available to us? What tag read and write mode is to be used? Are we gonna do synchronous or blocking reads and writes, or do we wanna use asynchronous or non-blocking reads and writes? Let's consider a simple example which exercises all of these options. Here in our designer, we've got four buttons representing the four possible read and write cases. And each of these buttons is simply a nice, neat user interface to an underlying action performed event handler script as we'll see in a moment. There are two reads and two writes, two of them blocking, and two of them non-blocking. Next in our tag browser, let's expand the writeable tags, and note that we've set a few of these to non-zero or non empty initial default values.
[01:13] These writeable tags just come from the generic simulator of the default ignition OPCUA server, which is really helpful as a source of sample test data. All of these example cases will have a lot in common. So let's look at this first example in some detail, and then the others will be quite similar. For this first example, let's keep this real simple. We're just going to read one tag's known value. We're going to use system.tag.read blocking, which is a synchronous read, which just means the function isn't going to return until the read has actually been issued. Its one input is the desired tag path, which we see a placeholder for here on line two. We can get the needed value in two ways. We can right click on the value of interest and select copy path. But the easier way is simply to use the tag button, then navigate down to the tag of interest like so, it's this writable double one, and we'll click okay to insert it.
[02:16] Both of these will give us the same tag path we see here. So on line five, we see the actual read using read blocking. In general, its input will be a list of tag paths. So this is just like a list with just one element. But when you call this, the value you get back is not directly the value of the tag. Rather, it's a list of what are called qualified value objects. So two things to note here. First, we have to index into that list, even if it's only for one element. So that's why we need the zero index here. Second, a qualified value has three different things inside of it, which we have to dereference. So here it has a value which is dot value, and this is the part we're really after, but it also has a quality.
[03:02] This is the data quality of whatever tag you read it from. And it has a timestamp. This is the timestamp of when the tag last changed. So to run this, we will click apply to save any changes. Then we'll go to the preview mode up here and click the read tag synchronous button, and let's bring back the scripting window. We see the quality and the value and the timestamp as noted. So remember that it's usually the dot value portion that we're really after. Let's now look at the other examples, which will be variations on the same pattern. For our next example, we're going to do the same thing, but in reverse. Now we wanna write one value to one tag, specifically the second string one down here. So on line two, just as before, we need the full tag path to be written to. Note that it's string two this time.
[04:02] As we saw before, we know there's two ways to get this. And on line five, we also need the value to be written. On line eight, we do the actual write using write blocking or a synchronous write. Here we need to input values, the tag to be written to, and the value to be written. And again, note that in the general case, these would be lists of values. So a list of tags and a list of values. To run this, let's go to preview mode up here and click the write tag synchronous button, and bring back our scripting window. We can see that the value world got written to the specified tag. And so that is all that there is to this one. For our next two examples, note that there will be two key differences. First, we'll show how to read and write multiple tags at once, not just one at a time. To do this, all we need to do is use lists of tag paths and values, not just individual ones. This is important from a program performance standpoint. If you need to read from or write to large groups of tags, say 100 tags or so, calling individual reads or writes 100 times in a row is very inefficient because each one needs to communicate separately with a gateway.
[05:15] Whereas if you group these into lists and make one single communication, the efficiency goes way up, and thus the performance of your application will go way up. Secondly, our first two examples were synchronous or blocking reads and writes, meaning the functions don't return until they've actually been issued. By contrast, asynchronous or non-blocking reads and writes return immediately, but the actual operation will take place sometime later. Soon afterwards, but we don't know exactly when that will be. So these functions will also need to provide a callback function to take care of these results when available. Beyond this, it's important to take into account whether a value has actually made its way to its final destination. For example, suppose you're writing a value down to a PLC through an OPC server.
[06:04] Write blocking will only return once the write has actually been communicated to the OPC server. But it may take some time for a write to get all the way down to the PLC, and for a value to be read back from the PLC, just something to keep in mind. For our next example, we're going to read from multiple tags asynchronously. So on lines eight to 10, we have individual tags of interest, this time grouped together into a list of tags. And for this example, we also need this callback function at the head of the file. Its required one input is a return list of qualified values. And what we'll do is simply loop over that list and print each return value field. So on line 14, we'll call the asynchronous read function, read async. Its first input is what tags are to be read from. And its second input is what to do with those values, ie the name of our function.
[07:04] As stated, this will take place at some indefinite time in the future, a fire and forget deal. So if we go to the preview mode and run this example, we see the three tag values that we intended to read back. And for our final example, it's going to be very similar to the prior example, except now we're going to write to multiple tags asynchronously. So on lines 11 to 13, we have the individual tags of interest grouped together into a list of tags. And just for the clear contrast, note that we're writing to the second of each such tag. On line 17, we see the values to be written, also this time in a list. And again, we have a callback function at the head of this file. This time, the required one input is a list of quality codes. And again, we're going to loop over that list. And for now we'll just print out whether or not that quality code is good.
[08:06] On line 18, we have the asynchronous write function, write async, and this time it needs three inputs, the tags to write to, the values to be written, and the function which acts upon the return quality codes. Again, this will take place sometime in the indefinite future. So if we go to the preview mode and run the write tags asynchronous example, we see that the three tags were written, and we see that they were all good writes. So in this lesson, we've seen how to read or write tags, either singly or multiply, and to do so either synchronously or asynchronously, or in a blocking or non-blocking manner.