import Connectors, { Connector } from '../types/Connectors';
 import { MeterValue, MeterValueLocation, MeterValueMeasurand, MeterValuePhase, MeterValueUnit, MeterValuesRequest, MeterValuesResponse, SampledValue } from '../types/ocpp/1.6/MeterValues';
 import { PerformanceObserver, performance } from 'perf_hooks';
-import Requests, { BootNotificationRequest, ChangeConfigurationRequest, GetConfigurationRequest, HeartbeatRequest, RemoteStartTransactionRequest, RemoteStopTransactionRequest, ResetRequest, SetChargingProfileRequest, StatusNotificationRequest, UnlockConnectorRequest } from '../types/ocpp/1.6/Requests';
+import Requests, { BootNotificationRequest, ChangeConfigurationRequest, GetConfigurationRequest, HeartbeatRequest, IncomingRequestCommand, RemoteStartTransactionRequest, RemoteStopTransactionRequest, RequestCommand, ResetRequest, SetChargingProfileRequest, StatusNotificationRequest, UnlockConnectorRequest } from '../types/ocpp/1.6/Requests';
 import WebSocket, { MessageEvent } from 'ws';
 
 import AutomaticTransactionGenerator from './AutomaticTransactionGenerator';
         // Incoming Message
         case MessageType.CALL_MESSAGE:
           if (this.getEnableStatistics()) {
-            this._statistics.addMessage(commandName, messageType);
+            this._statistics.addMessage(commandName as IncomingRequestCommand, messageType);
           }
           // Process the call
-          await this.handleRequest(messageId, commandName, commandPayload);
+          await this.handleRequest(messageId, commandName as IncomingRequestCommand, commandPayload);
           break;
         // Outcome Message
         case MessageType.CALL_RESULT_MESSAGE:
       // 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 !== MessageType.CALL_ERROR_MESSAGE && await this.sendError(messageId, error, commandName);
+      messageType !== MessageType.CALL_ERROR_MESSAGE && await this.sendError(messageId, error, commandName as IncomingRequestCommand);
     }
   }
 
   async sendHeartbeat(): Promise<void> {
     try {
       const payload: HeartbeatRequest = {};
-      await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'Heartbeat');
+      await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, RequestCommand.HEARTBEAT);
     } catch (error) {
-      logger.error(this._logPrefix() + ' Send Heartbeat error: %j', error);
-      throw error;
+      this.handleRequestError(RequestCommand.HEARTBEAT, error);
     }
   }
 
   async sendBootNotification(): Promise<BootNotificationResponse> {
     try {
-      return await this.sendMessage(Utils.generateUUID(), this._bootNotificationRequest, MessageType.CALL_MESSAGE, 'BootNotification') as BootNotificationResponse;
+      return await this.sendMessage(Utils.generateUUID(), this._bootNotificationRequest, MessageType.CALL_MESSAGE, RequestCommand.BOOT_NOTIFICATION) as BootNotificationResponse;
     } catch (error) {
-      logger.error(this._logPrefix() + ' Send BootNotification error: %j', error);
-      throw error;
+      this.handleRequestError(RequestCommand.BOOT_NOTIFICATION, error);
     }
   }
 
         errorCode,
         status,
       };
-      await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'StatusNotification');
+      await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, RequestCommand.STATUS_NOTIFICATION);
     } catch (error) {
-      logger.error(this._logPrefix() + ' Send StatusNotification error: %j', error);
-      throw error;
+      this.handleRequestError(RequestCommand.STATUS_NOTIFICATION, error);
     }
   }
 
         meterStart: 0,
         timestamp: new Date().toISOString(),
       };
-      return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'StartTransaction') as StartTransactionResponse;
+      return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, RequestCommand.START_TRANSACTION) as StartTransactionResponse;
     } catch (error) {
-      logger.error(this._logPrefix() + ' Send StartTransaction error: %j', error);
-      throw error;
+      this.handleRequestError(RequestCommand.START_TRANSACTION, error);
     }
   }
 
         timestamp: new Date().toISOString(),
         ...reason && { reason },
       };
-      return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'StopTransaction') as StartTransactionResponse;
+      return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, RequestCommand.STOP_TRANSACTION) as StartTransactionResponse;
     } catch (error) {
-      logger.error(this._logPrefix() + ' Send StopTransaction error: %j', error);
-      throw error;
+      this.handleRequestError(RequestCommand.STOP_TRANSACTION, error);
     }
   }
 
         transactionId: self.getConnector(connectorId).transactionId,
         meterValue: meterValue,
       };
-      await self.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, 'MeterValues');
+      await self.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, RequestCommand.METERVALUES);
     } catch (error) {
-      logger.error(self._logPrefix() + ' Send MeterValues error: %j', error);
-      throw error;
+      this.handleRequestError(RequestCommand.METERVALUES, error);
     }
   }
 
-  async sendError(messageId: string, err: Error | OCPPError, commandName: string): Promise<unknown> {
+  async sendError(messageId: string, err: Error | OCPPError, commandName: RequestCommand | IncomingRequestCommand): Promise<unknown> {
     // Check exception type: only OCPP error are accepted
     const error = err instanceof OCPPError ? err : new OCPPError(ErrorType.INTERNAL_ERROR, err.message, err.stack && err.stack);
     // Send error
     return this.sendMessage(messageId, error, MessageType.CALL_ERROR_MESSAGE, commandName);
   }
 
-  async sendMessage(messageId: string, commandParams, messageType = MessageType.CALL_RESULT_MESSAGE, commandName: string): Promise<any> {
+  async sendMessage(messageId: string, commandParams, messageType = MessageType.CALL_RESULT_MESSAGE, commandName: RequestCommand | IncomingRequestCommand): Promise<any> {
     // eslint-disable-next-line @typescript-eslint/no-this-alias
     const self = this;
     // Send a message through wsConnection
           break;
       }
       // Check if wsConnection opened and charging station registered
-      if (this._isWebSocketOpen() && (this._isRegistered() || commandName === 'BootNotification')) {
+      if (this._isWebSocketOpen() && (this._isRegistered() || commandName === RequestCommand.BOOT_NOTIFICATION)) {
         if (this.getEnableStatistics()) {
           this._statistics.addMessage(commandName, messageType);
         }
           self._statistics.addMessage(commandName, messageType);
         }
         // Send the response
-        await self.handleResponse(commandName, payload, requestPayload);
+        await self.handleResponse(commandName as RequestCommand, payload, requestPayload);
         resolve(payload);
       }
 
     });
   }
 
-  async handleResponse(commandName: string, payload, requestPayload): Promise<void> {
+  async handleResponse(commandName: RequestCommand, payload, requestPayload): Promise<void> {
     const responseCallbackFn = 'handleResponse' + commandName;
     if (typeof this[responseCallbackFn] === 'function') {
       await this[responseCallbackFn](payload, requestPayload);
     logger.debug(this._logPrefix() + ' Heartbeat response received: %j to Heartbeat request: %j', payload, requestPayload);
   }
 
-  async handleRequest(messageId: string, commandName: string, commandPayload): Promise<void> {
+  async handleRequest(messageId: string, commandName: IncomingRequestCommand, commandPayload): Promise<void> {
     let response;
     // Call
     if (typeof this['handleRequest' + commandName] === 'function') {
     logger.info(this._logPrefix() + ' Trying to remote stop a non existing transaction ' + transactionId.toString());
     return Constants.OCPP_RESPONSE_REJECTED;
   }
+
+  private handleRequestError(commandName: RequestCommand, error: Error) {
+    logger.error(this._logPrefix() + ' Send ' + commandName + ' error: %j', error);
+    throw error;
+  }
 }
 
 
 import CommandStatistics, { CommandStatisticsData, PerfEntry } from '../types/CommandStatistics';
+import { IncomingRequestCommand, RequestCommand } from '../types/ocpp/1.6/Requests';
 
 import CircularArray from './CircularArray';
 import Configuration from './Configuration';
     return Statistics.instance;
   }
 
-  addMessage(command: string, messageType: number): void {
+  addMessage(command: RequestCommand | IncomingRequestCommand, messageType: MessageType): void {
     switch (messageType) {
       case MessageType.CALL_MESSAGE:
         if (this._commandsStatistics[command] && this._commandsStatistics[command].countRequest) {
   }
 
   logPerformance(entry: PerformanceEntry, className: string): void {
-    this.addPerformanceTimer(entry.name, entry.duration);
+    this.addPerformanceTimer(entry.name as RequestCommand | IncomingRequestCommand, entry.duration);
     const perfEntry: PerfEntry = {} as PerfEntry;
     perfEntry.name = entry.name;
     perfEntry.entryType = entry.entryType;
     return (sortedDataSet[(middleIndex - 1)] + sortedDataSet[middleIndex]) / 2;
   }
 
-  private addPerformanceTimer(command: string, duration: number): void {
+  private addPerformanceTimer(command: RequestCommand | IncomingRequestCommand, duration: number): void {
     // Map to proper command name
     const MAPCOMMAND = {
       sendMeterValues: 'MeterValues',
       stopTransaction: 'StopTransaction',
     };
     if (MAPCOMMAND[command]) {
-      command = MAPCOMMAND[command] as string;
+      command = MAPCOMMAND[command] as RequestCommand | IncomingRequestCommand;
     }
     // Initialize command statistics
     if (!this._commandsStatistics[command]) {