Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.env*
.git
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,34 @@ npm install

## Running VCP

Configure env variables:
Create `.env` file in the root directory and configure env variables:

```
WS_URL - websocket endpoint
CP_ID - ID of this VCP
PASSWORD - if used for OCPP Authentication, otherwise can be left blank
ADMIN_PORT - port for admin access (default is 9999), can be left blank
CP_START_TYPE - available chargepoint types to start, allowed values: 16, 16_2_connectors, 201, 21 (default is 16)
```

Run OCPP 1.6:
To run OCPP 1.6 station you should set CP_START_TYPE=16; to run OCPP 2.0.1 station, set CP_START_TYPE=201, and so on.

To start the station run:
```bash
npx tsx index_16.ts
npm run start
```

Run OCPP 2.0.1:
## Example

```bash
npx tsx index_201.ts
`.env`:
```

When testing different configurations, you can create multiple `.env` files and pass the env file as an argument, for example:

```bash
npm start -- --env-file=.env index_16.ts
WS_URL=ws://localhost:3000
CP_ID=vcp_16_test
CP_START_TYPE=16
```

## Example

```bash
> WS_URL=ws://localhost:3000 CP_ID=vcp_16_test npx tsx index_16.ts
> npm run start

2023-03-27 13:09:17 info: Connecting... | {
endpoint: 'ws://localhost:3000',
Expand All @@ -70,6 +68,11 @@ npm start -- --env-file=.env index_16.ts
2023-03-27 13:10:17 info: Receive message ⬅️ [3,"79a41b2e-2c4a-4a65-9d7e-417967a8f95f",{"currentTime":"2023-03-27T11:10:17.955Z"}]
```

## Running VCP in Docker
```
cd docker && docker compose up --build
```

## Executing Admin Commands

Some messages are automatically sent by the VCP, for example, `BootNotification` or `StartTransaction` and `StopTransaction`.
Expand Down
10 changes: 10 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:23.11.0-alpine

ARG STACK_TRACE_LIMIT=1024
ARG MAX_OLD_SPACE_SIZE=768

ENV NODE_OPTIONS="--stack-trace-limit=${STACK_TRACE_LIMIT} --max-old-space-size=${MAX_OLD_SPACE_SIZE}"

COPY . ./
RUN npm install
ENTRYPOINT [ "npm" "run" "start" ]
14 changes: 14 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
ocpp-virtual-charge-point:
build:
context: ..
dockerfile: docker/Dockerfile
args:
STACK_TRACE_LIMIT: 1024
MAX_OLD_SPACE_SIZE: 768
restart: unless-stopped
entrypoint: [ "npm", "run", "start" ]
environment:
- WS_URL=ws://localhost:3000
- CP_ID=vcp_16_test
- CP_START_TYPE=16
33 changes: 0 additions & 33 deletions index_16.ts

This file was deleted.

40 changes: 0 additions & 40 deletions index_16_2_connectors.ts

This file was deleted.

35 changes: 0 additions & 35 deletions index_201.ts

This file was deleted.

35 changes: 0 additions & 35 deletions index_21.ts

This file was deleted.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"lint": "biome lint src",
"format": "biome format src",
"typecheck": "tsc --noEmit --esModuleInterop --skipLibCheck src/**/*.ts",
"check": "npm run lint && npm run format && npm run typecheck"
"check": "npm run lint && npm run format && npm run typecheck",
"start": "npx tsx src/start.ts"
},
"author": "Solidstudio",
"license": "Apache-2.0",
Expand Down
84 changes: 84 additions & 0 deletions src/start.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require("dotenv").config();

import { OcppVersion } from "./ocppVersion";
import { bootNotificationOcppMessage } from "./v16/messages/bootNotification";
import { statusNotificationOcppMessage } from "./v16/messages/statusNotification";
import { bootNotificationOcppOutgoing } from "../src/v21/messages/bootNotification";
import { statusNotificationOcppOutgoing } from "../src/v21/messages/statusNotification";
import { VCP } from "./vcp";

function createVcp(ocppVersion: OcppVersion): VCP {
return new VCP({
endpoint: process.env.WS_URL ?? "ws://localhost:3000",
chargePointId: process.env.CP_ID ?? "123456",
ocppVersion: ocppVersion,
basicAuthPassword: process.env.PASSWORD ?? undefined,
adminPort: Number.parseInt(process.env.ADMIN_PORT ?? "9999"),
});
}

function sendStatusNotifications(vcp: VCP, connectorsNum: number) {
for (let i = 1; i <= connectorsNum; i++) {
vcp.send(
statusNotificationOcppMessage.request({
connectorId: i,
errorCode: "NoError",
status: "Available",
}),
);
}
}

async function start_16(connectorsNum: number) {
const vcp = createVcp(OcppVersion.OCPP_1_6);
await vcp.connect();
vcp.send(
bootNotificationOcppMessage.request({
chargePointVendor: "Solidstudio",
chargePointModel: "VirtualChargePoint",
chargePointSerialNumber: "S001",
firmwareVersion: "1.0.0",
}),
);
sendStatusNotifications(vcp, connectorsNum);
}

async function start_2x(ocppVersion: OcppVersion) {
const vcp = createVcp(ocppVersion);
await vcp.connect();
vcp.send(
bootNotificationOcppOutgoing.request({
reason: "PowerUp",
chargingStation: {
model: "VirtualChargePoint",
vendorName: "Solidstudio",
},
}),
);
vcp.send(
statusNotificationOcppOutgoing.request({
evseId: 1,
connectorId: 1,
connectorStatus: "Available",
timestamp: new Date().toISOString(),
}),
);
}

(async () => {
const cpStartType = process.env.CP_START_TYPE ?? "16";

console.log(`CP_START_TYPE is ${JSON.stringify(cpStartType)}`)

if (cpStartType === "16_2_connectors") {
await start_16(2);
} else if (cpStartType === "16") {
await start_16(1);
} else if (cpStartType === "21") {
await start_2x(OcppVersion.OCPP_2_1);
} else if (cpStartType === "201") {
await start_2x(OcppVersion.OCPP_2_0_1);
} else {
throw new Error(`Invalid CP_START_TYPE: ${cpStartType}`);
}
})();