# IEC102 JavaScript API

## Connector functions IEC102 JS API guide

This API allows users to execute operations in the IEC102 client from a connector function.

## iec102 Object

The `iec` object is the main object of the IEC102 client. It allows to connect
to communicate with devices using IEC102 protocol.

### Establish connection

#### iec102.connect(registerType)

There is a `connect` method used to establish the connection with the device. When this method is called, it internally completes several actions:

- Depending on the `registerType` parameter (IP, VPN, GSM, ATR), not only will the connection be made, but it may also be necessary to send some commands to establish the connection correctly. If not defined, the IP registration type will be used.
- Once connection and registration is completed, connection status datapoints will be collected:
  - If `ATR` or `GSM` connection types are used, `device.communicationModules[].subscription.mobile.presence.gsm` with `OK` or `NOK` status.
- In case of error, `response` status will be set to `ERROR_PROCESSING` and obtained error description will be added.

After `connect` method call, returned status must be checked to know if it is possible to continue. If not, `response` object should be returned.

Connection example:

```javascript
iec102.ip="127.0.0.1";
iec102.port="3000";
iec102.linkAddress="1";
iec102.useMeasurePoint="1";
iec102.usePasswordAccess="1";

iec102.source="DEVICE_GSM_DATACALL";
iec102.sourcesInfo="Accessing Register through GSM data call to Device";

iec102.msisdn = "123412341324";
iec102.userName = "userName";
iec102.password = "password";
iec102.portConfig = "portConfig";

var connectionStatus = iec102.connect("GSM");
if(!connectionStatus.connected) {
    /* Connection not established. 
    At this point response object is fulfilled 
    with error code and description and skipped steps. 
    */
    return response;
}
```

In previous example, in case of error, there will be an implicit data collection with some data similar to this:

```json
{
    "datastreams": [
        {
            "id": "device.communicationModules[].subscription.mobile.presence.gsm",
            "datapoints": [
                {
                    "value": "NOK",
                    "at": 1698793200000,
                    "source": "DEVICE_GSM_DATACALL",
                    "sourceInfo": "Accessing Register through GSM data call to Device"
                }
            ]
        }
    ]
}
```

And the `response` will be something similar to this:

```json
{
    "version": "8.0",
    "trustedBoot": null,
    "operation": {
        "response": {
            "id": "request_id",
            "name": "GET_METER_INFO",
            "deviceId": "device_id",
            "resultCode": "ERROR_PROCESSING",
            "resultDescription": "Called meter responded an ERROR",
            "steps": [
                {
                    "name": "timeRequest",
                    "result": "SKIPPED",
                    "description": "Unable to make a data call"
                }
            ],
            "timestamp": 1698793200000
        }
    }
}
```

### ASDUs definition and execution.

Once the connection is established, it is possible to execute the desired ASDUs. There are three ways to execute ASDUs:
1. Execute directly one ASDU.
2. Define one by one all iec102.asdus and then execute.
3. Define iec102.asdus to be executed from operation params and then execute.

### ASDUs execution behavior specification

Each ASDU to be executed must be defined with some extra params to specify correctly its behavior. For this configuration a JSON object will be used:

| Field               | Type   | Description                                                                                                                                                                                  |
|---------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| period              | json   | Depending on the ASDU, it is necessary to specify a PERIOD                                                                                                                                   |
| sleepTimeBeforeExec | number | Wait time in milliseconds before ASDU is executed. If not defined or 0 value, no wait will be done.                                                                                           |
| step                | json   | Specify if related step must added and sent to `response` object. If not defined, no step will be added to `response` object                                                                 |
| collection          | json   | Specify if related collection must added and sent to `collection` object. If not defined, no datastream will be added to `collection` object. If defined, default datastreams will be added. |

`period` format:

| Field   | Type    | Description                                                                                                                                               |
|---------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| initial | number  | Initial instant of the period in milliseconds                                                                                                            |
| final   | boolean | Final instant of the period in milliseconds                                                                                                               |
| type    | string  | Period type. This type can be one of: `previousQuarter`, `previousDay`, `previousWeek`, `previousMonth`, `custom`, `lastMinutes`, `lastHours`, `lastDays` |

There are several utils methods to calculate this period. See [date utils](/api/device_integration/connector_functions/core_javascript_api/utils/)

`step` format:
| Field | Type    | Description                                              |
|-------|---------|----------------------------------------------------------|
| name  | string  | Step's name, if not defined default step will be added.  |
| sent  | boolean | If added step must be sent directly after ASDU execution |

`collection` format:
| Field | Type    | Description                                                     |
|-------|---------|-----------------------------------------------------------------|
| sent  | boolean | If added datastreams must be sent directly after ASDU execution |


An example of ASDU execution configuration:
```json
{
    "period": {
        "initial": 1698840000000,
        "final": 1698840899000,
        "type": "previousQuarter"
    }, 
    "sleepTimeBeforeExec": 1000,
    "step": {
        "name": "custom_name",
        "send": true
    },
    "step": {
        "send": true
    }
}
```


### ASDUs direct execution

#### iec102.asdus.timeRequest()

It is possible to execute one asdu directly. For example:

```javascript
var asduResult = iec102.asdus.timeRequest();
```

Execution result will be an object with following parameters:

Returned value will have following format:
| Parameter    | Type    | Description                                                            |
|--------------|---------|------------------------------------------------------------------------|
| status       | boolean | `true` if ASDU finished correctly.                                     |
| description  | string  | Descriptive message with execution result                              |
| readingState | string  | Parameter used to communicate all iec102.asdus execution status               |
| data         | object  | Json with ASDU execution result data. Each ASDU will have specific data |

In the previous example, the result could be:

```json
{
    "status": false,
    "description": "Success",
    "readingState": "READ",
    "data":{
        "Datetime": {
            "date": "2023-11-01",
            "time": "12:00:00",
            "timezone": "GMT+1",
            "dst": 0
        }
    }
}
```

In this case, `response` steps and `collected` data must defined and sent manually. For example:

```javascript
var asduResult = iec102.asdus.timeRequest();
if(asduResult.result){
    response.addStep("TIME_REQUEST", "SUCCESSFUL", asduResult.description);
    response.send();
    collection.addDatapoint("device.clock", asduResult.data.Datetime);
    collection.send();
}
```

An alternative to previous code:
```javascript
var execConfig = {
    "step": {
        "sent": true
    },
    "collection": {
        "sent": true
    }
}
var asduResult = iec102.asdus.timeRequest(execConfig);
```

### ASDUs definition from operations parameters

If launched operation has specific parameters and steps, it will be possible to calculate ASDUs from these parameters using `iec102.asdus.addFromParams()`. 

Expected parameters are: 

- Booleans with following names to know which iec102.asdus to execute.
  - `doTimeRequest`
  - `doParameters`
  - `doDeviceAndManufacturer`
  - `doLoadCurveAbsolut`
  - `doLoadCurveIncremental`
  - `doStoredPricing`
  - `doConfiguration`
  - `doCurrentPricing`
- `dataPeriod.period[0].tipo` that is a string with one of following values:
  - `previousQuarter`
  - `previousDay`
  - `previousWeek`
  - `previousMonth`
  - `custom`
- If `dataPeriod` is `custom`, following parameters must be defined with dates ISO string:
  - `dataPeriod.period[0].parameters[0].startDate`
  - `dataPeriod.period[0].parameters[0].finishDate`

If operation params do not match previous content, no ASDUs will be calculated.

Taking previous operation parameters specification and taking entities datastreams status into account, ASDUS to be executed will be calculated based on some predefined conditions to avoid losing data and avoid unnecessary retries.

By default, `login` and `logout` ASDUs will be added to the list. 

An example of thi method usage:
```javascript
/*
    Operation params:
    {
      "doTimeRequest": true,
      "doParameters": true,
      "doDeviceAndManufacturer": false,
      "doLoadCurveAbsolut": false,
      "doLoadCurveIncremental": false,
      "doStoredPricing": false,
      "doConfiguration": false,
      "doCurrentPricing": false,
      "dataPeriod": {
        "period": [
            "tipo": previousQuarter
        ]
      }
    }
*/

iec102.asdus.addFromParams();
var executionResult = iec102.asdus.execute();

/*
    iec102.asdus to be executed:
    [
        {
            "name": "login"
        },{
            "name": "timeRequest",
            "execConfig": {
                "period":{
                    "initial": 1698840000000,
                    "final": 1698840899000,
                    "type": "previousQuarter"
                },
                "sleepTimeBeforeExec": 5000
                "step": {
                    "send": true
                },
                "collection": {
                    "sent": true
                }
            }
        },{
            "name": "parameters",
            "execConfig": {
                "period":{
                    "initial": 1698840000000,
                    "final": 1698840899000,
                    "type": "previousQuarter"
                },
                "sleepTimeBeforeExec": 5000
                "step": {
                    "send": true
                },
                "collection": {
                    "sent": true
                }
            }
        },{
            "name": "logout",
            "execConfig": {
                "sleepTimeBeforeExec": 5000
            }
        }
    ]
*/
```

In this case, when executing all ASDUS, depending on executed ASDU, default steps could be sent directly and default collection could be done. 

As explained, this method implements default behavior for ASDUs executions. If this behaviour is no valid, ASDUs to be executed must be defined manually. See [ASDUs manual definition](#asdus-manual-definition).

### ASDUs manual definition:

#### iec102.asdus.add(name, execConfig)

It is possible to add manually using `iec102.asdus.add` method. This method expect following parameters to define ASDU execution correctly:
- `name`: ASDU to be executed name. One of:
  - `login`
  - `logout`
  - `dayLightSavingTime`
  - `timeRequest`
  - `parameters`
  - `deviceManufacturer`
  - `loadCurve`
  - `loadCurveQuarter`
  - `loadCurveIncremental`
  - `loadCurveIncrementalQuarter`
  - `storedPricing`
  - `currentPricing`
  - `configuration`
- `execConfig`: Json defined [ASDU execution configuration](#asdus-execution-behavior-specification)

For example to define 'timeRequest' ASDU this call must be done:

```javascript
var execConfig = {
    "period":{
        "initial": 1698840000000,
        "final": 1698840899000,
        "type": "previousQuarter"
    },
    "sleepTimeBeforeExec": 5000
    "step": {
        "send": true
    },
    "collection": {
        "sent": true
    }
}
iec102.asdus.add("timeRequest", execConfig);
```

Previous code will add to `asdus.asdusToExec` array following object:

```json
{
    "name": "timeRequest",
    "execConfig": {
            "period":{
                "initial": 1698840000000,
                "final": 1698840899000,
                "type": "previousQuarter"
            },
            "sleepTimeBeforeExec": 5000,
            "step": {
                "send": true
            },
            "collection": {
                "sent": true
            }
        }
}
```
In this case, after executing this ASDU default step will be sent with execution result and default datastream will be collected:
```json
// Step to be sent
{
    "version": "8.0",
    "trustedBoot": null,
    "operation": {
        "response": {
            "steps": [
                {
                    "name": "TIME_REQUEST",
                    "result": "SUCCESS",
                    "description": "Success."
                }
            ],
        }
    }
}
// Collection to be sent
{
    "datastreams": [
        "id": "device.clock",
        "datapoints":[
            {
                "value": {
                    "date": "2023-11-01",
                    "time": "12:00:00",
                    "timezone": "GMT+1",
                    "dst": 0
                },
                "at": 1698793200000
            }
        ]
    ]
}
```


### Defined ASDUs execution

If ASDUs are not executed one by one, but they are added from operation params or defining them one by one, `iec102.asdus.execute()` method must be used to execute all defined ASDUs.

`iec102.asdus.execute()` method will execute all added ASDUs one by one, and depending ASDU specification related steps and collection will be send.


For example, first we define manually following ASDUs and then we do execution:
```javascript

var period = utils.date.period.previousQuarter(iec102.referenceTime); 

iec102.asdus.add("login");

iec102.asdus.add("loadCurveIncremental", {
    "period": period,
    "sleepTimeBeforeExec": 1000,
    "step": {
        "sent": true,
    },
    "collection":{
        "sent": false
    }
});

iec102.asdus.add("loadCurve", 
    "period": period,
    "sleepTimeBeforeExec": 1000,
    "step": {
        "name": "CUSTOM_LOAD_CURVE_STEP",
        "sent": false,
    }
});

iec102.asdus.add("logout",{
    "sleepTimeBeforeExec": 1000
});

var executionResult = iec102.asdus.execute();

/* ASDUs to be executed
[
    {
        "name": "login"
    },{
        "name": "timeRequest",
        "execConfig": {
                "sleepTimeBeforeExec": 1000
                "step": {
                    "send": true
                },
                "collection": {
                    "sent": true
                }
            }
    },{
        "name": "loadCurve",
        "execConfig": {
                "period":{
                    "initial": 1698840000000,
                    "final": 1698840899000
                },
                "sleepTimeBeforeExec": 1000
                "step": {
                    "name": "CUSTOM_LOAD_CURVE_STEP",
                    "send": false
                }
            }
    },{
        "name": "logout",
        "execConfig": {
            "sleepTimeBeforeExec": 5000 
        }
    }
]
*/
```

In this example, we will suppose that `timeRequest` ASDU finish correctly:

1. First, `login` ASDU will be executed. After execution, no step or collection will be sent.

2. Before executing `timeRequest`, `1000` milliseconds wait will be done.

3. After `timeRequest` execution, default `TIME_REQUEST` step will be added because no name has been specified and it will be sent because `step.send` has been defined to `true`. This is the step to be sent directly: 
```json
    {
        "operation": {
            "response" :{
                //...
                "steps": [
                    {
                        "name": "TIME_REQUEST",
                        "result": "SUCCESSFUL",
                        "description": "Step completed successfully"
                    }
                ]
                //...
            }
        }
    }
```

4. After `timeRequest` execution, following datastream will be added to `collection` object because `collection` is defined and it will be sent directly because `collection.send` is true. Datastream to be collected:
```json
{
    "datastreams": [
        {
            "id": "device.clock",
            "datapoints":[
                {
                    "value": {
                        "date": "2023-11-01",
                        "time": "12:00:00",
                        "timezone": "GMT+1",
                        "dst": 0
                    },
                    "at": 1698793200000
                }
            ]
        }
    ]
}
```

5. Before executing `loadCurve`, `1000` milliseconds wait will be done.

6. After `loadCurve` execution, instead of adding default `STEP_NAME_LOAD_CURVE_ABSOLUT` step, a step with name `CUSTOM_LOAD_CURVE_STEP` will be added because `name` parameter has been specified. In this case, the step will be added to response, but not sent `send` has been defined to `false`. This is the step added to `response` object: 
```json
    {
        "operation": {
            "response" :{
                //...
                "steps": [
                    {
                        "name": "CUSTOM_LOAD_CURVE_STEP",
                        "result": "SUCCESSFUL",
                        "description": "Step completed successfully"
                    }
                ]
                //...
            }
        }
    }
```

7. After `loadCurve` execution no datastream will be added to `collection` object because no `collection` field has been defined in `execConfig`.

8. Finally, after `1000` milliseconds wait `logout` ASDU will be executed.

9. Final `executionResult` will contain all ASDUs execution result. 

Returned value will have following format:
| Parameter | Type    | Description                                  |
|-----------|---------|----------------------------------------------|
| status    | boolean | `true` if all ASDUs finished correctly.      |
| iec102.asdus     | object  | Json with each ASDU execution result object. |

Execution result could be something similar to this
```json
{
    "status": false,
    "asdus": {
        "login": {
            "status": true,
            "description": "Success"
            "readingState": null,
        },
        "timeRequest": {
            "status": true,
            "description": "Success",
            "readingState": "READ",
            "data":{
                "Datetime": {
                    "date": "2023-11-01",
                    "time": "12:00:00",
                    "timezone": "GMT+1",
                    "dst": 0
                }
            }
        },
        "loadCurve": {
            "status": true,
            "description": "Success",
            "readingState": "READ",
            "data":{
                "frames": [
                    {
                        "ImportedActive": 10,
                        "Quadrant4Reactive": 10,
                        "Quadrant2Reactive": 333,
                        "Quadrant3Reactive": 334,
                        "ExportedActive": 1000,
                        "Quadrant1Reactive": 333,
                        "Timestamp": 1705536000000
                    }
                ]
            }
        },
        "logout": {
            "status": false,
            "description": "Error in logout"
            "readingState": null,
        }
    }
}
```
Although, `login`, `timeRequest`, and `loadCurve` finished correctly, because `logout` ASDU failed, status is failed.
`timeRequest`, `loadCurve` ASDUs finished correctly and returns obtained `data`. Returned data depends on each ASDU.


### Default steps for ASDUs

These are defined default steps for each ASDU:
| ASDU                          | STEP                      |
|-------------------------------|---------------------------|
| `login`                       |                           |
| `logout`                      |                           |
| `timeRequest`                 | `TIME_REQUEST`            |
| `configuration`               | `CONFIGURATION`           |
| `parameters`                  | `PARAMETERS`              |
| `dayLightSavingTime`          |                           |
| `loadCurve`                   | `LOAD_CURVE_ABSOLUT`      |
| `loadCurveQuarter`            | `LOAD_CURVE_ABSOLUT`      |
| `loadCurveIncremental`        | `LOAD_CURVE_INCREMENTAL`  |
| `loadCurveIncrementalQuarter` | `LOAD_CURVE_INCREMENTAL`  |
| `deviceManufacturer`          | `DEVICE_AND_MANUFACTURER` |
| `currentPricing`              | `CURRENT_PRICING`         |
| `storedPricing`               | `STORED_PRICING`          |

### Default datastreams for ASDUs
| ASDU                          | Field                                    | Datastream                 |
|-------------------------------|------------------------------------------|----------------------------|
| `login`                       |                                          |                            |
| `logout`                      |                                          |                            |
| `timeRequest`                 | `DateTime`                               | `device.clock`             |
| `configuration`               | `ManufacturerCode`                       | `manufacturerCode`         |
| `configuration`               | `Model`                                  | `device.model`             |
| `configuration`               | `Firmware`                               | `device.software`          |
| `configuration`               | `SerialNumber`                           | `device.serialNumber`      |
| `configuration`               | `StandardDate`                           | `protocolRevDate`          |
| `configuration`               | `Datetime`                               | `protocolDate`             |
| `configuration`               | `BatteryPercentage`                      | `device.powersupply`       |
| `configuration`               | `SerialPort1Baudrate`                    | `serialPort1Speed`         |
| `configuration`               | `SerialPort1Codification`                | `serialPort1Conf`          |
| `configuration`               | `SerialPort1Mode`                        | `serialPort1ShipMode`      |
| `configuration`               | `SerialPort1StartingAsciiString `        | `serialPort1AsciiString`   |
| `configuration`               | `SerialPort2Baudrate`                    | `serialPort2Speed`         |
| `configuration`               | `SerialPort2Codification`                | `serialPort2Conf`          |
| `configuration`               | `VoltagePrimary`                         | `voltPrim`                 |
| `configuration`               | `VoltageSecondary`                       | `voltSec`                  |
| `configuration`               | `IntensityPrimary`                       | `intenPrim`                |
| `configuration`               | `IntensitySecondary`                     | `intenSec`                 |
| `configuration`               | `IntegrationPeriod1`                     | `IntPerLoadCurve1`         |
| `configuration`               | `IntegrationPeriod2`                     | `IntPerLoadCurve2`         |
| `configuration`               | `IntegrationPeriod3`                     | `IntPerLoadCurve3`         |
| `configuration`               | `ContractType`                           | `contractType`             |
| `configuration`               | `Contract1`                              | `contractState`            |
| `parameters`                  | `LinkAddressCollected`                   | `elinkAddress`             |
| `parameters`                  | `MeasurePointsQuantity`                  | `measurePointsQuantity`    |
| `parameters`                  | `MeasurePoint`                           | `measurePoint`             |
| `parameters`                  | `AccessPassword`                         | `accessPass`               |
| `parameters`                  | `IntegrationPeriod`                      | `intPeriod`                |
| `parameters`                  | `RegistryDepth`                          | `regDepth`                 |
| `deviceManufacturer`          | `ManufacturerCode`                       | `manufacturerCode`         |
| `deviceManufacturer`          | `DeviceId`                               | `contIdentifier`           |
| `dayLightSavingTime`          | `ToDaylightSavingTime`                   |                            |
| `dayLightSavingTime`          | `ToStandardTime`                         |                            |
| `loadCurve`                   | `Timestamp`                              |                            |
| `loadCurve`                   | `ImportedActive`                         | `eImpActTotDia`            |
| `loadCurve`                   | `ExportedActive`                         | `eExpActTotDia`            |
| `loadCurve`                   | `Quadrant1Reactive`                      | `eImpReQ1TotDia`           |
| `loadCurve`                   | `Quadrant2Reactive`                      | `eImpReQ2TotDia`           |
| `loadCurve`                   | `Quadrant3Reactive`                      | `eImpReQ3TotDia`           |
| `loadCurve`                   | `Quadrant4Reactive`                      | `eImpReQ4TotDia`           |
| `loadCurveQuarter`            | `frames[].Timestamp`                     |                            |
| `loadCurveQuarter`            | `frames[].ImportedActive`                | `eImpActTot`               |
| `loadCurveQuarter`            | `frames[].ExportedActive`                | `eExpActTot`               |
| `loadCurveQuarter`            | `frames[].Quadrant1Reactive`             | `eImpReQ1Tot`              |
| `loadCurveQuarter`            | `frames[].Quadrant2Reactive`             | `eImpReQ2Tot`              |
| `loadCurveQuarter`            | `frames[].Quadrant3Reactive`             | `eImpReQ3Tot`              |
| `loadCurveQuarter`            | `frames[].Quadrant4Reactive`             | `eImpReQ4Tot`              |
| `loadCurveIncremental`        | `frames[].Timestamp`                     |                            |
| `loadCurveIncremental`        | `frames[].ImportedActive`                | `eImpActIncDia`            |
| `loadCurveIncremental`        | `frames[].ExportedActive`                | `eExpActIncDia`            |
| `loadCurveIncremental`        | `frames[].Quadrant1Reactive`             | `eImpReQ1IncDia`           |
| `loadCurveIncremental`        | `frames[].Quadrant2Reactive`             | `eImpReQ2IncDia`           |
| `loadCurveIncremental`        | `frames[].Quadrant3Reactive`             | `eImpReQ3IncDia`           |
| `loadCurveIncremental`        | `frames[].Quadrant4Reactive`             | `eImpReQ4IncDia`           |
| `loadCurveIncrementalQuarter` | `frames[].Timestamp`                     |                            |
| `loadCurveIncrementalQuarter` | `frames[].ImportedActive`                | `eImpActInc`               |
| `loadCurveIncrementalQuarter` | `frames[].ExportedActive`                | `eExpActInc`               |
| `loadCurveIncrementalQuarter` | `frames[].Quadrant1Reactive`             | `eImpReQ1Inc`              |
| `loadCurveIncrementalQuarter` | `frames[].Quadrant2Reactive`             | `eImpReQ2Inc`              |
| `loadCurveIncrementalQuarter` | `frames[].Quadrant3Reactive`             | `eImpReQ3Inc`              |
| `loadCurveIncrementalQuarter` | `frames[].Quadrant4Reactive`             | `eImpReQ4Inc`              |
| `currentPricing`              | `frames[].Timestamp`                     |                            |
| `currentPricing`              | `frames[].RateIndex`                     | `({ri})`                   |
| `currentPricing`              | `frames[].Memory`                        | `({m})`                    |
| `currentPricing`              | `frames[].AbsoluteActive`                | `eRate{ri}ActTot{m}`       |
| `currentPricing`              | `frames[].IncrementalActive`             | `eRate{ri}ActInc{m}`       |
| `currentPricing`              | `frames[].AbsoluteInductiveReactive`     | `eRate{ri}ReIndTot{m}`     |
| `currentPricing`              | `frames[].IncrementalInductiveReactive`  | `eRate{ri}ReIndInc{m}`     |
| `currentPricing`              | `frames[].AbsoluteCapacitiveReactive`    | `eRate{ri}ReCapTot{m}`     |
| `currentPricing`              | `frames[].IncrementalCapacitiveReactive` | `eRate{ri}ReCapInc{m}`     |
| `currentPricing`              | `frames[].MaximumPower`                  | `eRate{ri}PowerMaxVal{m}`  |
| `currentPricing`              | `frames[].ExcessPower`                   | `eRate{ri}PowerExVal{m}`   |
| `currentPricing`              | `frames[].InitPeriodDateAsDatetime`      | `eRate{ri}PricInitPeri{m}` |
| `currentPricing`              | `frames[].EndPeriodDateAsDatetime`       | `eRate{ri}PricEndPeri{m}`  |
| `storedPricing`               | `frames[].Timestamp`                     |                            |
| `storedPricing`               | `frames[].RateIndex`                     | `({ri})`                   |
| `storedPricing`               | `frames[].Memory`                        | `({m})`                    |
| `storedPricing`               | `frames[].AbsoluteActive`                | `eRate{ri}ActTot{m}`       |
| `storedPricing`               | `frames[].IncrementalActive`             | `eRate{ri}ActInc{m}`       |
| `storedPricing`               | `frames[].AbsoluteInductiveReactive`     | `eRate{ri}ReIndTot{m}`     |
| `storedPricing`               | `frames[].IncrementalInductiveReactive`  | `eRate{ri}ReIndInc{m}`     |
| `storedPricing`               | `frames[].AbsoluteCapacitiveReactive`    | `eRate{ri}ReCapTot{m}`     |
| `storedPricing`               | `frames[].IncrementalCapacitiveReactive` | `eRate{ri}ReCapInc{m}`     |
| `storedPricing`               | `frames[].MaximumPower`                  | `eRate{ri}PowerMaxVal{m}`  |
| `storedPricing`               | `frames[].ExcessPower`                   | `eRate{ri}PowerExVal{m}`   |
| `storedPricing`               | `frames[].InitPeriodDateAsDatetime`      | `eRate{ri}PricInitPeri{m}` |
| `storedPricing`               | `frames[].EndPeriodDateAsDatetime`       | `eRate{ri}PricEndPeri{m}`  |



### iec102 Object Properties

      
| Property             | Type    | Default | Description                                                                                    |
|----------------------|---------|---------|------------------------------------------------------------------------------------------------|
| ip                   | string  |         | IP address to connect.                                                                         |
| port                 | number  |         | Port to connect                                                                                |
| isTls                | boolean | false   | Specifies if secure protocol must be used                                                      |
| retries              | number  | 5       | Number of retries.                                                                             |
| timeout              | number  | 30000   | Timeout in milliseconds.                                                                       |
| linkAddress          | number  |         | Mandatory parameter used as part of IEC102 protocol                                            |
| useMeasurePoint      | number  |         | Mandatory parameter used as part of IEC102 protocol                                            |
| usePasswordAccess    | number  |         | Mandatory parameter used as part of IEC102 protocol                                            |
| msisdn               | string  |         | Parameter used when connection is done with a data call through some caller                    |
| userName             | string  |         | Parameter used when connection is done with a data call through some caller                    |
| password             | string  |         | Parameter used when connection is done with a data call through some caller                    |
| referenceTime        | number  | Current | It will be used as reference time for period calculation and as datapoints 'at' value          |
| readingState         | string  | Current | Internally used parameter to keep ASDUs execution status                                       |
| portConfig           | string  |         | Parameter used when connection is done with a data call through some caller                    |
| source               | string  |         | It will be used as datapoints 'source' value                                                   |
| sourcesInfo          | string  |         | It will be used as datapoints 'sourcesInfo' value                                              |
| manufacturerCodeName | object  |         | Manufacturer code->name map                                                                    |
| asdus.asdusToExec    | array   |         | Internal array with the list of ASDUs to be executed. It must be initialized before connecting |


### iec102 Object Methods

#### connect (registerType, waitFor) ⇒ Object

Establish connection with specified device. Before using this method connection parameters such as ip, port, timeout, etc. must be specified (some of them can have default values).

See [Establish connection](#establish-connection)

| Parameter    | Type   | Description                          |
|--------------|--------|--------------------------------------|
| registerType | string | Specify connection procedure.        |
| waitFor      | array  | Strings to wait for in the response. |

This method will return an object with following format:
```json
{
    "status": true,
    "description": "Success"
}
```

#### connectWithIpAndPorts (ports, waitFor) ⇒ Object

Establish connection with specified device trying different ports. Before using this method connection parameters such as ip, timeout, etc. must be specified (some of them can have default values). In this case, a list of ports will be passed as parameters. For each port of the list, the `connect` method will be called until the connection is established correctly.

See [Establish connection](#establish-connection)

| Parameter | Type  | Description                          |
|-----------|-------|--------------------------------------|
| ports     | array | List of ports to be used             |
| waitFor   | array | Strings to wait for in the response. |

This method will return an object with following format:
```json
{
    "status": true,
    "description": "Success"
}
```

#### connectWithEndpoints (endpoints) ⇒ Object
This method is special case for GSM connection.

Establish connection with specified device trying different endpoints. Each endpoint is an object with following information:
- ip
- port
- userName
- password

For example:
```javascript
var endpoints = [
    {
        "ip": "127.0.0.1",
        "port": "3000",
        "userName": "userName",
        "password": "password"
    },
    {
        "ip": "127.0.0.2",
        "port": "3001",
        "userName": "userName2",
        "password": "password2"
    }
];
iec102.connectWithEndpoints(endpoints);
```

In this case, `GSM` register type will be used.

See [Establish connection](#establish-connection)

| Parameter | Type  | Description                         |
|-----------|-------|-------------------------------------|
| endpoints | array | List of objects with endpoints spec |

This method will return an object with following format:
```json
{
    "status": true,
    "description": "Success"
}
```

#### disconnect ()

Closes IEC102 connection


#### send (command, waitFor, pattern) ⇒ Object
Sends a command.

| Parameter | Type   | Description                                    |
|-----------|--------|------------------------------------------------|
| command   | string | Command to send.                               |
| waitFor   | List   | Strings to wait for in the response.           |
| pattern   | string | Pattern to extract response from sent command. |

Returns a json with `status` and `description` properties:
```json
{
    "status": true,
    "description": "Success"
}
```


#### iec102.asdus.add(name, execConfig)

Define an ASDU to be executed and add to `asdus.asdusToExec` array.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)
| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| name       | string | ASDU name               |
| execConfig | object | Execution configuration |

#### iec102.asdus.addFromParameters()

Calculates all ASDUs to be executed from operations parameters adding them to `asdus.asdusToExec` array. This method only works if parameters object has specific properties.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)


#### iec102.asdus.login(execConfig)

Execute directly `login` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)
| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:

```json
{
    "status": true,
    "description": "Success",
    "readingState": null,
}
```

#### iec102.asdus.logout(execConfig)

Execute directly `logout` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)
| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": null,
}
```

#### iec102.asdus.timeRequest(execConfig)

Execute directly `timeRequest` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:

```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "Datetime": {
            "date": "2024-01-19",
            "time": "09:36:58",
            "timezone": "GMT+1",
            "dst": 0
        }
    }
}
```

`data` object will contain data retrieved from executed ASDU.

#### iec102.asdus.configuration(execConfig)

Execute directly `configuration` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "Contract1": "unknown",
        "VoltageSecondary": 0,
        "ManufacturerCode": "1",
        "BatteryPercentage": 44,
        "SerialPort1StartingAsciiString": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
        "IntensityPrimary": 0,
        "IntegrationPeriod3": 0,
        "VoltagePrimary": 0,
        "IntegrationPeriod1": 60,
        "IntegrationPeriod2": 15,
        "SerialPort1Mode": 0,
        "IntensitySecondary": 0,
        "SerialNumber": 333,
        "Model": {
            "name": "AQ",
            "version": "",
            "manufacturer": "",
            "manufacturerOUI": ""
        },
        "SerialPort1Codification": "8/No/2",
        "ContractType": "Contract I",
        "StandardDate": "2002-05-01",
        "Firmware": [
            {
                "name": "Firmware version",
                "version": "2",
                "type": "FIRMWARE"
            }
        ],
        "SerialPort1Baudrate": 9600,
        "SerialPort2Baudrate": 0,
        "SerialPort2Codification": "8/No/2",
        "Datetime": {
            "date": "2002-04-10",
            "time": "00:00:00",
            "timezone": "GMT+1",
            "dst": 0
        }
    }
}
```

`data` object will contain data retrieved from executed ASDU.

#### iec102.asdus.parameters(execConfig)
Execute directly `parameters` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "RegistryDepth": 4000,
        "LinkAddressCollected": 1,
        "IntegrationPeriod": 60,
        "AccessPassword": 1,
        "MeasurePoint": 1,
        "MeasurePointsQuantity": 1
    }
}
```

`data` object will contain data retrieved from executed ASDU.

#### iec102.asdus.deviceManufacturer(execConfig)

Execute directly `deviceManufacturer` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "ManufacturerCode": "81",
        "DeviceId": "501606407"
    }
}
```

`data` object will contain data retrieved from executed ASDU.

#### iec102.asdus.dayLightSavingTime(execConfig)

Execute directly `dayLightSavingTime` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "ToDaylightSavingTime": {
            "date": "2002-04-10",
            "time": "00:00:00",
            "timezone": "GMT+1",
            "dst": 0
        },
        "ToStandardTime": {
            "date": "2002-04-10",
            "time": "00:00:00",
            "timezone": "GMT+1",
            "dst": 0
        }      
    }
}
```

`data` object will contain data retrieved from executed ASDU.

#### iec102.asdus.loadCurve(execConfig)

Execute directly `loadCurve` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "frames": [
            {
                "ImportedActive": 10,
                "Quadrant4Reactive": 10,
                "Quadrant2Reactive": 333,
                "Quadrant3Reactive": 334,
                "ExportedActive": 1000,
                "Quadrant1Reactive": 333,
                "Timestamp": 1705536000000
            },
            //...
        ]
    }
}
```

`data` object will contain a field named `frames` that is an array. Each array element is an object with the data retrieved.

#### iec102.asdus.loadCurveQuarter(execConfig)

Execute directly `loadCurveQuarter` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "frames": [
            {
                "ImportedActive": 10,
                "Quadrant4Reactive": 10,
                "Quadrant2Reactive": 333,
                "Quadrant3Reactive": 334,
                "ExportedActive": 1000,
                "Quadrant1Reactive": 333,
                "Timestamp": 1705536000000
            },
            {
                "ImportedActive": 0,
                "Quadrant4Reactive": 125,
                "Quadrant2Reactive": 125,
                "Quadrant3Reactive": 125,
                "ExportedActive": 500,
                "Quadrant1Reactive": 125,
                "Timestamp": 1705536900000
            }
            //...
        ]
    }
}
```

`data` object will contain a field named `frames` that is an array. Each array element is an object with the data retrieved.

#### iec102.asdus.loadCurveIncremental(execConfig)

Execute directly `loadCurveIncremental` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:

```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "frames": [
            {
                "ImportedActive": 10,
                "Quadrant4Reactive": 10,
                "Quadrant2Reactive": 333,
                "Quadrant3Reactive": 334,
                "ExportedActive": 1000,
                "Quadrant1Reactive": 333,
                "Timestamp": 1705536000000
            }
            //...
        ]
    }
}
```

`data` object will contain a field named `frames` that is an array. Each array element is an object with the data retrieved.

#### iec102.asdus.loadCurveIncrementalQuarter(execConfig)

Execute directly `loadCurveIncrementalQuarter` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "frames": [
            {
                "ImportedActive": 2,
                "Quadrant4Reactive": 0,
                "Quadrant2Reactive": 1,
                "Quadrant3Reactive": 1,
                "ExportedActive": 1,
                "Quadrant1Reactive": 2,
                "Timestamp": 1705536000000
            },
            {
                "ImportedActive": 0,
                "Quadrant4Reactive": 0,
                "Quadrant2Reactive": 0,
                "Quadrant3Reactive": 0,
                "ExportedActive": 2,
                "Quadrant1Reactive": 0,
                "Timestamp": 1705536900000
            }
            //...
        ]
    }
}
```

`data` object will contain a field named `frames` that is an array. Each array element is an object with the data retrieved.

#### iec102.asdus.currentPricing(execConfig)

Execute directly `currentPricing` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "frames": [
            {
                "IncrementalActive": 5060,
                "IncrementalCapacitiveReactive": 54,
                "Memory": "Cur",
                "AbsoluteCapacitiveReactive": 4564,
                "Timestamp": 1705653489884,
                "MaximumPower": 19,
                "EndPeriodDateAsDatetime": {
                    "date": "2024-02-29",
                    "time": "23:59:00",
                    "timezone": "GMT+1",
                    "dst": 0
                },
                "RateIndex": "Tot",
                "InitPeriodDateAsDatetime": {
                    "date": "2024-02-01",
                    "time": "00:00:00",
                    "timezone": "GMT+1",
                    "dst": 0
                },
                "ExcessPower": 0,
                "AbsoluteActive": 595452,
                "AbsoluteInductiveReactive": 1207,
                "IncrementalInductiveReactive": 6
            },
            //...
        ]
    }
}
```

`data` object will contain a field named `frames` that is an array. Each array element is an object with the data retrieved.

#### iec102.asdus.storedPricing(execConfig)

Execute directly `storedPricing` ASDU.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

| Parameter  | Type   | Description             |
|------------|--------|-------------------------|
| execConfig | object | Execution configuration |

Return a json with following format:
```json
{
    "status": true,
    "description": "Success",
    "readingState": "READ",
    "data": {
        "frames": [
            {
                "IncrementalActive": 5060,
                "IncrementalCapacitiveReactive": 54,
                "Memory": "Mem",
                "AbsoluteCapacitiveReactive": 4564,
                "Timestamp": 1705653478357,
                "MaximumPower": 19,
                "EndPeriodDateAsDatetime": {
                    "date": "2024-02-29",
                    "time": "23:59:00",
                    "timezone": "GMT+1",
                    "dst": 0
                },
                "RateIndex": "Tot",
                "InitPeriodDateAsDatetime": {
                    "date": "2024-02-01",
                    "time": "00:00:00",
                    "timezone": "GMT+1",
                    "dst": 0
                },
                "ExcessPower": 0,
                "AbsoluteActive": 595452,
                "AbsoluteInductiveReactive": 1207,
                "IncrementalInductiveReactive": 6
            }
            //...
        ]
    }
}
```

`data` object will contain a field named `frames` that is an array. Each array element is an object with the data retrieved.

#### iec102.asdus.execute()

Execute one by one all the ASDUs defined in `asdus.asdusToExec`.

See [ASDUs Definition and Execution](#asdus-definition-and-execution)

Returns an object with following format:
```json
{
    "status": true,
    "asdus": {
        "login": {
            "data": null,
            "description": "Success",
            "readingState": null,
            "status": true
        },
        "timeRequest": {
            "data": {
                "Datetime": {
                    "date": "2024-01-19",
                    "time": "09:36:58",
                    "timezone": "GMT+1",
                    "dst": 0
                }
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "parameters": {
            "data": {
                "RegistryDepth": 4000,
                "LinkAddressCollected": 1,
                "IntegrationPeriod": 60,
                "AccessPassword": 1,
                "MeasurePoint": 1,
                "MeasurePointsQuantity": 1
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "deviceManufacturer": {
            "data": {
                "ManufacturerCode": "81",
                "DeviceId": "501606407"
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "loadCurve": {
            "data": {
                "frames": [
                    {
                        "ImportedActive": 10,
                        "Quadrant4Reactive": 10,
                        "Quadrant2Reactive": 333,
                        "Quadrant3Reactive": 334,
                        "ExportedActive": 1000,
                        "Quadrant1Reactive": 333,
                        "Timestamp": 1705536000000
                    }
                ]
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "loadCurveQuarter": {
            "data": {
                "frames": [
                    {
                        "ImportedActive": 10,
                        "Quadrant4Reactive": 10,
                        "Quadrant2Reactive": 333,
                        "Quadrant3Reactive": 334,
                        "ExportedActive": 1000,
                        "Quadrant1Reactive": 333,
                        "Timestamp": 1705536000000
                    }
                    //...
                ]
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "loadCurveIncremental": {
            "data": {
                "frames": [
                    {
                        "ImportedActive": 10,
                        "Quadrant4Reactive": 10,
                        "Quadrant2Reactive": 333,
                        "Quadrant3Reactive": 334,
                        "ExportedActive": 1000,
                        "Quadrant1Reactive": 333,
                        "Timestamp": 1705536000000
                    }
                ]
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "loadCurveIncrementalQuarter": {
            "data": {
                "frames": [
                    {
                        "ImportedActive": 2,
                        "Quadrant4Reactive": 0,
                        "Quadrant2Reactive": 1,
                        "Quadrant3Reactive": 1,
                        "ExportedActive": 1,
                        "Quadrant1Reactive": 2,
                        "Timestamp": 1705536000000
                    }
                    //...
                ]
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "storedPricing": {
            "data": {
                "frames": [
                    {
                        "IncrementalActive": 5060,
                        "IncrementalCapacitiveReactive": 54,
                        "Memory": "Mem",
                        "AbsoluteCapacitiveReactive": 4564,
                        "Timestamp": 1705653478357,
                        "MaximumPower": 19,
                        "EndPeriodDateAsDatetime": {
                            "date": "2024-02-29",
                            "time": "23:59:00",
                            "timezone": "GMT+1",
                            "dst": 0
                        },
                        "RateIndex": "Tot",
                        "InitPeriodDateAsDatetime": {
                            "date": "2024-02-01",
                            "time": "00:00:00",
                            "timezone": "GMT+1",
                            "dst": 0
                        },
                        "ExcessPower": 0,
                        "AbsoluteActive": 595452,
                        "AbsoluteInductiveReactive": 1207,
                        "IncrementalInductiveReactive": 6
                    }
                    //...
                ]
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "configuration": {
            "data": {
                "Contract1": "unknown",
                "VoltageSecondary": 0,
                "ManufacturerCode": "1",
                "BatteryPercentage": 44,
                "SerialPort1StartingAsciiString": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
                "IntensityPrimary": 0,
                "IntegrationPeriod3": 0,
                "VoltagePrimary": 0,
                "IntegrationPeriod1": 60,
                "IntegrationPeriod2": 15,
                "SerialPort1Mode": 0,
                "IntensitySecondary": 0,
                "SerialNumber": 333,
                "Model": {
                    "name": "AQ",
                    "version": "",
                    "manufacturer": "",
                    "manufacturerOUI": ""
                },
                "SerialPort1Codification": "8/No/2",
                "ContractType": "Contract I",
                "StandardDate": "2002-05-01",
                "Firmware": [
                    {
                        "name": "Firmware version",
                        "version": "2",
                        "type": "FIRMWARE"
                    }
                ],
                "SerialPort1Baudrate": 9600,
                "SerialPort2Baudrate": 0,
                "SerialPort2Codification": "8/No/2",
                "Datetime": {
                    "date": "2002-04-10",
                    "time": "00:00:00",
                    "timezone": "GMT+1",
                    "dst": 0
                }
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "currentPricing": {
            "data": {
                "frames": [
                    {
                        "IncrementalActive": 5060,
                        "IncrementalCapacitiveReactive": 54,
                        "Memory": "Cur",
                        "AbsoluteCapacitiveReactive": 4564,
                        "Timestamp": 1705653489884,
                        "MaximumPower": 19,
                        "EndPeriodDateAsDatetime": {
                            "date": "2024-02-29",
                            "time": "23:59:00",
                            "timezone": "GMT+1",
                            "dst": 0
                        },
                        "RateIndex": "Tot",
                        "InitPeriodDateAsDatetime": {
                            "date": "2024-02-01",
                            "time": "00:00:00",
                            "timezone": "GMT+1",
                            "dst": 0
                        },
                        "ExcessPower": 0,
                        "AbsoluteActive": 595452,
                        "AbsoluteInductiveReactive": 1207,
                        "IncrementalInductiveReactive": 6
                    }
                    //...
                ]
            },
            "description": "Success",
            "readingState": "READ",
            "status": true
        },
        "logout": {
            "data": null,
            "description": "Success",
            "readingState": null,
            "status": true
        }
    }
}
```

### Catalog GetMeterInfo operation example

Following code shows the catalog connector function for GetMeterInfo operation 

```javascript
var registerType = entityValue(entity, 'provision.type');

iec102.ip = entityValue(entity, 'provision.ip');
iec102.port = entityValue(entity, 'provision.port');

iec102.linkAddress = Number(entityValue(entity, 'provision.linkAddress'));
iec102.useMeasurePoint = Number( entityValue(entity, 'provision.measurePoint'));
iec102.usePasswordAccess = Number( entityValue(entity, 'provision.passwordAccess'));

iec102.msisdn =  entityValue(entity, 'provision.device.communicationModules[].subscription.mobile.msisdn', 0);
iec102.userName =  entityValue(entity, 'provision.user');
iec102.password =  entityValue(entity, 'provision.password');
iec102.portConfig =  entityValue(entity, 'provision.portConfig');

if (!registerType) {
    response.errorProcessing('Meter type was not specified');
    return response;
}

var connectionStatus = iec102.connect(registerType);
collection.addDatapoint('atd.response', connectionStatus.description, iec102.referenceTime, iec102.source, iec102.sourceInfo);
if (!connectionStatus.status) {
    collection.addDatapoint('readingState', iec102.readingState, iec102.referenceTime, iec102.source, iec102.sourceInfo);
    collection.send();
    return response;
}

iec102.asdus.addFromParams();
var asdusResult = iec102.asdus.execute();

iec102.disconnect();

collection.addDatapoint('readingState', iec102.readingState, iec102.referenceTime, iec102.source, iec102.sourceInfo);
collection.send();
if (asdusResult.status) {
    response.successful('Finished Correctly');
}

log('Final response: ', response);
return response;
```
