DLMS JavaScript API
Connector functions DLMS JS API guide
This JavaScript code provides predefined functions to execute DLMS requests from the connector function. They are explained below.
Tip
For Smart Gas devices, there is a specialized extension of this API called DLMS Gas API which simplifies many common operations.
Types of south criteria for your DLMS connector function:
| Description | Format | Example |
|---|---|---|
| Identification via OBIS code for notifications that contain a description element | dlms://obis/<obis-code> |
dlms://obis/0.0.66.0.48.255 |
Identification via template ID for notifications containing only 1 or more octet-string values and taking first byte of each octet-string as template ID |
dlms://template/<template-id> |
dlms://template/48 |
Warning
The OBIS Code needs to be specified using only dots as separator, don’t use the complex form 0-0:66.0.48.255 or the Connector Function will not be called.
Input parameters in Collection Connector Function
The main script will have access to three main vars:
- entity: json with flattened operation target device entity representation.
- gateway: json with flattened gateway entity representation. It can be null.
- payload: json that represents the DLMS message received from the device.
- contextParams: json object with execution context information. It can have some of this params:
- apiKey: device or user apikey.
- remoteIp: remote host where DLMS message is invoked.
- obisCode: OBIS code of the message arrived.
- templateId: Template identifier of the message arrived.
ContextParams for COLLECTION Connector function for DLMS connection:
Here is a payload example:
JS DLMS API
For REQUEST Connector Functions we will use the functions described below. You have an object, named dlms, with all the functions described. You must use dlms.<function>.
If you want to collect data after executing any of these function you can call collectCF and you can set various obis code in the URL provided as you can see in the next example:
dlms.connect()
Opens DLMS connection (default via TCP transport).
Kind: global function
The connection parameters need to be set before calling connect:
| Config name | Type | Default value | Description |
|---|---|---|---|
ip |
string |
null |
IP address of the device you want to connect to. |
port |
number |
4059 |
Port of the device you want to connect to. |
connectionType |
string ("TCP", "UDP") |
"TCP" |
Protocol of the device you want to connect to. |
cwport |
number |
16 |
Client WPort. |
swport |
number |
1 |
Server WPort. |
refMethod |
string ("LN", "SN") |
"LN" |
Server WPort. |
securityLevel |
string ("MANUFACTURER", "HIGH", "LOW", "SHA1, "SHA256", "MD5", "GMAC", "ECDSA", "NONE") |
"NONE" |
Authentication mechanism to use in the connection. |
password |
string |
null |
Password to use with the authentication mechanism. |
timeout |
number |
5000 |
Timeout of the connection. |
security |
string (NONE, AUTHENTICATION, ENCRYPTION, AUTHENTICATION_ENCRYPTION) |
null |
Security used in every message. null value will be treated as NONE |
securitySuite |
string (SUITE_0, SUITE_1, SUITE_2) |
null |
Authentication, encryption and key wrapping algorithm. null value will be treated as SUITE_0 |
authenticationKey |
byte[] as hexadecimal string |
null |
Key used for message authentication. The length of the key in bytes must match the securitySuite used |
blockCipherKey |
byte[] as hexadecimal string |
null |
Key used for message encryption. The length of the key in bytes must match the securitySuite used |
hesSystemTitle |
byte[] as hexadecimal string |
null |
Overrides default System Title to be sent in requests to client |
ignoreSystemTitleInCiphering |
boolean |
false |
Whether the optional hesSystemTitle should be ignored (not sent) when sending ciphered messages |
forceGetWithoutList |
boolean |
false |
Whether to force get() by default to request elements one by one instead of using a list when MULTIPLE_REFERENCES conformance is enabled |
forceSetWithoutList |
boolean |
false |
Whether to force set() by default to request elements one by one instead of using a list when MULTIPLE_REFERENCES conformance is enabled |
conformance |
string[] ("MULTIPLE_REFERENCES", "GENERAL_PROTECTION") |
[] |
Communication conformance values. For example, ‘MULTIPLE_REFERENCES’ specifies it is possible to send to device multiple obis in unique request |
Warning
In case of security parameter is not NONE, next default values will be set:
blockCipherKey:000102030405060708090A0B0C0D0E0FauthenticationKey:D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF
Add attributes
addAttr() is used both for get() and set() methods and has multiple signatures:
dlms.addAttr(classId, obisCode, attrId)
Applicable for normal gets.
| Param | Type | Description |
|---|---|---|
classId |
Array |
The class ID of the object to access |
obisCode |
string |
The name of the object to access |
attrId |
number |
The attribute index of the object |
dlms.addAttr(classId, obisCode, attrId, type, value)
Applicable for normal sets.
| Param | Type | Description |
|---|---|---|
classId |
Array |
The class ID of the object to access |
obisCode |
string |
The name of the object to access |
attrId |
number |
The attribute index of the object |
type |
string |
The data type of the value to set |
value |
see data types | The data value to set |
dlms.addAttr(classId, obisCode, attrId, data)
Applicable for normal sets.
| Param | Type | Description |
|---|---|---|
classId |
Array |
The class ID of the object to access |
obisCode |
string |
The name of the object to access |
attrId |
number |
The attribute index of the object |
data |
object (with type and value) |
The data with both type and value to set |
where:
data attribute |
Type | Description |
|---|---|---|
type |
string |
The data type of the value to set |
value |
see data types | The data value to set |
This is an alternate way of using addAttr(classId, obisCode, attrId, type, value) with the data parameters in an object.
It’s helpful when used in combination with get().
dlms.addAttr(classId, obisCode, attrId, selectiveAccess)
Applicable for gets with selective access.
| Param | Type | Description |
|---|---|---|
classId |
Array |
The class ID of the object to access |
obisCode |
string |
The name of the object to access |
attrId |
number |
The attribute index of the object |
selectiveAccess |
object (with accessSelector and accessParameters) |
The selective access descriptor |
where:
selectiveAccess attribute |
Type | Description |
|---|---|---|
accessSelector |
number |
The access selector |
accessParameters |
object with type and value |
The access parameters |
and
accessParameters attribute |
Type | Description |
|---|---|---|
type |
string |
The data type of access parameters |
value |
see data types | The data value of the access parameters |
Info
The proper access selector and parameters depend on the manufacturer and object type. Some may implement by range and by entry defined in the DLMS Blue Book - Parameters for selective access to the buffer attribute (section 4.3.6 in Blue Book 12).
dlms.addAttr(attribute)
Generic signature applicable for all cases.
| Attribute | Type | Mandatory | Description |
|---|---|---|---|
classId |
Array |
The class ID of the object to access | |
obisCode |
string |
The name of the object to access | |
attrId |
number |
The attribute index of the object | |
type |
string |
only on set() |
The data type of the value to set |
value |
see data types | only on set() |
The data value to set |
accessSelector |
number |
only on get() with selective access |
The access selector |
accessParameters |
object with type and value |
only on get() with selective access |
The access parameters |
where:
accessParameters attribute |
Type | Description |
|---|---|---|
type |
string |
The data type of access parameters |
value |
see data types | The data value of the access parameters |
data types
| Name | Value type | Compatible type in set | Description | Example |
|---|---|---|---|---|
null-data |
null |
null |
||
array |
Array of object |
Complex data, all elements must be of the same type | [{"type":"unsigned","value":1},{"type":"unsigned","value":2}] |
|
structure |
Array of object |
Complex data, different elements possible | [{"type":"unsigned","value":1},{"type":"visible-string","value":"two"}] |
|
boolean |
boolean |
true |
||
bit-string |
Array of boolean |
string |
An ordered sequence of boolean values. In set() an string may be used instead of array of boolean as bit-string representation |
[true,false,true] ("101" as string representation in set()) |
double-long |
number |
Integer32 (-2147483648…2147483647) |
0 |
|
double-long-unsigned |
number |
Unsigned32 (0…4294967295 |
0 |
|
octet-string |
Array of number |
string |
An ordered sequence of octets (8 bit bytes). May contain a dateTime value, see getDateTime() and getDate() | [116,101,115,116] (or "test" in set()) |
visible-string |
string |
An ordered sequence of ASCII characters | "test" |
|
utf8-string |
string |
An ordered sequence of characters encoded as UTF-8 | "test" |
|
bcd |
number |
Binary Coded Decimal (0…99) |
0 |
|
integer |
number |
Integer8 (-128…127) |
0 |
|
long |
number |
Integer16 (-32768…32767) |
0 |
|
unsigned |
number |
Unsigned8 (0…255) |
0 |
|
long-unsigned |
number |
Unsigned16 (0…65535) |
0 |
|
compact-array |
Array of object |
Provides an alternative, compact encoding of complex data, all elements must be of the same type | [{"type":"unsigned","value":1},{"type":"unsigned","value":2}] |
|
long64 |
number |
Integer64 (-9007199254740991…9007199254740991) 1 |
0 |
|
long64-unsigned |
number |
Unsigned64 (0…9007199254740991) 1 |
0 |
|
enum |
number |
The elements of the enumeration type are defined in the Attribute description or Method description section of a COSEM IC specification (0…255) |
0 |
|
float32 |
number |
Floating point number in 4 bytes | 0 |
|
float64 |
number |
Floating point number in 8 bytes | 0 |
|
date-time |
object |
Object containing all fields in a dateTime object | {"year":2023,"month":11,"dayOfMonth":28,"dayOfWeek":2,"hour":10,"minute":26,"second":55,"hundredthsOfSecond":0,"deviation":-60,"status":0} |
|
date |
object |
Object containing year, month, dayOfMonth and dayOfWeek fields in a dateTime object |
{"year":2023,"month":11,"dayOfMonth":28,"dayOfWeek":2} |
|
time |
object |
Object containing hour, minute, second and hundredthsOfSecond fields in a dateTime object |
{"hour":16,"minute":1,"second":2,"hundredthsOfSecond":20} |
Warning
JavaScript does not support the whole range of DLMS numbers, see footnotes.
dateTime objects
A dateTime object is used to specify all possible values for date-time, date and time DLMS types. It may define the following attributes:
| Name | Normal values | Additional values |
|---|---|---|
year |
0..65534 |
65535 means unspecified |
month |
1..12 (jan-dec) |
253 = daylight savings end, 254 daylight savings begin, 255 not specified |
dayOfMonth |
1..31 |
224..252 reserved, 253 2nd last day of month, 254 last day of month, 255 not specified |
dayOfWeek |
1..7 (mon-sun) |
255 not specified |
hour |
0..23 |
255 not specified |
minute |
0..59 |
255 not specified |
second |
0..59 |
255 not specified |
hundredthsOfSecond |
0..99 |
255 not specified |
deviation |
-720..720 (in minutes of local time to UTC) |
32768 not specified |
status |
8 bit flags | 255 not specified |
Info
For more information see DLMS Blue Book - Date and time formats (section 4.1.6.1 in Blue Book 12)
To transform this object to a Date see getDate(). Keep in mind that sets of date-time, date, time and octet-string do not accept a Date object. To transform it to a dateTime object use getDateTime().
dlms.get(descriptive, forceWithoutList)
Executes a multi DLMS get attribute request with the previously specified payload (addAttr(classId, obisCode, attrId)).
Kind: global function
Returns: Array - Array of JSONs with responses. Each JSON will have six fields: result of the get operation, the requested classId, obisCode and attrId, type with the data type of the received value and the value received from the device. An optional error field may be returned for any error that happened during the get.
| Param | Type | Mandatory | Default | Description |
|---|---|---|---|---|
descriptive |
boolean |
true |
Descriptive mode returns complex data as Array of object containing type and value for each object, non descriptive mode flattens the returned array |
|
forceWithoutList |
boolean |
false |
Whether to force the get to request elements one by one instead of using a list when MULTIPLE_REFERENCES conformance is enabled (if it’s not set the global forceGetWithoutList will be used) |
Example for descriptive get:
Example for non descriptive get
Non descriptive get
Complex values returned in a non-descriptive get cannot be passed as value in a set.
get results
successhardware-faulttemporary-failureread-write-deniedobject-undefinedobject-class-inconsistentobject-unavailabletype-unmatchedscope-of-access-violateddata-block-unavailablelong-get-abortedno-long-get-in-progresslong-set-abortedno-long-set-in-progressdata-block-number-invalidother-reason
dlms.set(descriptive)
Executes a multi DLMS set attribute request with the previously specified payload (addAttr(classId, obisCode, attrId, type, value)).
Kind: global function
Returns: Array - Array of JSONs with responses. Each JSON will have six fields: result of the set operation, the requested classId, obisCode and attrId, type with the data type of the received value and the value received from the device. An optional error field may be returned for any error that happened during the set.
| Param | Type | Mandatory | Default | Description |
|---|---|---|---|---|
descriptive |
boolean |
true |
Does not matter on set(). It’s included to have the same signature as get() and in case a device returns something in a set. |
|
forceWithoutList |
boolean |
false |
Whether to force the set to request elements one by one instead of using a list when MULTIPLE_REFERENCES conformance is enabled (if it’s not set the global forceSetWithoutList will be used) |
Info
Normally, a set request should always return a null-data as type and null as value.
Warning
A set request for complex data must always specify the value in a descriptive manner (as Array of Object containing both type and value for each and all elements and sub-elements in case of more nested complex elements).
set results
They are the same as get results.
dlms.addMethod(classId, obisCode, methodId, type, value)
addMethod() is used for method() function.
| Param | Type | Mandatory | Description |
|---|---|---|---|
classId |
Array |
The class ID of the object to access | |
obisCode |
string |
The name of the object to access | |
methodId |
string |
The method index in the object | |
type |
string |
when needed | The data type of the value to pass to the method |
value |
string |
when needed | The data value to pass to the method |
dlms.method(descriptive)
Executes a multi DLMS method (or action) request with the previously specified payload (addMethod(classId, obisCode, methodId, type, value)).
Kind: global function
Returns: Array - Array of JSONs with responses. Each JSON will have six fields: result of the method operation, the requested classId, obisCode and methodId, type with the data type of the received value and the value received from the device. An optional error field may be returned for any error that happened during the method (for example an error decoding the optional return parameters).
| Param | Type | Mandatory | Default | Description |
|---|---|---|---|---|
descriptive |
boolean |
true |
Descriptive mode returns complex data as Array of object containing type and value for each object, non descriptive mode flattens the returned array |
Info
A method request may need and/or return whatever type and value it’s needed. Check Method description section of a COSEM IC specification.
action results
successhardware-faulttemporary-failureread-write-deniedobject-undefinedobject-class-inconsistentobject-unavailabletype-unmatchedscope-of-access-violateddata-block-unavailablelong-action-abortedno-long-action-in-progressother-reason
dlms.initializeNextFrameCounter(currentFrameCounter)
Sets the invocation counter of the ciphering to the next value of the received frame counter. This is used for devices that maintain two separate frame counters (one for transmit and one for receive). Usually the current Management Frame Counter - On-line is received in a CompactFrame notification and that value is the one that needs to be passed to this function for that device.
Kind: global function
| Param | Type | Mandatory | Description |
|---|---|---|---|
currentFrameCounter |
number |
The current frame counter sent by the device. |
dlms.getInvocationCounter()
Returns the current invocation counter of the ciphering.
Kind: global function
Returns: number (integer).
dlms.disconnect()
Close the DLMS connection.
Kind: global function
dlms.getCompactData(typeDescription, value, descriptive, italianMode)
Extract the compact data serialized in a byte array according to the description given.
Kind: global function
Returns: Object - Object containing result and/or error. On success, result contains the parsed compact data (either in descriptive (with type in each value) or non-descriptive (direct values) format depending on the descriptive parameter). On error, the error will contain the error description and result may be null or contain a best-effort decoding of the compact data that may be incorrect.
| Param | Type | Mandatory | Default | Description |
|---|---|---|---|---|
typeDescription |
Object |
Object with the description of the data. The attributes of the object will be different according to the data expected’ | ||
value |
Array of number (or Object containing an octet-string type with its value) |
Array of bytes with the compact data (for example the DLMS notification data or element received) | ||
descriptive |
boolean |
true |
Descriptive mode returns complex data as Array of object containing type and value for each object, non descriptive mode flattens the returned array |
|
italianMode |
boolean |
false |
Determines if the compact data decoding of arrays must be in italian mode or not (explicitArrayLengthInContent) |
Here is a description example:
Info
- Simple data types just need to define the
typeas seen in data types. arraytype description must define asubtype, which is atypeDescription, and alengthwhen not usingitalianMode.italianMode(orexplicitArrayLengthInContent) does not need the length because it’s encoded in the received data.structuretype description must define anarrayofitems, which are each atypeDescription.compact-arrayis not supported inside a compact data.
Here is an example of the function result in descriptive and non descriptive modes:
dlms.getDate(value) ⇒ Date
Extract the Date of a dateTime object or an octet-string. Some dateTime objects or octet-string may not contain a complete date and this method will return a date that may not be as accurate as you expect. You should check the dateTime object for unspecified value.
Kind: global function
Returns: Date
| Param | Type | Mandatory | Default | Description |
|---|---|---|---|---|
value |
dateTime object or Array of number (or Object having type date-time, date, time or octet-string with its value) |
The best-effort Date possible |
dlms.getDateTime(value)
Extract the dateTime object of a Date or an octet-string. The resulting dateTime objects generated from a Date will use UTC time specifying a deviation of 0. If you need something else construct the dateTime object manually.
Kind: global function
Returns: Object
| Param | Type | Mandatory | Default | Description |
|---|---|---|---|---|
value |
Date or Array of number (or Object having type of octet-string with its value) |
Value containing a dateTime compatible value |
dlms.undefinedDateTime()
Get dateTime object with all its fields set to not specified.
You can also use unspecifiedDateTime().
Kind: global function
Returns: Object
dlms.unspecifiedDateTime()
Get dateTime object with all its fields set to not specified.
You can also use undefinedDateTime().
Kind: global function
Returns: Object
-
See MAX_SAFE_INTEGER and MIN_SAFE_INTEGER ↩︎ ↩︎