import Constants from '../utils/Constants';
import { ErrorType } from '../types/ocpp/ErrorType';
import FileUtils from '../utils/FileUtils';
+import { JsonType } from '../types/JsonType';
import { MessageType } from '../types/ocpp/MessageType';
import OCPP16IncomingRequestService from './ocpp/1.6/OCPP16IncomingRequestService';
import OCPP16RequestService from './ocpp/1.6/OCPP16RequestService';
private async onMessage(data: Data): Promise<void> {
let [messageType, messageId, commandName, commandPayload, errorDetails]: IncomingRequest = [0, '', '' as IncomingRequestCommand, {}, {}];
- let responseCallback: (payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>) => void;
+ let responseCallback: (payload: JsonType | string, requestPayload: JsonType | OCPPError) => void;
let rejectCallback: (error: OCPPError, requestStatistic?: boolean) => void;
let requestCommandName: RequestCommand | IncomingRequestCommand;
- let requestPayload: Record<string, unknown>;
+ let requestPayload: JsonType | OCPPError;
let cachedRequest: CachedRequest;
let errMsg: string;
try {
import BaseError from '../exception/BaseError';
import Configuration from '../utils/Configuration';
import { IncomingMessage } from 'http';
+import { JsonType } from '../types/JsonType';
import UIServiceFactory from './ui-websocket-services/UIServiceFactory';
import Utils from '../utils/Utils';
import logger from '../utils/Logger';
}
}
- public broadcastToClients(message: string | Record<string, unknown>): void {
+ public broadcastToClients(message: string): void {
for (const client of this.clients) {
if (client?.readyState === OPEN) {
client.send(message);
import { DefaultResponse } from '../../../types/ocpp/Responses';
import { ErrorType } from '../../../types/ocpp/ErrorType';
import { IncomingRequestHandler } from '../../../types/ocpp/Requests';
+import { JsonType } from '../../../types/JsonType';
import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus';
import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus';
import { OCPP16StandardParametersKey } from '../../../types/ocpp/1.6/Configuration';
]);
}
- public async handleRequest(messageId: string, commandName: OCPP16IncomingRequestCommand, commandPayload: Record<string, unknown>): Promise<void> {
- let result: Record<string, unknown>;
+ public async handleRequest(messageId: string, commandName: OCPP16IncomingRequestCommand, commandPayload: JsonType): Promise<void> {
+ let result: JsonType;
if (this.chargingStation.isInPendingState()
&& (commandName === OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION || commandName === OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION)) {
throw new OCPPError(ErrorType.SECURITY_ERROR, `${commandName} cannot be issued to handle request payload ${JSON.stringify(commandPayload, null, 2)} while charging station is in pending state`, commandName);
setTimeout(() => {
this.chargingStation.ocppRequestService.sendBootNotification(this.chargingStation.getBootNotificationRequest().chargePointModel,
this.chargingStation.getBootNotificationRequest().chargePointVendor, this.chargingStation.getBootNotificationRequest().chargeBoxSerialNumber,
- this.chargingStation.getBootNotificationRequest().firmwareVersion, null, null, null, null, null, { triggerMessage: true }).catch(() => { /* This is intentional */ });
+ this.chargingStation.getBootNotificationRequest().firmwareVersion, this.chargingStation.getBootNotificationRequest().chargePointSerialNumber,
+ this.chargingStation.getBootNotificationRequest().iccid, this.chargingStation.getBootNotificationRequest().imsi,
+ this.chargingStation.getBootNotificationRequest().meterSerialNumber, this.chargingStation.getBootNotificationRequest().meterType,
+ { triggerMessage: true }).catch(() => { /* This is intentional */ });
}, Constants.OCPP_TRIGGER_MESSAGE_DELAY);
return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
case MessageTrigger.Heartbeat:
import Constants from '../../../utils/Constants';
import { ErrorType } from '../../../types/ocpp/ErrorType';
+import { JsonType } from '../../../types/JsonType';
import MeasurandPerPhaseSampledValueTemplates from '../../../types/MeasurandPerPhaseSampledValueTemplates';
import MeasurandValues from '../../../types/MeasurandValues';
import { MessageType } from '../../../types/ocpp/MessageType';
}
}
- public async sendResult(messageId: string, resultMessageData: Record<string, unknown>, commandName: OCPP16RequestCommand | OCPP16IncomingRequestCommand): Promise<unknown> {
+ public async sendResult(messageId: string, resultMessageData: JsonType, commandName: OCPP16RequestCommand | OCPP16IncomingRequestCommand): Promise<JsonType> {
try {
// Send error
- return await this.sendMessage(messageId, resultMessageData, MessageType.CALL_RESULT_MESSAGE, commandName);
- } catch (err) {
- this.handleRequestError(commandName as OCPP16RequestCommand, err as Error);
+ return await this.sendMessage(messageId, resultMessageData, MessageType.CALL_RESULT_MESSAGE, commandName) as JsonType;
+ } catch (error) {
+ this.handleRequestError(commandName as OCPP16RequestCommand, error as Error);
}
}
- public async sendError(messageId: string, error: OCPPError, commandName: OCPP16RequestCommand | OCPP16IncomingRequestCommand): Promise<unknown> {
+ public async sendError(messageId: string, ocppError: OCPPError, commandName: OCPP16RequestCommand | OCPP16IncomingRequestCommand): Promise<JsonType> {
try {
// Send error
- return await this.sendMessage(messageId, error, MessageType.CALL_ERROR_MESSAGE, commandName);
- } catch (err) {
- this.handleRequestError(commandName as OCPP16RequestCommand, err as Error);
+ return await this.sendMessage(messageId, ocppError, MessageType.CALL_ERROR_MESSAGE, commandName) as JsonType;
+ } catch (error) {
+ this.handleRequestError(commandName as OCPP16RequestCommand, error as Error);
}
}
}
import ChargingStation from '../../ChargingStation';
import { ErrorType } from '../../../types/ocpp/ErrorType';
+import { JsonType } from '../../../types/JsonType';
import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus';
import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
import { OCPP16StandardParametersKey } from '../../../types/ocpp/1.6/Configuration';
]);
}
- public async handleResponse(commandName: OCPP16RequestCommand, payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>): Promise<void> {
+ public async handleResponse(commandName: OCPP16RequestCommand, payload: JsonType | string, requestPayload: JsonType): Promise<void> {
if (this.chargingStation.isRegistered() || commandName === OCPP16RequestCommand.BOOT_NOTIFICATION) {
if (this.responseHandlers.has(commandName)) {
try {
import ChargingStation from '../ChargingStation';
import { IncomingRequestCommand } from '../../types/ocpp/Requests';
+import { JsonType } from '../../types/JsonType';
import logger from '../../utils/Logger';
export default abstract class OCPPIncomingRequestService {
throw error;
}
- public abstract handleRequest(messageId: string, commandName: IncomingRequestCommand, commandPayload: Record<string, unknown>): Promise<void>;
+ public abstract handleRequest(messageId: string, commandName: IncomingRequestCommand, commandPayload: JsonType): Promise<void>;
}
import ChargingStation from '../ChargingStation';
import Constants from '../../utils/Constants';
import { ErrorType } from '../../types/ocpp/ErrorType';
+import { JsonType } from '../../types/JsonType';
import { MessageType } from '../../types/ocpp/MessageType';
import { MeterValue } from '../../types/ocpp/MeterValues';
import OCPPError from '../../exception/OCPPError';
this.ocppResponseService = ocppResponseService;
}
- public async sendMessage(messageId: string, messageData: any, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand,
+ public async sendMessage(messageId: string, messageData: JsonType | OCPPError, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand,
params: SendParams = {
skipBufferingOnError: false,
triggerMessage: false
- }): Promise<unknown> {
+ }): Promise<JsonType | OCPPError | string> {
if (this.chargingStation.isInRejectedState() || (this.chargingStation.isInPendingState() && !params.triggerMessage)) {
throw new OCPPError(ErrorType.SECURITY_ERROR, 'Cannot send command payload if the charging station is not in accepted state', commandName);
} else if (this.chargingStation.isInAcceptedState() || (this.chargingStation.isInPendingState() && params.triggerMessage)) {
} else if (!params.skipBufferingOnError) {
// Buffer it
this.chargingStation.bufferMessage(messageToSend);
- const ocppError = new OCPPError(ErrorType.GENERIC_ERROR, `WebSocket closed for buffered message id '${messageId}' with content '${messageToSend}'`, messageData?.details ?? {});
+ const ocppError = new OCPPError(ErrorType.GENERIC_ERROR, `WebSocket closed for buffered message id '${messageId}' with content '${messageToSend}'`, commandName, messageData?.details as JsonType ?? {});
if (messageType === MessageType.CALL_MESSAGE) {
// Reject it but keep the request in the cache
return reject(ocppError);
return rejectCallback(ocppError, false);
} else {
// Reject it
- return rejectCallback(new OCPPError(ErrorType.GENERIC_ERROR, `WebSocket closed for non buffered message id '${messageId}' with content '${messageToSend}'`, messageData?.details ?? {}), false);
+ return rejectCallback(new OCPPError(ErrorType.GENERIC_ERROR, `WebSocket closed for non buffered message id '${messageId}' with content '${messageToSend}'`, commandName, messageData?.details as JsonType ?? {}), false);
}
// Response?
if (messageType !== MessageType.CALL_MESSAGE) {
* @param payload
* @param requestPayload
*/
- async function responseCallback(payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>): Promise<void> {
+ async function responseCallback(payload: JsonType | string, requestPayload: JsonType): Promise<void> {
if (self.chargingStation.getEnableStatistics()) {
self.chargingStation.performanceStatistics.addRequestStatistic(commandName, MessageType.CALL_RESULT_MESSAGE);
}
self.chargingStation.requests.delete(messageId);
reject(error);
}
- }), Constants.OCPP_WEBSOCKET_TIMEOUT, new OCPPError(ErrorType.GENERIC_ERROR, `Timeout for message id '${messageId}'`, messageData?.details ?? {}), () => {
+ }), Constants.OCPP_WEBSOCKET_TIMEOUT, new OCPPError(ErrorType.GENERIC_ERROR, `Timeout for message id '${messageId}'`, commandName, messageData?.details as JsonType ?? {}), () => {
messageType === MessageType.CALL_MESSAGE && this.chargingStation.requests.delete(messageId);
});
} else {
throw error;
}
- private buildMessageToSend(messageId: string, messageData: Record<string, unknown>, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand,
- responseCallback: (payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>) => Promise<void>,
+ private buildMessageToSend(messageId: string, messageData: JsonType | OCPPError, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand,
+ responseCallback: (payload: JsonType | string, requestPayload: JsonType) => Promise<void>,
rejectCallback: (error: OCPPError, requestStatistic?: boolean) => void): string {
let messageToSend: string;
// Type of message
public abstract sendTransactionBeginMeterValues(connectorId: number, transactionId: number, beginMeterValue: MeterValue): Promise<void>;
public abstract sendTransactionEndMeterValues(connectorId: number, transactionId: number, endMeterValue: MeterValue): Promise<void>;
public abstract sendDiagnosticsStatusNotification(diagnosticsStatus: DiagnosticsStatus): Promise<void>;
- public abstract sendResult(messageId: string, resultMessageData: Record<string, unknown>, commandName: RequestCommand | IncomingRequestCommand): Promise<unknown>;
- public abstract sendError(messageId: string, error: OCPPError, commandName: RequestCommand | IncomingRequestCommand): Promise<unknown>;
+ public abstract sendResult(messageId: string, resultMessageData: JsonType, commandName: RequestCommand | IncomingRequestCommand): Promise<JsonType>;
+ public abstract sendError(messageId: string, error: OCPPError, commandName: RequestCommand | IncomingRequestCommand): Promise<JsonType>;
}
import ChargingStation from '../ChargingStation';
+import { JsonType } from '../../types/JsonType';
import { RequestCommand } from '../../types/ocpp/Requests';
export default abstract class OCPPResponseService {
this.chargingStation = chargingStation;
}
- public abstract handleResponse(commandName: RequestCommand, payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>): Promise<void>;
+ public abstract handleResponse(commandName: RequestCommand, payload: JsonType | string, requestPayload: JsonType): Promise<void>;
}
import { ProtocolCommand, ProtocolRequestHandler } from '../../types/UIProtocol';
import BaseError from '../../exception/BaseError';
+import { JsonType } from '../../types/JsonType';
import UIWebSocketServer from '../UIWebSocketServer';
import logger from '../../utils/Logger';
]);
}
- public async handleMessage(command: ProtocolCommand, payload: Record<string, unknown>): Promise<void> {
- let messageResponse: Record<string, unknown>;
+ public async handleMessage(command: ProtocolCommand, payload: JsonType): Promise<void> {
+ let messageResponse: JsonType;
if (this.messageHandlers.has(command)) {
try {
// Call the method to build the message response
- messageResponse = await this.messageHandlers.get(command)(payload) as Record<string, unknown>;
+ messageResponse = await this.messageHandlers.get(command)(payload) as JsonType;
} catch (error) {
// Log
logger.error(this.uiWebSocketServer.logPrefix() + ' Handle message error: %j', error);
protected buildProtocolMessage(
command: ProtocolCommand,
- payload: Record<string, unknown>,
+ payload: JsonType,
): string {
return JSON.stringify([command, payload]);
}
import { ProtocolCommand, ProtocolRequestHandler } from '../../types/UIProtocol';
import AbstractUIService from './AbstractUIService';
+import { JsonType } from '../../types/JsonType';
import UIWebSocketServer from '../UIWebSocketServer';
export default class UIService001 extends AbstractUIService {
this.messageHandlers.set(ProtocolCommand.STOP_TRANSACTION, this.handleStopTransaction.bind(this) as ProtocolRequestHandler);
}
- private handleStartTransaction(payload: Record<string, unknown>): void { }
- private handleStopTransaction(payload: Record<string, unknown>): void { }
+ private handleStartTransaction(payload: JsonType): void { }
+ private handleStopTransaction(payload: JsonType): void { }
}
import BaseError from './BaseError';
import { ErrorType } from '../types/ocpp/ErrorType';
+import { JsonType } from '../types/JsonType';
export default class OCPPError extends BaseError {
code: ErrorType | IncomingRequestCommand;
command?: RequestCommand | IncomingRequestCommand;
- details?: Record<string, unknown>;
+ details?: JsonType;
- constructor(code: ErrorType | IncomingRequestCommand, message: string, command?: RequestCommand | IncomingRequestCommand, details?: Record<string, unknown>) {
+ constructor(code: ErrorType | IncomingRequestCommand, message: string, command?: RequestCommand | IncomingRequestCommand, details?: JsonType) {
super(message);
this.code = code ?? ErrorType.GENERIC_ERROR;
+import { JsonType } from './JsonType';
+
export enum Protocol {
UI = 'ui',
}
UNKNOWN = 'unknown',
}
-export type ProtocolRequest = [ProtocolCommand, Record<string, unknown>];
+export type ProtocolRequest = [ProtocolCommand, JsonType];
-export type ProtocolRequestHandler = (payload: Record<string, unknown>) => void | Promise<void> | Record<string, unknown> | Promise<Record<string, unknown>>;
+export type ProtocolRequestHandler = (payload: JsonType) => void | Promise<void> | JsonType | Promise<JsonType>;
import { OCPP16AvailabilityType, OCPP16BootNotificationRequest, OCPP16IncomingRequestCommand, OCPP16RequestCommand } from './1.6/Requests';
+import { JsonType } from '../JsonType';
import { MessageType } from './MessageType';
import { OCPP16DiagnosticsStatus } from './1.6/DiagnosticsStatus';
import OCPPError from '../../exception/OCPPError';
triggerMessage?: boolean
}
-export type IncomingRequestHandler = (commandPayload: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;
+export type IncomingRequestHandler = (commandPayload: JsonType) => JsonType | Promise<JsonType>;
export type BootNotificationRequest = OCPP16BootNotificationRequest;
...OCPP16DiagnosticsStatus
};
-export type Request = [MessageType, string, RequestCommand, Record<string, unknown>, Record<string, unknown>];
+export type Request = [MessageType, string, RequestCommand, JsonType, JsonType];
-export type IncomingRequest = [MessageType, string, IncomingRequestCommand, Record<string, unknown>, Record<string, unknown>];
+export type IncomingRequest = [MessageType, string, IncomingRequestCommand, JsonType, JsonType];
-export type CachedRequest = [(payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>) => void, (error: OCPPError, requestStatistic?: boolean) => void, RequestCommand | IncomingRequestCommand, Record<string, unknown>];
+export type CachedRequest = [(payload: JsonType, requestPayload: JsonType) => void, (error: OCPPError, requestStatistic?: boolean) => void, RequestCommand | IncomingRequestCommand, JsonType | OCPPError];
import { OCPP16AvailabilityStatus, OCPP16BootNotificationResponse, OCPP16ChargingProfileStatus, OCPP16ClearChargingProfileStatus, OCPP16ConfigurationStatus, OCPP16RegistrationStatus, OCPP16TriggerMessageStatus, OCPP16UnlockStatus } from './1.6/Responses';
-export type ResponseHandler = (payload: Record<string, unknown> | string, requestPayload?: Record<string, unknown>) => void | Promise<void>;
+import { JsonType } from '../JsonType';
+
+export type ResponseHandler = (payload: JsonType | string, requestPayload?: JsonType) => void | Promise<void>;
export type BootNotificationResponse = OCPP16BootNotificationResponse;