import Configuration from '../utils/Configuration';
import Constants from '../utils/Constants';
import ElectricUtils from '../utils/ElectricUtils';
+import { ErrorType } from '../types/ocpp/ErrorType';
import MeasurandValues from '../types/MeasurandValues';
+import { MessageType } from '../types/ocpp/MessageType';
import OCPPError from './OcppError';
import Statistics from '../utils/Statistics';
import Utils from '../utils/Utils';
// Check the Type of message
switch (messageType) {
// Incoming Message
- case Constants.OCPP_JSON_CALL_MESSAGE:
+ case MessageType.CALL_MESSAGE:
if (this.getEnableStatistics()) {
this._statistics.addMessage(commandName, messageType);
}
await this.handleRequest(messageId, commandName, commandPayload);
break;
// Outcome Message
- case Constants.OCPP_JSON_CALL_RESULT_MESSAGE:
+ case MessageType.CALL_RESULT_MESSAGE:
// Respond
// eslint-disable-next-line no-case-declarations
let responseCallback; let requestPayload;
responseCallback(commandName, requestPayload);
break;
// Error Message
- case Constants.OCPP_JSON_CALL_ERROR_MESSAGE:
+ case MessageType.CALL_ERROR_MESSAGE:
if (!this._requests[messageId]) {
// Error
throw new Error(`Error request for unknown message id ${messageId}`);
// Log
logger.error('%s Incoming message %j processing error %s on request content type %s', this._logPrefix(), messageEvent, error, this._requests[messageId]);
// Send error
- messageType !== Constants.OCPP_JSON_CALL_ERROR_MESSAGE && await this.sendError(messageId, error, commandName);
+ messageType !== MessageType.CALL_ERROR_MESSAGE && await this.sendError(messageId, error, commandName);
}
}
async sendHeartbeat(): Promise<void> {
try {
const payload: HeartbeatRequest = {};
- await this.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'Heartbeat');
+ await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'Heartbeat');
} catch (error) {
logger.error(this._logPrefix() + ' Send Heartbeat error: %j', error);
throw error;
async sendBootNotification(): Promise<BootNotificationResponse> {
try {
- return await this.sendMessage(Utils.generateUUID(), this._bootNotificationRequest, Constants.OCPP_JSON_CALL_MESSAGE, 'BootNotification') as BootNotificationResponse;
+ return await this.sendMessage(Utils.generateUUID(), this._bootNotificationRequest, MessageType.CALL_MESSAGE, 'BootNotification') as BootNotificationResponse;
} catch (error) {
logger.error(this._logPrefix() + ' Send BootNotification error: %j', error);
throw error;
errorCode,
status,
};
- await this.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'StatusNotification');
+ await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'StatusNotification');
} catch (error) {
logger.error(this._logPrefix() + ' Send StatusNotification error: %j', error);
throw error;
meterStart: 0,
timestamp: new Date().toISOString(),
};
- return await this.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'StartTransaction') as StartTransactionResponse;
+ return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'StartTransaction') as StartTransactionResponse;
} catch (error) {
logger.error(this._logPrefix() + ' Send StartTransaction error: %j', error);
throw error;
timestamp: new Date().toISOString(),
...reason && { reason },
};
- return await this.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'StopTransaction') as StartTransactionResponse;
+ return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'StopTransaction') as StartTransactionResponse;
} catch (error) {
logger.error(this._logPrefix() + ' Send StopTransaction error: %j', error);
throw error;
transactionId: self.getConnector(connectorId).transactionId,
meterValue: meterValue,
};
- await self.sendMessage(Utils.generateUUID(), payload, Constants.OCPP_JSON_CALL_MESSAGE, 'MeterValues');
+ await self.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'MeterValues');
} catch (error) {
logger.error(self._logPrefix() + ' Send MeterValues error: %j', error);
throw error;
async sendError(messageId: string, err: Error | OCPPError, commandName: string): Promise<unknown> {
// Check exception type: only OCPP error are accepted
- const error = err instanceof OCPPError ? err : new OCPPError(Constants.OCPP_ERROR_INTERNAL_ERROR, err.message, err.stack && err.stack);
+ const error = err instanceof OCPPError ? err : new OCPPError(ErrorType.INTERNAL_ERROR, err.message, err.stack && err.stack);
// Send error
- return this.sendMessage(messageId, error, Constants.OCPP_JSON_CALL_ERROR_MESSAGE, commandName);
+ return this.sendMessage(messageId, error, MessageType.CALL_ERROR_MESSAGE, commandName);
}
- async sendMessage(messageId: string, commandParams, messageType = Constants.OCPP_JSON_CALL_RESULT_MESSAGE, commandName: string): Promise<any> {
+ async sendMessage(messageId: string, commandParams, messageType = MessageType.CALL_RESULT_MESSAGE, commandName: string): Promise<any> {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
// Send a message through wsConnection
// Type of message
switch (messageType) {
// Request
- case Constants.OCPP_JSON_CALL_MESSAGE:
+ case MessageType.CALL_MESSAGE:
// Build request
this._requests[messageId] = [responseCallback, rejectCallback, commandParams];
messageToSend = JSON.stringify([messageType, messageId, commandName, commandParams]);
break;
// Response
- case Constants.OCPP_JSON_CALL_RESULT_MESSAGE:
+ case MessageType.CALL_RESULT_MESSAGE:
// Build response
messageToSend = JSON.stringify([messageType, messageId, commandParams]);
break;
// Error Message
- case Constants.OCPP_JSON_CALL_ERROR_MESSAGE:
+ case MessageType.CALL_ERROR_MESSAGE:
// Build Error Message
- messageToSend = JSON.stringify([messageType, messageId, commandParams.code ? commandParams.code : Constants.OCPP_ERROR_GENERIC_ERROR, commandParams.message ? commandParams.message : '', commandParams.details ? commandParams.details : {}]);
+ messageToSend = JSON.stringify([messageType, messageId, commandParams.code ? commandParams.code : ErrorType.GENERIC_ERROR, commandParams.message ? commandParams.message : '', commandParams.details ? commandParams.details : {}]);
break;
}
// Check if wsConnection opened and charging station registered
this._messageQueue.push(messageToSend);
}
// Reject it
- return rejectCallback(new OCPPError(commandParams.code ? commandParams.code : Constants.OCPP_ERROR_GENERIC_ERROR, commandParams.message ? commandParams.message : `WebSocket closed for message id '${messageId}' with content '${messageToSend}', message buffered`, commandParams.details ? commandParams.details : {}));
+ return rejectCallback(new OCPPError(commandParams.code ? commandParams.code : ErrorType.GENERIC_ERROR, commandParams.message ? commandParams.message : `WebSocket closed for message id '${messageId}' with content '${messageToSend}', message buffered`, commandParams.details ? commandParams.details : {}));
}
// Response?
- if (messageType === Constants.OCPP_JSON_CALL_RESULT_MESSAGE) {
+ if (messageType === MessageType.CALL_RESULT_MESSAGE) {
// Yes: send Ok
resolve();
- } else if (messageType === Constants.OCPP_JSON_CALL_ERROR_MESSAGE) {
+ } else if (messageType === MessageType.CALL_ERROR_MESSAGE) {
// Send timeout
- setTimeout(() => rejectCallback(new OCPPError(commandParams.code ? commandParams.code : Constants.OCPP_ERROR_GENERIC_ERROR, commandParams.message ? commandParams.message : `Timeout for message id '${messageId}' with content '${messageToSend}'`, commandParams.details ? commandParams.details : {})), Constants.OCPP_SOCKET_TIMEOUT);
+ setTimeout(() => rejectCallback(new OCPPError(commandParams.code ? commandParams.code : ErrorType.GENERIC_ERROR, commandParams.message ? commandParams.message : `Timeout for message id '${messageId}' with content '${messageToSend}'`, commandParams.details ? commandParams.details : {})), Constants.OCPP_WEBSOCKET_TIMEOUT);
}
// Function that will receive the request's response
}
} else {
// Throw exception
- await this.sendError(messageId, new OCPPError(Constants.OCPP_ERROR_NOT_IMPLEMENTED, `${commandName} is not implemented`, {}), commandName);
+ await this.sendError(messageId, new OCPPError(ErrorType.NOT_IMPLEMENTED, `${commandName} is not implemented`, {}), commandName);
throw new Error(`${commandName} is not implemented ${JSON.stringify(commandPayload, null, ' ')}`);
}
// Send response
- await this.sendMessage(messageId, response, Constants.OCPP_JSON_CALL_RESULT_MESSAGE, commandName);
+ await this.sendMessage(messageId, response, MessageType.CALL_RESULT_MESSAGE, commandName);
}
// Simulate charging station restart
static readonly OCPP_RESPONSE_UNLOCKED = Object.freeze({ status: UnlockStatus.UNLOCKED });
static readonly OCPP_RESPONSE_UNLOCK_FAILED = Object.freeze({ status: UnlockStatus.UNLOCK_FAILED });
static readonly OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED = Object.freeze({ status: UnlockStatus.NOT_SUPPORTED });
- static readonly OCPP_SOCKET_TIMEOUT = 60000; // 60 sec
- static readonly OCPP_JSON_CALL_MESSAGE = 2; // Caller to callee
- static readonly OCPP_JSON_CALL_RESULT_MESSAGE = 3; // Callee to caller
- static readonly OCPP_JSON_CALL_ERROR_MESSAGE = 4; // Callee to caller
- // Requested Action is not known by receiver
- static readonly OCPP_ERROR_NOT_IMPLEMENTED = 'NotImplemented';
- // Requested Action is recognized but not supported by the receiver
- static readonly OCPP_ERROR_NOT_SUPPORTED = 'NotSupported';
- // An internal error occurred and the receiver was not able to process the requested Action successfully
- static readonly OCPP_ERROR_INTERNAL_ERROR = 'InternalError';
- // Payload for Action is incomplete
- static readonly OCPP_ERROR_PROTOCOL_ERROR = 'ProtocolError';
- // During the processing of Action a security issue occurred preventing receiver from completing the Action successfully
- static readonly OCPP_ERROR_SECURITY_ERROR = 'SecurityError';
- // Payload for Action is syntactically incorrect or not conform the PDU structure for Action
- static readonly OCPP_ERROR_FORMATION_VIOLATION = 'FormationViolation';
- // Payload is syntactically correct but at least one field contains an invalid value
- static readonly OCPP_ERROR_PROPERTY_RAINT_VIOLATION = 'PropertyraintViolation';
- // Payload for Action is syntactically correct but at least one of the fields violates occurrence raints
- static readonly OCPP_ERROR_OCCURENCE_RAINT_VIOLATION = 'OccurenceraintViolation';
- // Payload for Action is syntactically correct but at least one of the fields violates data type raints (e.g. “somestring” = 12)
- static readonly OCPP_ERROR_TYPERAINT_VIOLATION = 'TyperaintViolation';
- // Any other error not covered by the previous ones
- static readonly OCPP_ERROR_GENERIC_ERROR = 'GenericError';
static readonly OCPP_PROTOCOL_JSON = 'json';
static readonly OCPP_PROTOCOL_SOAP = 'soap';
static readonly OCPP_VERSION_16 = '1.6';
static readonly OCPP_VERSION_20 = '2.0';
+ static readonly OCPP_WEBSOCKET_TIMEOUT = 60000; // 60 sec
+
static readonly CHARGING_STATION_DEFAULT_RESET_TIME = 60000; // Ms
static readonly CHARGING_STATION_ATG_WAIT_TIME = 2000; // Ms