Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🦈⚡ Add Edgeshark and Eonti MRE #60

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@
- Run the demo: 💄 exploring configs 🔧: `curl -o docker-compose.yml https://raw.githubusercontent.com/everest/everest-demo/main/docker-compose.admin-panel.yml && docker compose -p everest-admin-panel up`
- Access the visual representation at http://localhost:8849

### OPTIONAL: Explore a demo with Edgeshark

Check notice on line 102 in README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

README.md#L102

Expected: 1; Actual: 0; Below
- For each demo using `demo-iso15118-2-ac-plus-ocpp.sh`, the demo may be ran alongside [Edgeshark](httpos://github.com/siemans/edgeshark?tab=readme-ov-file#edgeshark) for additional information on the network connection between each container.

Check notice on line 103 in README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

README.md#L103

Lists should be surrounded by blank lines
- To launch a Edgeshark alongside one of these demos, include the `-s` flag when running the demo
- 🦈 Example Profile 2 ⚡: `curl https://raw.githubusercontent.com/everest/everest-demo/main/demo-iso15118-2-ac-plus-ocpp.sh | bash -s -- -s -2`
- Using your preferred web browser, navigate to [http://localhost:5001](http://localhost:5001) and explore the connections via the discovery engine.
- If you have installed the [cshargextcap plugin](https://github.com/siemens/cshargextcap?tab=readme-ov-file#containershark-extcap-plugin-for-wireshark), you may launch [Wireshark Desktop](https://www.wireshark.org/download.html) from the discovery engine, to perform a live capture.

### TEARDOWN: Clean up after the demo
- Kill the demo process
- Delete files and containers: `docker compose -p [prefix] down && rm docker-compose.yml`
Expand Down
95 changes: 68 additions & 27 deletions demo-iso15118-2-ac-plus-ocpp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
DEMO_REPO="https://github.com/everest/everest-demo.git"
DEMO_BRANCH="main"

CSMS_REPO="https://github.com/thoughtworks/maeve-csms.git"
CSMS_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit
CSMS_REPO="https://github.com/louisg1337/maeve-csms.git"
# CSMS_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit
CSMS_BRANCH="set_charging_profile"
CSMS="maeve"



usage="usage: $(basename "$0") [-r <repo>] [-b <branch>] [-c <csms>] [-j|1|2|3] [-h]
usage="usage: $(basename "$0") [-r <repo>] [-b <branch>] [-c <csms>] [-s] [-e] [-j|1|2|3] [-h]

This script will run EVerest ISO 15118-2 AC charging with OCPP demos.

Expand All @@ -21,6 +22,8 @@ where:
-r URL to everest-demo repo to use (default: $DEMO_REPO)
-b Branch of everest-demo repo to use (default: $DEMO_BRANCH)
-c Use CitrineOS CSMS (default: MaEVe)
-s Run with Edgeshark
-e Use EonTi Certificates (with OCPP v2.0.1 Security Profile 2 or 3)
-j OCPP v1.6j
-1 OCPP v2.0.1 Security Profile 1
-2 OCPP v2.0.1 Security Profile 2
Expand All @@ -30,16 +33,19 @@ where:

DEMO_VERSION=
DEMO_COMPOSE_FILE_NAME=

RUN_WITH_EDGESHARK=false
CERTS="self_signed"

# loop through positional options/arguments
while getopts ':r:b:cj123h' option; do
while getopts ':r:b:c:sej123h' option; do
case "$option" in
r) DEMO_REPO="$OPTARG" ;;
b) DEMO_BRANCH="$OPTARG" ;;
c) CSMS="citrine"
CSMS_REPO="https://github.com/citrineos/citrineos-core"
CSMS_BRANCH="63670f3adc09266a0977862d972b0f7e440c577f" ;;
s) RUN_WITH_EDGESHARK=true ;;
e) CERTS="eonti" ;;
j) DEMO_VERSION="v1.6j"
DEMO_COMPOSE_FILE_NAME="docker-compose.ocpp16j.yml" ;;
1) DEMO_VERSION="v2.0.1-sp1"
Expand Down Expand Up @@ -84,16 +90,29 @@ echo "DEMO VERSION: $DEMO_VERSION"
echo "DEMO CONFIG: $DEMO_COMPOSE_FILE_NAME"
echo "DEMO DIR: $DEMO_DIR"


cd "${DEMO_DIR}" || exit 1


echo "Cloning EVerest from ${DEMO_REPO} into ${DEMO_DIR}/everest-demo"
git clone --branch "${DEMO_BRANCH}" "${DEMO_REPO}" everest-demo
# cp -r "${DEMO_REPO}" everest-demo

echo "Run with Edgeshark? $RUN_WITH_EDGESHARK"

if [[ "$RUN_WITH_EDGESHARK" = true ]]; then
wget -q --no-cache -O - \
https://github.com/siemens/edgeshark/raw/main/deployments/wget/docker-compose-localhost.yaml \
| docker compose -f - up -d
fi

if [[ "$DEMO_VERSION" != v1.6j ]]; then
echo "Cloning ${CSMS} CSMS from ${CSMS_REPO} into ${DEMO_DIR}/${CSMS}-csms and starting it"
git clone ${CSMS_REPO} ${CSMS}-csms

if [[ ${CSMS} == "maeve" ]]; then
git clone --branch "${CSMS_BRANCH}" "${CSMS_REPO}" ${CSMS}-csms
else
git clone ${CSMS_REPO} ${CSMS}-csms
fi

pushd ${CSMS}-csms || exit 1

Expand All @@ -114,17 +133,28 @@ if [[ "$DEMO_VERSION" != v1.6j ]]; then
fi
else
cp ../everest-demo/manager/cached_certs_correct_name_emaid.tar.gz .

echo "Patching the CSMS to disable load balancer"
patch -p1 -i ../everest-demo/maeve/maeve-csms-no-lb.patch
fi

# Set up certificates for SP2 and SP3
if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then
if [[ "$CSMS" == "citrine" ]]; then
echo "Security profile 2/3 is not supported with Citrine yet!"
exit 1
else
fi
if [[ "$CERTS" == "eonti" ]]; then
echo "Copying EonTi certs into ${DEMO_DIR}/maeve-csms/config/certificates"
tar xf cached_certs_correct_name_emaid.tar.gz
cat dist/etc/everest/certs/eonti/evse_leaf_primary \
dist/etc/everest/certs/eonti/cpo_p256_CA2 \
dist/etc/everest/certs/eonti/cpo_CA1 \
> config/certificates/csms.pem
cat dist/etc/everest/certs/eonti/cpo_p256_CA2 \
dist/etc/everest/certs/eonti/cpo_CA1 \
> config/certificates/trust.pem
cp dist/etc/everest/certs/eonti/valid_evse_key config/certificates/csms.key
cp dist/etc/everest/certs/eonti/V2G_root config/certificates/root-V2G-cert.pem
cp dist/etc/everest/certs/eonti/MO_root config/certificates/root-MO-cert.pem
else # Use self-signed certs
echo "Copying certs into ${DEMO_DIR}/maeve-csms/config/certificates"
tar xf cached_certs_correct_name_emaid.tar.gz
cat dist/etc/everest/certs/client/csms/CSMS_LEAF.pem \
Expand All @@ -137,23 +167,23 @@ if [[ "$DEMO_VERSION" != v1.6j ]]; then
cp dist/etc/everest/certs/client/csms/CSMS_LEAF.key config/certificates/csms.key
cp dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem config/certificates/root-V2G-cert.pem
cp dist/etc/everest/certs/ca/mo/MO_ROOT_CA.pem config/certificates/root-MO-cert.pem
fi

echo "Validating that the certificates are set up correctly"
openssl verify -show_chain \
-CAfile config/certificates/root-V2G-cert.pem \
-untrusted config/certificates/trust.pem \
config/certificates/csms.pem

echo "Patching the CSMS to enable EVerest organization"
patch -p1 -i ../everest-demo/maeve/maeve-csms-everest-org.patch
echo "Patching the CSMS to enable local mo root"
patch -p1 -i ../everest-demo/maeve/maeve-csms-local-mo-root.patch
echo "Patching the CSMS to enable local mo root"
patch -p1 -i ../everest-demo/maeve/maeve-csms-ignore-ocsp.patch
echo "Validating that the certificates are set up correctly"
openssl verify -show_chain \
-CAfile config/certificates/root-V2G-cert.pem \
-untrusted config/certificates/trust.pem \
config/certificates/csms.pem

echo "Patching the CSMS to enable EVerest organization"
patch -p1 -i ../everest-demo/maeve/maeve-csms-everest-org.patch

echo "Patching the CSMS to enable local mo root"
patch -p1 -i ../everest-demo/maeve/maeve-csms-local-mo-root.patch

echo "Patching the CSMS to enable local mo root"
patch -p1 -i ../everest-demo/maeve/maeve-csms-ignore-ocsp.patch

fi
elif [[ ${CSMS} == "maeve" ]]; then
echo "Patching the CSMS to disable WSS"
patch -p1 -i ../everest-demo/maeve/maeve-csms-no-wss.patch
Expand All @@ -176,6 +206,7 @@ if [[ "$DEMO_VERSION" != v1.6j ]]; then
fi
fi

docker compose build
docker compose up -d

echo "Waiting 5s for CSMS to start..."
Expand Down Expand Up @@ -340,7 +371,17 @@ fi

pushd everest-demo || exit 1
docker compose --project-name everest-ac-demo --file "${DEMO_COMPOSE_FILE_NAME}" up -d --wait

# Configure and restart nodered
docker cp nodered/config/config-sil-iso15118-ac-flow.json everest-ac-demo-nodered-1:/config/config-sil-two-evse-flow.json
docker restart everest-ac-demo-nodered-1

# Configure and restart EVerest
docker cp config-sil-ocpp201-pnc.yaml everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml
docker cp manager/enable_payment_method.patch everest-ac-demo-manager-1:/tmp/
docker cp manager/enable_evcc_logging.cfg everest-ac-demo-manager-1:/ext/source/build/dist/etc/everest/default_logging.cfg
docker exec everest-ac-demo-manager-1 /bin/bash -c "apk add patch && cd /ext && patch -p0 -i /tmp/enable_payment_method.patch"

if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then
docker cp manager/cached_certs_correct_name_emaid.tar.gz everest-ac-demo-manager-1:/ext/source/build
docker exec everest-ac-demo-manager-1 /bin/bash -c "pushd /ext/source/build && tar xf cached_certs_correct_name_emaid.tar.gz"
Expand All @@ -349,7 +390,7 @@ if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then
docker exec everest-ac-demo-manager-1 /bin/bash -c "pushd /ext/source/build && openssl verify -show_chain -CAfile dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem --untrusted dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem --untrusted dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem dist/etc/everest/certs/client/csms/CSMS_LEAF.pem"
fi

if [[ ${CSMS} == "citrine" ]]; then
if [[ ${CSMS} == "citrine" && ! ("$DEMO_VERSION" =~ sp1) ]]; then
echo "TODO: Set up device model correctly!"
else
if [[ "$DEMO_VERSION" =~ sp1 ]]; then
Expand Down
101 changes: 101 additions & 0 deletions demo-scripts/citrine-set-charging-profile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/bash

# Check if the correct number of arguments are provided
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <identifier> <tenantId>"
exit 1
fi

# Assign arguments to variables
IDENTIFIER=$1
TENANT_ID=$2

echo "setChargingProfile called with Identifier: ${IDENTIFIER} and tenandId: ${TENANT_ID}"

curl -X 'POST' \
"http://localhost:8080/ocpp/smartcharging/setChargingProfile?identifier=${IDENTIFIER}&tenantId=${TENANT_ID}" \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"customData": {
"vendorId": "string"
},
"evseId": 0,
"chargingProfile": {
"customData": {
"vendorId": "string"
},
"id": 0,
"stackLevel": 0,
"chargingProfilePurpose": "ChargingStationExternalConstraints",
"chargingProfileKind": "Absolute",
"recurrencyKind": "Daily",
"validFrom": "2024-06-03T21:58:35.240Z",
"validTo": "2024-06-03T21:58:35.240Z",
"chargingSchedule": [
{
"customData": {
"vendorId": "string"
},
"id": 0,
"startSchedule": "2024-06-03T21:58:35.240Z",
"duration": 0,
"chargingRateUnit": "W",
"chargingSchedulePeriod": [
{
"customData": {
"vendorId": "string"
},
"startPeriod": 0,
"limit": 0,
"numberPhases": 0,
"phaseToUse": 0
}
],
"minChargingRate": 0,
"salesTariff": {
"customData": {
"vendorId": "string"
},
"id": 0,
"salesTariffDescription": "string",
"numEPriceLevels": 0,
"salesTariffEntry": [
{
"customData": {
"vendorId": "string"
},
"relativeTimeInterval": {
"customData": {
"vendorId": "string"
},
"start": 0,
"duration": 0
},
"ePriceLevel": 0,
"consumptionCost": [
{
"customData": {
"vendorId": "string"
},
"startValue": 0,
"cost": [
{
"customData": {
"vendorId": "string"
},
"costKind": "CarbonDioxideEmission",
"amount": 0,
"amountMultiplier": 0
}
]
}
]
}
]
}
}
],
"transactionId": "string"
}
}'
66 changes: 66 additions & 0 deletions demo-scripts/maeve-set-charging-profile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/bash

if [ "$#" -ne 1 ]; then
echo "Usage: $0 <chargingStation>"
exit 1
fi

CS=$1

echo "setChargingProfile called with Charging Station: ${CS}"

curl -X POST \
"http://localhost:9410/api/v0/cs/${CS}/setchargingprofile" \
-H "Content-Type: application/json" \
-d '{
"chargingProfileKind": "Absolute",
"chargingProfilePurpose": "TxProfile",
"chargingSchedule": [
{
"chargingRateUnit": "W",
"chargingSchedulePeriod": [
{
"limit": 22.5,
"startPeriod": 0,
"numberPhases": 3
},
{
"limit": 20.0,
"startPeriod": 3600,
"numberPhases": 3
}
],
"id": 1,
"minChargingRate": 5.0,
"salesTariff": {
"id": 1,
"numEPriceLevels": 2,
"salesTariffDescription": "Standard Tariff",
"salesTariffEntry": [
{
"relativeTimeInterval": {
"start": 0,
"duration": 3600
},
"consumptionCost": [
{
"cost": [
{
"amount": 15,
"costKind": "RelativePricePercentage"
}
],
"startValue": 10.0
}
]
}
]
}
}
],
"id": 1,
"stackLevel": 0,
"transactionId": "12345",
"validFrom": "2024-06-07T10:00:00Z",
"validTo": "2024-06-07T18:00:00Z"
}'
Loading