Typed OCPP unit tests
MODIFY
src/types/ChargingStation.ts
src/types/ChargingStation.ts
@@ -90,7 +90,7 @@ export enum StaticLimitAmps {
export interface Connector {
id?: string;
connectorId: number;
- currentInstantWatts: number;
+ currentInstantWatts?: number;
currentStateOfCharge?: number;
currentTotalConsumptionWh?: number;
currentTotalInactivitySecs?: number;
@@ -102,8 +102,8 @@ export interface Connector {
errorCode?: string;
info?: string;
vendorErrorCode?: string;
- power: number;
- type: ConnectorType;
+ power?: number;
+ type?: ConnectorType;
voltage?: Voltage;
amperage?: number;
amperageLimit?: number;

MODIFY
src/types/ocpp/OCPPServer.ts
src/types/ocpp/OCPPServer.ts
@@ -51,11 +51,11 @@ export enum RegistrationStatus {
export interface OCPPStatusNotificationRequest {
connectorId: number;
errorCode: ChargePointErrorCode;
- info: string;
+ info?: string;
status: ChargePointStatus;
timestamp: string;
- vendorId: string;
- vendorErrorCode: string;
+ vendorId?: string;
+ vendorErrorCode?: string;
}
export interface OCPPStatusNotificationRequestExtended extends OCPPStatusNotificationRequest {

MODIFY
test/api/OCPPCommonTests.ts
test/api/OCPPCommonTests.ts
+import { ChargePointErrorCode, ChargePointStatus, OCPPStatusNotificationRequest } from '../../src/types/ocpp/OCPPServer';
+import Transaction, { InactivityStatus } from '../../src/types/Transaction';
import chai, { expect } from 'chai';
import CentralServerService from './client/CentralServerService';
import ChargingStationContext from './context/ChargingStationContext';
import Factory from '../factories/Factory';
-import { InactivityStatus } from '../../src/types/Transaction';
import { PricingSettingsType } from '../../src/types/Setting';
import TenantContext from './context/TenantContext';
import User from '../../src/types/User';
@@ -26,26 +27,27 @@ export default class OCPPCommonTests {
public currentPricingSetting;
public priceKWH = 2;
- public chargingStationConnector1: any;
- public chargingStationConnector2: any;
+ public chargingStationConnector1: OCPPStatusNotificationRequest;
+ public chargingStationConnector2: OCPPStatusNotificationRequest;
public transactionStartUser: User;
public transactionStartUserService: CentralServerService;
public transactionStopUser: User;
- public transactionStartMeterValue: any;
- public transactionStartSoC: any;
- public energyActiveImportMeterValues: any;
- public socMeterValues: any;
- public transactionSignedData: any;
- public transactionEndSignedData: any;
- public meterValueIntervalSecs: any;
- public transactionStartTime: any;
- public transactionTotalConsumptionWh: any;
- public energyActiveImportFinalMeterValue: any;
- public socFinalMeterValue: any;
- public transactionTotalInactivitySecs: any;
- public totalPrice: any;
- public newTransaction: any;
- public transactionCurrentTime: any;
+ public transactionStartMeterValue: number;
+ public transactionStartSoC: number;
+ public energyActiveImportMeterValues: number[];
+ public powerMeterValues: number[];
+ public socMeterValues: number[];
+ public transactionSignedData: string;
+ public transactionEndSignedData: string;
+ public meterValueIntervalSecs: number;
+ public transactionStartTime: Date;
+ public transactionTotalConsumptionWh: number;
+ public energyActiveImportFinalMeterValue: number;
+ public socFinalMeterValue: number;
+ public transactionTotalInactivitySecs: number;
+ public totalPrice: number;
+ public newTransaction: Transaction;
+ public transactionCurrentTime: Date;
public createAnyUser = false;
public numberTag: number;
@@ -106,18 +108,19 @@ export default class OCPPCommonTests {
// Default Connector values
this.chargingStationConnector1 = {
connectorId: 1,
- status: 'Available',
- errorCode: 'NoError',
+ status: ChargePointStatus.AVAILABLE,
+ errorCode: ChargePointErrorCode.NO_ERROR,
timestamp: new Date().toISOString()
};
this.chargingStationConnector2 = {
connectorId: 2,
- status: 'Available',
- errorCode: 'NoError',
+ status: ChargePointStatus.AVAILABLE,
+ errorCode: ChargePointErrorCode.NO_ERROR,
timestamp: new Date().toISOString()
};
// Set meter value start
this.transactionStartMeterValue = 0;
+ this.meterValueIntervalSecs = 60;
this.transactionSignedData = '<?xml version=\"1.0\" encoding=\"UTF-8\" ?><signedMeterValue> <publicKey encoding=\"base64\">8Y5UzWD+TZeMKBDkKLpHhwzSfGsnCvo00ndCXv/LVRD5pAVtRZEA49bqpr/DY3KL</publicKey> <meterValueSignature encoding=\"base64\">wQdZJR1CLRe+QhS3C+kHpkfVL4hqPhc8YIt/+4uHBBb9N6JNygltdEhYufTfaM++AJ8=</meterValueSignature> <signatureMethod>ECDSA192SHA256</signatureMethod> <encodingMethod>EDL</encodingMethod> <encodedMeterValue encoding=\"base64\">CQFFTUgAAH+eoQxVP10I4Zf9ACcAAAABAAERAP8e/5KqWwEAAAAAAJ9sYQoCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtVP10AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</encodedMeterValue></signedMeterValue>';
this.transactionEndSignedData = '<?xml version=\"1.0\" encoding=\"UTF-8\" ?><signedMeterValue> <publicKey encoding=\"base64\">8Y5UzWD+TZeMKBDkKLpHhwzSfGsnCvo00ndCXv/LVRD5pAVtRZEA49bqpr/DY3KL</publicKey> <meterValueSignature encoding=\"base64\">GChPf/f+0Rw6DDWI0mujec6dOMDqm5cuCLXdEVV6MRua6OVqcHNP85q7K70tRPJKAJ8=</meterValueSignature> <signatureMethod>ECDSA192SHA256</signatureMethod> <encodingMethod>EDL</encodingMethod> <encodedMeterValue encoding=\"base64\">CQFFTUgAAH+eodYDQF0IrEb+ACgAAAABAAERAP8e/8OtYQEAAAAAAJ9sYQoCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtVP10AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</encodedMeterValue></signedMeterValue>';
// Energy Import Meter Value (14 values)
@@ -131,9 +134,18 @@ export default class OCPPCommonTests {
max: 90
})).concat([8, 8, 98, 99, 100, 100]).sort((a, b) => (a - b));
this.transactionStartSoC = this.socMeterValues[0];
+ // Power Import (14 values)
+ this.powerMeterValues = [];
+ for (let i = 0; i < this.energyActiveImportMeterValues.length; i++) {
+ this.powerMeterValues.push(
+ this.energyActiveImportMeterValues[i] * (3600 / this.meterValueIntervalSecs));
+ }
+ console.log('====================================');
+ console.log(this.energyActiveImportMeterValues);
+ console.log(this.powerMeterValues);
+ console.log('====================================');
// Meter Values params
- this.meterValueIntervalSecs = 60;
- this.transactionStartTime = moment().subtract(this.energyActiveImportMeterValues.length * this.meterValueIntervalSecs + 1, 'seconds');
+ this.transactionStartTime = moment().subtract(this.energyActiveImportMeterValues.length * this.meterValueIntervalSecs + 1, 'seconds').toDate();
this.transactionTotalConsumptionWh = this.energyActiveImportMeterValues.reduce((sum, meterValue) => sum + meterValue);
this.energyActiveImportFinalMeterValue = this.transactionStartMeterValue + this.transactionTotalConsumptionWh;
this.socFinalMeterValue = this.socMeterValues[this.socMeterValues.length - 1];
@@ -164,6 +176,7 @@ export default class OCPPCommonTests {
await this.centralUserService.settingApi.update(this.currentPricingSetting);
}
if (this.createdUsers && Array.isArray(this.createdUsers)) {
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
this.createdUsers.forEach(async (user) => {
await this.centralUserService.deleteEntity(
this.centralUserService.userApi, user);
@@ -198,7 +211,7 @@ export default class OCPPCommonTests {
public async testChangeConnectorStatus() {
// Set it to Occupied
- this.chargingStationConnector1.status = 'Occupied';
+ this.chargingStationConnector1.status = ChargePointStatus.OCCUPIED;
this.chargingStationConnector1.timestamp = new Date().toISOString();
// Update
let response = await this.chargingStationContext.setConnectorStatus(this.chargingStationConnector1);
@@ -222,7 +235,7 @@ export default class OCPPCommonTests {
errorCode: this.chargingStationConnector2.errorCode
});
// Reset Status of Connector 1
- this.chargingStationConnector1.status = 'Available';
+ this.chargingStationConnector1.status = ChargePointStatus.AVAILABLE;
this.chargingStationConnector1.timestamp = new Date().toISOString();
// Update
response = await this.chargingStationContext.setConnectorStatus(this.chargingStationConnector1);
@@ -300,6 +313,7 @@ export default class OCPPCommonTests {
this.transactionStartTime
);
if (validTransaction) {
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
const transactionId = response.data.transactionId;
await this.validateStartedTransaction(
@@ -329,7 +343,7 @@ export default class OCPPCommonTests {
expect(this.newTransaction).to.not.be.null;
// Set
const transactionId = this.newTransaction.id;
- this.transactionStartTime = moment().subtract(1, 'h');
+ this.transactionStartTime = moment().subtract(1, 'h').toDate();
// Clear old one
this.newTransaction = null;
// Start the 2nd Transaction
@@ -356,13 +370,13 @@ export default class OCPPCommonTests {
// Check on Transaction
expect(this.newTransaction).to.not.be.null;
// Current Time matches Transaction one
- this.transactionCurrentTime = moment(this.newTransaction.timestamp);
+ this.transactionCurrentTime = moment(this.newTransaction.timestamp).toDate();
// Start Meter Value matches Transaction one
let transactionCurrentMeterValue = this.transactionStartMeterValue;
// Send Transaction.Begin
let response = await this.chargingStationContext.sendBeginMeterValue(
this.newTransaction.connectorId,
- this.newTransaction.transactionId,
+ this.newTransaction.id,
transactionCurrentMeterValue,
this.transactionStartSoC,
this.transactionSignedData,
@@ -379,11 +393,11 @@ export default class OCPPCommonTests {
// Set new meter value
transactionCurrentMeterValue += this.energyActiveImportMeterValues[index];
// Add time
- this.transactionCurrentTime.add(this.meterValueIntervalSecs, 's');
+ this.transactionCurrentTime = moment(this.transactionCurrentTime).add(this.meterValueIntervalSecs, 's').toDate();
// Send consumption meter value
response = await this.chargingStationContext.sendConsumptionMeterValue(
this.newTransaction.connectorId,
- this.newTransaction.transactionId,
+ this.newTransaction.id,
transactionCurrentMeterValue,
this.transactionCurrentTime,
withSoC,
@@ -408,7 +422,7 @@ export default class OCPPCommonTests {
// Send Transaction.End
response = await this.chargingStationContext.sendEndMeterValue(
this.newTransaction.connectorId,
- this.newTransaction.transactionId,
+ this.newTransaction.id,
this.energyActiveImportFinalMeterValue,
this.socFinalMeterValue,
this.transactionEndSignedData,
@@ -437,7 +451,7 @@ export default class OCPPCommonTests {
expect(this.transactionCurrentTime).to.not.be.null;
// Set end time
- this.transactionCurrentTime.add(this.meterValueIntervalSecs, 's');
+ this.transactionCurrentTime = moment(this.transactionCurrentTime).add(this.meterValueIntervalSecs, 's').toDate();
// Stop the Transaction
let response = await this.chargingStationContext.stopTransaction(this.newTransaction.id, this.transactionStopUser.tags[0].id, this.energyActiveImportFinalMeterValue, this.transactionCurrentTime);
@@ -446,7 +460,7 @@ export default class OCPPCommonTests {
expect(response.data.idTagInfo.status).to.equal('Accepted');
// Set the connector to Available
- this.chargingStationConnector1.status = 'Available';
+ this.chargingStationConnector1.status = ChargePointStatus.AVAILABLE;
this.chargingStationConnector1.timestamp = new Date().toISOString();
// Update
response = await this.chargingStationContext.setConnectorStatus(this.chargingStationConnector1);
@@ -565,8 +579,8 @@ export default class OCPPCommonTests {
const transactionId = this.newTransaction.id;
expect(transactionId).to.not.equal(0);
- this.chargingStationConnector1.status = 'Available';
- this.chargingStationConnector1.errorCode = 'NoError';
+ this.chargingStationConnector1.status = ChargePointStatus.AVAILABLE;
+ this.chargingStationConnector1.errorCode = ChargePointErrorCode.NO_ERROR;
this.chargingStationConnector1.timestamp = new Date().toISOString();
// Update Status of Connector 1
let response = await this.chargingStationContext.setConnectorStatus(this.chargingStationConnector1);
@@ -587,7 +601,7 @@ export default class OCPPCommonTests {
});
// Check Transaction
this.newTransaction = (await this.centralUserService.transactionApi.readById(transactionId)).data;
- expect(this.newTransaction.message).to.contain('does not exist');
+ expect(this.newTransaction['message']).to.contain('does not exist');
}
public async testAuthorizeTagAsInteger() {
@@ -625,6 +639,7 @@ export default class OCPPCommonTests {
0,
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
response = await this.chargingStationContext.startTransaction(
this.chargingStationConnector1.connectorId,
@@ -632,6 +647,7 @@ export default class OCPPCommonTests {
0,
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
}
@@ -642,6 +658,7 @@ export default class OCPPCommonTests {
0,
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
}
@@ -652,6 +669,7 @@ export default class OCPPCommonTests {
'0',
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
}
@@ -662,6 +680,7 @@ export default class OCPPCommonTests {
faker.random.number(100000),
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
}
@@ -738,6 +757,7 @@ export default class OCPPCommonTests {
response = await this.chargingStationContext.startTransaction(
this.chargingStationConnector1.connectorId,
this.numberTag.toString(),
+ // eslint-disable-next-line no-undefined
undefined,
this.transactionStartTime
);
@@ -751,9 +771,10 @@ export default class OCPPCommonTests {
this.transactionStartMeterValue,
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
const transactionId = response.data.transactionId;
- this.transactionCurrentTime = moment();
+ this.transactionCurrentTime = moment().toDate();
const stopValue = this.transactionStartMeterValue + faker.random.number(100000);
response = await this.chargingStationContext.stopTransaction(transactionId, this.numberTag.toString(), stopValue, this.transactionCurrentTime);
expect(response.data).to.have.property('idTagInfo');
@@ -767,9 +788,10 @@ export default class OCPPCommonTests {
this.transactionStartMeterValue,
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
const transactionId = response.data.transactionId;
- this.transactionCurrentTime = moment();
+ this.transactionCurrentTime = moment().toDate();
const stopValue = this.transactionStartMeterValue + faker.random.number(100000);
let transactionData;
if (this.chargingStationContext.getChargingStation().ocppVersion === '1.6') {
@@ -845,9 +867,10 @@ export default class OCPPCommonTests {
this.transactionStartMeterValue,
this.transactionStartTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
const transactionId = response.data.transactionId;
- this.transactionCurrentTime = moment();
+ this.transactionCurrentTime = moment().toDate();
const stopValue = this.transactionStartMeterValue + faker.random.number(100000);
let transactionData;
// Provide TransactionData for wrong OCPP Version
@@ -957,6 +980,7 @@ export default class OCPPCommonTests {
meterValue,
currentTime
);
+ // eslint-disable-next-line @typescript-eslint/unbound-method
expect(response).to.be.transactionValid;
const transactionId = response.data.transactionId;
response = await this.chargingStationContext.sendConsumptionMeterValue(

Typed OCPP unit tests