0.2.1 • Published 2 months ago

typed-ocpp v0.2.1

Weekly downloads
-
License
MIT
Repository
github
Last release
2 months ago

Typed OCPP

A library for type-aware parsing, serialization and validation of OCPP 1.6-J messages.

Usage

OCPP namespace

This library exports all functions and typings under the OCPP namespace:

import { OCPP } from 'typed-ocpp';

OCPP.setAjv()

This library requires an instance of Ajv with support for string formats, as provided by the ajv-formats plugin. See https://npm.im/ajv and https://npm.im/ajv-formats.

import Ajv from 'ajv';
import formats from 'ajv-formats';
import { OCPP } from 'typed-ocpp';

OCPP.setAjv(formats(new Ajv()));

OCPP.parse()

The OCPP.parse() function returns a fully-typed and validated "view" of the original array. No additional transformation is applied beside the eventual JSON.parse() if a string is provided.

import { OCPP } from 'typed-ocpp';

const raw = '[2,"test","BootNotification",{"chargePointModel":"model","chargePointVendor":"vendor"}]';
const parsed = OCPP.parse(raw);

Array.isArray(parsed); // true

Values returned by the OCPP.parse() function have one of the following types:

OCPP.Call                 // union of all types for Call messages
OCPP.CallError            // type for Call Error messages
OCPP.UncheckedCallResult  // generic type for Call Result messages

As the result is fully-typed, the TS compiler can use known types to infer others:

if (parsed[0] === OCPP.MessageType.CALL) {
  parsed[2];                                        // TS gives type "OCPP.Action"          
  if (parsed[2] === OCPP.Action.BootNotification) {
    // TS infers the shape of the call payload based on the action
    parsed[3].chargePointModel;                     // TS gives type "string"
    parsed[3].randomProp;                           // TS compilation error
  }
}

OCPP.checkCallResult()

Call Result messages are first returned as having type OCPP.UncheckedCallResult by OCPP.parse() and must be checked against their originating OCPP.Call objects for further validation and type-awareness.

If OCPP.checkCallResult() does not throw, the resulting object is guaranteed to be a valid OCPP.CallResult object matching the provided OCPP.Call object. While the OCPP.CallResult type is the union of all Call Result message types, the TS compiler will infer the specific type of Call Result based on the action of the provided OCPP.Call:

const call = '[2,"test","BootNotification",{"chargePointModel":"model","chargePointVendor":"vendor"}]';
const result = '[3, "test", { status: "Accepted", currentTime: "1970-01-01T00:00:00.000Z", interval: 10 }]';

const parsedCall = OCPP.parse(call);
const parsedResult = OCPP.parse(result);

if (parsedCall[0] === OCPP.MessageType.CALL && parsedResult[0] === OCPP.MessageType.CALLRESULT) {
  if (parsedCall[2] === OCPP.Action.BootNotification) {
    const checkedResult = OCPP.checkCallResult(parsedResult, parsedCall);
    checkedResult[2].status;        // TS gives type "Accepted"|"Pending"|"Rejected"
  }
}

OCPP.stringify()

Returns the JSON serialization of the provided OCPP object.

const serialized = OCPP.stringify(parsed);

Types

Within the OCPP namespace, typed-ocpp exports a set of typings that covers all aspects of OCPP payloads.

We've already mentioned the primary types returned by OCPP.parse() and OCPP.checkCallResult():

OCPP.Call                 // union type of all Call message types
OCPP.CallResult           // union type of all Call Result message types
OCPP.CallError            // type of Call Error messages
OCPP.UncheckedCallResult  // type of unchecked Call Result messages

Specific types for Call and Call Result messages use the Call and CallResult suffixes: OCPP.AuthorizeCall, OCPP.AuthorizeCallResult,
OCPP.MeterValuesCall, OCPP.MeterValuesCallResult and so on.

The following enumerations are used within these primary types:

OCPP.MessageType          // enum of message types (CALL = 2, CALLRESULT = 3, CALLERROR = 4)
OCPP.Action               // enum of actions in Call messages ("Authorize", "BootNotification", ...)
OCPP.ErrorCode            // enum of error code in Call Error messages ("NotImplemented", "NotSupported", ...)

Additionally, the following types are used to model value descriptors within MeterValues Call messages:

OCPP.Context              // sampling context ("Transaction.Begin", "Sample.Periodic", ...)
OCPP.Measurand            // value measurand ("Power.Active.Import", "Frequency", ...)
OCPP.Phase                // AC phase ("L1", "L2", "L1-N", ...)
OCPP.Location             // sampling location ("Inlet", "Outlet", ...)
OCPP.Unit                 // value unit ("Wh", "kWh", ...)
OCPP.Format               // value format ("Raw" or "SignedData")
OCPP.SampledValue         // individual entry of the "sampledValue" array
OCPP.MeterValue           // individual entry of the "meterValue" array

JSON Schema(s)

typed-ocpp ships with a complete collection of JSON Schema objects, used for validation within OCPP.parse(). Schemas can be directly imported as follows:

import { AuthorizeSchema } from 'typed-ocpp/dist/schemas/Authorize.js';

Testing

Requires node >= 18.17.

npm test

License

MIT. See LICENSE file.