From: Jérôme Benoit Date: Mon, 29 Nov 2021 20:51:45 +0000 (+0100) Subject: Add charging stations listing to WS server commands X-Git-Tag: v1.1.36~12 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=ee0f106b09f38b1561d970ea4377eb199389298e;p=e-mobility-charging-stations-simulator.git Add charging stations listing to WS server commands Signed-off-by: Jérôme Benoit --- diff --git a/src/charging-station/Bootstrap.ts b/src/charging-station/Bootstrap.ts index 06bc50e3..fe344407 100644 --- a/src/charging-station/Bootstrap.ts +++ b/src/charging-station/Bootstrap.ts @@ -109,7 +109,11 @@ export default class Bootstrap { workerChoiceStrategy: Configuration.getWorkerPoolStrategy() }, messageHandler: async (msg: ChargingStationWorkerMessage) => { - if (msg.id === ChargingStationWorkerMessageEvents.PERFORMANCE_STATISTICS) { + if (msg.id === ChargingStationWorkerMessageEvents.STARTED) { + this.webSocketServer.webSocketServerService.chargingStations.add(msg.data.id); + } else if (msg.id === ChargingStationWorkerMessageEvents.STOPPED) { + this.webSocketServer.webSocketServerService.chargingStations.delete(msg.data.id); + } else if (msg.id === ChargingStationWorkerMessageEvents.PERFORMANCE_STATISTICS) { await this.storage.storePerformanceStatistics(msg.data); } } diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index db385612..c50d2ad9 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -14,6 +14,7 @@ import AutomaticTransactionGenerator from './AutomaticTransactionGenerator'; import { ChargePointStatus } from '../types/ocpp/ChargePointStatus'; import { ChargingProfile } from '../types/ocpp/ChargingProfile'; import ChargingStationInfo from '../types/ChargingStationInfo'; +import { ChargingStationWorkerMessageEvents } from '../types/ChargingStationWorker'; import { ClientRequestArgs } from 'http'; import Configuration from '../utils/Configuration'; import Constants from '../utils/Constants'; @@ -34,6 +35,7 @@ import Utils from '../utils/Utils'; import crypto from 'crypto'; import fs from 'fs'; import logger from '../utils/Logger'; +import { parentPort } from 'worker_threads'; import path from 'path'; export default class ChargingStation { @@ -335,6 +337,7 @@ export default class ChargingStation { this.wsConnection.on('ping', this.onPing.bind(this)); // Handle WebSocket pong this.wsConnection.on('pong', this.onPong.bind(this)); + parentPort.postMessage({ id: ChargingStationWorkerMessageEvents.STARTED, data: { id: this.stationInfo.chargingStationId } }); } public async stop(reason: StopTransactionReason = StopTransactionReason.NONE): Promise { @@ -353,6 +356,7 @@ export default class ChargingStation { this.performanceStatistics.stop(); } this.bootNotificationResponse = null; + parentPort.postMessage({ id: ChargingStationWorkerMessageEvents.STOPPED, data: { id: this.stationInfo.chargingStationId } }); this.stopped = true; } diff --git a/src/charging-station/WebSocketServer.ts b/src/charging-station/WebSocketServer.ts index 426c8072..81e57675 100644 --- a/src/charging-station/WebSocketServer.ts +++ b/src/charging-station/WebSocketServer.ts @@ -8,16 +8,16 @@ import WebSocket from 'ws'; import logger from '../utils/Logger'; export default class WebSocketServer extends WebSocket.Server { - private webSocketServerService: AbstractUIService; + public webSocketServerService: AbstractUIService; public constructor(options?: WebSocket.ServerOptions, callback?: () => void) { // Create the WebSocket Server - super(options, callback); + super({ ...options, port: 80 }, callback); // FIXME: version the instantiation this.webSocketServerService = new UIService(this); } - public broadcastToClients(message: Record): void { + public broadcastToClients(message: string | Record): void { for (const client of this.clients) { if (client?.readyState === WebSocket.OPEN) { client.send(message); @@ -34,7 +34,7 @@ export default class WebSocketServer extends WebSocket.Server { [version, command, payload] = JSON.parse(messageData.toString()) as ProtocolRequest; switch (version) { case ProtocolVersion['0.0.1']: - this.webSocketServerService.handleMessage(command, payload).catch(() => { + this.webSocketServerService.handleMessage(version, command, payload).catch(() => { logger.error(`${this.logPrefix()} Error while handling command %s message: %j`, command, payload); }); break; diff --git a/src/charging-station/WebSocketServices/ui/0.0.1/UIService.ts b/src/charging-station/WebSocketServices/ui/0.0.1/UIService.ts index 8ca0c6dc..f2db4512 100644 --- a/src/charging-station/WebSocketServices/ui/0.0.1/UIService.ts +++ b/src/charging-station/WebSocketServices/ui/0.0.1/UIService.ts @@ -1,4 +1,4 @@ -import { ProtocolCommand, ProtocolRequestHandler } from '../../../../types/UIProtocol'; +import { ProtocolCommand, ProtocolRequestHandler, ProtocolVersion } from '../../../../types/UIProtocol'; import AbstractUIService from '../AbstractUIService'; import BaseError from '../../../../exception/BaseError'; @@ -11,12 +11,13 @@ export default class UIService extends AbstractUIService { constructor(webSocketServer: WebSocketServer) { super(webSocketServer); this.messageHandlers = new Map([ + [ProtocolCommand.LIST_CHARGING_STATIONS, this.handleListChargingStations.bind(this)], [ProtocolCommand.START_TRANSACTION, this.handleStartTransaction.bind(this)], [ProtocolCommand.STOP_TRANSACTION, this.handleStopTransaction.bind(this)], ]); } - async handleMessage(command: ProtocolCommand, payload: Record): Promise { + async handleMessage(version: ProtocolVersion, command: ProtocolCommand, payload: Record): Promise { let messageResponse: Record; if (this.messageHandlers.has(command) && command !== ProtocolCommand.UNKNOWN) { try { @@ -32,7 +33,11 @@ export default class UIService extends AbstractUIService { throw new BaseError(`${command} is not implemented to handle message payload ${JSON.stringify(payload, null, 2)}`); } // Send the built response - this.webSocketServer.broadcastToClients(messageResponse); + this.webSocketServer.broadcastToClients(this.buildProtocolMessage(version, command, messageResponse)); + } + + private handleListChargingStations(payload: Record) { + return this.chargingStations; } private handleStartTransaction(payload: Record) { } diff --git a/src/charging-station/WebSocketServices/ui/AbstractUIService.ts b/src/charging-station/WebSocketServices/ui/AbstractUIService.ts index 7a078bc2..d8c61861 100644 --- a/src/charging-station/WebSocketServices/ui/AbstractUIService.ts +++ b/src/charging-station/WebSocketServices/ui/AbstractUIService.ts @@ -1,12 +1,23 @@ -import { ProtocolCommand } from '../../../types/UIProtocol'; +import { ProtocolCommand, ProtocolVersion } from '../../../types/UIProtocol'; + import WebSocketServer from '../../WebSocketServer'; export default abstract class AbstractUIService { + public readonly chargingStations: Set; protected readonly webSocketServer: WebSocketServer; constructor(webSocketServer: WebSocketServer) { + this.chargingStations = new Set(); this.webSocketServer = webSocketServer; } - abstract handleMessage(command: ProtocolCommand, payload: Record): Promise; + protected buildProtocolMessage( + version: ProtocolVersion, + command: ProtocolCommand, + payload: Record, + ): string { + return JSON.stringify([version, command, payload]); + } + + abstract handleMessage(version: ProtocolVersion, command: ProtocolCommand, payload: Record): Promise; } diff --git a/src/types/ChargingStationWorker.ts b/src/types/ChargingStationWorker.ts index f016d8ff..a48e0768 100644 --- a/src/types/ChargingStationWorker.ts +++ b/src/types/ChargingStationWorker.ts @@ -6,6 +6,8 @@ export interface ChargingStationWorkerData extends WorkerData { } enum InternalChargingStationWorkerMessageEvents { + STARTED = 'started', + STOPPED = 'stopped', PERFORMANCE_STATISTICS = 'performanceStatistics' } diff --git a/src/types/UIProtocol.ts b/src/types/UIProtocol.ts index a7dfa334..3e4d6232 100644 --- a/src/types/UIProtocol.ts +++ b/src/types/UIProtocol.ts @@ -5,6 +5,7 @@ export enum ProtocolVersion { } export enum ProtocolCommand { + LIST_CHARGING_STATIONS = 'listChargingStations', START_TRANSACTION = 'startTransaction', STOP_TRANSACTION = 'stopTransaction', UNKNOWN = 'unknown',