Skip to content

Commit

Permalink
Merge pull request #7 from US-JOET/ocpp16j-demo
Browse files Browse the repository at this point in the history
Provide an ISO 15118-2 AC plus OCPP 1.6J demo
  • Loading branch information
shankari authored Dec 7, 2023
2 parents 4619ac2 + 867ebf5 commit 5b1c5b5
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
TAG=0.0.6
TAG=0.0.8
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ The use cases supported by the three demos are summarized in conceptual block di
- 🚨 ISO 15118 DC Charging ⚡: `curl https://raw.githubusercontent.com/everest/everest-demo/main/demo-iso15118-2-dc.sh | bash`
- 🚨 Two EVSE Charging ⚡: `curl https://raw.githubusercontent.com/everest/everest-demo/main/demo-two-evse.sh | bash`
- 🚨 E2E Automated Tests ⚡: `curl https://raw.githubusercontent.com/everest/everest-demo/main/demo-automated-testing.sh | bash`
- 🚨 Basic and ISO 15118-2 AC Charging with OCPP 1.6J CSMS ⚡: `curl https://raw.githubusercontent.com/everest/everest-demo/main/demo-iso15118-2-ac-plus-ocpp16j.sh | bash`

### STEP 2: Interact with the demo
- Open the `nodered` flows to understand the module flows at http://127.0.0.1:1880
Expand Down
34 changes: 34 additions & 0 deletions demo-iso15118-2-ac-plus-ocpp16j.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash

DEMO_COMPOSE_FILE_NAME='docker-compose.ocpp16j.yml'
DEMO_DIR="$(mktemp -d)"

delete_temporary_directory() { rm -rf "${DEMO_DIR}"; }
trap delete_temporary_directory EXIT

if [[ ! "${DEMO_DIR}" || ! -d "${DEMO_DIR}" ]]; then
echo 'Error: Failed to create a temporary directory for the demo.'
exit 1
fi

download_demo_file() {
local -r repo_file_path="$1"
local -r repo_raw_url='https://raw.githubusercontent.com/everest/everest-demo/main'
local -r destination_path="${DEMO_DIR}/${repo_file_path}"

mkdir -p "$(dirname ${destination_path})"
curl -s -o "${destination_path}" "${repo_raw_url}/${repo_file_path}"
if [[ "$?" != 0 ]]; then
echo "Error: Failed to retrieve \"${repo_file_path}\" from the demo"
echo 'repository. If this issue persists, please report this as an'
echo 'issue in the EVerest project:'
echo ' https://github.com/EVerest/EVerest/issues'
exit 1
fi
}

download_demo_file "${DEMO_COMPOSE_FILE_NAME}"
download_demo_file .env

docker compose --project-name everest-ac-demo \
--file "${DEMO_DIR}/${DEMO_COMPOSE_FILE_NAME}" up
4 changes: 2 additions & 2 deletions docker-compose.automated-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ version: "3.6"

services:
mqtt-server:
image: ghcr.io/us-joet/everest-demo/mqtt-server:${TAG}
image: ghcr.io/everest/everest-demo/mqtt-server:${TAG}
logging:
driver: none

manager:
image: ghcr.io/us-joet/everest-demo/manager:${TAG}
image: ghcr.io/everest/everest-demo/manager:${TAG}
depends_on:
- mqtt-server
environment:
Expand Down
35 changes: 27 additions & 8 deletions docker-compose.build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,48 @@ services:
mqtt-server:
image: ghcr.io/everest/everest-demo/mqtt-server:${TAG}
build: mosquitto
platform: linux/x86_64
logging:
driver: none

manager:
image: ghcr.io/everest/everest-demo/manager:${TAG}
build: manager
platform: linux/x86_64
depends_on:
- mqtt-server
environment:
- MQTT_SERVER_ADDRESS=mqtt-server
entrypoint: "sh ./build/run-scripts/run-sil.sh"
entrypoint: "sh ./build/run-scripts/run-sil-ocpp.sh"
sysctls:
- net.ipv6.conf.all.disable_ipv6=0

node-red:
image: ghcr.io/everest/everest-demo/nodered:${TAG}
ocpp-db:
image: mariadb:10.4.30
command: [ "--datadir", "/var/lib/mysql-no-volume" ]
ports:
- 13306:3306
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: ocpp-db
MYSQL_USER: ocpp
MYSQL_PASSWORD: ocpp

steve:
build: steve
ports:
- 8180:8180
- 8443:8443
depends_on:
- ocpp-db

nodered:
build: nodered
image: ghcr.io/everest/everest-demo/nodered:${TAG}
depends_on:
- mqtt-server
environment:
- MQTT_SERVER_ADDRESS=mqtt-server
- FLOWS=/config/config-sil-flow.json
ports:
- 1880:1880
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
environment:
- MQTT_SERVER_ADDRESS=mqtt-server
- FLOWS=/config/config-sil-two-evse-flow.json
48 changes: 48 additions & 0 deletions docker-compose.ocpp16j.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
version: "3.6"

services:
mqtt-server:
image: ghcr.io/everest/everest-demo/mqtt-server:${TAG}
platform: linux/x86_64
logging:
driver: none

manager:
image: ghcr.io/everest/everest-demo/manager:${TAG}
platform: linux/x86_64
depends_on:
- mqtt-server
environment:
- MQTT_SERVER_ADDRESS=mqtt-server
entrypoint: "sh ./build/run-scripts/run-sil-ocpp.sh"
sysctls:
- net.ipv6.conf.all.disable_ipv6=0

ocpp-db:
image: ghcr.io/us-joet/everest-demo/ocpp-db-compiled:0.0.1
command: [ "--datadir", "/var/lib/mysql-no-volume" ]
ports:
- 13306:3306
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: ocpp-db
MYSQL_USER: ocpp
MYSQL_PASSWORD: ocpp

steve:
image: ghcr.io/us-joet/everest-demo/steve-configured:0.0.1
ports:
- 8180:8180
- 8443:8443
depends_on:
- ocpp-db

nodered:
image: ghcr.io/everest/everest-demo/nodered:${TAG}
depends_on:
- mqtt-server
ports:
- 1880:1880
environment:
- MQTT_SERVER_ADDRESS=mqtt-server
- FLOWS=/config/config-sil-two-evse-flow.json
17 changes: 17 additions & 0 deletions steve/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM maven:3.6.1-jdk-11

ENV LANG=C.UTF-8 LC_ALL=C.UTF-8

WORKDIR /steve

ENV DOCKERIZE_VERSION v0.6.1
RUN wget --no-verbose https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz

RUN wget -qO- https://github.com/RWTH-i5-IDSG/steve/archive/steve-3.6.0.tar.gz | tar xz --strip-components=1
COPY main.properties src/main/resources/config/docker
COPY init.sh .
COPY keystore.jks .

CMD /steve/init.sh
57 changes: 57 additions & 0 deletions steve/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# SteVe Image

The [SteVe](https://github.com/steve-community/steve) image provides a simulated
OCPP Central System for the OCPP 1.6J demo.

## Looking for the SteVe OCPP 1.6J demo?
You've gone to far! Please visit the root directory of this repository to find the OCPP 1.6J Docker Compose file and a one-liner in the README.md for executing it.

## For Demo Developers Only: Build & Configuration Process
There are currently automated and manual steps to building this image.

First, a SteVe image is created without chargers or OCPP ID tags configured and stood up as a service using Docker Compose. This can be done by running the following command from the root of this Git repository:
```shell
docker compose -f docker-compose.build.yml up -d steve
```

The build process is fairly long, taking anywhere from 5--30 minutes on a modern system. Once an image is built, a SteVe server will be running in a container alongside a MariaDB instance configured to provide a database layer for SteVe.

The remainder of the setup process is manual:
1. With SteVe and MariaDB containers still running, visit http://localhost:8180
2. Log into the SteVe server with username `admin` and password `1234` when prompted.
3. Visit http://localhost:8180/steve/manager/chargepoints/add
4. Enter a `ChargeBox ID` of `cp001` and set `Registration status` to `Accepted`.
5. Click the `Add` button at the bottom of the form.
6. Visit http://localhost:8180/steve/manager/ocppTags/add
7. Enter an `ID Tag` value of `DEADBEEF` and a `Max. Active Transaction Count` of `2`.
8. Click the `Add` button at the bottom of the form.
9. Repeat steps 6--8 for two additional OCPP ID tags with the following attributes:
- `ID Tag`: `ABC12345`, `Max. Active Transaction Count`: `1`
- `ID Tag`: `VID:AABBCCDDEEFF`, `Max. Active Transaction Count`: `0`
10. Visit the [EVerest steve-configured package page](https://github.com/EVerest/everest-demo/pkgs/container/everest-demo%2Fsteve-configured) on GitHub and determine the most recent `A.B.C` tag for this image.
11. Use [semantic versioning](https://semver.org) to determine what the appropriate updated tag is for your new version of the `steve-configured` image.
12. From a terminal, commit the running SteVe container using
```shell
docker commit everest-demo-steve-1 ghcr.io/everest/everest-demo/steve-configured:X.Y.Z
```
where `X.Y.Z` should be replaced with the new semantic version for the image you determined in step 11.
13. Repeat steps 10--12 for the running MariaDB container and [EVerest `ocpp-db-compiled` image](https://github.com/EVerest/everest-demo/pkgs/container/everest-demo%2Focpp-db-compiled). Your Docker Commit command should look like the following:
```shell
docker commit everest-demo-ocpp-db-1 ghcr.io/everest/everest-demo/ocpp-db-compiled:X.Y.Z
```
again replacing `X.Y.Z` with the relevant semantic version from step 11.
14. Push each of these newly-created image versions to the EVerest project with
```shell
# Remember to replace the X.Y.Z with your new version tag!
docker push ghcr.io/everest/everest-demo/steve-configured:X.Y.Z
```
and
```shell
# Remember to replace the X.Y.Z with your new version tag!
docker push ghcr.io/everest/everest-demo/ocpp-db-compiled:X.Y.Z
```

> **Note:** The OCPP ID tags are configured so that `DEADBEEF` (the default) can authenticate against two chargers simultaneously (that is, can be involved in two concurrent transactions). In contrast, `ABC12345` can only work one charger at a time, and `VID:AABBCCDDEEFF` is blocked entirely from charging vehicles. Choosing different combinations of demo connectors and OCPP tags (as well as authenticating before/after plugging in a simulated vehicle) can demonstrate a variety of basic authentication scenarios. The configurations for these IDs can be modified within the SteVe administration webapp to support other scenarios.
>
> The OCPP Tag IDs themselves are defined in the Node-Red flows for the two EVSE demo.
10 changes: 10 additions & 0 deletions steve/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
set -e # exit on any error
dockerize -wait tcp://ocpp-db:3306 -timeout 60s

if [ ! -f ".buildsuccess" ]; then
mvn clean package -Pdocker -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"
touch .buildsuccess
fi

java -jar target/steve.jar
Binary file added steve/keystore.jks
Binary file not shown.
57 changes: 57 additions & 0 deletions steve/main.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Just to be backwards compatible with previous versions, this is set to "steve",
# since there might be already configured chargepoints expecting the older path.
# Otherwise, might as well be changed to something else or be left empty.
#
context.path = steve

# Database configuration
#
db.ip = ocpp-db
db.port = 3306
db.schema = ocpp-db
db.user = ocpp
db.password = ocpp

# Credentials for Web interface access
#
auth.user = admin
auth.password = 1234

# Jetty configuration
#
server.host = 0.0.0.0
server.gzip.enabled = false

# Jetty HTTP configuration
#
http.enabled = true
http.port = 8180

# Jetty HTTPS configuration
#
https.enabled = true
https.port = 8443
keystore.path = /steve/keystore.jks
keystore.password = 123456

# When the WebSocket/Json charge point opens more than one WebSocket connection,
# we need a mechanism/strategy to select one of them for outgoing requests.
# For allowed values see de.rwth.idsg.steve.ocpp.ws.custom.WsSessionSelectStrategyEnum.
#
ws.session.select.strategy = ALWAYS_LAST

# if BootNotification messages arrive (SOAP) or WebSocket connection attempts are made (JSON) from unknown charging
# stations, we reject these charging stations, because stations with these chargeBoxIds were NOT inserted into database
# beforehand. by setting this property to true, this behaviour can be modified to automatically insert unknown
# stations into database and accept their requests.
#
# CAUTION: setting this property to true is very dangerous, because we will accept EVERY BootNotification or WebSocket
# connection attempt from ANY sender as long as the sender knows the URL and sends a valid message.
#
auto.register.unknown.stations = false

### DO NOT MODIFY ###
steve.version = ${project.version}
git.describe = ${git.commit.id.describe}
db.sql.logging = false
profile = prod

0 comments on commit 5b1c5b5

Please sign in to comment.