Create a custom function
- Last UpdatedApr 15, 2025
- 3 minute read
- Create a new Visual C# Class Library Project which targets the .NET Framework 4.8 with Visual Studio 2017/2019.
NOTE: The assembly created must include the file extension in its name for the AVEVA Mobile Operator Plug-In system to load it. The assembly created must also have the string "Extension" in the name (e.g. "CustomFunction.Extensions.dll"). - Add references to SAT.Core.dll and AA.Core.Mobile.dll, located in the AVEVA Mobile Operator Client installation directory (by default, "\Program Files\AVEVA\Mobile Operator\Client") in the new project.
- Open AssemblyInfo.cs, located in the "Properties" section of the solution file, and add the following lines:
[assembly: SAT.ComponentModel.Extensibility.AssemblyPlatform(SAT.ComponentModel.Extensibility.PlatformContext.Any)][assembly: SAT.ComponentModel.Services.CallingContext(SAT.ComponentModel.Services.CallingContextEnum.Default)]
- Add a new PluginInfo attribute as given below, and insert it before the new class definition:
[PluginInfo("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", "@MyCustomFunction")]
- Create a new class that inherits from Sat.Calculation.FunctionInfo.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using SAT.ComponentModel.Extensibility;
using SAT.Calculation.Abstract;
using SAT.Calculation.Specialized;
using SAT.Calculation;
using SAT.Calculation.Exceptions;
namespace CustomFunction.Extensions
{
/// <summary>
/// Function MyCustomFunction
/// </summary>
[PluginInfo("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", "@MyCustomFunction")]
public class MyCustomFunction : FunctionInfo
{
#regionConstructor(s)
/// <summary>
/// Creates an instance of MyCustomFunction.
/// </summary>
public MyCustomFunction()
: base(null)
{
NumberOfParameters = 1;
DisplayName = "My Custom Function";
CategoryName = "My Functions";
// Set parameter definition
SetParamDef(0, new ParamDef("Number to process", "Number which will be processed by the equation"));
// Set return type matrix
SetReturnTypeMatrix(new RetTypeMatrix(typeof(double), new Type[1] { typeof(double) }));
}
#endregion//Constructor(s)
/// <summary>
/// Calculates the value using the parameter value.
/// </summary>
/// <returns>The calculated value.</returns>
protected override object CalcValue()
{
Object objOp = Parameters[0].Value;
if (Utilities.IsNumeric(objOp))
{
Double d = (Double)objOp;
Double dResult = d;
return dResult;
}
else
{
throw new CalcEngineException(string.Format("Non Numeric Value", Token));
}
}
}
}
-
Override the following methods:
- public override string SetParamDef()
This function sets the parameter definition for the tooltip. - public override string SetReturnTypeMatrix()
This function sets the return and input type(s) for the function. - protected override object CalcValue()
This function returns the calculated value using the parameter values.
- public override string SetParamDef()
- Compile the DLL.
- To use the custom action in Procedure Builder, copy the compiled DLL (from the output directory specified by the build process) to the AVEVA Mobile Operator Client installation directory (by default: "\Program Files\AVEVA\Mobile Operator\Client").
Overloaded Custom Function Example
Following is an example of an overloaded custom function, which takes two number values and adds them, and two string values which it concatenates.
usingSystem;
usingSystem.Linq;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSAT.ComponentModel.Extensibility;
usingSAT.Calculation.Abstract;
usingSAT.Calculation.Specialized;
usingSAT.Calculation.Exceptions;
namespaceOverloadedFunction.Extensions
{
[PluginInfo("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", "@OVERLOADED")]
public class MyOverloadedFunction : FunctionInfo
{
#regionConstructor(s)
public MyOverloadedFunction()
: base(null)
{
NumberOfParameters = 2;
DisplayName = "Overloaded Function";
CategoryName = "My Functions";
// Set parameter definition
SetParamDef(0, new ParamDef("First Parameter", "First Parameter"));
SetParamDef(1, new ParamDef("Second Parameter", "Second Parameter"));
// Set return type matrix
SetReturnTypeMatrix(new RetTypeMatrix(typeof(double), new Type[2] { typeof(double), typeof(double) }));
SetReturnTypeMatrix(new RetTypeMatrix(typeof(string), new Type[2] { typeof(string), typeof(string) }));
}
#endregion//Constructor(s)
#regionOverride Methods
/// <summary>
/// Calculates value from the parameter values.
/// </summary>
/// <returns>Calculated value.</returns>
protected override object CalcValue()
{
Object objOp1 = Parameters[0].Value;
Object objOp2 = Parameters[1].Value;
if (objOp1.GetType() == typeof(Double) && objOp2.GetType() == typeof(Double))
{
return (((double)objOp1) + ((double)objOp2));
}
else if (objOp1.GetType() == typeof(string) && objOp2.GetType() == typeof(string))
{
return (string.Concat(objOp1 as string, objOp2 as string));
}
throw new CalcEngineException(string.Format("Invalid input type for {0}", Token));
}
#endregion//Override Methods
}
}