2.1 Script Builder

The
Script Builder provides an advanced function to extract data from messages and apply customized algorithms to generate new metrics and events. Scripts can be written in C# language.
The Script Builder can be accessed in the following ways:
• Selecting Script Builder from the Tools menu on the Main Window.
• Clicking the
Script Builder 
button on the Main Window toolbar.
The Script Builder allows creation of the following script types:
• Condition Expression
• Custom Metric
• Global Parameter
• Advanced Metric & Event. This is the most flexible type, and also the most complicated. It allows you to generate multiple metrics, events, and report desired parameters or including troubleshooting information in the script.
2.1.1 Script Editor & Private Functions Editor
TEMS Discovery provides the Script Editor and the Private Functions Editor. The Script Editor is used to implement algorithms; the Private Functions Editor is used to create procedures that can be used only by the script.
Script/Private Functions Editor Toolbar
| Cut. |
| Copy. |
| Paste. |
| Undo. |
| Redo. |
| Search. |
| Next. Search next. |
| Replace. Search and replace. |
| Size. Left-click or right-click mouse to enlarge or reduce font size. |
| Collapse. Collapse definitions. |
| Expand. Expand all definitions. |
| Split V. Split the editor to 50-50 in the vertical direction, or remove the vertical splitter. |
| Split H. Split the editor to 50-50 in the horizontal direction, or remove the horizontal splitter. |
2.1.2 Data Object: Metric List
The Metric List tab lists all available information elements (IEs), including Layer 3 signaling IEs that can be used as sources of data. These IEs can be dragged-and-dropped into the spreadsheet on the right to define an Alias, which will be used as a variable in the script.
2.1.3 Data Object: RRC IEs
The RRC IEs tab lists all available "terminal" WCDMA RRC information elements (IEs). These IEs can be dragged-and-dropped into the spreadsheet on the right to define an Alias, which will be used as a variable in the script.
When a script is executed, TEMS Discovery will automatically search for the values from all RRC signaling messages containing the IEs defined.
2.1.4 Data Object: Threshold
The Threshold tab lists all of the available default and user-defined thresholds. These thresholds can be dragged-and-dropped into the spreadsheet on the right to define an Alias, which will be used as a variable in the script.
See
User Defined Parameters for more information.
2.1.5 Built-in Flags
2.1.5.1 CONDITION_FLAG
A pre-defined variable that is used to hold the result of a condition expression. This flag is valid only for the Condition Expression script type.
Example:
CONDITION_FLAG = EcIo>-10 && EcIo<-5;
Where:
EcIo is a user-defined alias in the spreadsheet
2.1.5.2 TARGET_VALUE:
A pre-defined variable that is used to hold the result of a global parameter. This flag is valid only for the Global Parameter script type.
Example:
TARGET_VALUE = EcIo+5;
Where:
EcIo is a user-defined alias in the spreadsheet
2.1.5.3 EVENT:
A qualifier that is used to describe an event type defined in the spreadsheet.
Example:
EVENT_TYPE = EVENT.Call_Drop;
Where:
Call_Drop is a user-defined event in the spreadsheet.
2.1.5.4 EVENT_TIMESTAMP:
A pre-defined Hash table that is used to store events and their corresponding timestamp (in milliseconds) of the current computing iteration.
Example:
EVENT_TIMESTAMP[EVENT.Call_Drop] = TIMESTAMP-3000; //backward 3 second
Where:
Call_Drop is a user-defined event in the spreadsheet.
TIMESTAMP is a pre-defined variable in milliseconds.
Remarks:
By doing this, the timestamp of an event can be manually adjusted.
2.1.5.5 EVENT_TYPE:
A collection that is used to store one or many events in the current computing iteration.
Example:
EVENT_TYPE = EVENT.Call_Drop;
Where:
Call_Drop is a user-defined event in the spreadsheet
Remarks:
Each time you call 'EVENT_TYPE = EVENT.<specific event>;' the specified event type will be added to the collection.
Related Functions:
ClearAllEvents(), ClearEvent(), ReplaceEvent()
2.1.5.6 MESSAGE:
A pre-defined variable that represents an additional message of the current computing iteration.
Example:
MESSAGE += string.Format(""Current EcIo value: {0}"", EcIo);
Where:
EcIo is a user-defined alias in the spreadsheet.
2.1.5.7 MESSAGE_INDEX:
A pre-defined variable that represents the index of the currently computing iteration.
Example:
MESSAGE_INDEX = MESSAGE_INDEX-10;
Remarks:
You can modify this variable so that the next computing iteration can go to a particular index.
2.1.5.8 EOF:
A pre-defined variable (Boolean) that indicates whether the current iteration is the end of file.
Example:
if(EOF)
{
//do something
}
2.1.5.9 TIMESTAMP:
A pre-defined variable that represents the time stamp (in millisecond) of current computing iteration.
Example:
TIMESTAMP= TIMESTAMP-3000; //backward 3 second
Remarks:
By doing this, the timestamp of the result can be manually adjusted.
2.1.5.10 LOG_FILE_NAME:
A pre-defined variable that represents the log file name of the currently computing iteration.
Example:
MESSAGE += ""Drive test data log file: ""+ LOG_FILE_NAME;
2.1.5.11 IS_NEMO_DATA:
A pre-defined variable that indicates whether the current drive test data was collected by Nemo.
Example:
if(IS_NEMO_DATA)
{
//do something
}
2.1.5.12 IS_TEMS_DATA:
A pre-defined variable that indicates whether the current drive test data was collected by TEMS.
Example:
if(IS_TEMS_DATA)
{
//do something
}
2.1.5.13 IS_JDSU_DATA:
A pre-defined variable that indicates whether the current drive test data was collected by JSDU.
Example:
if(IS_JDSU_DATA)
{
//do something
}
2.1.5.14 TIMESTAMP_START_OF_FILE:
A pre-defined variable that represents the start timestamp (in milliseconds) of the log file.
2.1.6 Built-in User-defined Functions
2.1.6.1 ClearAllEvents:
Clear all events in the specified message index.
Syntax:
void ClearAllEvents(object oMessageIndex)
oMessageIndex: message index
Example:
ClearAllEvents(MESSAGE_INDEX-2);
2.1.6.2 ClearEvent:
Remove a specific event in the specified message index.
Syntax:
void ClearEvent(object oMessageIndex, object oEventType)
oMessageIndex: message index
oEventType: event type to be removed
Example:
ClearEvent(MESSAGE_INDEX-2, EVENT.Drop_Call);
Where:
Call_Drop is a user-defined event in the spreadsheet.
2.1.6.3 ReplaceEvent:
Replace a specific event in the specified message index with another event.
Syntax:
void ReplaceEvent(object oMessageIndex, object oOrigEventType, object oNewEventType)
oMessageIndex: message index
oOrigEventType: event type to be replaced
oNewEventType: new event type
Example:
//replace EVENT.Drop_Call with EVENT.Call_Release
ReplaceEvent(MESSAGE_INDEX-2, EVENT.Drop_Call, EVENT.Call_Release);
Where:
Call_Drop and Call_Release are user-defined events in the spreadsheet.
2.1.6.4 AddEvent:
Add a specific event in the specified message index.
Syntax:
void AddEvent(object oMessageIndex, object oEventType)
oMessageIndex: message index
oEventType: event type to add
Example:
//Add EVENT.Drop_Call
AddEvent(MESSAGE_INDEX-2, EVENT.Drop_Call);
Where:
Call_Drop is a user-defined event in the spreadsheet.
2.1.6.5 AssignMetricValue:
Assign a value to a specific metric in the specified message index.
Syntax:
void AssignMetricValue(object oMessageIndex, string szMetricName, object oValue)
oMessageIndex: message index
szMetricName: target metric name
oValue: value to assign
Example:
AssignMetricValue(MESSAGE_INDEX-2, Metric_EcIo, -10);
Where:
Metric_EcIo is a user-defined metric in the spreadsheet.
2.1.6.6 ReplaceMetricValue:
Replace the value of a specific metric within a certain message range from one to another.
Syntax:
bool ReplaceMetricValue(object oStartIndex, object oEndIndex, string szMetricName, object oValueOrig, object oValueNew)
oStartIndex: start index of the message range
oEndIndex: start index of the message range
szMetricName: target metric name
oValueOrig: original metric value
oValueNew: new metric value
return true if metric valus has been successfully replaced, otherwise, return false.
Example:
AssignMetricValue(MESSAGE_INDEX-2, Metric_EcIo, -10);
Where:
Metric_EcIo is a user-defined metric in the spreadsheet.
2.1.6.7 GetLatLon:
Get the geo position at the specfied timestamp.
Syntax:
void GetLatLon(object oTimestampInMs, out double dLat, out double dLon)
oTimestampInMs: timestamp
dLat: latitude
dLon: longitude
Example:
double dLat, dLon;
GetLatLon(TIMESTAMP, out dLat, out dLon);
2.1.6.8 IsValueValidStatic:
Check whether a value is valid.
Syntax:
bool IsValueValidStatic(object oVal)
oVal: value to check
return true if the value is valid, otherwise, return false;
Example:
if( IsValueValidStatic(oValue))
{
//do somthing
}
2.1.6.9 IsValueValid:
Check whether a value is valid.
Syntax:
bool IsValueValid(object oVal)
oVal: value to check
return true if the value is valid, otherwise, return false;
Example:
if( IsValueValid(oValue))
{
//do somthing
}
2.1.6.10 GetDeviceAttribute:
Get the value of a specified device attribute.
Syntax:
string GetDeviceAttribute(string szAttribute)
szAttribute: name of device attribute
return value of the specified device attribute
Example:
string szIMEI = GetDeviceAttribute("IMEI");
2.1.6.11 SetDeviceAttribute:
Set the value of a specified device attribute.
Syntax:
void SetDeviceAttribute(string szAttribute, string szValue)
szAttribute: name of device attribute
szValue: value of the device attribute
Example:
SetDeviceAttribute("Operator", "TEMS");
2.1.6.12 GetWcdmaUarfcnIndex:
Get the index of a specified UARFCN.
Syntax:
int GetWcdmaUarfcnIndex(object oUARFCN)
oUARFCN: UARFCN
return index of the specified UARFCN
Example:
int iIndex = GetWcdmaUarfcnIndex(4085);
Remarks:
Each WCDMA UARFCN will be assigned a unique integer automatically by TEMS Discovery during data import.
2.1.6.13 ElementNotContain:
Return elements in an array list that do not exist in another array list.
Syntax:
string ElementNotContain(ArrayList sourceList, ArrayList targetList)
sourceList: array list
targetList: array list
return a comma delimited string that represents the elements of array list sourceList which do not exist in array list targetList.
Example:
string szMissing = ElementNotContain(sourceList, targetList);
2.1.6.14 ElementMissing:
Return elements in an array list that do not exist in another array list.
Syntax:
ArrayList ElementMissing(ArrayList sourceList, ArrayList targetList)
sourceList: array list
targetList: array list
return array list that represents the elements of array list sourceList which do not exist in array list targetList.
Example:
ArrayList alMissing = ElementMissing(sourceList, targetList);
2.1.6.15 FindPairValue:
Find index of a given value in a specified array list; then return the value of the element in the same index of another array list.
Syntax:
float FindPairValue(float key, ArrayList sourceList, ArrayList targetList)
float: the value of element in sourceList
sourceList: array list
targetList: array list
return the paired value of the element in another array list.
Example:
float fEcIo = FindPairValue(218, alPSCList, alEcIoList)
2.1.6.16 MaxOfArrayList:
Find the maximum value of the specified array list.
Syntax:
float MaxOfArrayList(ArrayList al)
al: array list
return the maximum value of the specified array list
2.1.6.17 CountOfArrayList:
Find the count of the specified array list.
Syntax:
int CountOfArrayList(ArrayList al)
al: array list
return the count of the specified array list
2.1.6.18 IsIdentical:
Check whether two array lists are exactly identical, including their sequences of elements.
Syntax:
bool IsIdentical(ArrayList al1, ArrayList al2)
al1: array list
al2: array list
return true if two array lists are identical, otherwise, return false
2.1.6.19 IsIdenticalIgnoreOrder:
Check whether two array lists are identical, ignoring the sequence of elements.
Syntax:
bool IsIdenticalIgnoreOrder(ArrayList al1, ArrayList al2)
al1: array list
al2: array list
return true if two array lists are identical, otherwise, return false
2.1.6.20 IsIdenticalFloatArray:
Check whether two float array lists are exactly indentical, including their sequence.
Syntax:
bool IsIdenticalFloatArray(ArrayList al1, ArrayList al2)
al1: float array list
al2: float array list
return true if two array lists are identical, otherwise, return false
2.1.6.21 GetDisplayString:
Get a string representation of the specified array list. Elements of the specified array list will be concatenated and delimited with commas.
Syntax:
string GetDisplayString(ArrayList alValue)
alValue: array list
2.1.6.22 ArrayListContains:
Check whether an array list contains the specified value.
Syntax:
bool ArrayListContains(ArrayList arrData, object targetVal)
arrData: array list
targetVal: value to check
Example:
if(ArrayListContains(alPSCList, 218))
{
//do something
}
2.1.6.23 ArrayListIndexOf:
Get the index of the specified value in an array list.
Syntax:
int ArrayListIndexOf(ArrayList arrData, object targetVal)
arrData: array list
targetVal: target value
Example:
int index = ArrayListIndexOf(alPSCList, 218);
2.1.6.24 SameMemberInt:
Check whether two integer array lists are indentical, ignoring their sequences.
Syntax:
bool SameMemberInt(ArrayList al1, ArrayList al2)
al1: integer array list
al2: integer array list
return true if two array lists are identical, otherwise, return false
2.1.6.25 ConvertToInt:
Convert a float array list to an integer array list.
Syntax:
ArrayList ConvertToInt(ArrayList alFloat)
alFloat: float array list
return integer array list.
2.1.6.26 ConvertToDateString:
Convert a timestamp (in milliseconds) to date string such as MM/dd/YYYY.
Syntax:
string ConvertToDateString(object oTimestampIsMs)
oTimestampIsMs: time stamp in millisecond
return date string.
Example:
string szDate = ConvertToDateString(TIMESTAMP);
2.1.6.27 ConvertToTimeString:
Convert a timestamp (in milliseconds) to a time string such as HH:mm:ss.fff.
Syntax:
string ConvertToTimeString(object oTimestampIsMs)
oTimestampIsMs: time stamp is millisecond
return time string.
Example:
string szTime = ConvertToTimeString(TIMESTAMP);
2.1.6.28 ConvertToDateTimeString:
Convert a timestamp (in milliseconds) to a date time string such as
MM/dd/YYYY HH:mm:ss.fff.
Syntax:
string ConvertToDateTimeString(object oTimestampIsMs)
oTimestampIsMs: time stamp is millisecond
return date time string.
Example:
string szDateTime = ConvertToDateTimeString(TIMESTAMP);
2.1.6.29 ExtractNumericValue:
Extract a numeric value from a string that contains numbers.
Syntax:
float ExtractNumericValue(string szString)
szString: a string that contains numbers
return float value.
Example:
float fVal = ExtractNumericValue(""Call Duration: 300.5 ms"");
fVal will be 300.5.
2.1.6.30 GetSectorParameter:
Get a sector parameter value.
Syntax:
string GetSectorParameter(string szSiteId, string szSectorId, string szTech, string szParmName)
szSiteId: site ID
szSectorId: sector ID
szTech: technology flag (available flags: CDMA, EVDO, GSM, WCDMA, TD, LTE)
szParmName: sector parameter name
return the value of the specified sector parameter.
Syntax of overloading function:
string GetSectorParameter(string szSector_SiteId, string szTech, string szParmName)
szSector_SiteId: contains sector and site id in the format of "<sectorID> [[<SiteID>]"
szTech: technology flag (available flags: CDMA, EVDO, GSM, WCDMA, TD, LTE)
szParmName: sector parameter name
return the value of the specified sector parameter.
Example:
string szAngle = GetSectorParameter(SiteID,SectorID,"", "Azimuth");
string szLtePCI= GetSectorParameter(SiteID, SectorID, "LTE", "PCI");
string szLtePCI= GetSectorParameter(Sector_SiteID, "LTE", "PCI");
Where:
SiteID is alias of [!Mid].[Common].[Cell ID - LTE].[Site ID].[Sort By: Signal Strength].[Top #1] defined in Alias spreadsheet
SectorID is alias of [!Mid].[Common].[Cell ID - LTE].[Sector ID].[Sort By: Signal Strength].[Top #1] defined in Alias spreadsheet
Sector_SiteID is alias of [!Mid].[Common].[Cell ID - LTE].[Serving Sector] defined in Alias spreadsheet
2.1.6.31 GetSectorParameters:
Get sector parameter value by passing the sector keys and the geo location of sector detected.
Syntax:
string[] GetSectorParameters(string szKey1, string szKey2, string szTech, double dLatitude, double dLongitude, string[] arrParmName)
szKey1: first key of the sector. It is PN for CDMA and EVDO, BSIC_Octal for GSM, PSC for WCDMA, CPI for TD, and PCI for LTE.
szKey2: second key of the sector. It is BCCH for GSM,UARFCN for WCDMA and TD, and EARFCN for LTE. Pass ""null"" (DON'T include quotation marks) if this key is unknown.
szTech: technology flag (available flags: CDMA, EVDO, GSM, WCDMA, TD, LTE)
dLatitude: latitude of the sector detected.
dLongitude: longitude of the sector detected.
arrParmName: list of sector parameter names
szCellConfig: cell configuration selection argument, with one of the following options permitted:
"D", default cell configuration, or
"NM", dataset name matching cell configuration, or
"<numerical value>", cell configuration with matching mapping index (e.g. "1", "2"), or
"<text string>", cell configuration with matching name
return the list of value corresponding to the specified list of sector parameters.
Example:
if(IsValueValid(Psc)
{
string szUarfcn=null;
if(IsValueValid(Uarfcn))
szUarfcn=Uarfcn.ToString();
string[] arrResults = GetSectorParameters(Psc.ToString(), szUarfcn, "WCDMA", dLat, dLon,
new string[]{"Latitude", "Longitude", "Azimuth", "Antenna_Type", “D”});
double dSectorLat, dSectorLon;
int iSectorAzimuth;
bool bSectorLocationOK = false;
if(double.TryParse(arrResults[0], out dSectorLat) && double.TryParse(arrResults[1], out dSectorLon))
bSectorLocationOK = true;
int.TryParse(arrResults[2], out iSectorAzimuth);
string szAntennaType = arrResults[3];
}
Where:
Psc is alias of [!M].[WCDMA].[WCDMA Cell Measurements].[Categorized PSC:A1]
Uarfen is alias of [!M].[WCDMA].[WCDMA Cell Measurements].[Categorized UARFCN_DL:A1]
dLat is the alias of [!M].[Common].[GPS Position].[Latitude]
dLon is the alias of [!M].[Common].[GPS Position].[Longitude]
2.1.6.32 GetOperatorByMncMcc:
Get operator name from the lookup table (accessible from menu Configuration->Wireless Operator Lookup Table) by MNC and MCC
Syntax:
string GetOperatorByMncMcc(object MNC, object MCC)
MNC: MNC value
MCC: MCC value
return operator name.
Example:
string szOperator = GetOperatorByMncMcc(123, 321);
2.1.6.33 GetOperatorBySid:
Get operator name from the lookup table (accessible from menu Configuration->Wireless Operator Lookup Table) by SID
Syntax:
string GetOperatorBySid(object SID)
SID: SID value
return operator name.
Example:
string szOperator = GetOperatorBySid(123);
2.1.6.34 GetOperatorByOperatorId:
Get operator name from the lookup table (accessible from menu Configuration->Wireless Operator Lookup Table) by SID
Syntax:
string GetOperatorBySid(object SID)
SID: SID value
return operator name.
Example:
string szOperator = GetOperatorBySid(123);
2.1.6.35 TimeDiff:
Return the time difference of two messages in second
Syntax:
double TimeDiff(double msg1, double msg2)
msg1: the alias of first message
msg2: the alias of second message
return time difference in second.
Syntax of overloading function :
double TimeDiff(double msg1, double msg2, int Option)
msg1: the alias of first message
msg2: the alias of second message
Option: if set to 0, the output timestamp will be the current timestamp which is timestamp of the second message; If set to 1, change the output timestamp to timestamp of the first message (May mess up output timestamps, be careful of using this option)
return time difference in second.
.
Example:
double dDiff = TimeDiff(msg1, msg2);
double dDiff = TimeDiff(msg1, msg2, 1);
2.1.7 Built-in Math Function
2.1.8 Built-in String Function
• string.Format
2.1.9 Built-in Classes
• ArrayList
• Hashtable
• SortedList
• Queue
• Stack
2.1.10 Declaration
• Alias. An alias that can be referred as a metric when writing a script.
• Static Variables. Variables whose values will be kept valid while computing the next data point. It is not possible to assign null to a static variable. In order to remove the value of a static variable, it must be set to empty (for strings) or to the default minimum value (for other types).
− MyString = “”;
− MyFloat = float.MinValue;
− MyTimestamp = double.MinValue;
• Event Enum. Event enumeration.
• Metrics. Metric to be generated.
• Report Variables. The varaibles to report around the timestamp when an event occurs.
• Technologies Related. Define the technologies that the script can ba applied. This information will be used to determine if the script will be visible under a particular file/device in
Data Explorer
All variable types may be tested for valid values using IsValidValue(MyVariable). It will return false for both null and empty values.
Strings may be tested with String.IsNullOrEmpty(MyString). It will return true for both null and empty values.
2.1.11 Programming in C# Language
The Script Builder uses a subset of C# programming language. For more detailed information about C#, refer to the online resource:
http://msdn2.microsoft.com/en-us/library/default.aspx.
This section describes basic programming concepts that apply to script building and provides an
example.
2.1.11.1 Statements
The sequence of a script’s execution is controlled by statements, which are executed for their effect and do not have values. All C# statements end in a semicolon (;).
#region
#region lets you specify a block of code that you can expand or collapse when using the outlining feature of the Script Editor. A #region block must be terminated with a #endregion directive.
#region a loop statements
for(int i=0; i<50; i++)
{
statement 1;
statement 2;
}
#endregion
2.1.11.2 Declaring and Initializing Variables
The following build-in numeric data types are supported:
Build-in Numeric Data Type: | Ranges |
bool | true, false |
byte | 0~255 |
short | -32768~32768 |
int | 2147483648 ~ 2147483647 |
long | -9223372036854775808 ~ 9223372036854775807 |
double | 5.0E-324 ~ 1.7E308, 15-digit precision |
In the script, you can declare a variable by using its type and a given name:
int i; // create an integer
To initialize the variable, you can give it a value or use the new operator:
int j=5; // create an integer and set its value to 5
2.1.11.3 Casting Variables
To cast a data type to a different but compatible type, you may simply place (<new data type>) in front of the variable of interest. For example:
Delta_PSCH_RS = (float) RP_PSCH[(int)CellIndex] -(float) RSRP[(int)CellIndex]
2.1.11.4 Writing Comments
C# uses two forms of comments: a single-line comment starting with //, and a multi-line comment starting with /* and ending with */.
The single-line comment does not have a terminator. It ends at the end of the current line.
int i; //simple counter
i++;
Multi-line comments start with /* and end with */.
/*this code block is commented out
int i=3;
i++;
end of comments */
2.1.11.5 Using Blocks { }
C# does not contain special keywords for the end of many control statements (for, if, switch, foreach, do, while, and others). Instead, C# uses the opening brace { to denote the beginning of the block and the closing brace } to denote the end of the block.
for(int i=0; i<50; i++)
{
statement 1;
statement 2;
}
2.1.11.6 Declaring Functions
A function declaration contains any optional modifiers, the return type, the name of the function, any parameters, and the body of the function. For example:
int foo()
{
return 5;
}
To define a function that does not return a value, specify a return type of void.
void bar()
{
//do work ...
}
2.1.11.7 Using the return statement
The return statement exits a function. It is necessary for any function that returns a value.
int foo()
{
return 5; //necessary to get the value out of the function
}
2.1.11.8 Branching Statements
Branching statements are the programming equivalent of “do this, or do that, or do something else.” They provide the means to select which “branch” of code to take. C# contains two different syntax elements that control branching: if/else and the switch/case/break statement.
Using the if/else Statement
The if/else statement lets us pick one of two paths based on a Boolean expression. Examine the following code:
if ( val > 5 )
{
//do work ...
}
else
{
//do work ...
}
If this expression is true, then the next statement is executed. If the expression is false, then the next statement is skipped, and the statement after the optional else is executed.
Also, notice in this example that the else clause is optional. We can omit the else clause if no actions will be taken if the expression is false.
if ( val > 5 )
{
//do work ...
}
//continue other works
However, the else clause can contain another if statement.
if ( val > 5 )
{
//do work ...
}
else if ( val > 3 )
{
//do work ...
}
else
{
//do work ...
}
Using the switch/case/break Statement
The switch/case statement provides a multi-way branching statement. The switch statement defines the variable to use as the branching element. Each case statement defines the beginning of a block. That block is executed only when the value control variable has a value equal to the value in the case statement.
switch( day )
{
case "Monday"
//do work;
break;
case "Wednesday"
//do work;
break;
default:
//do work;
break;
}
2.1.11.9 Iterations
Iteration statements provide the means to execute a block of code multiple times.
Using while and do/while Statement
C# contains statements that let you execute a series of statements multiple times. The while loop and the do/while loop are closely related:
int i=0;
while( i < 10 )
{
//do work...
i++;
}
The above example works for every value of i from 0 to 9. The do/while loop can work in almost the same way:
int i=0;
do{
//do work ...
i++;
} while ( i < 10 );
The only difference between the while loop and the do/while loop is that a do/while loop is always executed at least once. The while loop evaluates the Boolean expression before entering the block of code. The do/while loop evaluates the Boolean expression only after executing the block of code the first time.
Using for Loops
The code in the preceding section can be just as easily written using a for loop. A for statement contains three clauses: the first clause sets the initial value of the looping variable; the second clause defines the loop termination expression; and the third clause defines the expression that modifies the looping variable. The first and third clauses may contain multiple statements separated by commas. The second clause must evaluate to a single Boolean expression:
for( int i=0, j=0; ( i<10 ) & ( j<10 ); i++, j++)
{
// do work ...
}
Using foreach Loops
The foreach statement provides a shortcut to loop through a collection, as shown in the following example:
foreach( int i in collectionOfi)
{
//do work...
}
Using break/continue in Loops
We use the break and continue statement to modify the execution paths of loops. The break statement terminates the block being executed inside the loop and exits the loop. The continue statement terminates the block being executed inside the loop and starts the next iteration.
for( int i=50; i<100; i++)
{
if( i > 80 )
continue; //terminate the block and start a new iteration if the expression is true
if( i == 95)
break; //exit if the expression is true
//do work
}
2.1.11.10 Expression
An expression defines some kind of computation. Expressions include variables or literal values, and some set of operators. They may be variable assignments, mathematical computations, or Boolean computations.
Arithmetic Operators
The standard mathematical operators in C# are:
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus
++ Increment
-- Decrement
Boolean Operators
C# supports the usual logical operators:
&& Logical AND
|| Logical OR
! Logical NOT
C# also supports bitwise Boolean operators:
& Bitwise AND
| Bitwise OR
^ Bitwise exclusive OR (XOR)
~ Bitwise NOT operator
Equality and Comparison Operators
C# contains operators that let you compare values:
< Smaller than
<= Smaller than or equal to
== Equal to
!= Not equal to
>= Greater than or equal to
> Greater than
All of these work in the same way. They compare two values of the same type and return a Boolean value:
if( a == b )
//do work ...
2.1.12 Example
5. Create Alias for Metric
Expand the tree in the Metric List. Drag-and-drop the target metric into the Source Data column. An Alias should be defined for this metric so that when writing script, the alias will represent the corresponding metric.
6. Create Static Variables
To retain the values of a variable from one message to another, one must define the variable as a static variable. The static variable allows you to keep track of the timestamp of a message or a status. By defining multiple static variables, you are effectively running multiple state machines.
7. Create Event Enum
The Event Enum tab allows you to assign an event enum to be used in the script and defines the following important information:
• Event category
• Event description: Event name to be displayed in the user interface.
• Priority
• Associated analysis set
• Color scheme
• Event icon selection
• Attributes (1-10) to be used in the tooltip when viewing an event in the Map View
8. Create Output Metric
The Metrics tab allows you to assign the names and properties of the metrics to be created in the script.
9. Define Report Variable
The Report Variables tab allows you to define the parameters or variables to be reported, along with any generated events. The search window determines the period of time before and after an event durign which report variables are looked up. Report variables are available in Data Explorer under script definition and can be sent to any of TEMS Discovery views.
10. Write Script
if( TxPw > -5 )
TxPw_TooHigh = TxPw;
11. Save Script
Click the
Save button

to save the script. If the coding has an error, an output window will appear and list all errors. The errors must be corrected before the script can be saved.
12. Run Script
From the
Data Explorer, drag-and-drop the script into any view to generate the output metric.