// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
import { createHash } from 'node:crypto';
+import { EventEmitter } from 'node:events';
import { type FSWatcher, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { URL } from 'node:url';
type BootNotificationResponse,
type CachedRequest,
type ChargingStationConfiguration,
+ ChargingStationEvents,
type ChargingStationInfo,
type ChargingStationOcppConfiguration,
type ChargingStationTemplate,
// watchJsonFile,
} from '../utils';
-export class ChargingStation {
+export class ChargingStation extends EventEmitter {
public readonly index: number;
public readonly templateFile: string;
public stationInfo!: ChargingStationInfo;
private reservationExpirationSetInterval?: NodeJS.Timeout;
constructor(index: number, templateFile: string) {
+ super();
this.started = false;
this.starting = false;
this.stopping = false;
this.idTagsCache = IdTagsCache.getInstance();
this.chargingStationWorkerBroadcastChannel = new ChargingStationWorkerBroadcastChannel(this);
+ this.on(ChargingStationEvents.started, () => {
+ parentPort?.postMessage(buildStartedMessage(this));
+ });
+ this.on(ChargingStationEvents.stopped, () => {
+ parentPort?.postMessage(buildStoppedMessage(this));
+ });
+ this.on(ChargingStationEvents.updated, () => {
+ parentPort?.postMessage(buildUpdatedMessage(this));
+ });
+
this.initialize();
}
// },
// );
this.started = true;
- parentPort?.postMessage(buildStartedMessage(this));
+ this.emit(ChargingStationEvents.started);
this.starting = false;
} else {
logger.warn(`${this.logPrefix()} Charging station is already starting...`);
delete this.bootNotificationResponse;
this.started = false;
this.saveConfiguration();
- parentPort?.postMessage(buildStoppedMessage(this));
+ this.emit(ChargingStationEvents.stopped);
this.stopping = false;
} else {
logger.warn(`${this.logPrefix()} Charging station is already stopping...`);
this.automaticTransactionGenerator?.start();
}
this.saveAutomaticTransactionGeneratorConfiguration();
- parentPort?.postMessage(buildUpdatedMessage(this));
+ this.emit(ChargingStationEvents.updated);
}
public stopAutomaticTransactionGenerator(connectorIds?: number[]): void {
this.automaticTransactionGenerator?.stop();
}
this.saveAutomaticTransactionGeneratorConfiguration();
- parentPort?.postMessage(buildUpdatedMessage(this));
+ this.emit(ChargingStationEvents.updated);
}
public async stopTransactionOnConnector(
);
}
if (this.isRegistered() === true) {
+ this.emit(ChargingStationEvents.registered);
if (this.inAcceptedState() === true) {
+ this.emit(ChargingStationEvents.accepted);
await this.startMessageSequence();
}
} else {
}
this.wsConnectionRestarted = false;
this.autoReconnectRetryCount = 0;
- parentPort?.postMessage(buildUpdatedMessage(this));
+ this.emit(ChargingStationEvents.updated);
} else {
logger.warn(
`${this.logPrefix()} Connection to OCPP server through ${this.wsConnectionUrl.toString()} failed`,
this.started === true && (await this.reconnect());
break;
}
- parentPort?.postMessage(buildUpdatedMessage(this));
+ this.emit(ChargingStationEvents.updated);
}
private getCachedRequest(messageType: MessageType, messageId: string): CachedRequest | undefined {
logger.error(`${this.logPrefix()} ${errorMsg}`);
throw new OCPPError(ErrorType.PROTOCOL_ERROR, errorMsg);
}
- parentPort?.postMessage(buildUpdatedMessage(this));
+ this.emit(ChargingStationEvents.updated);
} else {
throw new OCPPError(
ErrorType.PROTOCOL_ERROR,
// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
-import { parentPort } from 'node:worker_threads';
-
import type { JSONSchemaType } from 'ajv';
import { secondsToMilliseconds } from 'date-fns';
import { OCPPError } from '../../../exception';
import {
type ChangeConfigurationResponse,
+ ChargingStationEvents,
type ClearChargingProfileResponse,
ErrorType,
type GenericResponse,
type SetChargingProfileResponse,
type UnlockConnectorResponse,
} from '../../../types';
-import {
- Constants,
- buildUpdatedMessage,
- convertToInt,
- isNullOrUndefined,
- logger,
-} from '../../../utils';
+import { Constants, convertToInt, isNullOrUndefined, logger } from '../../../utils';
import { OCPPResponseService } from '../OCPPResponseService';
const moduleName = 'OCPP16ResponseService';
OCPP16ChargePointStatus.Available,
);
}
- parentPort?.postMessage(buildUpdatedMessage(chargingStation));
+ chargingStation.emit(ChargingStationEvents.updated);
}
private async handleResponseStopTransaction(
}
resetConnectorStatus(chargingStation.getConnectorStatus(transactionConnectorId!)!);
chargingStation.stopMeterValues(transactionConnectorId!);
- parentPort?.postMessage(buildUpdatedMessage(chargingStation));
+ chargingStation.emit(ChargingStationEvents.updated);
const logMsg = `${chargingStation.logPrefix()} Transaction with id ${
requestPayload.transactionId
} STOPPED on ${
import type { WebSocket } from 'ws';
import type { ChargingStationAutomaticTransactionGeneratorConfiguration } from './AutomaticTransactionGenerator';
+import { ChargingStationEvents } from './ChargingStation';
import type { ChargingStationInfo } from './ChargingStationInfo';
import type { ChargingStationOcppConfiguration } from './ChargingStationOcppConfiguration';
import type { ConnectorStatus } from './ConnectorStatus';
}
enum ChargingStationMessageEvents {
- started = 'started',
- stopped = 'stopped',
- updated = 'updated',
performanceStatistics = 'performanceStatistics',
}
export const ChargingStationWorkerMessageEvents = {
...WorkerMessageEvents,
+ ...ChargingStationEvents,
...ChargingStationMessageEvents,
} as const;
-export type ChargingStationWorkerMessageEvents = WorkerMessageEvents | ChargingStationMessageEvents;
+export type ChargingStationWorkerMessageEvents =
+ | WorkerMessageEvents
+ | ChargingStationEvents
+ | ChargingStationMessageEvents;
export type ChargingStationWorkerMessageData = ChargingStationData | Statistics;