1 import { JsonType
} from
'@/type/JsonType';
7 } from
'@/type/UIProtocol';
8 import Utils from
'./Utils';
9 import config from
'@/assets/config';
10 import { v4
as uuidv4
} from
'uuid';
12 type ResponseHandler
= {
13 resolve
: (value
: ResponsePayload
| PromiseLike
<ResponsePayload
>) => void;
14 reject
: (reason
?: any) => void;
15 procedureName
: ProcedureName
;
18 export default class UIClient
{
19 private static _instance
: UIClient
| null = null;
21 private _ws
: WebSocket
;
22 private _responseHandlers
: Map
<string, ResponseHandler
>;
24 private constructor() {
25 this._ws
= new WebSocket(
26 `ws://${config.emobility.host}:${config.emobility.port}`,
27 config
.emobility
.protocol
30 this._responseHandlers
= new Map
<string, ResponseHandler
>();
32 this._ws
.onmessage
= this.responseHandler
.bind(this);
35 public static get
instance() {
36 if (UIClient
._instance
=== null) {
37 UIClient
._instance
= new UIClient();
39 return UIClient
._instance
;
42 public onOpen(listener
: (this: WebSocket
, ev
: Event
) => void) {
43 this._ws
.addEventListener('open', listener
);
46 public async listChargingStations(): Promise
<ResponsePayload
> {
47 console
.debug('listChargingStations');
49 return this.sendRequest(ProcedureName
.LIST_CHARGING_STATIONS
, {});
52 public async startTransaction(
56 ): Promise
<ResponsePayload
> {
57 console
.debug('startTransaction');
59 return this.sendRequest(ProcedureName
.START_TRANSACTION
, {
66 public async stopTransaction(hashId
: string, transactionId
: number): Promise
<ResponsePayload
> {
67 console
.debug('stopTransaction');
69 return this.sendRequest(ProcedureName
.STOP_TRANSACTION
, {
75 private setResponseHandler(
77 resolve
: (value
: ResponsePayload
| PromiseLike
<ResponsePayload
>) => void,
78 reject
: (reason
?: any) => void,
79 procedureName
: ProcedureName
81 this._responseHandlers
.set(id
, { resolve
, reject
, procedureName
});
84 private getResponseHandler(id
: string): ResponseHandler
| undefined {
85 return this._responseHandlers
.get(id
);
88 private async sendRequest(command
: ProcedureName
, data
: JsonType
): Promise
<ResponsePayload
> {
90 return Utils
.promiseWithTimeout(
91 new Promise((resolve
, reject
) => {
93 const msg
= JSON
.stringify([uuid
, command
, data
]);
95 if (this._ws
.readyState
=== this._ws
.OPEN
) {
96 console
.debug(`Send request ${command} message: `, msg
);
99 throw new Error(`Send request ${command} message: connection not opened`);
102 this.setResponseHandler(uuid
, resolve
, reject
, command
);
105 Error(`Send request ${command} message timeout`),
107 this._responseHandlers
.delete(uuid
);
112 private responseHandler(messageEvent
: MessageEvent
<string>): void {
113 const data
= JSON
.parse(messageEvent
.data
) as ProtocolResponse
;
115 if (Utils
.isIterable(data
) === false) {
116 throw new Error('Response not iterable: ' + JSON
.stringify(data
, null, 2));
119 const [uuid
, response
] = data
;
121 if (this._responseHandlers
.has(uuid
) === true) {
122 switch (response
.status) {
123 case ResponseStatus
.SUCCESS
:
124 this.getResponseHandler(uuid
)?.resolve(response
);
126 case ResponseStatus
.FAILURE
:
127 this.getResponseHandler(uuid
)?.reject(response
);
130 throw new Error(`Response status not supported: ${response.status}`);
133 throw new Error('Not a response to a request: ' + JSON
.stringify(data
, null, 2));