From 4e3ff94d15f16cbeb7f65d14525bca7af3c551fd Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Tue, 23 Aug 2022 16:03:49 +0200 Subject: [PATCH] Forward UI request UUID to broadcast channel request MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 31 ++++++++------- .../ChargingStationWorkerBroadcastChannel.ts | 2 + .../WorkerBroadcastChannel.ts | 6 +++ .../ui-services/AbstractUIService.ts | 15 ++++---- .../ui-server/ui-services/UIService001.ts | 38 ++++++++++--------- src/types/UIProtocol.ts | 3 +- src/types/WorkerBroadcastChannel.ts | 17 ++++++--- src/ui/web/src/type/UIProtocol.ts | 21 ++++++---- 8 files changed, 78 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 9b18fed9..0e02383d 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,7 @@ Tweak them to your needs by following the section [configuration files syntax](R To start the program, run: `npm start`. -To start the program with a UI controller, run: `npm run start:server`. -Then, start/stop the simulator by going to `https://` in a browser. Localhost port will default to 8080. For Cloud Foundry, the port is assigned based on the `process.env.PORT` environment variable. +## Start Web UI ## Configuration files syntax @@ -383,20 +382,18 @@ All kind of OCPP parameters are supported in a charging station configuration or ## UI protocol -Protocol to control the simulator via a Websocket protocol +Protocol to control the simulator via a Websocket -### Version 0.0.1 - -Set the HTTP header Sec-Websocket-Protocol to `ui0.0.1` +### Protocol -#### Protocol +PDU stands for Protocol Data Unit Request: [`uuid`, `ProcedureName`, `PDU`] `uuid`: String uniquely representing this request `ProcedureName`: The procedure to run on the simulator -`PDU (for Protocol Data Unit)`: The parameters (if any) for said procedure +`PDU`: The parameters (if any) for said procedure Response: [`uuid`, `PDU`] @@ -404,18 +401,22 @@ Response: `uuid`: String uniquely linking the response to the request `PDU`: Response data to requested procedure +### Version 0.0.1 + +Set the HTTP header _Sec-Websocket-Protocol_ to `ui0.0.1` + #### Procedures ##### List Charging stations Request: -`ProcedureName`: 'listChargingStation' +`ProcedureName`: 'listChargingStations' `PDU`: {} Response: `PDU`: { `status`, -An array of ChargingStationData as described in `ChargingStationWorker.ts` file +`Indexed ChargingStationData as described in ChargingStationWorker.ts file` } ##### Start Transaction @@ -423,15 +424,14 @@ An array of ChargingStationData as described in `ChargingStationWorker.ts` file Request: `ProcedureName`: 'startTransaction' `PDU`: { -`hashId`: the unique identifier of a chargingStation +`hashId`: the unique identifier of a charging station `connectorId`: the id of the connector (start at 1) `idTag`: An allowed badge authetification ID } Response: `PDU`: { -`status`, -**null** +`status` } ##### Stop Transaction @@ -439,14 +439,13 @@ Response: Request: `ProcedureName`: 'stopTransaction' `PDU`: { -`hashId`: the unique identifier of a chargingStation +`hashId`: the unique identifier of a charging station `transactionId`: the id of the transaction } Response: `PDU`: { -`status`, -**null** +`status` } ## Support, Feedback, Contributing diff --git a/src/charging-station/ChargingStationWorkerBroadcastChannel.ts b/src/charging-station/ChargingStationWorkerBroadcastChannel.ts index edb7475a..7212f09d 100644 --- a/src/charging-station/ChargingStationWorkerBroadcastChannel.ts +++ b/src/charging-station/ChargingStationWorkerBroadcastChannel.ts @@ -13,6 +13,8 @@ import { import ChargingStation from './ChargingStation'; import WorkerBroadcastChannel from './WorkerBroadcastChannel'; +const moduleName = 'ChargingStationWorkerBroadcastChannel'; + type MessageEvent = { data: unknown }; export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChannel { diff --git a/src/charging-station/WorkerBroadcastChannel.ts b/src/charging-station/WorkerBroadcastChannel.ts index 563da458..d1d430c3 100644 --- a/src/charging-station/WorkerBroadcastChannel.ts +++ b/src/charging-station/WorkerBroadcastChannel.ts @@ -1,7 +1,13 @@ import { BroadcastChannel } from 'worker_threads'; +import { BroadcastChannelRequest } from '../types/WorkerBroadcastChannel'; + export default class WorkerBroadcastChannel extends BroadcastChannel { constructor() { super('worker'); } + + public sendRequest(request: BroadcastChannelRequest): void { + this.postMessage(request); + } } diff --git a/src/charging-station/ui-server/ui-services/AbstractUIService.ts b/src/charging-station/ui-server/ui-services/AbstractUIService.ts index 070119bb..2e35299c 100644 --- a/src/charging-station/ui-server/ui-services/AbstractUIService.ts +++ b/src/charging-station/ui-server/ui-services/AbstractUIService.ts @@ -56,7 +56,7 @@ export default abstract class AbstractUIService { } // Call the message handler to build the response payload - responsePayload = await this.messageHandlers.get(command)(requestPayload); + responsePayload = await this.messageHandlers.get(command)(messageId, requestPayload); } catch (error) { // Log logger.error( @@ -87,12 +87,13 @@ export default abstract class AbstractUIService { // Validate the raw data received from the WebSocket // TODO: should probably be moved to the ws verify clients callback private dataValidation(rawData: RawData): ProtocolRequest { - logger.debug( - `${this.uiServer.logPrefix( - moduleName, - 'dataValidation' - )} Raw data received: ${rawData.toString()}` - ); + // logger.debug( + // `${this.uiServer.logPrefix( + // moduleName, + // 'dataValidation' + // )} Raw data received: ${rawData.toString()}` + // ); + const data = JSON.parse(rawData.toString()) as JsonType[]; if (Utils.isIterable(data) === false) { diff --git a/src/charging-station/ui-server/ui-services/UIService001.ts b/src/charging-station/ui-server/ui-services/UIService001.ts index 94060b5e..1f926c93 100644 --- a/src/charging-station/ui-server/ui-services/UIService001.ts +++ b/src/charging-station/ui-server/ui-services/UIService001.ts @@ -6,8 +6,10 @@ import { ResponsePayload, ResponseStatus, } from '../../../types/UIProtocol'; -import { BroadcastChannelProcedureName } from '../../../types/WorkerBroadcastChannel'; -import Utils from '../../../utils/Utils'; +import { + BroadcastChannelProcedureName, + BroadcastChannelRequestPayload, +} from '../../../types/WorkerBroadcastChannel'; import { AbstractUIServer } from '../AbstractUIServer'; import AbstractUIService from './AbstractUIService'; @@ -32,38 +34,38 @@ export default class UIService001 extends AbstractUIService { ); } - private handleStartTransaction(payload: RequestPayload): ResponsePayload { - this.workerBroadcastChannel.postMessage([ - Utils.generateUUID(), + private handleStartTransaction(uuid: string, payload: RequestPayload): ResponsePayload { + this.workerBroadcastChannel.sendRequest([ + uuid, BroadcastChannelProcedureName.START_TRANSACTION, - payload, + payload as BroadcastChannelRequestPayload, ]); return { status: ResponseStatus.SUCCESS }; } - private handleStopTransaction(payload: RequestPayload): ResponsePayload { - this.workerBroadcastChannel.postMessage([ - Utils.generateUUID(), + private handleStopTransaction(uuid: string, payload: RequestPayload): ResponsePayload { + this.workerBroadcastChannel.sendRequest([ + uuid, BroadcastChannelProcedureName.STOP_TRANSACTION, - payload, + payload as BroadcastChannelRequestPayload, ]); return { status: ResponseStatus.SUCCESS }; } - private handleStartChargingStation(payload: RequestPayload): ResponsePayload { - this.workerBroadcastChannel.postMessage([ - Utils.generateUUID(), + private handleStartChargingStation(uuid: string, payload: RequestPayload): ResponsePayload { + this.workerBroadcastChannel.sendRequest([ + uuid, BroadcastChannelProcedureName.START_CHARGING_STATION, - payload, + payload as BroadcastChannelRequestPayload, ]); return { status: ResponseStatus.SUCCESS }; } - private handleStopChargingStation(payload: RequestPayload): ResponsePayload { - this.workerBroadcastChannel.postMessage([ - Utils.generateUUID(), + private handleStopChargingStation(uuid: string, payload: RequestPayload): ResponsePayload { + this.workerBroadcastChannel.sendRequest([ + uuid, BroadcastChannelProcedureName.STOP_CHARGING_STATION, - payload, + payload as BroadcastChannelRequestPayload, ]); return { status: ResponseStatus.SUCCESS }; } diff --git a/src/types/UIProtocol.ts b/src/types/UIProtocol.ts index 4c25c58e..2c591495 100644 --- a/src/types/UIProtocol.ts +++ b/src/types/UIProtocol.ts @@ -17,7 +17,8 @@ export type ProtocolRequest = [string, ProcedureName, RequestPayload]; export type ProtocolResponse = [string, ResponsePayload]; export type ProtocolRequestHandler = ( - payload: RequestPayload + uuid?: string, + payload?: RequestPayload ) => ResponsePayload | Promise; export enum ProcedureName { diff --git a/src/types/WorkerBroadcastChannel.ts b/src/types/WorkerBroadcastChannel.ts index 381f57e4..9d1133d0 100644 --- a/src/types/WorkerBroadcastChannel.ts +++ b/src/types/WorkerBroadcastChannel.ts @@ -1,7 +1,12 @@ import { JsonObject } from './JsonType'; +import { RequestPayload, ResponsePayload } from './UIProtocol'; -export type BroadcastChannelRequest = [string, BroadcastChannelProcedureName, RequestPayload]; -export type BroadcastChannelResponse = [string, ResponsePayload]; +export type BroadcastChannelRequest = [ + string, + BroadcastChannelProcedureName, + BroadcastChannelRequestPayload +]; +export type BroadcastChannelResponse = [string, BroadcastChannelResponsePayload]; export enum BroadcastChannelProcedureName { START_CHARGING_STATION = 'startChargingStation', @@ -10,14 +15,16 @@ export enum BroadcastChannelProcedureName { STOP_TRANSACTION = 'stopTransaction', } -interface BasePayload extends JsonObject { +interface BroadcastChannelBasePayload extends JsonObject { hashId: string; } -export interface RequestPayload extends BasePayload { +export interface BroadcastChannelRequestPayload + extends BroadcastChannelBasePayload, + Omit { connectorId?: number; transactionId?: number; idTag?: string; } -export type ResponsePayload = BasePayload; +export type BroadcastChannelResponsePayload = ResponsePayload; diff --git a/src/ui/web/src/type/UIProtocol.ts b/src/ui/web/src/type/UIProtocol.ts index f7a4ac0c..4c25c58e 100644 --- a/src/ui/web/src/type/UIProtocol.ts +++ b/src/ui/web/src/type/UIProtocol.ts @@ -1,4 +1,4 @@ -import { JsonObject, JsonType } from './JsonType'; +import { JsonObject } from './JsonType'; export enum Protocol { UI = 'ui', @@ -13,13 +13,25 @@ export enum ProtocolVersion { '0.0.1' = '0.0.1', } +export type ProtocolRequest = [string, ProcedureName, RequestPayload]; +export type ProtocolResponse = [string, ResponsePayload]; + +export type ProtocolRequestHandler = ( + payload: RequestPayload +) => ResponsePayload | Promise; + export enum ProcedureName { LIST_CHARGING_STATIONS = 'listChargingStations', + START_CHARGING_STATION = 'startChargingStation', + STOP_CHARGING_STATION = 'stopChargingStation', START_TRANSACTION = 'startTransaction', STOP_TRANSACTION = 'stopTransaction', START_SIMULATOR = 'startSimulator', STOP_SIMULATOR = 'stopSimulator', } +export interface RequestPayload extends JsonObject { + hashId?: string; +} export enum ResponseStatus { SUCCESS = 'success', @@ -29,10 +41,3 @@ export enum ResponseStatus { export interface ResponsePayload extends JsonObject { status: ResponseStatus; } - -export type ProtocolRequest = [string, ProcedureName, JsonType]; -export type ProtocolResponse = [string, ResponsePayload]; - -export type ProtocolRequestHandler = ( - payload: JsonType -) => void | Promise | ResponsePayload | Promise; -- 2.34.1