1. Batch Database


Batch processing presents several issues that warrant specific server support. Continuous process enterprises tend to have less but larger equipment. Data sources (PI Points) on this equipment tend to be large in number with each source being unique.

Batch process enterprises tend to have many similar processing units. The data source count may be large; but from unit to unit there are many similar data sources. The duplication of many data sources across units lends itself to a hierarchy of structures to encapsulate common unit attributes. These concepts are handled in the PI Module Database/SDK.

Production runs on continuous processing equipment generally cover relatively long time periods with little down time between runs. The runs have associated identifiers, but the long runs lead to few unique identifiers. In practice, a dedicated database to relate identifiers with processing time is not required; time period of run is often more descriptive than the identifier.

The time series data associated with batch processing tends to be relatively short runs with down times between runs; unique identifiers are normally assigned to the runs. Products and process may vary considerably from run to run. The large number of runs, with down time between, places more emphasis on the batch identifiers. A database is needed to relate the batch identifiers to the time series data. The PI Batch Database/SDK provides this functionality.

  1. Time Series Data

Time series data is organized in three distinct groups: PI Archive, PI Batch, and other sources.

The PI Archive generally contains the bulk of the data associated with equipment or processes. A few typical data sources that are stored in the Archive are:

Generally, any data from a consistently identifiable source may be stored in the Data Archive. If you know when and where the data came from, it belongs in a PI Point.

The PI Archive is accessed through two primary keys, time and point. Data from a batch processing have periods of meaningful data--during equipment operation; and periods of meaningless data--during equipment-idle periods. Knowledge of equipment operation periods is required to informatively view PI Archive data. The PI Batch databases provide this information by linking batch identifiers to appropriate time periods in the Archive.

  1. ANSI/ISA S88

The Instrument Society of America Batch Specification (ANSI/ISA S88) played a significant role in the design of the PI Batch Database. As the name implies, batches are stored in the PI Batch Database. What is a batch? An explicit definition is required before a database can be designed. ANSI/ISA S88 provides the following definition:

batch:

  1. The material that is being produced or that has been produced by a single execution of a batch process.
  2. An entity that represents the production of a material at any point in the process.

NOTE: Batch means both the material made by and during the process and also an entity that represents the production of that material. Batch is used as an abstract contraction of the words 'the production of a batch.'" (ANSI/ISA-S88.01-1995 page 14)

Clearly, these are two distinct definitions and a separate data model is required for each:

These objects are the PIBatch and PIUnitBatch, respectively. Usually, but not necessarily, a PIBatch is made up of one or more PIUnitBatch objects.

  1. PIBatch

The PIBatch object is the primary time series object used to record and track batch production. Batch in this case, is the material made--not the physical processing required in making the material. PIBatch objects do not directly relate to production equipment; PIUnitBatch objects handle this. The PIBatch object effectively tracks the production management of the material--PIUnitBatch objects track the production processes. Data associated with a PIBatch may be stored in the PIBatch object's PIProperties collection.

PIBatch objects are created and accessed through the PI-SDK PIBatchDB object. The PIBatchDB object supplies interfaces to all the batch time series objects that are not tightly coupled to equipment. The other supported time series objects are PITransferRecord objects and PICampaign objects.

Calling the Add Method of PIBatchDB creates PIBatch objects. PIBatch creation has very few restrictions: A start time must be specified and a valid archive must be online for the start time.

  1. Initializing the PIBatch Data Store

The data store for the PIBatch objects is created in the primary archive, on the first addition of a PIBatch object. The actual data store is a PI Point of type String. One PI Point is used to store all PIBatch objects. Only the primary archive sees newly created points, therefore, initially, PIBatch objects can only be added for times valid for the primary archive--no more than 10 minutes into the future, back to the start time of the primary archive.

Once the data store is added, PIBatch objects can be added to all new archives. Adding PIBatch objects to earlier times is similar to "back-filling" data into newly created PIPoints--older archives, without knowledge of the new PIPoints, must be unregistered, then new archive covering target time range must be created.

Here is an example of PIBatch creation:

Private Sub cmdCreatePIBatch_Click()

Dim Batch As PIBatch

Servers.DefaultServer.Open "UID=piadmin"

Set Batch = Servers.DefaultServer.PIBatchDB.Add("", "", "", #3/16/2001#)

End Sub

This example creates a simple batch; it just has a start time. Since there are few restrictions on start time, this function could be called many times, each time creating a new PIBatch. Each newly created PIBatch is assigned a unique id. Even if many PIBatches are created at the same time they are still uniquely identifiable. PIBatch objects may have overlapping times.

The PIBatch objects are stored in the PI Data Archive. The storage algorithm validates data associated with the new PIBatch. After validation, a unique ID is assigned. A PI Event (a time/value pair) is created; the value is the unique ID; the timestamp is the PIBatch start time. The event is written to the PIBatch PI Point. If the write fails, the PIBatch is not created and an error is returned to the calling application. The archive write will fail if no valid archive is online for the target time, or if the calling application has insufficient rights. All the PIBatch object's properties are written to the archive annotation file associated with the target archive when the event is successfully written.

  1. PIBatch Properties

The PIBatch object created above has very few properties set: start time and Unique ID. Obviously, to be of use, the PIBatch requires other properties. Here's a description of each property.

StartTime/EndTime

StartTime and EndTime represent the period of time where this PIBatch was in production. "In production" does not necessarily infer continuous production activity. Actual production activity is tracked via the PIUnitBatch object--the PIBatch StartTime/EndTime generally represents the time from when the PIBatch was first scheduled through completion of the PIBatch. The StartTime is the primary index; its value must be within a time span of a valid archive. There are no restrictions on the EndTime.

StartTime and EndTime are changed using the corresponding set method--SetStartTime or SetEndTime. StartTime and EndTime are PITime objects

BatchID

The BatchID is an identification string. The BatchID is often an identifier assigned by a production planning or control system. The identifier is often assigned early in the production process. This identifier is normally assigned to all processing activities used specifically in the production of the batch. The BatchID is the site assigned identifier; this is not the UniqueID automatically assigned by the PI Server on initial PIBatch object creation.

Currently, the PI Batch Database does not index BatchID; future releases will.

Product

Product Name assigned to material being produced. The data type of the Product property is a VARIANT. The VARIANT data type allows flexible product identification; for example, a link to a product database.

Allowable VARIANT types for this property are strings, numeric, and single dimension arrays of numeric. This property may be set to VARIANTS of any of these types, but current search methods only support string matches. If Product is set to a non-string, it can be accessed (read or write) but wild card searches will not attempt to filter on the property.

For example, a search over a time period for all PIBatch objects that contain the string "Red" will return all PIBatch objects where product VARIANT type is string and contains "Red", plus, all the PIBatch objects over the period where product VARIANT is not a string.

Future releases will have defined interpretation of non-string types for all the search methods.

Recipe

This property represents the recipe used to produce the material. Like Product, the data type is a VARIANT. The reasons are similar--a VARIANT allows more flexibility, perhaps a link to a Recipe management system. The current release has the same limitations and behavior of the Product property.

PIUnitBatches

A PIUnitBatch object represents an actual production process used in the material production. Often there are several processing steps. The PIUnitBatches collection allows grouping these processing steps within the PIBatch object. A PIBatch object, through its PIUnitBatches collection, can own many PIUnitBatch objects, but a PIUnitBatch object may only belong to one PIBatch object.

PIProperties

A PIBatch object is not closely related to equipment. Also, a PIBatch object does not necessarily cover a period of time with continuous processing. Thus, data associated with the PIBatch object does not fit the criteria for data archive storage--well defined time and well defined source. Data associated with a PIBatch object is stored in the object's PIProperties collection.

The PIProperties collection, as the name suggests, is a collection of PIProperty objects. PIProperty objects are name/value pairs. The value can be a VARIANT of type strings, numeric, or single dimension numeric arrays.

PICampaign

The PICampaign object allows logical grouping of PIBatch objects. Future releases will support this.

  1. Server Assigned Properties

There are several properties assigned during creation of the PIBatch object. See the PI-SDK reference documentation for more information.

The simplest way to edit a PIBatch object is to set the target property to the desired value. The following example edits the recipe and product properties:

Batch.Recipe = "Rec:129.35"

Batch.Product = "Salt Water"

In both cases, a string is assigned to the PIBatch object property. Each assignment sends the modified object to the server; the server validates and if successful stores the changes by modifying current record. In this example two complete round trips--to the server and back--are made. An error is raised if validation fails.

Modifying the StartTime or EndTime is slightly different. Rather than assigning a time to the property, the SetStartTime or SetEndTime method must be called. Changing the EndTime modifies the currently stored PIBatch record. Changing the StartTime involves more server activity.

The StartTime is indexed by the data archive. As described above, an event is inserted into the archive at the PIBatch StartTime. Therefore changing the StartTime requires re-writing the PIBatch record to the data archive, and upon success, removing the PIBatch record at the previous StartTime. The EndTime property, when not set, evaluates to "Nothing." The PIBatch is considered to be active, or running, if the EndTime is not set.

Each property assignment, as mentioned above, requires a round trip to the server. If several properties require modification, several server round trips are required. This can be slow. A more efficient method is available: ModifyAttributes. This method allows building a table of desired edits, and then in one call to the server, performs all the edits. The table of requested changes is a NamedValues collection.

ModifyAttributes involves creating a NamedValues collection, then adding a name-value pair for each property to be modified. The name is the property name; the value is a VARIANT containing the new property setting. Since this method may be used to modify several properties, several errors could occur. Therefore, errors, if any, are returned in another NamedValues collection. The AttributeName method, supported by the PIBatchDB object, is supplied to programmatically get attribute names. This prevents programming errors.

Here's an example using ModifyAttributes to change the Recipe, Product, and EndTime in one call; notice the use of AttributeName method:

Private Sub ModifyAttributesExample(Batch As PIBatch)

Dim nvsAttributes As New NamedValues

Dim nvsErrors As New NamedValues

Dim nvError As NamedValue

Dim ptEnd As New PITime

Dim BatchDB As PIBatchDB

ptEnd.LocalDate = Now()

Set BatchDB = Servers.DefaultServer.PIBatchDB

nvsAttributes.Add BatchDB.AttributeName(mbaEndTime), ptEnd

nvsAttributes.Add BatchDB.AttributeName(mbaProduct), "DI Water"

nvsAttributes.Add BatchDB.AttributeName(mbaRecipe), "Rec:120.21"

On Error GoTo EH0

Batch.ModifyAttributes nvsAttributes, nvsErrors

Exit Sub

EH0:

For Each nvError In nvsErrors

MsgBox nvError.Name & " " & nvError.Value

Next nvError

End Sub

PIBatch objects may be removed from the PIBatchDB by calling the PIBatchDB.Remove method. The Remove method takes one argument: the PIBatch object to be removed. The object is sent to the server. Based on the UniqueID and StartTime, the archive event is located and removed from the data archive.

Here's a VB subroutine demonstrating PIBatch object removal:

Private Sub RemoveBatch(Batch As PIBatch)

Dim BatchDB As PIBatchDB

Set BatchDB = Batch.Database

BatchDB.Remove Batch

End Sub

  1. Searching the PIBatch Database

PIBatchDB has two search methods: a general search that takes SQL-like statements and a search method that allows string masks or UniqueID specification. The SQL-like method, PIBatchDB.Search, will be supported in a future release. The other method is PIBatchDB.PIBatchSearch. This method takes the following arguments

SearchStartTime and SearchEndTime define the time range to search. Any PIBatch that has any portion of its time period overlapping the time range is considered within the time range. This includes PIBatch objects with a StartTime equal to the SearchEndTime and PIBatch objects with an EndTime equal to the SearchStartTime. The times are passed as VARIANTS. Supported types are PITime objects, strings that represent Local Date, and Doubles or Integers in UTC seconds since 1970. Basically any format supported by the PITime object will work.

NOTE: The PIBatch database supports records with overlapping times. For example, there are no restrictions to having a PIBatch which runs from 1-Jan-1980 through 31-Dec-2000, with many shorter batches between these times. This poses a significant search algorithm problem.

The PIBatch records are stored in a PI Archive and thus are indexed on start time. The find methods, which take a search start and end time algorithm attempt to find all matching records that are active over the search period. Therefore, using the above example, a search for all active PIBatch's during December 2002 would have to search every PI Archive online. Obviously this approach could take a considerable amount of time and computer resources; therefore, a compromise algorithm is necessary.

The compromise is to only return records that are active within the search period and have started within the last 30 days. A future PI3 release will support end time indexing. When this feature is available, searches will return all records that are active over the search period and the 30 day limit will no longer be necessary.

The current search algorithm is only indexed on time. Therefore, narrow time ranges result in quicker searches. Future releases will likely support more indexing. In this version, BatchIDMask, ProductMask, and RecipeMask are effectively filters. The mask data types are strings; any string may be passed, special characters are '*' for a sub-string wildcard, and '?' for a single character wild card.

The AsynchStatus argument allows asynchronous searches and canceling of long running searches. This property will be supported in a future release. This argument should be set to Nothing until it is supported.

The PI Batch Database search algorithm first finds all PIBatch objects within the search time range. Each passed mask is case insensitive compared to the corresponding property of each PIBatch found in the time range. If any passed mask does not match the property, the PIBatch is not returned. Non-string Product and Recipe types, for example a Product set to an integer, are not compared with the mask; as long as the other masks match, the PIBatch object is returned.

All PIBatch objects are assigned a UniqueID on creation. To find a specific PIBatch object, the PIBatchSearch method supports passing the UniqueID. When the UniqueID is passed, all masks are ignored. The SearchStartTime and SearchEndTime are still required--all PIBatch objects are indexed on StartTime--supplying a search time range that covers the time period of the target PIBatch is required.

All matching PIBatch objects are placed in a PIBatchList collection and returned to the caller. If no matching PIBatch objects are found, the call returns success, but the PIBatchList collection is empty.

The PIBatchList collection has all the methods and properties expected of an ActiveX collection. There are two methods to note: Insert and Merge. Explaining these methods requires an explanation of the PI-SDK collection types.

The PI-SDK has two types of collections--server connected collections and creatable connections. Server connected collections are direct interfaces to a server database or a portion of a server database. Adding an object to a server collection adds the object to the server database; removing an object removes it from the server. Generally, the naming convention of server-connected objects is the plural form of the object it contains. For example the PI Point Database is represented by the PIPoints collection.

Creatable collections exist in an application with no corresponding collection on the server. They are used to collect objects returned by searches, such as the PIBatchSearch method, or other database access methods, for example, Server.GetPoints. They are not directly connected to the server--removing an object from the collection does not remove it from the server, just the local collection. The naming convention of creatable collections is the object it contains appended with "List."

These lists are handy for organizing objects obtained by various means from the server. The Insert method allows adding an existing object to the collection. For example, two PIBatchSearch calls results in two PIBatchList collections. The PIBatchList.Insert method allows adding a PIBatch object, obtained from one list, to another. The PIBatchList.Merge method allows adding all objects of one list to the other.

In summary, PIBatch objects represent the overall production or production management of a material or product. A PIBatch is not tightly coupled to processing equipment. The lack of a tight relationship with equipment makes it difficult to have a tight relationship with PIPoints and the Archive. Therefore, the PIProperties collection of the PIBatch object is available to store associated data. Each PIBatch object has a PIUnitBatches collection for associating physical processing with the PIBatch.

  1. PIUnitBatch

PIUnitBatch objects represent a period of processing or activity in a specific piece of equipment. A specialized PIModule represents the equipment. PIModule objects have a Boolean property "IsPIUnit." PIUnitBatch objects can be added to the PIModule if this property is set to true; a PIModule with this property true is logically considered a PIUnit.

IsPIUnit is a Read/Write property. Setting this property as true does incur some overhead--the PIModule is added to the server maintained PIUnit index and a PIPoint is added for PIUnitBatch storage; the PIPoint is actually created on the first attempt to add a PIUnitBatch.

Storage of PIUnitBatch objects is similar to PIBatch objects, except that there is a PIPoint for each PIUnit; there is only one PIPoint for all PIBatch object storage. The PIUnitBatch storage technique has the same issues as PIBatch storage: when the storage point is created, PIUnitBatches can only be added for times more recent than the primary archive start time. This design allows for PIUnitBatch objects to be indexed by their owning PIModule (a PIUnit) and StartTime. Future releases will have indexes on other PIUnitBatch properties.

The AddPIUnitBatch method of PIModule creates PIUnitBatch objects. There is an important difference between creating a PIBatch object and PIUnitBatch object. PIBatch objects are added to the PIBatchDB; PIUnitBatch objects are added to specialized PIModules--PIUnit's. Logically, PIUnitBatch objects are stored and accessed through the PIModuleDB

Here's an example of PIUnitBatch creation:

Dim ExampleUnit As PIModule

Dim UnitBatch As PIUnitBatch

Dim ptStart As New PITime

ptStart.SetToCurrent

Servers.DefaultServer.Open "uid=piadmin"

Set ExampleUnit = Servers.DefaultServer.PIModuleDB.PIModules.Item("Examples")

Set ExampleUnit = ExampleUnit.PIModules.Item("PIBatchDbTest1")

Set ExampleUnit = ExampleUnit.PIModules.Item("Unit1")

Set UnitBatch = ExampleUnit.AddPIUnitBatch("", "", ptStart)

The PIUnitBatch is added to the PIUnit "Unit1;" remember, PIUnit is terminology for a PIModule with the IsPIUnit property set true. The PIUnitBatch object was created with empty strings for the BatchID and Product. StartTime is approximately current time and the EndTime is not set, therefore the PIUnitBatch is considered active or running. Unlike PIBatch objects, there are server-enforced rules for PIUnitBatch StartTime and EndTime.

Only one PIUnitBatch may be active in a PIUnit over any time period. The StartTime of a batch may equal the EndTime of the previous batch; no other overlap is allowed. If EndTime is not set, the PIUnitBatch is active; a newer PIUnitBatch cannot be added to a PIUnit until the active PIUnitBatch has ended. A PIUnitBatch may be added back in time while one is active as long as both start and end times are set. Edits of the StartTime or EndTime force the server to check for overlaps; the edit will fail if an overlap is detected.

  1. PIUnitBatch Properties

The AddPIUnitBatch method allows setting the BatchID, Product, StartTime, and EndTime on creation. These properties and all other Read/Write properties can be set at anytime. A description of all PIUnitBatch properties follows:

StartTime/EndTime

StartTime and EndTime represent the period of time when this PIUnitBatch was active. During this period, the PIUnit and sub-modules of the PIUnit are considered involved with the PIUnitBatch. These properties are read only. Use the SetStartTime and SetEndTime methods to modify these properties.

BatchID

The BatchID is an identification string. The BatchID is often a unique ID assigned by a production planning or control system. The ID is usually assigned early in the production process. This ID is normally assigned to all processing activities used specifically in the production of the batch.

Currently, BatchID is not indexed; future releases may index this property for performance improvement.

Product

The Product property is the name assigned to material being produced. The data type of the Product property is a VARIANT. The VARIANT data type allows flexible product identification; for example, a link to a product database. Allowable VARIANT types for this property are strings, numeric, and single dimension arrays of numeric. This property may be set to VARIANTS of any of these types, but current search methods only support string matches.

If Product is set to a non-string, it can be accessed (read or write) but wild card searches will not attempt to filter on the property. For example, a search over a time period for all PIUnitBatch objects that contain the string "Red" will return all PIUnitBatch objects where product VARIANT type is string and contains "Red", plus, all the PIBatch objects over the period where product VARIANT is not string.

Future releases will have defined interpretation of non-string types for all the search methods.

ProductName

In strict ANSI/ISA S88 terms a PIUnitBatch could be called a unit procedure. A procedure is usually a portion of a Recipe. This string property is used as an additional identifier, and can be used to refer to a particular portion of a recipe.

PIBatch

The PIBatch object has a PIUnitBatches collection. PIUnitBatch objects that are part of a PIBatch may be added to this collection. This establishes the link between physical processing (PIUnitBatch) and the management of producing the material (PIBatch). This property is set when the PIUnitBatch is added to the PIBatch.PIUnitBatches collection.

PISubBatches

This property is a collection of PISubBatch objects associated with the PIUnitBatch. A PISubBatch represents an identifiable portion of a PIUnitBatch. Examples of sub-batches are Operation, Phase, and Step.

PISubBatch objects allow special identification to portions of a PIUnitBatch. This collection is hierarchical, thus allowing collection of PISubBatch objects within other PISubBatch objects. For example, it is possible to have 2 simultaneous (parallel) phases and explicitly assign steps to the appropriate phase.

S88 examples of sub-batch classification or types are Operation, Phase, and Step. This is common terminology, but may not be applicable everywhere. For flexibility, the PISubBatch object has a PIHeading property. This allows creation of PIHeadingSets, which represent sub-batch classification names.

  1. PIUnit

This property is the PIModule where the PIUnitBatch object was created. PIUnit is a read only property.

  1. Server Assigned Properties

There are several properties assigned during creation of the PIUnitBatch object. See the PI-SDK reference documentation for more information.

PIUnitBatch objects represent time series data associated with the PIUnit. The StartTime and EndTime must be specified unambiguously. Therefore, the two criteria for archive data are met: known data source, the PIUnit, known time: the time period of the PIUnitBatch.

A PIUnit is just a specialized PIModule. The PIAliases collection of the PIModule is used to specify the PIPoints associated with the module. PIModule objects support hierarchical organization of sub-modules, which effectively allows hierarchical organization of data associated with the PIModule.

The unambiguous relationship among the PIUnitBatch, PIUnit, and time period makes the Archive the ideal store for PIUnitBatch data. The data archive has the advantage of many applications that can write, read and properly interpret the data.

  1. Edits and Deletes

Editing a PIUnitBatch object is similar to editing a PIBatch object. Any Read/Write property can be set to the desired value. The ModifyAttributes method may be used to make several edits in one call.

A PIUnitBatch is removed from the server by calling the Remove Method of the owner PIUnit. Here's an example subroutine that removes a PIUnitBatch.

Private Sub RemoveUnitBatch(UnitBatch As PIUnitBatch)

Dim PIUnit As PIModule

Set PIUnit = UnitBatch.PIUnit

PIUnit.Remove UnitBatch

End Sub

  1. Searching for PIUnitBatch Objects

PIUnitBatch objects are logically part of the PIModuleDB. There are four methods available to find PIUnitBatch objects:

PIModuleDB.Search*

PIModule.Search*

PIModuleDB.PIUnitBatchSearch

PIModule.PIUnitBatchSearch

* The first two Search methods support SQL-like queries; the PIModuleDB implementation searches the entire PI Module Database, the PIModule implementation searches the module and sub-modules owned by the module. These two methods are not supported in this release.

The two PIUnitBatchSearch methods are supported. They are identical except that the PIModuleDB implementation searches all PIUnit's in the PI Module Database and the PIModule implementation only searches PIUnitBatch objects that were created on the module. These methods take the following arguments

SearchStartTime and SearchEndTime define the time range to search. Any PIUnitBatch that has any portion of its time period overlapping the time range is considered within the time range. This includes PIUnitBatch objects with a StartTime equal to the SearchEndTime and PIUnitBatch objects with an EndTime equal to the SearchStartTime.

The times are passed as VARIANTS. Supported types are PITime objects, strings that represent Local Date, and Doubles or Integer in UTC seconds since 1970. Basically supported types are any format supported by the PITime object.

The current search algorithm is indexed on time and PIUnit. Future releases will likely support more indexes. BatchIDMask, ProductMask, ProcedureMask, and SubBatchMask, in this version, are effectively filters. The mask data types are strings; any string may be passed, special characters are '*' for a sub-string wildcard, and '?' for a single character wild card.

The AsynchStatus argument allows asynchronous searches and canceling long running searches. This property will be supported in a future release. This argument should be set to Nothing until it is supported.

The search algorithm first builds a list of PIModules to search. Of course, if the PIModule implementation is called, the calling PIModule is the only one searched. The PIModuleDB method searches the PIUnit index for all PIUnit names that match the PIModuleNameMask. Each PIUnit is searched for all PIUnitBatch objects within the search time range. Each passed mask is case insensitive compared to the corresponding property of each PIUnitBatch found in the time range. If any passed mask does not match the property, the PIUnitBatch is not returned. Non-string Product types, for example a Product set to an integer, are not compared with the mask; as long as the other masks match, the PIUnitBatch object is returned.

All PIUnitBatch objects are assigned a UniqueID on creation. To find a specific PIUnitBatch object, the PIUnitBatchSearch method supports passing the UniqueID. When the UniqueID is passed, the BatchID, Procedure, and product masks are ignored. The SearchStartTime, SearchEndTime and PIModule mask are still required--all PIUnitBatch objects are indexed on StartTime--supplying a search time range that covers the time period of the target PIUnitBatch is required.

All matching PIUnitBatch objects are placed in a PIUnitBatchList collection and returned to the caller. The collection has zero entries if there are no matching PIUnitBatch objects.

The PIUnitBatchList collection has all the methods and properties expected of an ActiveX collection. The PIUnitBatchList is analogous to the PIBatchList. The PIBatchList discussion, above, applies to the PIUnitBatchList.

  1. PI TransferRecord Database

The PI Transfer Record Database is part of the PI Batch Database. The PI Transfer Record Database is used to track material movements and transfers; for example, the database provides storage for genealogy or data reconciliation type applications.

This database stores PITransferRecord objects; a PITransferRecord represents an instance of material movement or transfer. PITransferRecord objects are time series data. Like PIBatch objects, and PIUnitBatch objects, they are stored in the Data Archive.

A PIPoint is created on first PITransferRecord creation; a single PIPoint provides storage for all PITransferRecord objects. The PITransferRecord is stored at the object's StartTime, therefore, the archive covering the StartTime must be the primary archive or an archive created after creation of the PIPoint used to store the PITransferRecord objects. This is the same issue explained above for PIBatch and PIUnitBatch objects.

The PITransferRecord is a rather simple but abstract object. The Source and Destination properties define where the material came from and where it went. The StartTime and EndTime properties identify the time period of the transfer. The PIProperties collection of the PITransferRecord may be used to store data associated with the transfer, for example, quantity and engineering units. The Source and Destination properties may be set to one of several object types.

The Source and Destination properties are defined as IUnknown types to accommodate several PI-SDK objects. Properties defined as IUnknown allow late binding--actual object type is resolved during run time rather than compile time. Currently, Destination and Source may be set to objects of type PIModule, PIBatch, and PIUnitBatch. There are no limitations other than the types--Source and Destination may be independently set to any of the 3 supported types. Here's a conceptual breakdown of how each of these types may be used:

  1. PIModule

A PIModule usually represents physical equipment. Therefore, setting Source or Destination to a PIModule object infers transfer from or to a piece of equipment, such as a material transfer from one tank to another.

  1. PIBatch

A PIBatch represents some material made; it can also be used to represent a lot of material from a supplier. A Source set to a PIBatch object may imply the source was some identifiable material, perhaps transferred to some equipment or as a material for a batch. A Destination set to a PIBatch may imply addition to, or blending into, some identifiable material.

  1. PIUnitBatch

A PIUnitBatch represents the processing of an intermediate step in a PIBatch production. A PIUnitBatch object as a source would not be common; a set of related PIUnitBatch objects are usually organized in the PIBatch object's PIUnitBatches collection. Although a PIUnitBatch object as a Source could represent dividing an intermediate product among other PIUnitBatch objects. A PIUnitBatch object as a Destination may represent adding ingredients to a PIUnitBatch. A PIBatch object or a PIModule (representing the storage equipment) may represent the ingredients.

The Source and Destination properties are of type IUnknown. Querying the IUnknown for each supported type is the only way to access the object. In VB this involves setting the IUnknown to each type. Here's some example code:

Private Sub ReportType(TR As PITransferRecord)

Dim modSource As PIModule

Dim bSource As PIBatch

Dim uSource As PIUnitBatch

Dim modDestination As PIModule

Dim bDestination As PIBatch

Dim uDestination As PIUnitBatch

' suppress error caused by expected failure when setting to wrong object

On Error Resume Next

Set modSource = TR.Source ' This line Queries the IUknown for the PIModule interface

If Not modSource Is Nothing Then

MsgBox "The source is PIModule: " & modSource.Name

GoTo DestinationTests

End If

Set bSource = TR.Source ' This line Queries the IUknown for the PIBatch interface

If Not bSource Is Nothing Then

MsgBox "The source is PIBatch: " & bSource.BatchID

GoTo DestinationTests

End If

Set uSource = TR.Source ' This line Queries the IUknown for the PIUnitBatch interface

If Not uSource Is Nothing Then

MsgBox "The source is PIUnitBatch: " & bSource.BatchID

GoTo DestinationTests

End If

DestinationTests:

Set modDestination = TR.Destination

If Not modDestination Is Nothing Then

MsgBox "The Destination is PIModule: " & modDestination.Name

Exit Sub

End If

Set bDestination = TR.Destination

If Not bDestination Is Nothing Then

MsgBox "The Destination is PIBatch: " & bDestination.BatchID

Exit Sub

End If

Set uDestination = TR.Destination

If Not uDestination Is Nothing Then

MsgBox "The Destination is PIUnitBatch: " & bDestination.BatchID

Exit Sub

End If

End Sub

  1. PITransferRecord Properties
  2. Source

The Source property contains the transfer source. This may be equipment--a PIModule, or material--a PIBatch or PIUnitBatch. Source is a read only property. Use SetSource to modify this property.

  1. Destination

The Destination property contains the transfer destination. This may be equipment--a PIModule, or material--a PIBatch or PIUnitBatch. Destination is a read only property. Use SetDestination to modify this property.

  1. StartTime/EndTime

StartTime and EndTime represent the period of time of transfer. As with all the time series batch objects, each PITransferRecord object is stored in the PI archive based on the StartTime. These properties are read only. Use the SetStartTime and SetEndTime methods to modify these properties.

  1. PIProperties

Name/Value collection. May be used to store data associated with the transfer.

  1. Server Assigned Properties

There are several properties assigned during creation of the PITransferRecord object. See the PI-SDK reference documentation for details.

Data associated with the transfer may be stored in the PIProperties collection. This collection allows hierarchical storage of Name/Value pairs. The Source and Destination properties provide the majority of data. These properties may a PIModule, PIBatch, or PIUnitBatch.

  1. Create, Edit and Delete

Calling the PITransferRecordDB.Add method creates PITransferRecord objects. The Add method requires a source, destination, and a StartTime. EndTime may be set later, but is not required. The transfer duration is considered insignificant if the EndTime is not set. The following are example VB subroutines, which create PITransferRecord objects.

Dim g_Srv As Server

Dim g_BDB As PIBatchDB

Dim g_MDB As PIModuleDB

Dim g_TRDB As PITransferRecordDB

Private Sub Form_Load()

Set g_Srv = Servers.DefaultServer

g_Srv.Open

Set g_BDB = g_Srv.PIBatchDB

Set g_MDB = g_Srv.PIModuleDB

Set g_TRDB = g_BDB.PITransferRecordDB

End Sub

Private Sub TRExampel1(srcBatch As PIBatch, destUnitBatch As PIUnitBatch, Quantity As Double)

Dim TR As PITransferRecord

Dim ptStartTime As New PITime

' The srcBatch is an ingredient used in the unit batch. The srcBatch may supply the

' ingredient for several unit batches. In this case we are using the properties

' collection to store the quantity transferred. The quantity transferred could

' also be stored in a PIPoint associated with the PIModule where the unitbatch is

' created.

ptStartTime.SetToCurrent

Set TR = g_TRDB.Add(srcBatch, destUnitBatch, ptStartTime)

TR.PIProperties.Add "Quantity", Quantity

TR.PIProperties.Add "Engineering Units", "Pounds"

End Sub

Private Sub TRExample2(srcTank As PIBatch, destTank As PIModule, ptStart As PITime, Duration As Long)

Dim TR As PITransferRecord

' This demonstrates a material movement from one tank to another. There are

' flow meters associated with the tanks, therefore, no need to store

' any data in the PIProperties collection. EndTime is important--the flow meter can

' be integrated over the time to determine the amount transferred.

Set TR = g_TRDB.Add(srcTank, destTank, ptStart, ptStart.UTCSeconds + Duration)

End Sub

Editing a PITransferRecord is similar to editing PIBatch and PIUnitBatch objects. Modifying any property immediately changes the object on the server. Modifying the StartTime involves moving the object in the data archive. The PITransferRecord supports the ModifyAttributes method--this allows several property changes with one server call.

PITransferRecord objects are removed by calling the PITransferRecordDB Remove method. This method takes a PITransferRecord object as an argument.

  1. Searching for PITransferRecord Objects

The PITransferRecordDB supports three methods for finding PITransferRecord objects:

SearchStartTime and SearchEndTime define the time range to search. The times are passed as VARIANTS. Supported types are PITime objects, strings that represent Local Date, and Doubles or Integer in UTC seconds since 1970. Basically any format supported by the PITime object.

The current search algorithm is indexed only on time. Future releases may support additional indexing. Like the PIUnitBatchSearch and PIBatchSearch the masks are effectively filters. Until more indexing is provided, specifying tight time ranges will improve performance.

NOTE: The PITransferRecord database supports records with overlapping times. For example, there are no restrictions to having a PITransferRecord which runs from 1-Jan-1980 through 31-Dec-2000, with many shorter batches between these times. This poses a significant search algorithm problem.

The PITransferRecord records are stored in a PI Archive and thus are indexed on start time. The find methods, which take a search start and end time algorithm attempt to find all matching records that are active over the search period. Therefore, using the above example, a search for all active Transfer Records during December 2002 would have to search every PI Archive online. Obviously this approach could take a considerable amount of time and computer resources; therefore, a compromise algorithm is necessary.

The compromise is to only return records that are active within the search period and have started within the last 30 days. A future PI3 release will support end time indexing. When this feature is available, searches will return all records that are active over the search period and the 30 day limit will no longer be necessary.

The AsynchStatus argument allows asynchronous searches and canceling long running searches. This property will be supported in a future release. This argument should be set to Nothing until it is supported.

All results are returned in a PITransferRecordList. This list behaves very similar to PIBatchList and PIUnitBatchList collections.

The search algorithm effectively has two modes. First it acts as a general search for all PITransferRecord objects involving PIBatch or PIUnitBatches that match specific BatchID or Product strings. In this mode, one or more masks are specified but no UniqueID's are specified. This mode is useful in genealogy tracking. Here are two search examples and corresponding VB code fragments. The examples assume a reasonable time range can be specified.

"A PIBatch was assigned to a lot of raw material supplied by a vendor; the vendor lot number was assigned to the BatchID. PITransferRecords were used to track this material as it was used. Find all the PIUnitBatch objects that used this lot of raw material."

Private Function FindAffectedUnitBatches(BatchID As String, ptStart As PITime, ptEnd As PITime) As PIUnitBatchList

Dim TRList As PITransferRecordList

Dim TR As PITransferRecord

Dim UB As PIUnitBatch

Set FindAffectedUnitBatches = New PIUnitBatchList

Set TRList = g_TRDB.PITransferRecordSearch(ptStart, ptEnd, BatchID)

On Error Resume Next

For Each TR In TRList

Set UB = TR.Destination

If Not UB Is Nothing Then

FindAffectedUnitBatches.Insert UB

Set UB = Nothing

End If

Next TR

End Function

"A unit procedure calls for butane as an ingredient. Some procedure failures resulted in using isobutane in some PIUnitBatch objects. Find the PIUnitBatch objects that have the isobutane as an ingredient."

Private Function ISOButaneUnitBatches(ptStart As PITime, ptEnd As PITime) As PIUnitBatchList

Dim TRList As PITransferRecordList

Dim TR As PITransferRecord

Dim UB As PIUnitBatch

Set ISOButaneUnitBatches = New PIUnitBatchList

Set TRList = g_TRDB.PITransferRecordSearch(ptStart, ptEnd, "*", "ISOBUTANE")

On Error Resume Next

For Each TR In TRList

Set UB = TR.Destination

If Not UB Is Nothing Then

ISOButaneUnitBatches.Insert UB

Set UB = Nothing

End If

Next TR

End Function

All PIUnitBatch, PIBatch, and PIModule objects are assigned a UniqueID on creation. The UniqueID always unambiguously identifies an object. PITransferRecord objects that involve a particular object can be located by passing the object's UniqueID to this call. For example, an application may require all the transfers between two specific tanks. Here's a subroutine, which demonstrates this:

Private Function FindSpecicTransfers(ptStart As PITime, ptEnd As PITime, Tank1 As PIModule, Tank2 As PIModule) As PITransferRecordList

'use the default masks of "*" for all masks.

Set FindSpecicTransfers = g_TRDB.PITransferRecordSearch(ptStart, ptEnd, , , , , , , Tank1.UniqueID, Tank2.UniqueID)

End Function

Finally, a specific PITransferRecord can be found by setting the argument "TransferRecordUniqueID" leaving all other arguments to their defaults.

Enabling Operational Intelligence