DCC Boxed is a tool for (emulated) end-2-end testing within the UK smart metering network. This project provides a number of nodes that enable Node-RED to send and receive requests to a DCC Boxed instance. The intention is to provide an easy to use tool set to allow users to interface with DCC Boxed without worrying about technical issues such as xml and correctly signing commands.
Below shows the context of this Node-RED project and demonstrates a typical interaction of sending of a command along with receiving its response. Notice, the two optional blocks, these allow for sending critical commands and reading sensitive (i.e. encrypted) data from end devices with out the user needing to be aware of additional processing requirements. An example of reading sensitive data is given in the above animation of performing a SRV 4.1.1 to read the current energy usage from a meter, also compare the below sequence diagram with the above animation to understand why two responses are obtained (the I99 and later the I0).
The functionality exposed includes:
- A library of DUIS templates, i.e. commands (taken from RTDS)
- Send the DUIS request to a DCC Boxed (critical, non-critical, device and non-device supported).
- Receive a DUIS response (both synchronous and asynchronously)
- Generate and submit UTRN tokens.
These three functions greatly reduce the complexity needed to interface with DCC Boxed as they hide the cryptographic operations and different request processing strategies. Thus, allowing the user to focus on the application layer, e.g. configuring devices or automating business processes.
- When a UTRN token is generated, only the least significant 10 bits (of 32 bits) counter is encoded into the UTRN. Thus, when using this package to generate UTRN's and the user relies on a EPOCH based counter its possible that the UTRN, if entered manually using the buttons on a smart meter will be rejected. This is due to the algorithm used to guess the remaining 22 bits of the counter; all 32 bits are needed for validation of the UTRN. This is not an issue when the UTRN is programmatically sent to the device with service request 2.2 (Top Up Device) because the whole counter is transmitted along with the UTRN.
Ensure you are using Node 16x or later. This is because some of the nodes rely
on features in the crypto
library of Node 16x.
If you have not already, install Node-RED. The below assumes that Node-RED is installed globally and not running in a sandbox/docker. The nodes in the project are developed and tested against version 3.0.2 of Node-RED.
Install @smartdcc/dccboxed-nodered-nodes
package into Node-RED's palette
using the standard process. See below image for an example of
installing from the user interface.
Once installed, it should make available a number of purple nodes under the
smartdcc
category (see image to right).
Note: To use "duis - sign & validate", "dccboxed-send" or
"dccboxed-receive" nodes it is required to install Java (developed and
tested against Java 11). This means, that java
should be in the PATH
of
the Node-RED application. For this reason, it is recommended to run Node-RED
directly on the host without a sandbox/docker environment. This simplifies the
process of installing java
.
- If running without
java
installed, an error will be generated when the sign/validate node is executed. Thus, will be unable to submit the command to DCC Boxed.
The typical use case of the nodes in this project is built around the following 3 nodes:
duis-template
- Provides template DUIS requests.dccboxed-send
- Send a DUIS request to a DCC Boxed and output any synchronous responses (i.e. the response will likely be an acknowledgement or result of a non-device request).dccboxed-receive
- Asynchronously receive DUIS responses from DCC Boxed (i.e. typically will involve response from a device or an alert)
For an example of how to configure these nodes, please see the following
video. Remember, it is also required to configure the
Receive Response Service address
on DCC Boxed.
The following shows a minimal setup using these three nodes:
The duis-template
node provides access to a catalog of DUIS
templates. The catalog can be searched by keywords or service
requests. The node is used by dragging it to the canvas and then configuring its
properties in the usual way. Below shows the properties pane of the
duis-template
node:
-
The Template option is used to search for a DUIS template. Below shows an example of searching the catalog:
-
The option to use "Simplified Template" is highly recommended (and required when using
dccboxed-send
node as described below). Information about what simplified means can be found here. -
The Show Inject Button option toggles whether the button is displayed on the left of the node. This button triggers the node to generate a template. Alternatively, the template can be generated in response to an incoming message, in which case the Originator/Target can be extracted from the input message.
-
The Output option defines where the template will be saved in the output message from the node. In most cases the default value is fine and aligns with the default location expected when using the
dccboxed-send
node. -
The Originator and Target allow for configuration of the DUIS header. In most cases, the Originator does not need to be changed and the Target is the EUI of the end device (or ACB). More information about the meaning of these values can be found in the DUIS specification. For Target field, the device EUI can typically be found from the HAN page in DCC Boxed.
These Originator and Target fields also support looking up their values from the input message, global variables or flow variables.
-
The text box below is used for showing the payload of the DUIS template. This can be edited by the user to change the default values in the chosen template. The following shows an example of a service request selected with the text box populated:
If the template is edited for a given node, a symbol is shown in bottom right corner of the editor.
Moreover, it is possible to use
global
/flow
variables in the editor view. A common use-case for this is when performing a pair-wise join of two devices (such as an ESME and PPMID):
The dccboxed-send
and dccboxed-receive
node are both dependent on a
dccboxed-config
node. This node is used to provide a single interface between
DCC Boxed and both dccboxed-send
and dccboxed-receive
nodes.
When adding either dccboxed-send
and dccboxed-receive
for the first time, it
will be required to configure a DCC Boxed server (as a dccboxed-config
).
The properties of a dccboxed-config
are as follows:
Importantly, ensure the Host and Port align point to the DCC Boxed
server. The Response field needs to be configured on the DCC Boxed DUIS
Interface, so DCC Boxed will be able to correctly send responses. For
example, if NodeRED is running on a machine with IP address 192.168.0.5
,
DCC Boxed could be configured as follows (assuming a default value of
/smartdcc/duis
in the Response field):
The dccboxed-send
node provides a fully managed interface to send DUIS
requests to a DCC Boxed instance. This includes:
- Converting the DUIS request from JSON into XML.
- Adding an XML digital signature.
- Transparently handle critical request processing (i.e., call the transform service and sign the resulting pre-command).
- Return synchronous responses.
- If response is an
I99
(acknowledgement), then store the original request (i.e.msg
object).
The dccboxed-receive
node provides a fully managed interface for receiving
asynchronous DUIS responses from a DCC Boxed instance. This includes:
- Validating the received DUIS response (according to XSD and digital signature).
- Convert XML into JSON.
- If response contains a GBCS payload, decode and decrypt it.
- Attempt to reconcile response with request (i.e. stored
msg
object indccboxed-send
).
The final step of of reconciliation is used so its possible to link asynchronous
responses with the context of the message that triggered the request. For
example, it could link a HTTP request input with its output as the original
msg
object is preserved. The following shows this, where if a user makes a
http request to the /trigger
endpoint, it will start a SRV 4.1.1, and once the
response is obtained it is sent to the http client that make the request to
/trigger
.
Please note, when the msg
object is reconciled it is only shallow copied. E.g.
if there are multiple dccboxed-receive
nodes (see below), each could receive a
copy of the same msg.payload
, resulting in changes by one node in
msg.payload
being observed unexpectedly in a different flow. If a deep copy is
required, this will need to be done in any of the nodes downstream from
dccboxed-receive
.
It is also possible to have multiple dccboxed-receive
nodes. This allows for
responses of different service requests or alerts to be processed by different
parts of the NodeRED flow (or different flows). The following two screen shots
demonstrate this, where the first one only will receive the response to a 4.1.1
service request and the second node will receive all device alerts.
Provides an alternative to the duis-template
node for building ESME (single
element) SRV 1.1.1 commands. Offers a slightly simplified option for specifying
a JSON tariff. For more information about the input of this node see
duis-templates
.
The node comes pre-configured with 3 example tariffs:
TOU (simple)
- A single rate tariff.TOU (complex)
- A TOU tariff with multiple day profiles and special days.Block
- A sample block tariff.
Or alternatively, the tariff can be provided through its input connector.
The above high level nodes automate the sending and receiving of DUIS requests and responses. However, if lower level access to the functional primitives are required this is provided by the following nodes:
duis-construct
- convert a JSON version DUIS into XML.duis-parser
- convert an XML DUIS into JSON.duis-sign
&duis-validate
- validate the input XML against the DUIS. schema and either add XML digital signature, or remove the signature.gbcs-parser
- parse a GBCS message into JSON, includes ability to decrypt (where needed) and validate signatures (where available).gbcs-signer
- adds a signature to a GBCS pre-command, i.e. outputs a signed pre-command.
These blocks are designed to be configurable, and expose many more configuration
options than dccboxed-send
and dccboxed-receive
. For instance, the
gbcs-parser
and gbcs-signer
allows fine grain control over key material used
and the duis-parser
can provide raw view of the parsed XML before it is
processed/enriched.
This project is a thin wrapper/user interface over a handful of other projects. These other projects provide the essential functions required to interface with a DCC Boxed and include:
duis-parser
- TypeScript library that is capable of encoding and decoding DUIS requests and responses.duis-templates
- TypeScript collection of RTDS DUIS templates.dccboxed-signing-tool
- TypeScript/Java application to sign and validate XML signatures required by DCC Boxed.gbcs-parser
- TypeScript library that can decode GBCS messages, validate remote party signatures and sign pre-commands. This library is based on theHenryGiraldo/gbcs-parser-js
parser.dccboxed-keystore
- TypeScript library that stores remote party/organisation certificates and private keys along with the ability to query the SMKI interface on DCC Boxed for device certificates.
These tools are all open source and can easily be reused and assembled into a
tool that interfaces with DCC Boxed as required. See the
dccboxed-config.ts
file for an example of how they
can be tied together into an application.
To build locally, run the following:
npm run build
This will build both the frontend (using webpack
) and backend (using tsc
).
The result will be placed into dist
folder.
You can then use npm pack
or npm link
; afterwards install into the NodeRED
data directory. Typically this will be located at ~/.nodered
.
Contributions are welcome!
When submitting a pull request, please ensure:
- Each PR is concise and provides only one feature/bug fix.
- Currently project does not have a test suit, however it is expected the change is manually tested.
- Bugfixes are reference the GitHub issue.
- If appropriate, update documentation.
- Before committing, run
npm run lint
andnpm run prettier-check
.
If you are planning a new non-trivial feature, please first raise a GitHub issue to discuss it to before investing your time to avoid disappointment.
Any contributions will be expected to be licensable under GPLv3.
Copyright 2022, Smart DCC Limited, All rights reserved. Project is licensed under GPLv3.