There is a blog post that shows how to use AFSDK with Python.

PI and Python? PIthon! (Rafael Borges created it)

Sometimes I provide training courses in OSIsoft Japan office and some customers wanted to use python to get data from PI.

For connecting PI from python, PI Web API can be used.

Using PI Web API with Python

Though AFSDK is also works as Rafael's post, so I created some codes and want to share it with community.

 

At first download Python.

https://www.python.org/downloads/

There are 2.7 and 3.6. This time, I used python 3.6.1.

We need to install pythonnet too.

http://pythonnet.github.io/

I used pip command and could install easily.

From command prompt, go to python 3.6's directory and run following commands.

cd scripts
pip install pythonnet

This screenshot's install path is C:\Python36

After that, create PIthon.py file with following codes. Put this file to Python.exe's directory and run following from command prompt.

python.exe PIthon.py

 

I uploaded the code to GitHub too.

GitHub - kenji0711/PIthon: Python and AFSDK project

 

* This code includes write value to PI Tag.

Please change write tag name within the code.

writept = PIPoint.FindPIPoint(piServer,"PleaseEnterWriteTagName")

Also this code use NuGreen database. Please change element, attribute name as your AF object name.

import sys
import clr


sys.path.append(r'C:\Program Files (x86)\PIPC\AF\PublicAssemblies\4.0')  
clr.AddReference('OSIsoft.AFSDK')


from OSIsoft.AF import *
from OSIsoft.AF.PI import *
from OSIsoft.AF.Asset import *
from OSIsoft.AF.Data import *
from OSIsoft.AF.Time import *
from OSIsoft.AF.UnitsOfMeasure import *


print("Welcome to PIthon!!")
# PI Data Archive
piServers = PIServers()  
piServer = piServers.DefaultPIServer;


pt = PIPoint.FindPIPoint(piServer, "sinusoid")
name = pt.Name.lower()
# CurrentValue
print('\nShowing PI Tag CurrentValue from {0}'.format(name))
current_value = pt.CurrentValue()
print( '{0}\'s Current Value: {1}'.format(name, current_value.Value))


#recordedvalues
timerange = AFTimeRange("*-3h", "*")
recorded = pt.RecordedValues(timerange, AFBoundaryType.Inside, "", False)
print('\nShowing PI Tag RecordedValues from {0}'.format(name))
for event in recorded:
    print('{0} value: {1}'.format(event.Timestamp.LocalTime, event.Value))


#plotValues
plotvalues = pt.PlotValues(timerange, 1)
print('\nShowing PI Tag PlotValues from {0}'.format(name))
for event in plotvalues:
    print('{0} value: {1}'.format(event.Timestamp.LocalTime, event.Value))


#interpolatedvalues
span = AFTimeSpan.Parse("1h")
interpolated = pt.InterpolatedValues(timerange, span, "", False)
print('\nShowing PI Tag InterpolatedValues from {0}'.format(name))
for event in interpolated:
    print('{0} value: {1}'.format(event.Timestamp.LocalTime, event.Value))


#summariesvalues
summaries = pt.Summaries(timerange, span, AFSummaryTypes.Average, AFCalculationBasis.TimeWeighted, AFTimestampCalculation.Auto)
print('\nShowing PI Tag SummariesValues(Average) from {0}'.format(name))
for summary in summaries:
    for event in summary.Value:
        print('{0} value: {1}'.format(event.Timestamp.LocalTime, event.Value))


#writeValue
writept = PIPoint.FindPIPoint(piServer,"test999")
writeptname = writept.Name.lower()
val = AFValue()
val.Value = 20
#val.Timestamp = AFTime("t+9h")


print('\nWrite value to {0} value: {1}'.format(writeptname, val.Value))
writept.UpdateValue(val, AFUpdateOption.Replace, AFBufferOption.BufferIfPossible)


#Connect to AF
print ('\nConnect to AF')
afServers = PISystems()
afServer = afServers.DefaultPISystem
#DB = afServer.Databases.DefaultDatabase
DB = afServer.Databases.get_Item("NuGreen")
element = DB.Elements.get_Item("NuGreen").Elements.get_Item("Little Rock").Elements.get_Item("Extruding Process").Elements.get_Item("Equipment").Elements.get_Item("K-435")


attribute = element.Attributes.get_Item("Steam Flow")
attval = attribute.GetValue()


print ('Element Name: {0}'.format(element.Name))
print ('Attribute Name: {0} | Value : {1} {2}'.format(attribute.Name, attval.Value, attribute.DefaultUOM))


#create element with attribute
print('\nCreate Element with Attribute')
if DB.Elements.get_Item("Test New Element") is not None:
    print("Already Existing Element: Test New Element")
else:
    newelement = DB.Elements.Add("Test New Element")
    newelement.Description = "Created element from PIthon"
    newattribute = newelement.Attributes.Add("Test Attribute")
    newattribute.DataReferencePlugIn = afServer.DataReferencePlugIns.get_Item("PI Point")
    newattribute.DataReference.ConfigString = "cdt158"
    DB.CheckIn()
    print("Created new Element : Test New Element")











The results are following.

This code can be run by both Python 3.6, 2.7.

With Python 2.7, I needed to create AFValue by

val = AFValue()  
val.Value = 20  
val.Timestamp = AFTime("t+9h") 

 

Python 3.6 works by

val = AFValue(20, AFTime("t+9h"))

 

Python 3.6 is easier than 2.7 to write code.

AFSDK help file does not contain Python example.

So we need to looking for how to write codes by python. I hope this post helps someone.

If you have any questions, please comment it.