An Industrial IOT Platform

OPScript Documentation

Introduction to OPScript

OPScript: The language for Open-Plant Analytics

OPScript, short for Open-Plant Script, is the script language used to power the Open-Plant Analytics Engine. Open-Plant Analytics is provided in all version of Open-Plant, even the free version.

OPScipt is C# DotNet. Learn it if you haven't

OPScript is a based on Microsoft C# .NET language. We chose C# as unlike Java, it is the most used language within the corporate world.

If you know C#, learning OPScript would be a breeze. Though, if you are new to C# I recommend you going through a C# tutorial from Mosh Hamedani at the following link:

Getting Started

Launch Open-Plant Analytics from the Open-Plant Client

Open-Plant Analytics is accessed by clicking on the 'Analytics Link' from the Open-Plant Client.

Click on 'New Analysis' and run 'Hello world!'

Click on 'New Analysis' to run the code. A default code should appear, which is basically a code the show 'Hello World!' to the console. The black screen on the right hand side is the coder's console. It's purpose is only to help the coder see what's going on, by using 'OP.Log' to view results. Click on 'Run Analysis' to run the code and you should see 'Hello World' appear on the console. 

Run Analysis only runs the code once, usually for testing purpose. Normally, analytics will be run on a periodic schedule, explained further below.

The OP Object

Access Open-Plant via the OP Object

The main component of OPScript is the OP object. Simply type 'OP.' (OP with dot), a list of objects and methods can be accessed for script manipulation.

Next Step

if you are an experienced coder, scroll down to the sample codes below to learn faster. 
If you are new, click on the links below to learn further.

1) Learn how to create, access, and edit Tags

2) Learn how to access and write Tag Data Samples

3) Learn about OPScript Parameters 

4) Learn about Schedules 

Sample Codes (For experienced coders)

The following are some example codes for those who are eager to start coding!
Sample Code

Generate an Average Value Tag

The following code creates and maintains a new tag which is based on the average of three input tags. This code is scheduled periodically to continously generate the average data.
//Create the Average Tag if it does not exist
if (!OP.TagExists("FIC101.Average")) OP.CreateAndSaveTag("FIC101.Average", "m3hr", DataType.Real, Interpolation.Linear, "Main Feed Flow Meter (Average)");

//Calculate the average value and insert the results into the Average Tag
var AverageValue = (OP.Tag("FIC101A.Value").Value.ToDouble() + OP.Tag("FIC101B.Value").Value.ToDouble() + OP.Tag("FIC101C.Value").Value.ToDouble()) / 3;
if (OP.InsertSample("FIC101.Average", AverageValue))
	OP.Log("Successfully inserted average value = " + AverageValue);

Sample Code

Generate a Moving Average Value Tag

The following code creates and maintains a new tag which is based on the moving average of a single tags This code is scheduled periodically to continously generate the moving average data.
//Create the Tag if it doesn't exist
if (!OP.TagExists("FIC101.MovingAverage")) OP.CreateAndSaveTag("FIC101.MovingAverage", "m3hr", DataType.Real, Interpolation.Linear, "Main Feed Flow Meter (60seconds MovingAverage)");

//Obtain 60 samples in the last minute
List Samples = OP.Tag("FIC101.Value").Samples("Now-60s","Now",1000);

//Total up the samples
double TotalValue = 0;
foreach (Sample S in Samples)
	TotalValue = TotalValue + S.Value.ToDouble();

//Calculate the moving average and insert the sample
double MovingAverage = TotalValue / Samples.Count.ToDouble();
if (OP.InsertSample("FIC101.MovingAverage",MovingAverage))
	OP.Log("Successfully inserted FIC101 Moving Average Value = " + MovingAverage);

Sample Code

Generate Dummy Tags and Data

The following code generates dummy data for specific tags and writes it into Open-Plant. The tags that it will create are  FIC101.Value, TIC102.Value, WIC103.Valuue, PIC104.Value and LIC105.Value. It will then create dummy data (using a randomizer) and insert it into relevant tags.

Data is inserted from the last 30 days to the current, at a 1 second interval.

To allow the script to continue where it left on consecutive runs of the script, the last value of the Tag and timestamp are saved using OPScript Parameters.
double ValueFIC = 2000;
double ValueTIC = 250;
double ValueWIC = 100;
double ValuePIC = 50;
double ValueLIC = 60;
DateTime TimeStamp;
Random Random = new Random();

//Create the Tags
OP.CreateAndSaveTag("FIC101.Value", "m3hr", DataType.Real, Interpolation.Linear, "Main Feed Flow Meter");
OP.CreateAndSaveTag("TIC102.Value", "DegC", DataType.Real, Interpolation.Linear, "Main Feed Temperature");
OP.CreateAndSaveTag("WIC103.Value", "ton/hr", DataType.Real, Interpolation.Linear, "Main Feed Weightometer");
OP.CreateAndSaveTag("PIC104.Value", "kPa", DataType.Real, Interpolation.Linear, "Main Feed Pressure");
OP.CreateAndSaveTag("LIC105.Value", "m", DataType.Real, Interpolation.Linear, "Main Feed Drum Level");

//Read exsiting Parameters
if (!OP.ParameterExists("TimeStamp"))
    TimeStamp = DateTime.UtcNow.AddDays(-30);
    OP.SetParameter("TimeStamp", TimeStamp);
else TimeStamp = OP.GetParameter("TimeStamp").ToDateTime();
if (OP.ParameterExists("FIC101_LastValue")) ValueFIC = OP.GetParameter("FIC101_LastValue").ToDouble(); else OP.SetParameter("FIC101_LastValue", ValueFIC);
if (OP.ParameterExists("TIC102_LastValue")) ValueTIC = OP.GetParameter("TIC102_LastValue").ToDouble(); else OP.SetParameter("TIC102_LastValue", ValueTIC);
if (OP.ParameterExists("WIC103_LastValue")) ValueWIC = OP.GetParameter("WIC103_LastValue").ToDouble(); else OP.SetParameter("WIC103_LastValue", ValueWIC);
if (OP.ParameterExists("PIC104_LastValue")) ValuePIC = OP.GetParameter("PIC104_LastValue").ToDouble(); else OP.SetParameter("PIC104_LastValue", ValuePIC);
if (OP.ParameterExists("LIC105_LastValue")) ValueLIC = OP.GetParameter("LIC105_LastValue").ToDouble(); else OP.SetParameter("LIC105_LastValue", ValueLIC);

//Loop until all data inserted
while (true)
    ValueFIC = ValueFIC + (Random.NextDouble() * 2) - 1;
    ValueTIC = ValueTIC + (Random.NextDouble() * 2) - 1;
    ValueWIC = ValueWIC + (Random.NextDouble() * 2) - 1;
    ValuePIC = ValuePIC +(Random.NextDouble() * 2) - 1;
    ValueLIC = ValueLIC + (Random.NextDouble() * 2) - 1;
    TimeStamp = TimeStamp.AddSeconds(1);
    OP.InsertSample("FIC101.Value", ValueFIC, TimeStamp);
    OP.InsertSample("TIC102.Value", ValueTIC, TimeStamp);
    OP.InsertSample("WIC103.Value", ValueWIC, TimeStamp);
    OP.InsertSample("PIC104.Value", ValuePIC, TimeStamp);
    OP.InsertSample("LIC105.Value", ValueLIC, TimeStamp);

    OP.Log("Generating Data for " + TimeStamp);
    if (TimeStamp >= DateTime.UtcNow) break;

//Save Parameters for the next run
OP.SetParameter("TimeStamp", TimeStamp);
OP.SetParameter("FIC101_LastValue", ValueFIC);
OP.SetParameter("TIC102_LastValue", ValueTIC);
OP.SetParameter("WIC103_LastValue", ValueWIC);
OP.SetParameter("PIC104_LastValue", ValuePIC);
OP.SetParameter("LIC105_LastValue", ValueLIC);

Open-Plant is a revolutionary Industrial IOT Platform software, used to create and deploy Industrial IT apps/solutions. It is an all-encompassing solution offering both back-end and front-end components i.e. the full stack. From our user's experience, creating and deploying Industrial IT apps became 10x faster and 10x less cost. We serve the mining, energy, oil & gas, construction and manufacturing industry. 


Perth, Australia