Examples
  • 27 Nov 2024
  • 7 Minutes to read
  • PDF

Examples

  • PDF

Article summary

Sending and receiving data

In this example, Custom Client is sending data over a TCP channel and receiving an echo of the data sent, which will then be saved to a different tag. There are two tags involved: the first tag labelled as /CustomClient/Write for writing the value data using R/W permissions, and the second tag labelled as /CustomClient/Read, to receive the echo of the data, with R permissions only.

 


 In Custom Client configuration, a TCP channel connects to an endpoint to produce an echo. In this example, it uses a locally hosted TCP echo server on port 8. The name of the channel is "Example1", and the associated Device is labelled "Device". This Device contains a single Transaction labelled "echo", which will be triggered whenever the user writes a value to the "/CustomClient/Write" tag, meaning that the transaction Type is “Write”, and the trigger variable is "example1_write", which is the same name used as the Variable for the write tag.


Finally, the steps for this transaction are as follows.

  • The first step will be used to extract the data from the /CustomClient/Write tag and to create the $.tx buffer with this value using a script.
/*Gets the data by calling $.variableGet("VARIABLE_NAME"), and appends an EOT ASCII character (code 0x04) to it to mark the end of the data.*/
$.tx = $.variableGet("example1_write")+"\x04"


  • The second step is a Send step with an empty Data field, as the buffer has already been configured in the previous step.
  • Next, a Receive step receives the same sent data (since the remote device is simply an echo server). The Receive step only uses the Frame delimiter to determine the end of the data. In this case, the delimiter is the EOT (x04) character that was added in the first step at the end of the data.
  • Finally, a Regular Expression extracts information from the data received. In this example, it is extracting a number with any number of digits, so the regular expression is "(\d+)".

The below example shows the final configuration settings for all steps :

 

Send a custom buffer

In this example, Custom Client sends a custom buffer based on the tag value, which is the transaction trigger. There is a tag with R/W permissions labelled "/CustomClient/Cmd", which is used to represent a command. Depending on the value of this tag, it will send a different buffer to the endpoint.


This example uses a Channel called "Example2", and a Device called "Device". In this case, it’s a serial port channel, using COM2 (Windows). The transaction is a Write Transaction labelled "write", and the trigger variable is "example2", which is associated to the tag created above


This example refers to sending data out without expecting any response back and therefore, has only two steps:

  • The first step is a Script step to populate the TX buffer depending on the tag value. It uses the following script:
//Gets the tag value
let value = $.variableGet("example2");
//Prints it in the log for debugging purposes
$.logger.debug("Value is %s", value);
//Based on the value, executes one command or another
switch(value){
	case 0:
	    $.tx = Buffer.from("getStatus\x00");
	    break;
	case 1:
	    $.tx = Buffer.from("getAnalogData\x00");
	    break;
	case 2:
	    $.tx = Buffer.from("getDigitalData\x00");
	    break;
	default:
	    $.nextStep = null; //ends the transaction if command is unknown
}

  • The second step is a Send step with a blank data field, meaning it would send the data previously written to $.tx.

Conditionally selecting the next step

In this example, Custom Client uses a read transaction to receive data from an endpoint and saves it to one tag or another depending on the type of data received. It uses three tags, labelled /CustomClient/Number, /CustomClient/String, and /CustomClient/Boolean, each with a different tag type.


This example uses a Channel over a serial port labelled "Example3", and a Device labelled "Device". The Transaction is labelled "read" and is a Read (Periodic) transaction. 


 See below for the steps used to obtain this data:

  • First, a Send step is used to simulate the action of waking a device from sleep mode on the endpoint .This example sends a NUL byte to simulate a wake-up request on the device.
  • Next, a Receive step receives the response on the device to simulate that it has been woken up correctly. In this example, it will wait for an ACK byte with a timeout of 5000 milliseconds in case it takes some time for the device to wake up.
  • After receiving confirmation that the device is ready, it sends the "getData" (as a NUL terminated string) command with a Send step
  • The remote device answers this command indicating which type of data is being sent, "bool", "number" or "string", with a NUL terminated string. Next is a Receive step using NUL (0x00) as the delimiter.
  • The fourth step is a Script step, used to parse the RX buffer ($.rx) and to select the next step based on the data type.
//Prints the RX buffer for debugging purposes
$.logger.debug("Received data type: %s", $.rx);
//Uses slice to remove the delimiter (0x00) from the end of the string
switch($.rx.slice(0,-1)){
 case "bool":
   $.nextStep = "bool00"
   break;
 case "number":
   $.nextStep = "number00";
   break;
 case "string":
   $.nextStep = "string00";
   break;
 default:
   $.logger.warn("Unknown data type: %s", $.rx);
}
//Prints the next step for debugging purposes (if there's no error)
if(!$.err) $.logger.debug("Next step is: %s", $.nextStep);


This last step has no next step as the script is overriding it.

 See below for a summary of the first 5 steps:


The below examples show the steps required to parse the data received based on data type. 

Boolean

  • This step is a Receive step used to receive the body of the data. Since this is boolean data, the value can either be set to "true" or "false", followed by a NUL character used as a delimiter. After receiving all data, it extracts the value and saves it to the tag. Because this step has to cast a string into a boolean, it needs to use a Script:
$.logger.debug("Data is %r", $.rx);
//Removes the delimiter from the string
let data = $.rx.slice(0,-1);
//Converts the data from string to boolean
let boolData = data === "true"
//Updated the variable "boolean" bounded to /CustomClient/Boolean 
$.variableSet("boolean", boolData);

 

The configuration of this step is shown below:


Number

  • This step is a Receive step used to receive the data as a string of digits, with a NUL character as a delimiter.
  • As the data received is a string of digits, it uses a Regular Expression step to extract the number and save it to the tag. The following regex is used: ^(\d+)\x00. The extracted number is then parsed to the "number" variable, which is bound to the "/CustomClient/Number" tag.

 The configuration of these steps is shown below:


 String

  • The first step is a Receive step to retrieve the data from the endpoint. In this case, it’s a NUL terminated string, so the NUL character is used (0x00) as a delimiter.
  • It then proceeds to extract the data. To do this, a Regular Expression is used with the following regex ^(.+)\x00. It then binds this data to the \CustomClient\String tag using the "string" variable.

The configuration of these steps is shown below:


Implementing IEC 62056-21 to read an electrical meter

This example shows how to read a Landis-Gyr electricity meter using IEC 62056-21 protocol in its ASCII variant (modes A to D). The same approach can be used to communicate to other electricity meter brands such as IskraEmeco, Actaris, Cewe, DPEE and more.
The below snippet shows an example of the payload sent by the meter:


/LGZ5\2ZMD4104407.B24<CR><LF>
<STX>F.F(00000000)<CR><LF>
0.0.0()<CR><LF>
0.0.1(96054628)<CR><LF>
0.9.1(14:50:22)<CR><LF>
0.9.2(18-11-16)<CR><LF>
0.9.6(00:00)<CR><LF>
0.9.7(18-11-01)<CR><LF>
0.1.0(34)<CR><LF>
1.8.0(000000.00*kWh)<CR><LF>
1.8.0*34(000000.00*kWh)<CR><LF>
1.8.1(0000.000*kWh)<CR><LF>
1.8.1*34(0000.000*kWh)<CR><LF>
1.8.2(0000.000*kWh)<CR><LF>
1.8.2*34(0000.000*kWh)<CR><LF>
1.8.3(0000.000*kWh)<CR><LF>
1.8.3*34(0000.000*kWh)<CR><LF>
1.8.4(0000.000*kWh)<CR><LF>
1.8.4*34(0000.000*kWh)<CR><LF>
2.8.0(000000.00*kWh)<CR><LF>
2.8.0*34(000000.00*kWh)<CR><LF>

…<more data here>…

32.7.0(234.8*V)<CR><LF>
52.7.0(235.2*V)<CR><LF>
72.7.0(234.6*V)<CR><LF>
C.7.1(00000080)<CR><LF>
C.7.2(00000000)<CR><LF>
C.7.3(00000076)<CR><LF>
C.7.0(00000159)<CR><LF>
32.32.0(0002)(09-05-21 19:31)<CR><LF>
52.32.0(0002)(00-01-22 02:30)<CR><LF>
72.32.0(0003)(11-01-28 11:06)<CR><LF>
32.36.0(0002)(00-01-01 01:00)<CR><LF>
52.36.0(0002)(00-01-01 01:00)<CR><LF>
72.36.0(0002)(00-01-01 01:00)<CR><LF>
!<CR><LF>


The connection can either be established through a serial port or through an Ethernet to serial converter acting as a TCP server. The communication includes the following phases:

  1. Sends request "/?!<\r><\n>" to meter. If there are several meters in the same serial bus, the ID of the meter must be included in this request ("/?<ID>!<\r><\n>").
  2. Receives the payload up until the ETX (End of Text) frame delimiter.
  3. Parses received data using one step for each signal captured by applying the corresponding Regular Expression for each signal (see table below). 

 The following table shows the Regular expressions used for each signal that is captured. Please note that this may vary depending on the payload sent by the meter.

Signal

Regular Expression

Serial number

(?:0\.0\.1\()(\d+\d)(?:.*\r?\n)

Time

(?:0\.9\.1\()(.*)(?:\))(?:.*\r?\n)

Date

(?:0\.9\.2\()(.*)(?:\))(?:.*\r?\n)

Active energy generated

(?:1\.8\.0\()(\d.+\d)(?:.*\r?\n)

Active energy consumed

(?:2\.8\.0\()(\d.+\d)(?:.*\r?\n)

Reactive energy Q1

(?:5\.8\.0\()(\d.+\d)(?:.*\r?\n)

Reactive energy Q2

(?:6\.8\.0\()(\d.+\d)(?:.*\r?\n)

Reactive energy Q3

(?:7\.8\.0\()(\d.+\d)(?:.*\r?\n)

Reactive energy Q4

(?:8\.8\.0\()(\d.+\d)(?:.*\r?\n)

Voltage phase 1 to neutral

(?:32\.7\.0\()(\d.+\d)(?:.V.*\r?\n)

Voltage phase 2 to neutral

(?:52\.7\.0\()(\d.+\d)(?:.V.*\r?\n)

Voltage phase 3 to neutral

(?:72\.7\.0\()(\d.+\d)(?:.V.*\r?\n)


The “Captured variables” field contains the name of all variables used in the tag configuration for each Regular expression step capturing the value of a signal.

The configuration of the steps is shown below:




Was this article helpful?

What's Next