Skip navigation
All Places > PI Developers Club > Blog > 2009 > July

Paths and Default Servers

Posted by smohr Jul 31, 2009

PI SDK, as everyone knows, will use the default server if you request a tag without specifying a server, e.g., sinusoid rather than \\server1\sinusoid.  Off the top of one's head, then, you would want PI WS to support the same behavior for pi: and pe: paths.


Or would you? PI WS is remote to the caller (well, usually).  For implementation reasons I won't go into here, there could be yet another hop involved.  Consequently, the user making the call might not know the default, or the default might have been changed without his knowledge.


What's your opinion?  Allow paths like pi:sinusoid to use the configured default server of the remote machine, or insist that any pi or pe path name the server?

I'm thinking if we had some kind of "Friday Good News" series, this would be a real good candidate: I finally got a hold of the recording of the Web Services webinar held yesterday! As confirmed by the LiveMeeting support people, they had technical problems and I couldn't access the recording until this morning - 2 days later. This really scared me for a bit as I thought we really lost the thing...


But everything's back to normal, I should be able to post the recording shortly under the vCampus Auditorium (a few edits are necessary to make it better quality). I'll post a little something in the "Web Services and PI" discussion forum when it's there.


Have a good week-end!


Sample code coming soon

Posted by smohr Jul 29, 2009

The demo we gave today only scratched the surface of what is available in PI Web Services.  We will be posting sample code very soon.  Currently, we have code for .NET and Java (Eclipse + SWT + Axis).  We will also be posting directions for connecting to the CTP hosted web service so you can 'kick the tires' for yourself.  Be sure to check back frequently.

PI SDK Web Service Examples

Posted by spilon Jul 29, 2009

What I suggest in this download is an updated version of the "PI Web Service Examples", which can be found on the Technical Support website's download center. It presents 4 Visual Studio 2008 projects in C#: 2 web services and 2 web service clients. They are grouped in 2 solutions (.sln files), so make sure you choose the right one:

  • PI SDK Web Service and Client Examples (IIS6-).sln:
    if you are running IIS6 and earlier (e.g. Windows XP, Windows Server 2003)
  • PI SDK Web Service and Client Examples (IIS7+).sln:
    if you are running IIS7 and later (e.g. Windows Vista, Windows 7, Windows Server 2008)

Please note that those are only examples and should not be used "as is" in production environments. They were originally developed with the idea to keep it really simple and as concise as possible; some parts need to be adapted to make them appropriate for real-life, larger-scale applications. One example of this is the cross-thread calling of UI elements after an asynchronous tag search - you should make sure to use the appropriate threading model to fit the structure and the needs of your applications.


With that said, it is definitely simpler to use the PI Web Services product (released as CTP - Community Technology Preview - to the vCampus community) rather than creating your web services to wrap some PI SDK functionality. Find out more about PI Web Services on the newly-created "Web Services and PI" blog!


PI ProcessBook: SetViewPort

Posted by andreas Jul 10, 2009


Another post on some small code snippets that might be of use for you.


ProcessBook displays can be huge and the amount of information overwhelming. With the help of VBA we can zoom the view to a certain area to catch the attention of the observer .


So what are we going to do?

  1. For demonstration we simply put a Value object on the PI ProcessBook. The example below uses the values of CDM158 - so adjust to your needs.
  2. Now we switch to VBA by hitting Alt+F11.
  3. Use the two combo boxes on the top of the code window to open the Value1_DataUpdate Sub.
  4. Type the following code into Value1_DataUpdate:
    Dim AspectRatio AsDouble
    AspectRatio = Me.ViewWidth / Me.ViewHeight
    SelectCaseMe.Value1.GetValue(vrDate, vrStatus)
          CallMe.SetViewPort(15000, -15000, 30000 / AspectRatio, 30000)
          CallMe.SetViewPort(15000, 0, 15000 / AspectRatio, 15000)
          CallMe.SetViewPort(0, -15000, 15000 / AspectRatio, 15000)
          CallMe.SetViewPort(0, 0, 15000 / AspectRatio, 15000)
          CallMe.SetViewPort(15000, -15000, 30000 / AspectRatio, 30000)

The result is a PI ProcessBook display that changes it's visible area dependent of the value of CDM158.


The top left corner of a PI ProcessBook display is (15000,-15000).

As suggested in David's blog post, OSIsoft will be well represented next week at the Microsoft Worldwide Partner Conference (WPC) in New Orleans. And I will be there to represent the OSIsoft Virtual Campus and promote how people can leverage our products as well as Microsoft's to do great things.


2 questions for you:

  1. Will you be there?
    Don't hesitate to come and connect with me (come see us at the OSIsoft booth or arrange face-to-face with me through the WPC Connect tool)
  2. Do you have any Dynamic OBA (Office Business Application) - OBA with PI - to share with us?

And for those of you coming to the WPC, don't miss the following talk, where Prabal Acharyya (Director of the Microsoft World Wide Partner Alliance at Microsoft) will be co-presenting with Carlo Malaguzzi from Microsoft:
***BP005 Reducing Costs and Maximizing Revenue with Office Business Applications
***Mon 7/13 | 5:00 PM-6:00 PM | 208-210

When reading this discussion on the forums (where Yannick was inquiring about a PI SDK method that would perform multiple calculations at once) I realized something and I'm glad to see I'm not the only one in this boat: we, developers, are expecting more and more out of the various SDKs we are using nowadays. We expect the SDKs to expose always more "1-call" functionalities, with increased complexity, and we slowly get accustomed to fewer and fewer lines of code.


And I think I found why: the Microsoft .NET Framework. Let me explain:


In my opinion, Microsoft has significantly raised the bar in terms of SDKs with the .NET Framework, with its wide (wide? no, huge!) variety of classes and methods - and method overrides. When dealing with .NET classes (think of the various classes in System.Collection or the ADO.NET objects in System.Data, for instance), it seems to me like classes always expose a version of the method that perfectly suits my needs. The .NET designers thought of so many use cases and they expose so much functionality... good work, Microsoft!  But man, you're making us lazier...


We often take it for granted because it's more "infrastructural" (i.e. it's everywhere and invisible at the same time) than an actual product, but it is an actual product and it greatly simplifies (and reduces) the code we have to write. The Framework does so much behind the scene that it makes the (not-so-old) good old days look so far... manually-created and -maintained linked lists, bubble sorting, memory management and pointers, reading files or network streams, performing drawing, SQL or FTP tasks, etc.  When's the last time you wrote more than 10 lines of code to read a file?


I suggest you do this little exercise, just for the fun of it: open an old piece of code you wrote (say in 2000) and compare the number of loops you have with the number of loops you write in today's code - the difference is amazing. Happy .NET coding!

The Modified property

Have you ever thought about exiting a ProcessBook Display without getting prompted to save the changes?


The ProcessBook Display class exposes a property called Modified. Simply catch the BeforeClose event of the Display and set the Modified property to False. ProcessBook will not ask you to save the changes.


This can be handy if your users are allowed to change the display but you neither want them to safe the changes nor bother them with the question.

Private Sub Display_BeforeClose( ByVal bCancelDefault As Boolean
    Me.Modified = False
End Sub

A WebBrowser inside the Display

Adding a Browser to a ProcessBook is fairly simple:

  1. Open a ProcesBook Display.
  2. Press the Control button and add a Microsoft WebBrowser Control.
Now we will have to add some code to select the URL to display. For the sake of simplicity we will just choose a website to navigate to when the display is opened:
  1. Open the VBA editor either by pressing the apropriate button or by ALT+F11.
  2. Open the Code Window by a double-click on ThisDisplay in the Project Tree.
  3. Use the two combo boxes on the top of the code window to open the Display_Open Sub.
  4. Add the code below.

PrivateSub Display_Open()
    Me.WebBrowser1.Navigate( "" )

You may imagine that other events can be used to drive the content of the WebBrowser control guiding the user of ProcessBook from events out of the process.

Last week the Portaledge research team at Digitalbond reached another milestone with beta release of the Enumeration Event class!


The Enumeration Event class is implemented using the PI Advanced Calculation Engine to flag unexpected network communication patterns (collected by the IP Flow interface).


Raw IP Flow tag data (source, destination, ports, protocols, and octets) is first added to a shared collection object representing session activity captured over the calculation interval. Separate analytic modules are provided for each type of enumeration event.


Browsing the analytic logic shows effective use of the popular .NET System Data namespace for further handling of session data, alert rules (eg. maximum ports touched threshold) and exception rules (eg. allowed communication protocol).


DataTable objects provide an in memory cache for structured data but the schema is created explicitly. The DataView object provides built-in methods for searching, sorting and filtering.


Dim myTable As New DataTable
Dim column As DataColumn
Dim row As DataRow
Dim myView As DataView


' ...


column = New DataColumn()
column.DataType = System.Type.GetType("System.String")
column.ColumnName = "SrcIP"




row("SrcIP") = LocalSessions(i).SrcIP
row("DstIP") = LocalSessions(i).DstIP
row("SrcPort") = LocalSessions(i).SrcPort
row("DstPort") = LocalSessions(i).DstPort
row("Protocol") = LocalSessions(i).Protocol




myView = New DataView(myTable)
myView.Sort = "DstIP ASC, DstPort ASC, SrcIP ASC" 

Portaledge enumeration analysis adds another dimension to the tried and true IP Flow interface. This method is especially useful for monitoring communication patterns involving a protected network.  The code is open source thanks to the US DoE and DigitalBond's nominal subscription, so have a look at Portaledge and get this app up and running!

One of the more advanced features of PI WebParts is to allow the creation of a named set of appearance and behavior characteristics for many of our web parts. Called "Advanced Configurations", these named sets of appearance and behavior characteristics can be created for RtMessenger, RtTrend and RtXYPlot, and for the tabular web parts: RtTable, RtValues, and RtTimeSeries. Advanced configurations are created using the administrative web site.


Conditionally changing the foreground and background colors for a dataset column is one of the more powerful options of advanced configurations for tabular web parts. As of version 2.1 of RtWebParts, any number of conditional format specifications can be added to a single dataset column. These specifications are evaluated in order, from top to bottom, and the first specification whose condition is satisfied is applied for the applicable column for each row in the dataset.


There are two subtle points to note about conditional format specifications. First, both operands in the comparison can be column values, even though the second operand is entered with a text box instead of selected from a list of known columns. To compare one column value to another, select the first column in the first operand pull-down, then select the operator, then for the second operand use the "col()" function, with an argument of the column name. The second subtle point follows from the first, and that is that the condition applied to a column does not have to be based on that column's value. In other words, when specifying the condition, none of the operands have to be the column that is being conditionally formatted.


As an example, imagine a dataset with three columns: A, B and C. You can create an Advanced Configuration for the tabular web parts that will change the foreground and background colors of the cells in column A based on comparison of the values of columns B and C in that same row.



Filter Blog

By date: By tag: