Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
18 files changed:
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node == '20.x' }}
run: pnpm lint
- name: pnpm build
if: ${{ matrix.os == 'ubuntu-latest' && matrix.node == '20.x' }}
run: pnpm lint
- name: pnpm build
- run: |
- pnpm build:prepare
- pnpm build
- name: pnpm test
run: pnpm test
- name: pnpm coverage
- name: pnpm test
run: pnpm test
- name: pnpm coverage
&& pnpm set progress=false \
&& pnpm config set depth 0 \
&& pnpm install --ignore-scripts --frozen-lockfile \
&& pnpm set progress=false \
&& pnpm config set depth 0 \
&& pnpm install --ignore-scripts --frozen-lockfile \
- && pnpm build:prepare \
&& pnpm build
FROM node:lts-alpine
&& pnpm build
FROM node:lts-alpine
.DS_Store
node_modules
/dist
.DS_Store
node_modules
/dist
# Created by git for backups. To disable backups in git:
# $ git config --global mergetool.keepBackup false
# Created by git for backups. To disable backups in git:
# $ git config --global mergetool.keepBackup false
#### Web UI configuration
#### Web UI configuration
-Copy the configuration template [src/assets/config-template.ts](src/assets/config-template.ts) to `src/assets/config.ts`.
+Copy the configuration template [src/assets/config-template.json](src/assets/config-template.json) to `public/config.json`.
For both options above you can then follow the link displayed in the terminal at the end of compilation. The Web UI looks like the following
For both options above you can then follow the link displayed in the terminal at the end of compilation. The Web UI looks like the following
-![webui](./assets/webui.png)
+![webui](./src/assets/webui.png)
1. With the top 2 buttons you can now stop and afterwards start the simulator and inspect the server console for the number of charging stations, e.g. with the default configuration: `Charging stations simulator ... started with 10 charging station(s)`
2. Each charging station is a row in the table below, try "Stop Charging Station" and refresh with the large blue button and see the status Started turns from Yes into No.
1. With the top 2 buttons you can now stop and afterwards start the simulator and inspect the server console for the number of charging stations, e.g. with the default configuration: `Charging stations simulator ... started with 10 charging station(s)`
2. Each charging station is a row in the table below, try "Stop Charging Station" and refresh with the large blue button and see the status Started turns from Yes into No.
"start": "pnpm build && node start.js",
"dev": "vite",
"preview": "vite preview",
"start": "pnpm build && node start.js",
"dev": "vite",
"preview": "vite preview",
- "build:prepare": "node build-prepare.js",
"build": "vite build",
"clean:dist": "npx rimraf dist",
"clean:node_modules": "npx rimraf node_modules",
"build": "vite build",
"clean:dist": "npx rimraf dist",
"clean:node_modules": "npx rimraf node_modules",
--- /dev/null
+{
+ "uiServer": {
+ "host": "localhost",
+ "port": 8080,
+ "protocol": "ui",
+ "version": "0.0.1",
+ "authentication": {
+ "enabled": false,
+ "type": "basic-auth",
+ "username": "admin",
+ "password": "admin"
+ }
+ }
+}
+++ /dev/null
-import { AuthenticationType, type ConfigurationData, Protocol, ProtocolVersion } from '@/types'
-
-const configuration: ConfigurationData = {
- uiServer: {
- host: 'localhost',
- port: 8080,
- protocol: Protocol.UI,
- version: ProtocolVersion['0.0.1'],
- authentication: {
- enabled: false,
- type: AuthenticationType.BASIC_AUTH,
- username: 'admin',
- password: 'admin'
- }
- }
-}
-
-export default configuration
</template>
<script setup lang="ts">
</template>
<script setup lang="ts">
-// import { reactive } from 'vue'
-import Button from '../buttons/Button.vue'
-// import IdTagInputModal from './IdTagInputModal.vue'
+import { getCurrentInstance } from 'vue'
+// import { reactive } from 'vue';
+// import IdTagInputModal from '@/components/charging-stations/IdTagInputModal.vue'
+import Button from '@/components/buttons/Button.vue'
import type { ConnectorStatus } from '@/types'
import type { ConnectorStatus } from '@/types'
-import { UIClient } from '@/composables/UIClient'
-// import { compose } from '@/composables/Utils'
+// import { compose } from '@/composables'
const props = defineProps<{
hashId: string
const props = defineProps<{
hashId: string
// state.isIdTagModalVisible = false
// }
// state.isIdTagModalVisible = false
// }
+const UIClient = getCurrentInstance()?.appContext.config.globalProperties.$UIClient
+
function startChargingStation(): void {
function startChargingStation(): void {
- UIClient.getInstance().startChargingStation(props.hashId)
+ UIClient.startChargingStation(props.hashId)
}
function stopChargingStation(): void {
}
function stopChargingStation(): void {
- UIClient.getInstance().stopChargingStation(props.hashId)
+ UIClient.stopChargingStation(props.hashId)
}
function openConnection(): void {
}
function openConnection(): void {
- UIClient.getInstance().openConnection(props.hashId)
+ UIClient.openConnection(props.hashId)
}
function closeConnection(): void {
}
function closeConnection(): void {
- UIClient.getInstance().closeConnection(props.hashId)
+ UIClient.closeConnection(props.hashId)
}
function startTransaction(): void {
}
function startTransaction(): void {
- UIClient.getInstance().startTransaction(props.hashId, props.connectorId, props.idTag)
+ UIClient.startTransaction(props.hashId, props.connectorId, props.idTag)
}
function stopTransaction(): void {
}
function stopTransaction(): void {
- UIClient.getInstance().stopTransaction(props.hashId, props.transactionId)
+ UIClient.stopTransaction(props.hashId, props.transactionId)
}
function startAutomaticTransactionGenerator(): void {
}
function startAutomaticTransactionGenerator(): void {
- UIClient.getInstance().startAutomaticTransactionGenerator(props.hashId, props.connectorId)
+ UIClient.startAutomaticTransactionGenerator(props.hashId, props.connectorId)
}
function stopAutomaticTransactionGenerator(): void {
}
function stopAutomaticTransactionGenerator(): void {
- UIClient.getInstance().stopAutomaticTransactionGenerator(props.hashId, props.connectorId)
+ UIClient.stopAutomaticTransactionGenerator(props.hashId, props.connectorId)
<script setup lang="ts">
// import { reactive } from 'vue'
<script setup lang="ts">
// import { reactive } from 'vue'
-import CSConnector from './CSConnector.vue'
+import CSConnector from '@/components/charging-stations/CSConnector.vue'
import type { ChargingStationData, ChargingStationInfo, ConnectorStatus } from '@/types'
const props = defineProps<{
import type { ChargingStationData, ChargingStationInfo, ConnectorStatus } from '@/types'
const props = defineProps<{
</template>
<script setup lang="ts">
</template>
<script setup lang="ts">
-import CSData from './CSData.vue'
+import CSData from '@/components/charging-stations/CSData.vue'
import type { ChargingStationData } from '@/types'
const props = defineProps<{
import type { ChargingStationData } from '@/types'
const props = defineProps<{
</template>
<script setup lang="ts">
</template>
<script setup lang="ts">
-import Button from '../buttons/Button.vue'
+import Button from '@/components/buttons/Button.vue'
import Modal from '@/components/Modal.vue'
const props = defineProps<{
import Modal from '@/components/Modal.vue'
const props = defineProps<{
import {
ApplicationProtocol,
import {
ApplicationProtocol,
+ type ConfigurationData,
ProcedureName,
type ProtocolResponse,
type RequestPayload,
type ResponsePayload,
ResponseStatus
} from '@/types'
ProcedureName,
type ProtocolResponse,
type RequestPayload,
type ResponsePayload,
ResponseStatus
} from '@/types'
-// @ts-expect-error: configuration file can be non existent
-// eslint-disable-next-line import/no-unresolved
-import configuration from '@/assets/config'
type ResponseHandler = {
procedureName: ProcedureName
type ResponseHandler = {
procedureName: ProcedureName
private ws!: WebSocket
private responseHandlers: Map<string, ResponseHandler>
private ws!: WebSocket
private responseHandlers: Map<string, ResponseHandler>
- private constructor() {
+ private constructor(private configuration: ConfigurationData) {
this.openWS()
this.responseHandlers = new Map<string, ResponseHandler>()
}
this.openWS()
this.responseHandlers = new Map<string, ResponseHandler>()
}
- public static getInstance() {
+ public static getInstance(configuration: ConfigurationData) {
if (UIClient.instance === null) {
if (UIClient.instance === null) {
- UIClient.instance = new UIClient()
+ UIClient.instance = new UIClient(configuration)
}
return UIClient.instance
}
}
return UIClient.instance
}
private openWS(): void {
this.ws = new WebSocket(
private openWS(): void {
this.ws = new WebSocket(
- `${configuration.uiServer.secure === true ? ApplicationProtocol.WSS : ApplicationProtocol.WS}://${configuration.uiServer.host}:${configuration.uiServer.port}`,
- `${configuration.uiServer.protocol}${configuration.uiServer.version}`
+ `${this.configuration.uiServer.secure === true ? ApplicationProtocol.WSS : ApplicationProtocol.WS}://${this.configuration.uiServer.host}:${this.configuration.uiServer.port}`,
+ `${this.configuration.uiServer.protocol}${this.configuration.uiServer.version}`
)
this.ws.onmessage = this.responseHandler.bind(this)
this.ws.onerror = errorEvent => {
)
this.ws.onmessage = this.responseHandler.bind(this)
this.ws.onerror = errorEvent => {
const sendTimeout = setTimeout(() => {
this.responseHandlers.delete(uuid)
return reject(new Error(`Send request '${procedureName}' message timeout`))
const sendTimeout = setTimeout(() => {
this.responseHandlers.delete(uuid)
return reject(new Error(`Send request '${procedureName}' message timeout`))
try {
this.ws.send(msg)
this.responseHandlers.set(uuid, { procedureName, resolve, reject })
try {
this.ws.send(msg)
this.responseHandlers.set(uuid, { procedureName, resolve, reject })
-// export const compose = <T>(...fns: ((arg: T) => T)[]): ((x: T) => T) => {
-// return (x: T) => fns.reduceRight((y, fn) => fn(y), x)
-// }
+export const compose = <T>(...fns: ((arg: T) => T)[]): ((x: T) => T) => {
+ return (x: T) => fns.reduceRight((y, fn) => fn(y), x)
+}
--- /dev/null
+export { UIClient } from './UIClient'
+export { compose } from './Utils'
import { createApp } from 'vue'
import { createApp } from 'vue'
-import App from './App.vue'
-import router from './router'
+import router from '@/router'
+import { UIClient } from '@/composables'
+import App from '@/App.vue'
-createApp(App).use(router).mount('#app')
+const app = createApp(App)
+
+fetch('/config.json')
+ .then(response => response.json())
+ .then(config => {
+ app.config.globalProperties.$UIClient = UIClient.getInstance(config)
+ app.use(router).mount('#app')
+ })
</template>
<script setup lang="ts">
</template>
<script setup lang="ts">
-import { onMounted, reactive } from 'vue'
+import { getCurrentInstance, onMounted, reactive } from 'vue'
import CSTable from '@/components/charging-stations/CSTable.vue'
import type { ChargingStationData } from '@/types'
import Container from '@/components/Container.vue'
import ReloadButton from '@/components/buttons/ReloadButton.vue'
import CSTable from '@/components/charging-stations/CSTable.vue'
import type { ChargingStationData } from '@/types'
import Container from '@/components/Container.vue'
import ReloadButton from '@/components/buttons/ReloadButton.vue'
-import { UIClient } from '@/composables/UIClient'
-const UIClientInstance = UIClient.getInstance()
+const UIClient = getCurrentInstance()?.appContext.config.globalProperties.$UIClient
- UIClientInstance.registerWSonOpenListener(load)
+ UIClient.registerWSonOpenListener(load)
async function load(): Promise<void> {
if (state.isLoading === true) return
state.isLoading = true
async function load(): Promise<void> {
if (state.isLoading === true) return
state.isLoading = true
- const listChargingStationsPayload = await UIClientInstance.listChargingStations()
+ const listChargingStationsPayload = await UIClient.listChargingStations()
state.chargingStations =
listChargingStationsPayload.chargingStations as unknown as ChargingStationData[]
state.isLoading = false
}
function startSimulator(): void {
state.chargingStations =
listChargingStationsPayload.chargingStations as unknown as ChargingStationData[]
state.isLoading = false
}
function startSimulator(): void {
- UIClientInstance.startSimulator()
+ UIClient.startSimulator()
}
function stopSimulator(): void {
}
function stopSimulator(): void {
- UIClientInstance.stopSimulator()
+ UIClient.stopSimulator()