Skip navigation
All Places > PI Developers Club > Blog > 2018 > May
2018

Note: Development and Testing purposes only. Not supported in production environments.

 

Link to other containerization articles

Containerization Hub

 

Introduction

In one of my previous blog posts, I was spinning up an AF Server container using local accounts for authentication. For non-production purposes, this is fine. But since Kerberos is the authentication method that we recommend, I would like to show you that it is also possible to use Kerberos authentication for the AF Server container. To do this, you will have to involve a domain administrator since a Group Managed Service Account (GMSA) will need to be created. Think of GMSA as a usable version of the Managed Service Account. A single gMSA can be used for multiple hosts. For more details about GMSA, you can refer to this article: Group Managed Service Accounts Overview

 

Prerequisite

You will need the AF Server image from this blog post.

Spin up AF Server container (SQL Server included)

 

Procedure

1. Request GMSA from your domain administrator. The steps are listed here.

Add-KDSRootKey -EffectiveTime (Get-Date).AddHours(-10) #Best is to wait 10 hours after running this command to make sure that all domain controllers have replicated before proceeding
Add-WindowsFeature RSAT-AD-PowerShell
New-ADServiceAccount -name <name> -DNSHostName <dnshostname> -PrincipalsAllowedToRetrieveManagedPassword <containerhostname> -ServicePrincipalNames "AFServer/<name>"

2. Once you have the GMSA, you can proceed to install it on your container host.

Install-ADServiceAccount <name>

3. Test that the GMSA is working. You should get a return value of True

Test-ADServiceAccount <name>

4. Get script to create AF Server container with Kerberos.

Invoke-WebRequest "https://raw.githubusercontent.com/elee3/AF-Server-container-build/master/New-KerberosAFServer.ps1" -UseBasicParsing -OutFile New-KerberosAFServer.ps1

5. Create a new AF Server container

.\New-KerberosAFServer.ps1 -ContainerName <containername> -AccountName <name>

 

Usage

Now you can open up PI System Explorer on your container host to connect to your containerized AF Server with the <name> parameter that you have been using in the procedure section. On the very first connect, you should connect with the afadmin user (password:qwert123!) so that you can set up mappings for your domain accounts. Otherwise, your domain accounts will only have 'World' permissions. After you set up your mappings, you can choose to delete that afadmin user or just keep it. With the mappings for your domain account created, you can now disconnect from your AF Server and reconnect to it with Kerberos authentication. From now on, you do not need explicit logins for your AF Server anymore!

 

Conclusion

We can see that security is not a limitation when it comes to using an AF Server container. It is just more troublesome to get it going and requires the intervention of a domain administrator. However, this will remove the need of using local accounts for authentication which is definitely a step towards using the AF Server container for production. I will be showing how to overcome some limitations of containers in future posts such as letting containers have static IP and the ability to communicate outside of the host.

 

New updates (3 Aug 2018)

Script updated to allow GMSA to work in both child and parent domains. For example, mycompany.com and test.mycompany.com.

Script now uses the new image with 18x tag based on a newer version of Windows Server Core.

Enhancing the Hello World example from Part 1

 

Now we're going to take the Line Pressure and Tubing Pressure AF Elements that were under the gas wells from our example database and convert those Elements into Attributes that live directly under the wells.  This is pretty easy!

 

 

The additions to the AF Transform XML file are straightforward.   First, the Measures template defines the two AF Elements where the values for each sensor are.   And these elements are always found underneath each well, so we can enhance the search for the wells to bring in the Line Pressure and Tubing Pressure child elements, like this:

 

...
<SearchShapes>
  <!-- Specify the elements and attributes of the search pattern that AF Transformer uses to search the source PI AF database -->
  <Shape ID="1001" Required="true" FilterMatchType="Any" ShapeWalkType="TopBottom">
    <ShapeElements>
      <ShapeElement ID="1" Required="true" FilterMatchType="Any" MaxDepthFromParent="1" IsEntryPoint="false">
        <Filters>
          <ElementFilter Category="" Template="Facility" Name="*" />
        </Filters>
        <Attributes>
          <ShapeAttribute ID="10" Required="true" FilterMatchType="Any">
            <Filters>
              <AttributeFilter Category="" Template="" Name="Contractor Name" />
            </Filters>
          </ShapeAttribute>
          <ShapeAttribute ID="11" Required="true" FilterMatchType="Any">
            <Filters>
              <AttributeFilter Category="" Template="" Name="Description" />
            </Filters>
          </ShapeAttribute>
        </Attributes>
        <ShapeElements>
          <!-- Line Pressure AF Element -->
          <ShapeElement ID="2" Require="true" FilterMatchType="Any" MaxDepthFromParent="1" IsEntryPoint="false">
            <Filters>
              <ElementFilter Category="" Template="Measures" Name="*PLN" />
            </Filters>
            <Attributes>
              <ShapeAttribute ID="20" Required="true" FilterMatchType="Any">
                <Filters>
                  <AttributeFilter Category="" Template="" Name="Value" />
                </Filters>
              </ShapeAttribute>
            </Attributes>
          </ShapeElement>
          <!-- End of Line Pressure AF Element -->
          <!-- Tubing Pressure AF Element -->
          <ShapeElement ID="3" Require="true" FilterMatchType="Any" MaxDepthFromParent="1" IsEntryPoint="false">
            <Filters>
              <ElementFilter Category="" Template="Measures" Name="*PTUB" />
            </Filters>
            <Attributes>
              <ShapeAttribute ID="30" Required="true" FilterMatchType="Any">
                <Filters>
                  <AttributeFilter Category="" Template="" Name="Value" />
                </Filters>
              </ShapeAttribute>
            </Attributes>
          </ShapeElement>
          <!-- End of Tubing Pressure AF Element -->
        </ShapeElements>
      </ShapeElement>
    </ShapeElements>
  </Shape>
</SearchShapes>
...

 

 

And then we just add the line pressure and tubing pressure attributes, referring back to the two elements:

 

...
<OutputElementShapes>
  <!-- Create and populate the asset model in the destination database -->
  <OutputElementShape ID="1003">
    <Elements>
      <Element Name="Injection Wells by Contractor" Guid="" ReadOnly="false" Template="">
        <Elements>
          <Element Name="[10.Value]" Guid="" Description="Contractor" ReadOnly="false" Template="">
            <Elements>
              <Element Name="[1.Name]">
                <Attributes>
                  <Attribute Name="Description" Value="[11.Value]" />
                  <Attribute Name="Line Pressure" Value="[20.DataReference]" />
                  <Attribute Name="Tubing Pressure" Value="[30.DataReference]" />
                </Attributes>
              </Element>
            </Elements>
          </Element>
        </Elements>
      </Element>
    </Elements>
  </OutputElementShape>
</OutputElementShapes>
...

 

Make sure when you're using PI Point data references (as well as AF table lookups) you use the .DataReference reference and not the .Value reference, otherwise you'll be pulling across the snapshot values of what those attributes are at the time you run AF Transformer.

Note: Development and Testing purposes only. Not supported in production environments.

 

Link to other containerization articles

Containerization Hub

 

Introduction

In this blog post, I will be giving an overview of how to use Docker Compose to create a PI System compose architecture that you can use for

 

1. Learning PI System development

2. Running your unit tests with a clean PI System

3. Compiling your AF Client code

4. Exploring PI Web API structure

5. Testing out Asset Analytics syntax

5. Other use cases that I haven't thought of (Post in the comments!)

 

What is Compose?

It is a tool for defining and running multi-container Docker applications. With Compose, you use a single file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. It is both easy and convenient.

 

Setup images

The Setup involved is simple. You can refer to my previous blog posts set up these images. Docker setup instructions can be found in the Containerization Hub link above.

Spin up PI Web API container (AF Server included)

Spin up PI Data Archive container

Spin up AF Client container

Spin up PI Analysis Service container

 

Compose setup

In Powershell, run as administrator these commands:

 

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest "https://github.com/docker/compose/releases/download/1.21.2/docker-compose-Windows-x86_64.exe" -UseBasicParsing -OutFile $Env:ProgramFiles\docker\docker-compose.exe

 

Obtain Compose file from docker-compose.yml. Place it on your desktop.

 

Deployment

Open a command prompt and navigate to your desktop. Enter

docker-compose up

 

Wait until the screen shows

Once you see that. You can close the window. Your PI System architecture is now up and running!

 

Usage

There are various things you can try out. If you are experiencing networking issues between the containers, turn off the firewall for the Public Profile on your container host.

 

1. You can try browsing the PI Web API structure by using this URL (https://eleeaf/piwebapi) in your web browser. When prompted for credentials, you can use

username: afadmin

password: qwert123!

 

2. Test network connectivity from client container to the PI Data Archive and AF Server by running

docker exec -it desktop_client_1 afs

The hostname of the AF Server is eleeaf. When prompted to use NTLM, enter q. The hostname of the PI Data Archive is eleepi. You should see the following results.

 

3. You can install PI System Management Tools on your container host and connect to the PI Data Archive via IP address of the container. Somehow, PI SMT doesn't let you connect with hostname.

 

4. You can also install PI System Explorer and connect to the AF Server to create new databases.

 

5. You can try compiling some open source AF SDK code found in our Github repository using the AF Client container. (so that you do not have to install Visual Studio)

 

6. You can use PI System Explorer to experiment with some Asset Analytics equations that you have in mind to check if they are valid.

 

Destroy

Once you are done with the environment, you can destroy it with

docker-compose down

 

Limitations

This example does not persist data or configuration between runs of the container.

These applications do not yet support upgrade of container without re-initialization of the data.

This example relies on PI Data Archive trusts and local accounts for authentication.

AF Server, PI Web API, and SQL Express are all combined in a single container. 

 

Conclusion

Notice how easy it is to set up a PI System compose architecture. You can do this in less than 10 minutes. No more having to wait hours to install a PI System for testing and developing with.

The current environment contains PI Data Archive, AF Server, AF Client, PI Web API, a AF SDK sample application (called afs) and PI Analysis Service. More services will be added in the future!

Eugene Lee

Spin up AF Client container

Posted by Eugene Lee Employee May 21, 2018

Note: Development and Testing purposes only. Not supported in production environments.

 

Link to other containerization articles

Containerization Hub

 

In this blog post, the instructions for building an AF Client image will be shown. For instructions on how to install Docker, please see the link above.

 

1. Please clone this git repository. GitHub - elee3/AF-Client-container-build

2. Download AF Client 2017R2 from the Techsupport website. AF Client 2017 R2

3. Extract AF Client into the cloned folder.

4. Run build.bat

 

If you prefer us to build the image for you so that you can docker pull it immediately (less hassle). Please post in the comments!

 

Usage

This container can be used to compile your AF SDK code (so that you do not have to install Visual Studio) and you can use the container to pack an AF SDK application with its AF Client dependency for easier distribution. An AF SDK sample application (called afs) has been included in the image for you to try compiling it.

 

Limitations

Containers cannot run applications with GUI such as WPF and Windows Forms applications.

 

Update 27 Jun 2018

Fixed an issue with the registry links breaking.

Eugene Lee

Containerization Hub

Posted by Eugene Lee Employee May 21, 2018

Good day everyone, I am creating this blog post as a convenient way for users to find the containerization articles that have already been published and also list those that have yet to be published (subject to changes). Users will just need to bookmark this page rather than bookmark all the individual articles.

 

Standalone

Spin up AF Server container (SQL Server included)

Spin up PI Web API container (AF Server included)

Spin up PI Data Archive container

Spin up AF Client container

Spin up PI Analysis Service container

Overcome limitations of the PI Data Archive container

Spin up PI to PI Interface container (new!)

Spin up stateless AF Server container (in progress)

 

Upgrading

Upgrade to PI Data Archive 2018 container with Data Persistence

Upgrade to AF Server 2018 container with Data Persistence

 

Security

Spin up AF Server container (Kerberos enabled)

Container Kerberos Double Hop

 

Health

AF Server container health check

PI Data Archive container health check

 

Cloud

AF Server container in the cloud

 

Orchestration

Compose PI System container architecture

Containers and Swarm Part 1 (Setup, Service)

Containers and Swarm Part 2 (Secrets, Configs)

Containers and Swarm Part 3 (Scaling, Self-Healing)

Containers and Swarm Part 4 (Overlay Networking)

Containers and Swarm Part 5 (External Traffic, Load Balancing)

 

Miscellaneous

Form collectives with PIDA container

Spin up stateless PI Web API container

Spin up PI Web API website container

 

 

 

 

Install Docker

The steps to setup Docker are below.

 

For Windows 10,

You can install Docker for Windows. Please follow the instructions here.

 

For Windows Server 2016,

You can use the OneGet provider PowerShell module. Open an elevated PowerShell session and run the below commands.

 

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider -Force
Restart-Computer -Force

Introduction

 

After publishing the PI Web API client libraries on GitHub, I have received several enhancement requests (for .NET Standard, Java and Python) from our customers and partners. Some of them were added to the libraries!

 

Enhancements for the client library for .NET Standard

 

Migrated from RestSharp to HttpClient

 

Although there is no change for the end user,  RestSharp was replaced by the native HttpClient. The main reason is to use the CancellationTokenSource which will be commented on the next item. Also, HttpClient is available natively on .NET Standard so there is no need to download an extra NuGet package.

 

CancellationToken added for Async requests

 

Using the CancellationTokenSource allows you to cancel HTTP requests during a running operation. Below you can find an example:

 

Stopwatch watch = Stopwatch.StartNew();
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
PIItemsStreamValues bulkValues = null;
try
{
     Task t = Task.Run(async () =>
     {
          bulkValues = await client.StreamSet.GetRecordedAdHocAsync(webId: webIds, startTime: "*-1800d", endTime: "*", maxCount: 50000, cancellationToken: cancellationTokenSource.Token);
     });
     //Cancel the request after 1s
     System.Threading.Thread.Sleep(1000);
     cancellationTokenSource.Cancel();
     t.Wait();
     Console.WriteLine("Completed task: Time elapsed: {0}s", 0.001 * watch.ElapsedMilliseconds);
}
catch (Exception)
{
     Console.WriteLine("Cancelled task: Time elapsed: {0}s", 0.001 * watch.ElapsedMilliseconds);
};

 

Fixed known issue on the Calculation controller

 

There was a known issue reported on GitHub when calling Calculation.GetAtTimes() method using expressions with comma. This was fixed so the code below works successfully!

 

string expression = "'sinusoid'*2 + 'cdt158'";
PITimedValues values = client.Calculation.GetAtTimes(webId: dataServer.WebId, expression: expression , time: new List<string>() { "*-1d" });

string expression2 = "'cdt158'+tagval('sinusoid','*-1d')";
PITimedValues values2 = client.Calculation.GetAtTimes(webId: dataServer.WebId, expression: expression2, time: new List<string>() { "*-1d" });

 

Enhancements for the client library for Java

 

PI Web API Batch was added in order to make more complex requests with better performance. You can find more information about PI Web API Batch here.

 

Added PI Web API Batch

 

Map<String, PIRequest> batch = new HashMap<String, PIRequest>();
PIRequest req1 = new PIRequest();
PIRequest req2 = new PIRequest();
PIRequest req3 = new PIRequest();
req1.setMethod("GET");
req1.setResource("https://marc-web-sql.marc.net/piwebapi/points?path=\\\\MARC-PI2016\\sinusoid");
req2.setMethod("GET");
req2.setResource("https://marc-web-sql.marc.net/piwebapi/points?path=\\\\MARC-PI2016\\cdt158");
req3.setMethod("GET");
req3.setResource("https://marc-web-sql.marc.net/piwebapi/streamsets/value?webid={0}&webid={1}");

List<String> parameters = new ArrayList<>();
parameters.add("$.1.Content.WebId");
parameters.add("$.2.Content.WebId" );
req3.setParameters(parameters);


List<String> parentIds = new ArrayList<>();
parentIds.add("1");
parentIds.add("2");
req3.setParentIds(parentIds);

batch.put("1", req1);
batch.put("2", req2);
batch.put("3", req3);
Map<String, PIResponse> batchResponse = client.getBatch().execute(batch);

Object content1 = batchResponse.get("1").getContent();
Object content2 = batchResponse.get("2").getContent();
Object content3 = batchResponse.get("3").getContent();

JSON json = new JSON(client.getApiClient());
PIPoint pointBatch1 = json.deserialize(json.serialize(content1), new TypeToken<PIPoint>(){}.getType());
PIPoint pointBatch2 = json.deserialize(json.serialize(content2), new TypeToken<PIPoint>(){}.getType());
PIItemsStreamValue batchStreamValues = json.deserialize(json.serialize(content3), new TypeToken<PIItemsStreamValue>(){}.getType());

 

 

Added Web ID 2.0 client generation

 

Now, it is also possible to generate Web ID 2.0 without having to make an HTTP request against PI Web API. The library also provides a way to get information for a particular Web ID. Remember that this only works with PI Web API 2017 R2+.

 

PIDataServer dataServer = client.getDataServer().getByPath("\\\\MARC-PI2016", null, null);
PIPoint point = client.getPoint().getByPath("\\\\marc-pi2016\\sinusoid",null, null);
PIElement element = client.getElement().getByPath("\\\\MARC-PI2016\\CrossPlatformLab\\marc.adm",null, null);
PIAttribute attribute = client.getAttribute().getByPath( "\\\\MARC-PI2016\\CrossPlatformLab\\marc.adm|Heading",null,null);

WebIdInfo webIdInfo2 = client.getWebIdHelper().getWebIdInfo(attribute.getWebId());
WebIdInfo webIdInfo = client.getWebIdHelper().getWebIdInfo(element.getWebId());
WebIdInfo webIdInfo4 = client.getWebIdHelper().getWebIdInfo(point.getWebId());
WebIdInfo webIdInfo3 = client.getWebIdHelper().getWebIdInfo(dataServer.getWebId());

String web_id1 = client.getWebIdHelper().generateWebIdByPath("\\\\PISRV1\\CDF144_Repeated24h_forward", PIPoint.class, null);
String web_id2 = client.getWebIdHelper().generateWebIdByPath("\\\\PISRV1\\Universities\\UC Davis\\Buildings\\Academic Surge Building|Electricity Totalizer", PIAttribute.class, PIElement.class);

 

Available for downloading through JitPack

 

I've received a request on GitHub to publish the library on Maven Central. Since it is not an easy process, especially if you are not familiar, I've decided to publish it though JitPack.

 

If you want to use the Java library, please read the instructions here about how to retrieve the library without having to compile it locally.

 

 

Enhancements for the client library for Python

 

 

Added Kerberos as an authentication method

 

Robert Raesemann asked me in this blog post to make the client library for Python compatible with Kerberos authentication. Now it is possible to instantiate the PI Web API top level object as:

 

from osisoft.pidevclub.piwebapi.pi_web_api_client import PIWebApiClient
  client = PIWebApiClient("https://test.osisoft.com/piwebapi", useKerberos=True, verifySsl=False)

 

 

Added PI Web API Batch

 

PI Web API Batch was also added to Python.

 

  req1 = PIRequest()
  req2 = PIRequest()
  req3 = PIRequest()
  req1.method = "GET"
  req1.resource = "https://localhost/piwebapi/points?path=\\\\MARC-PI2016\\sinusoid"
  req2.method = "GET"
  req2.resource = "https://localhost/piwebapi/points?path=\\\\MARC-PI2016\\cdt158"
  req3.method = "GET"
  req3.resource = "https://localhost/piwebapi/streamsets/value?webid={0}&webid={1}"
  req3.parameters = ["$.1.Content.WebId", "$.2.Content.WebId"]
  req3.parent_ids = ["1", "2"]

  batch = {
"1": req1,
"2": req2,
"3": req3
  }

  batchResponse = client.batch.execute(batch)
  point1 = client.api_client.deserialize_object(batchResponse["1"].content, 'PIPoint')
  point2 = client.api_client.deserialize_object(batchResponse["2"].content, 'PIPoint')
  itemsStreamValue = client.api_client.deserialize_object(batchResponse["3"].content, 'PIItemsStreamValue')

 

Thanks Rafael Borges for helping me with this task!

 

 

Optional parameters with default values

 

In this new version, you don't need to define all parameters of each method. Optional parameters have default values which are going to be used if they are not defined. Let's see an example:

 

piItemsStreamValues = client.streamSet.get_recorded_ad_hoc(webIds, start_time="*-3d", end_time="*",
                                                                   include_filtered_values=True, max_count=1000)

 

 

Added Web ID 2.0 client generation

 

Web ID 2.0 client generation was also added to the library. Here is an example:

 

pi_data_server_web_id = client.webIdHelper.generate_web_id_by_path("\\\\PISRV1", type(PIDataServer()), None)
  point1_web_id = client.webIdHelper.generate_web_id_by_path("\\\\PISRV1\\SINUSOID", type(PIPoint()))
  point2_web_id = client.webIdHelper.generate_web_id_by_path("\\\\PISRV1\\CDT158", type(PIPoint()))
  point3_web_id = client.webIdHelper.generate_web_id_by_path("\\\\PISRV1\\SINUSOIDU", type(PIPoint()))
  pi_attribute_web_id = client.webIdHelper.generate_web_id_by_path(
"\\\\PISRV1\\Universities\\UC Davis\\Buildings\\Academic Surge Building|Electricity Totalizer",
type(PIAttribute()), type(PIElement()))

  pi_element_web_id= client.webIdHelper.generate_web_id_by_path(
"\\\\PISRV1\\Universities\\UC Davis\\Buildings\\Academic Surge Building", type(PIElement()), None)

 

Available for downloading through PyPI (Python Package Index)

 

Just run the code below to download it:

 

pip install osisoft.pidevclub.piwebapi

 

You can find more information on the PyPI library page.

 

Conclusion

 

I hope you find value in those improvements. If you have an enhancement request concerning one of the client libraries, please let me know!

 

It is almost time to update to 2018!

 

Stay tuned for new updates and releases!

Sometimes you wish your AF database was reorganized differently

 

I would hope your AF Database models follow a plant heirarchy and be nothing like tags in the Data Archive.  But you might not be so lucky.  Or, when using a PI Connector, AF Assets are created for you and they tend to follow the networking pattern for how the sensors assets are organized.  Often though, there are projects in your organization that would benefit greatly if your asset model were organized differently.  By reorganizing your AF database you could save yourself from expensive lookup queries or worse: traversing complicated parent/child chains using AF SDK or PI Web API.  It can make a lot more sense to get your asset model structured in a way that makes sense for whatever your present needs are.

 

Since AF SDK went public users have taken upon themselves to build AF SDK programs that do this sort of (re) "mapping".

 

AF Transformer helps you accomplish this remapping task without the need to build, compile and test C# code using AF SDK.  By editing an XML configuration file (with a good text editor ;-) and running the tool you can transform one or more AF databases into a new model that can greatly assist your projects and your downstream users who want to see assets in a way they understand.

 

 

Presented April 25, 2018 at PI World

 

Why might I use AF Transformer?

 

  • A downstream application is being built that needs to see/traverse your AF model in a way that would require a large number of lookups.  It might make a lot more sense to produce a new AF model that's pre-sorted to meet the needs of your downstream application--boosting performance and decreasing the amount of time it takes to develop.
  • You need to build a segmented AF model that limits the scope of assets to a particular group of users
  • You need to flatten, expand or pivot an AF model so it makes more sense to the various different business consumers in your organization

 

Getting Started - Let's pivot an AF database based on an attribute value

 

Inside the AF Transformer kit are examples that include two AF databases you can import.  I have an enhanced version of WellsDb.xml attached to this blog post (called WellsDBWithAFTable.xml) that includes an additional AF table of well maintenance contractors who are assigned to a well.  I have also added an attribute to link each well to a contractor and resolve the contractor's name.

 

2018-05-11_14-54-17.png

 

Import WellsDBWithAFTable.xml into a new AF Database in PI System Explorer (under File->Import From File...) I prefer to call it WellsDb, but you can name it whatever you like.

 

Next, create a second empty AF Database.  Let's call it TransformedWells.  This is where we're going to deposit the output from the transform.

 

Now, let's transform this.  Write an XML file with the following sections.  Be careful to update the <DataSource> and <Writers> tags to your correct source and target AF database host name and database names.  (CLSAF is the name of my own AF Server; which is likely not going to be the name of your own AF Server)

 

<?xml version="1.0" encoding="UTF-8"?>
<CASTDataSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <LogFilePath>c:\Program Files\PIPC\AFTransformer\AF Transformer Examples\example.log</LogFilePath>
   <StatInfo />
   <ProcessProperties>
      <!-- Default values for process properties are used -->
   </ProcessProperties>
   <Tasks>
      <Task Id="1000">
         <SearchShapes>
            <SearchShape Id="1001" ReaderId="1002" FilterMatchType="Any">
               <DataFilters />
            </SearchShape>
         </SearchShapes>
         <OutputElementShapes>
            <OutputElement Id="1003" />
         </OutputElementShapes>
         <TaskWriters>
            <TaskWriter Id="1004" />
         </TaskWriters>
      </Task>
   </Tasks>
   <DataSources>
      <DataSource MEFClass="AF" HighID="0" ID="1002">
         <Properties>
            <Properties Key="Host" Value="CLSAF" />
            <Properties Key="Database" Value="WellsDb" />
            <Properties Key="UserName" Value="" />
            <Properties Key="Password" Value="" />
            <Properties Key="DefaultPIServer" Value="" />
         </Properties>
      </DataSource>
   </DataSources>
   <Writers>
      <Writer MEFClass="AF" Enabled="true" Encoding="UTF8" ID="1004">
         <Properties>
            <Properties Key="Host" Value="CLSAF" />
            <Properties Key="Database" Value="TransformedWells" />
         </Properties>
      </Writer>
   </Writers>
   <SearchShapes>
      <!-- Specify the elements and attributes of the search pattern that AF Transformer uses to search the source PI AF database -->
      <Shape ID="1001" Required="true" FilterMatchType="Any" ShapeWalkType="TopBottom">
         <ShapeElements>
            <ShapeElement ID="1" Required="true" FilterMatchType="Any" MaxDepthFromParent="1" IsEntryPoint="false">
               <Filters>
                  <ElementFilter Category="" Template="Facility" Name="*" />
               </Filters>
               <Attributes>
                  <ShapeAttribute ID="10" Required="true" FilterMatchType="Any">
                     <Filters>
                        <AttributeFilter Category="" Template="" Name="Contractor Name" />
                     </Filters>
                  </ShapeAttribute>
                  <ShapeAttribute ID="11" Required="true" FilterMatchType="Any">
                     <Filters>
                        <AttributeFilter Category="" Template="" Name="Description" />
                     </Filters>
                  </ShapeAttribute>
               </Attributes>
            </ShapeElement>
         </ShapeElements>
      </Shape>
   </SearchShapes>
   <OutputElementShapes>
      <!-- Create and populate the asset model in the destination database -->
      <OutputElementShape ID="1003">
         <Elements>
            <!--Here is where the new AF Database model begins-->
            <Element Name="Injection Wells by Contractor" Guid="" ReadOnly="false" Template="">
               <Elements>
                  <Element Name="[10.Value]" Guid="" Description="Contractor" ReadOnly="false" Template="">
                     <Elements>
                        <Element Name="[1.Name]">
                           <Attributes>
                              <Attribute Name="Description" Value="[11.Value]" />
                           </Attributes>
                        </Element>
                     </Elements>
                  </Element>
               </Elements>
            </Element>
         </Elements>
      </OutputElementShape>
   </OutputElementShapes>
</CASTDataSet>

 

Now, let's run this.

 

In a command prompt window, call the utility directly with the /configxml="{path to your xml transform file here}" option.

 

2018-05-11_16-08-49.png

 

Go check your output

 

Take a look at the console output.  Make sure the AF Reader and the AF Writer in the console output both report that they've found their respective AF databases.  If so, the remaining part of the orchestration will complete and transpose the AF Objects.  Let's check the TransformedWells AF database to be sure.

 

2018-05-11_16-10-59.png

 

Yup, they're there.

 

This is the simplest example of AF Transformer working so that you grasp how to do grouping.  In Part 2, we will build off this example and convert the Line Pressure and Tubing Pressure AF Elements into Attributes that report directly on these transformed well elements.

 

>> Let's continue on to Part 2

Note: Development and Testing purposes only. Not supported in production environments.

 

Link to other containerization articles

Containerization Hub

 

Introduction

I now present to you another blog post in the containerization series on spinning up PI Web API in less than 3 minutes (My test came out to be 2 min 44 sec!).

 

I will repeat the steps here for setting up Docker for your convenience. If you have already done so while using the AF Server image, then you do not need to repeat it again. The PI Web API image offered here is fully self contained. In other words, you do not have to worry about any dependencies such as where to store your PI Web API configuration. In a later blog post, I will be posting on a PI Web API image that only contain the application service for those of you who want the application service to be separate from the database service. In that image, you will need to furnish your own AF Server then. For now, you do not have to care about that.

 

Set up

Install PI Web API image

Run the following command at a console. When prompted for the username and password during login, please contact me (elee@osisoft.com) for them. Currently, this image is only offered for users who already have a PI Server license or are PI Developers Club members (try it now for free!). You will have to login before doing the pull. Otherwise, the pull will be unsuccessful.

docker login  
docker pull elee3/afserver:piwebapi  
docker logout  

Remember to check digest of image to make sure it is not tampered with.

Update 2 Jul 2018: Please use the fast version with tag webapifast17R2 as that image is better in every possible way. Boot up time 15 sec compared to 3 minutes.

 

Deployment

Now that the setup is complete, you can proceed to running the container image. To do so, use the following command. Replace <DNS hostname> and <containername> with one of your own picking. Remember to pick a DNS hostname that is unique.

docker run -it --hostname <DNS hostname> --name <containername> elee3/afserver:piwebapi  

 

After about 3 minutes, you will see that the command prompt indicates that both the PI Web API and AF Server are Ready.

This indicates that your PI Web API is ready for usage. At this point, you can just close the window.

Update 2 Jul 2018: Please use the fast version with tag webapifast17R2 as that image is better in every possible way. Boot up time 15 sec compared to 3 minutes.

 

Usage

Now you can open a browser on your container host and connect to it with the DNS hostname that you chose earlier.

https://<DNS hostname>/piwebapi

 

When prompted for credentials, you can use

User name: afadmin

Password: qwert123!

 

Browsing your PI Data Archive

You can use a URL of the form

https://<DNS hostname>/piwebapi/dataservers?path=\\<PI Data Archive hostname>

to access your PI Data Archive. Of course, you need to give access permissions by creating a local user on the PI Data Archive machine with the same username and password above and give a PI mapping to that user.

 

Browsing your AF Server

You can use a URL of the form

https://<DNS hostname>/piwebapi/assetservers?path=\\<AF Server hostname>

to access your AF Server. Again, you need to give access permissions by creating a local user on the AF Server machine with the same username and password above. By default, everyone has World identity in AF Server so you do not need to give any special AF mapping.

 

Multiple PI Web API instances

You can spin up several PI Web API instances by using the docker run command multiple times with a difference hostname and containername.

You can see above that I have spin up several instances on my container host.

 

Destroy PI Web API instance

If you no longer need the PI Web API instance, you can destroy it using

docker stop <containername>  
docker rm <containername>  

 

Limitations

AF Server, PI Web API, and SQL Express are all combined in a single container. There will be an upcoming blog post for a container with just PI Web API in it.

This example relies on local accounts for authentication.

 

Conclusion

Observe that the steps to deploy both the AF Server and PI Web API containers are quite similar and can be easily scripted. This helps to provision testing environments quickly and efficiently which helps in DevOps.

 

New updates (12 Jun 2018)

In the never ending quest for speed and productivity, every minute and second that we save waiting for applications to boot up can be better utilized elsewhere such as taking a nap or watching that cat video clip that your friend sent you. Therefore, I present to you a faster PI Web API container image that is more than 60% faster than the original one.

 

docker pull elee3/afserver:webapifast17R2

Remember to check digest of image to make sure it is not tampered with.

 

3 test runs were performed to compare the boot up time.

 

Run 1

Start time was 13:48:00 for both. The original image finished in 2 min 36 sec while the new one finished in 55 sec.

 

Run 2

Start time was 13:58:00 for both. The original image finished in 2 min 27 sec while the new one finished in 55 sec.

 

Run 3

Start time was 14:29:00 for both. The original image finished in 2 min 28 sec while the new one finished in 57 sec.

 

Summary of results

Run
Original (s)
New (s)
115655
214755
314857
Average15055

 

The results show that the new image is about 63% faster than the original one.

 

New updates (18 Jun 2018)

1. Added reminder to check digest of the image to make sure image has not been tampered with.

 

New updates (2 Jul 2018)

1. Removed telemetry and changed tag from webapifast to webapifast17R2. Took down image with tag piwebapi from repository. Boot up time for webapifast17R2 has been further reduced to 15 sec!!

 

New updates (26 Oct 2018)

1. New tag webapi18s for version 2018.

Note: Development and Testing purposes only. Not supported in production environments.

 

Link to other containerization articles

Containerization Hub

 

Introduction

Currently, in order to set up an AF Server for testing/development purposes, you have two choices.

 

1. Install SQL Server and AF Server on your local machine

The problem with this method is that there is no isolation from the host operating system. Therefore, you risk the stability of the host computer if something goes wrong. You also can't spin up multiple AF Servers this way.

 

2. Provision a VM and then install SQL Server and AF Server on it

While this method provides isolation, the problem lies in the time it takes to get it set up and also the size of the VM which includes many unnecessary components.

 

There is a better way!

Today, I will be teaching you how spin up AF Server instances in less than 1 minutes (after performing the initial setup which might take a bit longer). This is made possible by the usage of containerization technology.

 

Requirements

Windows Server build 1709, Windows Server 2016 (Core and with Desktop Experience) or Windows 10 Professional and Enterprise (Anniversary Edition). Ensure that your system is current with the Windows Update.

 

Benefits

1. Portability. Easy to transfer containers to other container hosts that meet the prerequisites. No need to do tedious migrations.

2. Side by side versioning. Ability to run multiple versions of AF Server on the same container host for compatibility testing and debugging purposes.

3. Speed. Very fast to deploy.

4. Resource efficiency and density. More AF Servers can run on the same bare metal machine compared to virtualization.

5. Isolation. If you no longer need the AF Server. You can remove it easily. It won’t leave any temporary or configuration files on your container host.

6. Able to use with container orchestration systems such as Swarm or Service Fabric.

 

Set up

Install Docker

For Windows 10,

You can install Docker for Windows. Please follow the instructions here

 

For Windows Server 2016,

You can use the OneGet provider PowerShell module. Open an elevated PowerShell session and run the below commands.

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider -Force
Restart-Computer -Force

 

Install AF Server image

Run the following command at a console. When prompted for the username and password during login, please contact me (elee@osisoft.com) for them. Currently, this image is only offered for users who already have a PI Server license or are PI Developers Club members (try it now for free!). You will have to login before doing the pull. Otherwise, the pull will be unsuccessful.

docker login
docker pull elee3/afserver:18x
docker logout

Remember to check digest of image to make sure it is not tampered with.

18x: digest: sha256:4ce64e6dafa4fe93d3cf2ef4fb3a38ddadd4493e10e7a68efd809b92d946a77f

 

Deployment

Now that the setup is complete, you can proceed to running the container image. To do so, use the following command.

Replace <DNS hostname> and <containername> with one of your own picking. Remember to pick a DNS hostname that is unique in your domain.

docker run -d --hostname <DNS hostname> --name <containername> elee3/afserver:18x

 

You can now open up PI System Explorer on your local machine and connect to the AF Server by specifying the DNS Hostname that you chose earlier. When prompted for credentials, use

User name: afadmin

Password: qwert123!

Check the box to remember the credentials so that you won't have to enter it every time.

 

You can choose to rename the AF Server if you wish.

 

And you are done! Enjoy the new AF Server instance that you have created!

 

Using with AF SDK

To connect to the AF Server from code using AF SDK, the following Connect overload can be utilized with the same credentials as above.

PISystem.Connect Method (NetworkCredential)

 

Multiple AF Servers

In order to spin up another AF Server instance, follow the steps above. When you get the new container running. You have to change the ServerID. You can do this via

docker exec -i <containername> cmd /c "cd %pihome64%\af&afdiag.exe /cid:<guid>"

You can generate a new guid using this.

 

You do not need to manually generate a new Server ID anymore. The image does it automatically for you.

 

Destroy AF Server

If you no longer need the AF Server, you can destroy it using

docker stop <containername>
docker rm <containername>

 

Limitations

This example uses a public SQL Express container image which is currently not available for use in a production environment. (Changed to a SQL Express image that I built myself)

This example relies on local accounts for authentication. Refer to the following article if you want to use Kerberos. Spin up AF Server container (Kerberos enabled)

 

New updates (14 Feb 2018)

1. 2017R2 tag is now available

2. Image has been updated with ability to import in an existing AF Server backup in the form of PIFD.bak file. To do this, run

docker run -di --hostname <DNS hostname> --name <containername> -v <path to folder containing PIFD.bak>:c:\db elee3/afserver:2017R2 migrate.bat

 

New updates (30 May 2018)

1. Local account is no longer in the administrators group. Only a mapping to an AF Identity is done (better security)

 

New updates (18 Jun 2018)

1. Added reminder to check digest of the image to make sure image has not been tampered with

 

New updates (2 Jul 2018)

1. Changed tag from 2017R2 to 17R2

2. Removed telemetry

 

New updates (13 Jul 2018)

1. Changes to facilitate upgrading to 2018 container

 

New updates (4 Sep 2018)

1. Updated to use tag 18x which comes with health check and some performance improvements

 

New updates (26 Oct 2018)

1. New tag 18s comes with SQL data files persisted externally

Motivation

 

Recently, during PI World 2018, I was surprised by the number of people asking me if it's possible to list all PI Points and AF Attributes used in PI Vision's displays. The good news is that it's possible to do it, the bad news is that it's not that straightforward.

 

I will show two different ways to achieve this. The first one using Powershell and the second one querying directly PI Vision's database. Warning: we strongly recommend that you don't mess around with PI Vision's database unless you know what you are doing. If you have questions, please contact tech support or leave a comment in this post.

 

Powershell

 

The PowerShell method is the simplest and safest. In order to understand how it works, let's first do a quick recap of PI's architecture.

 

In a very high-level description, PI uses a producer-consumer pattern: multiple producers (interfaces, connectors, AFSDK writes, etc) send data to a central repository, while consumers subscribe to updates on a set of PI Points. Whenever a new data comes in, the Update Manager Subsystem notifies subscribers that fresh data is available.

 

If you open your PI System Management Tools and navigate to Operation -> Update Manager, you will see a list of all processes consuming and producing data.

 

2018-05-07 09_19_19-Update Manager - PI System Management Tools.png

 

Now, if you filter by *w3wp* (the name of the IIS process) you can drill down the data and get the list of tags being consumed by that specific signup.

 

2018-05-07 09_37_34-Update Manager - PI System Management Tools.png

 

But hey, this is PI DevClub! What about doing it programmatically? Unfortunately, the Update Manager information is not available in AF SDK, but we have the PowerShell tools to help us with this task:

 

$conn = Connect-PIDataArchive -PIDataArchiveMachineName "emiller-vm2";
$pointIds = @();
While ($true)
{
     $consumers = Get-PIUpdateManagerSignupStatistics -Connection $conn -ConsumerName "*w3wp*";
     $consumers | ForEach-Object -Process {
          $pointId = $_.Qualifier;
          if ($pointIds -notcontains $pointId -And $pointId -ne 0)
          {
               $pointIds += $pointId;
               $piPoint = Get-PIPoint -Connection $conn -WhereClause "pointid:=$pointId" -AllAttributes;
               $printObj = New-Object PSObject;
               $printObj | Add-Member Name $piPoint.Point.Name;
               $printObj | Add-Member Description $piPoint.Attributes.descriptor;
               $printObj | Add-Member Changer $piPoint.Attributes.changer;
               Write-Output $printObj;
          }
     }
}

 

If you run this script it will keep listening for every call to your PI Server originated from an IIS:

 

2018-05-07 17_09_02-Windows PowerShell.png

 

By now you may have noticed the two problems of this method: (1) it only shows a new entry if somebody request data for a given PI point (i.e.: open a display) and (2), we are just listing tags and we totally ignore AF attributes. A workaround for the first one is to leave the script running for a while and pipe the result to a text file.

 

PI Vision's Database

 

Let me say this once again before we proceed: we strongly recommend users to not touch PI Visions' database. That said...

 

There are two ways to extract this information from the database. The first one is dead simple, but only works if you don't have displays imported from ProcessBook:

 

SELECT 
     E.Name [DisplayName],
     E.Owner [DisplayOwner],
     D.FullDatasource [Path]
FROM 
     BrowseElements E,
     DisplayDatasources D
WHERE
     E.ID = D.DisplayID

 

The result of this select is a table with all AF Attributes and PI Points used by PI Vision.

 

2018-05-07 17_05_28-SQLQuery1.sql - bmoura-vm3.PIVisualization (OSI_rborges (53))_ - Microsoft SQL S.png

 

This may work for you, but one person that approached me during PI World, also asked me if it was possible to list not only the data sources but also the Symbols using them. Also, most of the displays were imported from ProcessBook. And that's when things get tricky:

 

SELECT
     E.Name as [DisplayName],
     E.Owner as [DisplayOwner],
     S.c.value('../@Id', 'nvarchar(128)') as [Symbol],
     D.c.value('local-name(.)', 'nvarchar(2)') as [Source],
     CASE -- Constructing the path according to the data source
          WHEN D.c.value('local-name(.)', 'nvarchar(2)') = 'PI' -- The data comes from a PI Point
          THEN '\\' +
               CASE WHEN CHARINDEX('?',D.c.value('@Node', 'nvarchar(128)')) > 0 -- Here we check if the server ID is present
               THEN LEFT(D.c.value('@Node', 'nvarchar(128)'), CHARINDEX('?',D.c.value('@Node', 'nvarchar(128)'))-1)
               ELSE D.c.value('@Node', 'nvarchar(128)')
               END 
               + '\' + 
               CASE WHEN CHARINDEX('?',T.c.value('@Name', 'nvarchar(128)')) > 0 -- Here we check if the point ID is present
               THEN LEFT(T.c.value('@Name', 'nvarchar(128)'), CHARINDEX('?',T.c.value('@Name', 'nvarchar(128)'))-1)
               ELSE T.c.value('@Name', 'nvarchar(128)')
               END
          WHEN D.c.value('local-name(.)', 'nvarchar(2)') = 'AF' -- The data comes from an AF attribute
               THEN '\\' + D.c.value('@Node', 'nvarchar(128)')  + '\' + D.c.value('@Db', 'nvarchar(256)') +  '\' 
               + CASE 
               WHEN T.c.value('@ElementPath', 'nvarchar(128)') IS NOT NULL 
               THEN T.c.value('@ElementPath', 'nvarchar(128)') + '|' + T.c.value('@Name', 'nvarchar(128)')
               ELSE O.c.value('@ElementPath', 'nvarchar(128)') + T.c.value('@Name', 'nvarchar(128)')
               END
     END as [Path]
FROM
     BaseDisplays B
     CROSS APPLY B.COG.nodes('/*:COG/*:Datasources/*/*') T(c)
     CROSS APPLY B.COG.nodes('/*:COG/*:Databases/*') D(c)
     CROSS APPLY B.COG.nodes('/*:COG/*:Symbols/*:Symbol/*') S(c)
     LEFT JOIN BaseDisplays B2 OUTER APPLY B2.COG.nodes('/*:COG/*:Contexts/*:AFAttributeParameter') O(c) 
          ON T.c.value('../@Id', 'nvarchar(128)') = O.c.value('@Datasource', 'nvarchar(128)'),
     BrowseElements E
WHERE
     E.ID = B.BrowseElementID
     AND E.DeleteFlag = 'N'
     AND D.c.value('@Id', 'nvarchar(128)') = T.c.value('../@DbRef', 'nvarchar(128)')
     AND T.c.value('../@Id', 'nvarchar(128)') = S.c.value('@Ref', 'nvarchar(128)')

 

The result is a little more comprehensive than the previous script:

 

2018-05-07 17_05_47-SQLQuery2.sql - bmoura-vm3.PIVisualization (OSI_rborges (55))_ - Microsoft SQL S.png

 

These queries were made for the latest version available (2017 R2 Update 1) and it's not guaranteed to be future-proof. It's known that PI Vision 2018 will use a different data model, so, If needed, I will revisit this post after the launch of the 2018 version.

 

I'm not going to dig into the specifics of this script as it has a lot of T-SQL going on to deal with the XML information that is stored in the database. If you have specific questions about how it works, leave a comment. Also keep in mind that this query is a little expensive, so you should consider running during off-peak hours or on a dev database.

 

Conclusion

 

List all tags and attributes used by PI Vision is a valid use case and most PI admins will agree that it helps to understand their current tag usage. We have been increasing our efforts on system usage awareness and, with this post, I hope to help with this goal.

The recording for this Live Coding presentation may be found at: Getting the most out of AFSearch

 

Associated code may be found on this GitHub repository:

GitHub - Rick-at-OSIsoft/AF-SDK-TechCon-2018-AFSearch-LiveCoding: Presentation also titled "Getting the most out of AFSe…

 

GitHub also includes a PDF file of the slide deck.  Topics include:

 

Demo 1: What's new in AF SDK 2.9.5 and 2.10

Demo 2: Breaking it down line-by-line to see what's happening on the client versus the server

Demo 3: Caching versus Not Caching

Demo 4: Accurate counts especially when client-side filtering is required

Demo 5: The perils of LINQ

 

Along the way we touch upon AFAttributeSearch, using the skinny, lightweight FindObjectFields with AFEventFrames, why caching is so important to performance, and why you need to properly dispose of the AFSearch objects.

We are excited to present the PI World Innovation Hackathon 2018 winners!

 

DCP Midstream kindly provided a sample of their data with boosters and compressors information. Participants were encouraged to create killer applications for DCP Midstream by leveraging the PI System infrastructure.

 

The participants had 23 hours to create an app using any of the following technologies:

  • PI Server 2017 R2
  • PI Web API 2017 R2
  • PI Vision 2017  R2

 

Our judges evaluated each app based on their creativity, technical content, potential business impact, data analysis and insight and UI/UX. Although it is a tough challenge to create an app in 23 hours, six groups were able to finish their app and present to the judges!

 

Prizes:

1st place: Sonos PLAY 5 + Echo Dot, one year free subscription to PI Developers Club, one time free registration at OSIsoft PI World over the next 1 year

2nd place: Bose Quiet Comfort 35 (Series II), one year free subscription to PI Developers Club, 50% discount for registration at OSIsoft PI World over the next 1 year

3rd place: Vilros Raspberry Pi 3 Retro Arcade Gaming Kit + 5 USB Classic Controllers and one year free subscription to PI Developers Club

 

 

Without further do, here are the winners!

 

1st place - Oogway

 

The team members were: Kshitiz Jain, Matthew Wallace, Paurav Joshi and Diego Eduardo Mercadal

 

 

1st place.jpg

 

1st place winners interview.jpg

 

Team Oogway built a dashboard that enables the plants to make a more informed decision on the route boosters should take. This is done through providing the optimal plant for each booster and telling the current target of each booster. While giving the ability to drill down into each of the boosters to understand efficiency and anomalies.

 

The team used the following technologies:

  • Google Maps API embedded into PI Vision
  • PI AF SDK

Here are some screenshots presented by the Oogway team!

 

Compressor Page:

 

 

 

 

 

2nd place - <Insert Obligatory Gas Joke Here>

 

The team members were:  Rob Raesemann, Greg Busch, Lonnie Bowling and David Rodriguez

 

2nd place.jpg

 

They developed an app which utilizes PI AF event frames to generate leading data sets for further analysis. Utilizes PI Web API client library in Python to analyze and visualize data. Uses the PI AF SDK and Angular to provide visualization and interaction with event frames by end users. Explores novel voice interaction with end users.

 

The team used the following technologies:

  • Python
  • PI AF SDK
  • PI Web API and its client library for Python
  • Angular

 

Here are some screenshots presented by <Insert Obligatory Gas Joke Here>!

 

 

 

 

3rd place - Fantastic Four

 

The team members were: Xihui Zhang, Michael Baldauff, Jonathan Mejeur  and Syed Rehanrawos

 

3rd place.jpg

 

Team Fantastic Four developed an app which leverages features of PI Vision 4 in order to display IIOT results from a high level overview to multistate reporting.

 

The team used the following technologies:

  • PI Vision 4

 

Here is a screenshot presented by the Fantastic Four!

 

This is the material for the talk "Build PI Applications Faster with PI Web API Client Libraries" held during the PI World SF 2018 Developer Track.

 

GitHub - osimloeff/Building-Apps-Faster-Client-Libs-TechCon2018: Samples used on the "Building applications faster using…

 

It includes:

1. Visual Studio Solution

2. PowerPoint Presentation

 

Click "Download ZIP" on the right-side of the toolbar or fork and clone to your local repository.

 

This talk and source code have 10 examples:

 

  • Example 1 - Authentication
  • Example 2 - Retrieve basic PI Objects: PIElement, PIAttributes
  • Example 3 - Handling exceptions
  • Example 4 - Updating PI Point description
  • Example 5 - Retrieve data in bulk
  • Example 6 - Update data in bulk
  • Example 7 - PI Web API Batch
  • Examples 8 and 9 - Web ID 2.0 client generation
  • Example 10 - PI Web API Channels

 

This is the material for the "Developing Modern Web Apps Using Angular 5 and PI Web API " hands-on-lab held during the PI World SF 2018 Developer Track.

 

GitHub - osimloeff/Modern-Web-Technologies-TechCon2018

 

It includes:

1. Two Visual Studio Code Projects

2. Workbook

3. XML to be imported in PI AF

4. PowerPoint Presentation

 

Click "Download ZIP" on the right-side of the toolbar or fork and clone to your local repository.

 

The screenshot below shows the sample app used in this lab.

 

 

This lab has 5 exercises.

  • Exercises 1 and 2 are about retrieving the cities geolocation.
  • Exercises 3 is about getting live and performing calculations.
  • Exercise 4 will explain how integrate your app with PI Vision 3.
  • Exercise 5 is about PI Web API Batch

 

The Virtual Machine for this lab is available on OSIsoft Virtual Learning Environment whose link is below:

https://learning.osisoft.com/Labs/LabInformation/

Filter Blog

By date: By tag: