An Industrial IOT Platform

OPScript - Working with Data Samples

Accessing Tag Data Samples

In Open-Plant Analytics, the best way to obtain values from tags is by reading the Tag Samples data. A sample is an object which holds the timestamp in UTC format (TSUTC) and the value of a data. From the OP.Tag([TagId]) object, the following methods are available:

OPScript

OP.Tag.Sample

This function returns the current sample of a tag. A sample is an object which holds the timestamp in UTC format (TSUTC) and the value of a data. Use "ToLocalTime()" to change to current time. OP.Tag.Value mentioned above is equivalent Sample.Value.

A sample is considered current if it is not older than it's timeout value.
If there is no current sample, the sample object will return with "sample.value" equals to NULL.

The timeout value is a property of the tag. If not set, it's default value is 180seconds (3 minutes).

//This shows the current sample of 'FIC101.Value' in the console
var CurrentSample= OP.Tag("FIC101.Value").Sample;
OP.Log("Current Sample Value is = " + CurrentSample.Value);
OP.Log("Current Sample Time is = " + CurrentSample.TSUTC.ToLocalTime());
OPScript

OP.Tag.LastSample

This function returns the last or most recent sample of a tag. A sample is an object which holds the timestamp in UTC format (TSUTC) and the value of a data. Unlike 'OP.Tag.Sample' it will not return 'sample.value' as null if the value is old. 

//This shows the last known value of 'FIC101.Value' in the console
var LastKnownValue = OP.Tag("FIC101.Value").Value;
OP.Log(LastKnownValue);

//This shows the current sample of 'FIC101.Value' in the console
var LastKnownSample = OP.Tag("FIC101.Value").LastSample;
OP.Log("Last known sample Value is = " + LastKnownSample.Value);
OP.Log("Last known sample Time is = " + LastKnownSample.TSUTC);
OPScript

OP.Tag.FirstSample

This function returns the first (first ever) sample of a tag. A sample is an object which holds the timestamp in UTC format (TSUTC) and the value of a data. 

//This shows the first sample of 'FIC101.Value' in the console
var FirstSample = OP.Tag("FIC101.Value").FirstSample;
OP.Log("First Sample Value is = " + CurrentSample.Value);
OP.Log("First Sample Time is = " + CurrentSample.TSUTC);
OPScript

OP.Tag.SpotSample

This function returns the sample of a tag at a specified timestamp. This function works similar to 'OP.Tag.Value' though instead of returning only a value, it returns a sample. A sample is an object which holds the timestamp in UTC format (TSUTC) and the value of a data.  

The timestamp can be specified as:
- a DateTime object. The DateTime must be specified in UTC.
- a string Timestamp semantic.

A timestamp semantic is a format which takes a timestamp relative to the current time (NOW). For example:
- NOW
- NOW-1 Hour
- NOW-10 Minutes
- NOW-5 Second

Time semantic works in UTC by default so no UTC conversion is required.
var SpotSample1 = OP.Tag("FIC101.Value").SpotSample(DateTime.UtcNow);
OP.Log("Sample1 Value = " + SpotSample1.Value);

//The specified date must be in UTC
var SpotSample2 = OP.Tag("FIC101.Value").SpotSample("2020-06-18 20:02:00"); 
OP.Log("Sample2 Value = " + SpotSample2.Value);

var SpotSample3 = OP.Tag("FIC101.Value").SpotSample("Now");
OP.Log("Sample3 Value = " + SpotSample3.Value);

var SpotSample4 = OP.Tag("FIC101.Value").SpotSample("Now-1Hour");
OP.Log("Sample4 Value = " + SpotSample4.Value);

var SpotSample5 = OP.Tag("FIC101.Value").SpotSample("Now-5Day");
OP.Log("Sample5 Value = " + SpotSample5.Value);

var SpotSample6 = OP.Tag("FIC101.Value").SpotSample("Now-10Minute");
OP.Log("Sample6 Value = " + SpotSample6.Value);

//The specified date is in local time but it is converted to UniversalTime
var SpotSample7 = OP.Tag("FIC101.Value").SpotSample((new DateTime(2020,6,18,10,2,0)).ToUniversalTime()); 
OP.Log("Sample7 Value = " + SpotSample7.Value);
OPScript

OP.Tag.Samples

OP.Tag.Samples is one of them most important function for Data Analytics.
It obtains a list of sample objects (List<Sample>) between two specified dates 'StartTime' and 'EndTime'. Both dates need to be specified in UTC time format. Use 'ToUniversalTime()' extension to convert a Local DateTime to Universal Time.

The StartTime and EndTime can be specified with either a DateTime object or a timestamp semantic string. The DateTime must be specified in UTC.

A timestamp semantic is a format which takes a timestamp relative to the current time (NOW). For example:
- NOW
- NOW-1 Hour
- NOW-10 Minutes
- NOW-5 Second

An optional SamplePeriodInMS parameter can be specified. This parameter denotes the time interval between samples in miliseconds. Samples will be interpolated based on existing raw samples to achieve the maintain the required interval.

If this parameter is not specified, the sample period default value will be:
- 1000ms for durations less than 10 minutes; 
- 1 minute (60000ms) for durations less than 24 hour interval;
- 1 hour for durations less than 7 days interval
- 1 day for durations more 7 days interval
Duration is the specified EndTime minus StartTime

Example usage:
//This list all samples in the last hour for FIC101.Value. 
//Since interval is not specified and the duration is less than 24 hours, it defaults to 1 minute or 60000ms.
List Samples = OP.Tag("FIC101.Value").Samples("Now-1Hour","Now");
OP.Log("Number of Samples = " + Samples.Count);
foreach (Sample S in Samples) 
{
	OP.Log("Sample time: " + S.TSUTC.ToLocalTime() + ", Value: " + S.Value);
}
//This list all the samples in the last hour
List Samples = OP.Tag("FIC101.Value").Samples(DateTime.UtcNow.AddMinutes(-60),DateTime.UtcNow,30000);
OP.Log("Number of Samples = " + Samples.Count);
foreach (Sample S in Samples) 
{
	OP.Log("Sample time: " + S.TSUTC.ToLocalTime() + ", Value: " + S.Value);
}
OPScript

OP.Tag.RawSamples

OP.Tag.RawSamples is similar to OP.Tag.Samples (above). Instead of returning values at specific intervals, it returns the actual raw data stored in the Open-Plant database. It returns a list of sample objects (List<Sample>) between two specified dates 'StartTime' and 'EndTime'. Both dates need to be specified in UTC time format.  Use 'ToUniversalTime()' extension to convert a Local DateTime to Universal Time.

The StartTime and EndTime can be specified with either a DateTime object or a timestamp semantic string. The DateTime must be specified in UTC.

A timestamp semantic is a format which takes a timestamp relative to the current time (NOW). For example:
- NOW
- NOW-1 Hour
- NOW-10 Minutes
- NOW-5 Second

An optional IntervalInMS parameter can be specified in Miliseconds. This parameter ensure that the raw samples are only obtained every 'interval'. In other words, there will exist a minimum 'interval' space between the returned raw samples.

If this parameter is not specified, all raw samples will be returned. Though Open-Plant will limit the return to 100,000 samples to avoid overload. This limit can be disabled by specifying another parameter as false (See examples below)

Example usage:
//This lists all raw samples in the last 10 minutes for FIC101.Value. 
//Since interval is not specified, it will return all existing samples in the database between this period
//Open-Plant enforces a soft limit of 100,000 samples returned to avoid overloading the system.
//This limit can be disabled, see the other examples
List RawSamples = OP.Tag("FIC101.Value").RawSamples("Now-10minutes","Now");
foreach (Sample S in RawSamples) 
{
	OP.Log("Sample time: " + S.TSUTC.ToLocalTime() + ", Value: " + S.Value);
}
OP.Log("Number of Raw Samples = " + RawSamples.Count);
//This lists all raw samples in the last 10 minutes for FIC101.Value. 
//Interval is set as 30s, which mean it will only return a raw sample every 30s
//This variant also uses dateTime input rather than the timestamp semantic
List RawSamples = OP.Tag("FIC101.Value").RawSamples(DateTime.UtcNow.AddHours(-1),DateTime.UtcNow,30000);
foreach (Sample S in RawSamples) 
{
	OP.Log("Sample time: " + S.TSUTC.ToLocalTime() + ", Value: " + S.Value);
}
OP.Log("Number of Raw Samples = " + RawSamples.Count);
//This lists all raw samples in the last 3 days for FIC101.Value. 
//Interval is set as 1s, which mean it will return a raw sample every second
//The soft limit of 100,000 is disabled here by setting the last input parameter as false
List RawSamples = OP.Tag("FIC101.Value").RawSamples("Now-3day","Now",1000, false);
foreach (Sample S in RawSamples) 
{
	OP.Log("Sample time: " + S.TSUTC.ToLocalTime() + ", Value: " + S.Value);
}
OP.Log("Number of Raw Samples = " + RawSamples.Count);

Writing Data - Inserting Samples

OPScript

OP.InsertSample

Writing data to an Open-Plant tag is straight forward. The TagId and Value is to be specified.  

If a Tag does not exist or if the write fails, the function will return false. An error will also be shown on the console. The code will still continue.

It will return true if the write was successful.

See the examples below:
//This writes the value 10 to FIC101.Value at the current time
OP.InsertSample("FIC101.Value",10);

//This writes the value 10 to FIC101.Value at the current time. It is same as above
OP.InsertSample("FIC101.Value",10, DateTime.UtcNow);

//This writes the value 10 to FIC101.Value at 3rd Sept 2019 3:00:00PM
OP.InsertSample("FIC101.Value",10, "2019-09-03 15:00:00");

//This writes the value 10 to FIC101.Value at 3rd Sept 2019 3:00:00PM, 250milisecond
OP.InsertSample("FIC101.Value",10, "2019-03 15:00:00.250");

Accessing Table of Values

OPScript

OP.GetTableOfValues

OPScript provides a function which allows users to obtain a table of values typically used when evaluating a multi variable function. The table of values has been the most used function when it comes to evaluating complex analytics.

The function creates a consistent set of values pegged to a common timestamp series. In simpler words, it generates a table of values vs timestamps. Column 0 will be the time stamps (in UTC). Subsequent columns will be tag data values. 

The main benefit of this table is that it can be easily iterated in a loop. 

The actual output is an OutputTable object, which holds a list of OutputRows, which holds a List of Values. The first value i.e. Column 0, will be time stamp. Subsequent values will hold the tag data values.

The examples below should give a clear picture on how this works. In this example, the tag values are printed into the console.

A third input to the function "IfError", specifies what to do when a value is erroneous.
-'IfError.GetPreviousValue' will fill erroneous values with previous values and forward values (if there are no previous values).
-'IfError.SetToNull' will set the value to null.
//This generates a table of value from the last 30minutes with a 60second interval for 3 Tags. The result is printed on the console
OutputTable Table = OP.GetTableOfValues("Now-30mins","Now",60000,IfError.GetPreviousValue, "FIC101.Value","TIC102.Value","WIC103.Value");

//This is similar to the above, but with input specified with DateTime instead
//OutputTable Table = OP.GetTableOfValues(DateTime.UtcNow.AddMinutes(-30),DateTime.UtcNow,60000,IfError.GetPreviousValue, "FIC101.Value","TIC102.Value","WIC103.Value");

foreach (OutputRow Row in Table)
{
	//Column 0 is for Time Stamp
	DateTime Timestamp = ((DateTime)Row[0]).ToLocalTime();	
	
	//Column 1 is for FIC101.Value
	var FIC101 = Row[1];
	
	//Column 2 is for TIC102.Value
	var TIC102 = Row[2];
	
	//Column 3 is for WIC103.Value
	var WIC103 = Row[3];
	
	OP.Log(Timestamp + ", FIC101=" + FIC101 + ", TIC102=" + TIC102 + ", WIC103=" + WIC103);
}
OP.Log("Number of Rows = " + Table.Count);
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. 

OPEN-PLANT PTY LTD

Perth, Australia

EMAIL

info@open-plant.com
homedownloadenvelopeangle-double-leftangle-double-right