From 80a66b1a2d57a89aab9737fe59a97c3a22d9e36f Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 29 May 2024 13:28:30 +0200 Subject: [PATCH 01/18] add SP1 citrineos support --- citrineos/add-charger.sh | 176 ++++++++++++++++++ citrineos/directus-env-config.cjs | 13 ++ citrineos/docker-compose.yml | 95 ++++++++++ demo-iso15118-2-ac-plus-ocpp.sh | 43 ++++- manager/Dockerfile | 2 +- ...eve_sp1.db => device_model_storage_sp1.db} | Bin 81920 -> 81920 bytes ...eve_sp2.db => device_model_storage_sp2.db} | Bin ...eve_sp3.db => device_model_storage_sp3.db} | Bin 8 files changed, 322 insertions(+), 7 deletions(-) create mode 100755 citrineos/add-charger.sh create mode 100644 citrineos/directus-env-config.cjs create mode 100644 citrineos/docker-compose.yml rename manager/{device_model_storage_maeve_sp1.db => device_model_storage_sp1.db} (98%) rename manager/{device_model_storage_maeve_sp2.db => device_model_storage_sp2.db} (100%) rename manager/{device_model_storage_maeve_sp3.db => device_model_storage_sp3.db} (100%) diff --git a/citrineos/add-charger.sh b/citrineos/add-charger.sh new file mode 100755 index 00000000..5fe19f47 --- /dev/null +++ b/citrineos/add-charger.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash + +# Configuration +DIRECTUS_API_URL="http://localhost:8055" +CHARGEPOINT_ID="cp001" +CP_PASSWORD="DEADBEEFDEADBEEF" +DIRECTUS_EMAIL="admin@citrineos.com" +DIRECTUS_PASSWORD="CitrineOS!" + +#TODO put github images +PROJECT_LOGO_IMAGE_URL="https://public-citrineos-logo.s3.amazonaws.com/Citrine-Directus-Project-Logo.png" +PUBLIC_BACKGROUND_IMAGE_URL="https://public-citrineos-logo.s3.amazonaws.com/Citrine-Directus-Public-Background.png" + +# Function to get the Directus token +get_directus_token() { + local login_url="${DIRECTUS_API_URL}/auth/login" + local json_body=$(printf '{"email": "%s", "password": "%s"}' "$DIRECTUS_EMAIL" "$DIRECTUS_PASSWORD") + local response=$(curl -s -X POST "$login_url" -H "Content-Type: application/json" -d "$json_body") + + # Extract token from the response + local token=$(jq -r '.data.access_token' <<< "$response") + echo "$token" +} + +# Function to upload an image via URL to Directus +upload_image() { + + local token=$1 + local image_url=$2 + local title=$3 + local response=$(curl -s -X POST "${DIRECTUS_API_URL}/files/import" \ + -H "Authorization: Bearer ${token}" \ + -H "Content-Type: application/json" \ + -d "{ + \"url\": \"${image_url}\", + \"data\": { + + \"title\": \"${title}\" + } + }"| tee /dev/tty && echo) + + local file_id=$(jq -r '.data.id' <<< "$response") + + echo "$file_id" +} + +# Function to set the project image +set_project_image() { + local token=$1 + local project_logo=$2 + local project_background=$3 + curl -s -X PATCH "${DIRECTUS_API_URL}/settings" \ + -H "Authorization: Bearer ${token}" \ + -H "Content-Type: application/json" \ + -d "{ + \"project_logo\": \"${project_logo}\", + \"public_background\": \"${project_background}\" + }" | tee /dev/tty && echo +} + +# Function to add a new location +add_location() { + local token=$1 + local response=$(curl -s -X POST "${DIRECTUS_API_URL}/items/Locations" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + -d '{ + "id": "2", + "name": "New EVerst", + "coordinates": { + "type": "Point", + "coordinates": [-74.0620872, 41.041548] + } + }' | tee /dev/tty && echo) + + local location_id=$(jq -r '.data.id' <<< "$response") + echo "$location_id" +} + +# Function to add a charging station +add_charging_station() { + local token=$1 + local location_id=$2 + local chargepointId=$3 + curl -s --request POST \ + --url "${DIRECTUS_API_URL}/items/ChargingStations" \ + --header "Authorization: Bearer $token" \ + --header "Content-Type: application/json" \ + --data '{ + "id": "'$chargepointId'", + "locationId": "'$location_id'" + }' | tee /dev/tty && echo +} + +# Function to update SP1 password +add_cp001_password() { + local response + local success=false + local attempt=1 + local passwordString=$1 + + until $success; do + echo "Attempt $attempt: Updating SP1 password..." + response=$(curl -s -o /dev/null -w "%{http_code}" --location --request PUT "http://localhost:8080/data/monitoring/variableAttribute?stationId=${CHARGEPOINT_ID}&setOnCharger=true" \ + --header "Content-Type: application/json" \ + --data-raw '{ + "component": { + "name": "SecurityCtrlr" + }, + "variable": { + "name": "BasicAuthPassword" + }, + "variableAttribute": [ + { + "value": "'$passwordString'" + } + ], + "variableCharacteristics": { + "dataType": "passwordString", + "supportsMonitoring": false + } + }' | tee /dev/tty) + + + if [[ $response -ge 200 && $response -lt 300 ]]; then + echo "Password update successful." + success=true + else + echo "Password update failed with HTTP status: $response. Retrying in 2 second..." + sleep 2 + ((attempt++)) + fi + done +} + +# Main script execution +TOKEN=$(get_directus_token) +echo "Received Token: $TOKEN" + +if [ -z "$TOKEN" ]; then + echo "Failed to retrieve access token." + exit 1 +fi + +# Upload image and set as project logo +echo "Uploading project images..." +FILE_ID_LOGO=$(upload_image "$TOKEN" "$PROJECT_LOGO_IMAGE_URL" "Citrine Logo") + +if [ -z "$FILE_ID_LOGO" ]; then + echo "Failed to upload project image." + exit 1 +fi +FILE_ID_BACKGROUND=$(upload_image "$TOKEN" "$PUBLIC_BACKGROUND_IMAGE_URL" "Citrine Background") +if [ -z "$FILE_ID_BACKGROUND" ]; then + echo "Failed to upload project image." + exit 1 +fi + +echo "Setting project image..." +set_project_image "$TOKEN" "$FILE_ID_LOGO" "$FILE_ID_BACKGROUND" + +echo "Adding a new location..." +LOCATION_ID=$(add_location "$TOKEN") + +if [ -z "$LOCATION_ID" ]; then + echo "Failed to add new location." + exit 1 +fi + +echo "Location ID: $LOCATION_ID" + +echo "Adding new station..." +add_charging_station "$TOKEN" "$LOCATION_ID" "$CHARGEPOINT_ID" + +echo "Add cp001 password to citrine..." +add_cp001_password "$CP_PASSWORD" \ No newline at end of file diff --git a/citrineos/directus-env-config.cjs b/citrineos/directus-env-config.cjs new file mode 100644 index 00000000..1e3882b9 --- /dev/null +++ b/citrineos/directus-env-config.cjs @@ -0,0 +1,13 @@ +module.exports = function (env) { + const config = { + // API Paths + CITRINEOS_SUBSCRIPTION_API_PATH: '/data/ocpprouter/subscription', + DIRECTUS_CHARGING_STATION_UPDATE_STATUS_PATH: + '/charging-stations/update-station-status', + // Environment-specific urls + CITRINEOS_URL: 'http://citrine:8080', + DIRECTUS_URL: 'http://directus:8055', + }; + + return config; +}; \ No newline at end of file diff --git a/citrineos/docker-compose.yml b/citrineos/docker-compose.yml new file mode 100644 index 00000000..2b70f33f --- /dev/null +++ b/citrineos/docker-compose.yml @@ -0,0 +1,95 @@ +services: + amqp-broker: + image: rabbitmq:3-management + ports: + - 15672:15672 + - 5672:5672 + environment: + RABBITMQ_DEFAULT_USER: 'guest' + RABBITMQ_DEFAULT_PASS: 'guest' + volumes: + - ./data/rabbitmq:/var/lib/rabbitmq + healthcheck: + test: rabbitmq-diagnostics -q ping + interval: 10s + timeout: 10s + retries: 3 + ocpp-db: + image: citrineos/postgis:v1.1.0 + ports: + - 5432:5432 + volumes: + - ./data/postgresql/pgdata:/var/lib/postgresql/data + environment: + POSTGRES_DB: citrine + POSTGRES_USER: citrine + POSTGRES_PASSWORD: 'citrine' + healthcheck: + test: 'pg_isready --username=citrine' + interval: 5s + timeout: 10s + retries: 5 + + redis: + image: redis:latest + ports: + - '6379:6379' + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 10s + timeout: 5s + retries: 3 + citrine: + image: ghcr.io/citrineos/citrineos-server:1.1.2 + environment: + APP_NAME: 'all' + APP_ENV: 'docker' + CITRINEOS_UTIL_DIRECTUS_USERNAME: 'admin@citrineos.com' + CITRINEOS_UTIL_DIRECTUS_PASSWORD: 'CitrineOS!' + depends_on: + ocpp-db: + condition: service_healthy + amqp-broker: + condition: service_healthy + directus: + condition: service_healthy + redis: + condition: service_healthy + ports: + - 8080:8080 + - 8081:8081 + - 8082:8082 + - 9229:9229 + + directus: + image: ghcr.io/chrisweissmann/everest-demo/citrineos-directus:1.1.0 + ports: + - 8055:8055 + volumes: + - ./directus-env-config.cjs:/directus/config.cjs + depends_on: + ocpp-db: + condition: service_healthy + environment: + APP_NAME: 'all' + KEY: '1234567890' + SECRET: '0987654321' + ADMIN_EMAIL: 'admin@citrineos.com' + ADMIN_PASSWORD: 'CitrineOS!' + CONFIG_PATH: '/directus/config.cjs' + EXTENSIONS_AUTO_RELOAD: 'true' + EXTENSIONS_CACHE_TTL: '1s' + DB_CLIENT: 'pg' + DB_HOST: ocpp-db + DB_PORT: 5432 + DB_DATABASE: 'citrine' + DB_USER: 'citrine' + DB_PASSWORD: 'citrine' + WEBSOCKETS_ENABLED: 'true' + healthcheck: + test: wget --no-verbose --tries=1 --spider http://127.0.0.1:8055/server/health || exit 1 + start_period: 15s + start_interval: 5s + interval: 15s + timeout: 15s + retries: 3 \ No newline at end of file diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 7c211634..7d31d423 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -8,7 +8,7 @@ MAEVE_REPO="https://github.com/thoughtworks/maeve-csms.git" MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit -usage="usage: $(basename "$0") [-r ] [-b ] [-j|1|2|3] [-h] +usage="usage: $(basename "$0") [-r ] [-b ] [-j|1|2|3|m|c] [-h] This script will run EVerest ISO 15118-2 AC charging with OCPP demos. @@ -22,15 +22,18 @@ where: -1 OCPP v2.0.1 Security Profile 1 -2 OCPP v2.0.1 Security Profile 2 -3 OCPP v2.0.1 Security Profile 3 + -m MaEVe CSMS + -c CitrineOS CSMS -h Show this message" DEMO_VERSION= DEMO_COMPOSE_FILE_NAME= +DEMO_CSMS= # loop through positional options/arguments -while getopts ':r:b:j123h' option; do +while getopts ':r:b:j123mch' option; do case "$option" in r) DEMO_REPO="$OPTARG" ;; b) DEMO_BRANCH="$OPTARG" ;; @@ -42,6 +45,8 @@ while getopts ':r:b:j123h' option; do DEMO_COMPOSE_FILE_NAME="docker-compose.ocpp201.yml" ;; 3) DEMO_VERSION="v2.0.1-sp3" DEMO_COMPOSE_FILE_NAME="docker-compose.ocpp201.yml" ;; + m) DEMO_CSMS="maeve" ;; + c) DEMO_CSMS="citrineos" ;; h) echo -e "$usage"; exit ;; \?) echo -e "illegal option: -$OPTARG\n" >&2 echo -e "$usage" >&2 @@ -57,7 +62,14 @@ if [[ ! "${DEMO_VERSION}" ]]; then exit 1 fi +if [[ "${DEMO_VERSION}" != "v1.6j" && -z "${DEMO_CSMS}" ]]; then + echo 'Error: no 2.0.1 csms option provided.' + echo 'Use -c for CitrineOS or -m MaEVe' + echo + echo -e "$usage" + exit 1 +fi DEMO_DIR="$(mktemp -d)" @@ -77,15 +89,17 @@ echo "DEMO BRANCH: $DEMO_BRANCH" echo "DEMO VERSION: $DEMO_VERSION" echo "DEMO CONFIG: $DEMO_COMPOSE_FILE_NAME" echo "DEMO DIR: $DEMO_DIR" +echo "DEMO CSMS: $DEMO_CSMS" cd "${DEMO_DIR}" || exit 1 +ls -la echo "Cloning EVerest from ${DEMO_REPO} into ${DEMO_DIR}/everest-demo" git clone --branch "${DEMO_BRANCH}" "${DEMO_REPO}" everest-demo -if [[ "$DEMO_VERSION" != v1.6j ]]; then +if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then echo "Cloning MaEVe CSMS from ${MAEVE_REPO} into ${DEMO_DIR}/maeve-csms and starting it" git clone ${MAEVE_REPO} maeve-csms @@ -130,10 +144,10 @@ if [[ "$DEMO_VERSION" != v1.6j ]]; then patch -p1 -i ../everest-demo/maeve/maeve-csms-no-wss.patch fi - echo "Starting the CSMS" + echo "Starting the MaEVe CSMS" docker compose up -d - echo "Waiting 5s for CSMS to start..." + echo "Waiting 5s for MaEVe CSMS to start..." sleep 5 if [[ "$DEMO_VERSION" =~ sp1 ]]; then @@ -167,9 +181,26 @@ if [[ "$DEMO_VERSION" != v1.6j ]]; then popd || exit 1 fi +ls -la +pushd everest-demo || exit 1 +ls -la +if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then + echo "Starting the CitrineOS CSMS" + pushd citrineos || exit 1 + if ! docker compose --project-name citrineos-csms -f ./docker-compose.yml up -d --wait; then + echo "Failed to start CitrineOS." + exit 1 + fi + + ./add-charger.sh + # TODO add SP2 and 3 support here + popd || exit 1 + + +fi + -pushd everest-demo || exit 1 docker compose --project-name everest-ac-demo --file "${DEMO_COMPOSE_FILE_NAME}" up -d --wait docker cp config-sil-ocpp201-pnc.yaml everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then diff --git a/manager/Dockerfile b/manager/Dockerfile index b1605f25..7f681315 100644 --- a/manager/Dockerfile +++ b/manager/Dockerfile @@ -19,7 +19,7 @@ RUN git clone https://github.com/EVerest/everest-core.git \ # Copy over the custom config *after* compilation and installation COPY config-docker.json ./dist/share/everest/modules/OCPP/config-docker.json COPY config.json ./dist/share/everest/modules/OCPP201/config.json -COPY device_model_storage_maeve_sp1.db ./dist/share/everest/modules/OCPP201/device_model_storage.db +COPY device_model_storage_sp1.db ./dist/share/everest/modules/OCPP201/device_model_storage.db COPY run-test.sh /ext/source/tests/run-test.sh diff --git a/manager/device_model_storage_maeve_sp1.db b/manager/device_model_storage_sp1.db similarity index 98% rename from manager/device_model_storage_maeve_sp1.db rename to manager/device_model_storage_sp1.db index 7b96f36b8feeb74ead15f1d8987a757f5a46d981..5d39f3a83752b8f23f8acd295dd4d232f513fbbf 100644 GIT binary patch delta 111 zcmV-#0FeKHfCYen1&|v74v`!~1r7i%c8P&xwPXR#9|8sow=^IDt^ooBE3uI$1Pp^j z76||W0SO2QhJTkEE&<&EESDZG0Tux=mo+W{R0TRXFgP-oj4lCfx6&s8Aq4^s54ZI! R0U7}W0002$w-YV_?GY0&8)X0h delta 68 zcmV-K0K5NyfCYen1&|v74Urr}1q}c$Q(%E)wPXR#9|8^!w=^IDt^ooC^0ATb1-H^C a0U-qf006i3ECCt;1c7H33AYn20qqf@^b=|T diff --git a/manager/device_model_storage_maeve_sp2.db b/manager/device_model_storage_sp2.db similarity index 100% rename from manager/device_model_storage_maeve_sp2.db rename to manager/device_model_storage_sp2.db diff --git a/manager/device_model_storage_maeve_sp3.db b/manager/device_model_storage_sp3.db similarity index 100% rename from manager/device_model_storage_maeve_sp3.db rename to manager/device_model_storage_sp3.db From 335ffdb753d6872f6407fc1796cf49f7eb7d46c0 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 29 May 2024 17:43:19 +0200 Subject: [PATCH 02/18] add citrineos cert support --- citrineos/add-certs-volumes.patch | 13 +++++++ demo-iso15118-2-ac-plus-ocpp.sh | 63 +++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 citrineos/add-certs-volumes.patch diff --git a/citrineos/add-certs-volumes.patch b/citrineos/add-certs-volumes.patch new file mode 100644 index 00000000..7a3677a2 --- /dev/null +++ b/citrineos/add-certs-volumes.patch @@ -0,0 +1,13 @@ +--- docker-compose.yml 2024-05-29 16:26:46 ++++ docker-compose-modified.yml 2024-05-29 16:34:45 +@@ -88,6 +88,10 @@ + - /usr/local/apps/citrineos/03_Modules/Reporting/dist/ + - /usr/local/apps/citrineos/03_Modules/SmartCharging/dist/ + - /usr/local/apps/citrineos/03_Modules/Transactions/dist/ ++ - ./data/certificates/leafKey.pem:/usr/local/apps/citrineos/Server/src/assets/certificates/leafKey.pem ++ - ./data/certificates/certChain.pem:/usr/local/apps/citrineos/Server/src/assets/certificates/certChain.pem ++ - ./data/certificates/subCAKey.pem:usr/local/apps/citrineos/Server/src/assets/certificates/subCAKey.pem ++ - ./data/certificates/rootCertificate.pem:/usr/local/apps/citrineos/Server/src/assets/certificates/rootCertificate.pem + environment: + APP_NAME: 'all' + APP_ENV: 'docker' diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 7d31d423..0c5230b0 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -7,6 +7,10 @@ DEMO_BRANCH="main" MAEVE_REPO="https://github.com/thoughtworks/maeve-csms.git" MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit +CITRINEOS_REPO="https://github.com/citrineos/citrineos-core.git" +CITRINEOS_BRANCH="feature/authorization-c07" + + usage="usage: $(basename "$0") [-r ] [-b ] [-j|1|2|3|m|c] [-h] @@ -22,18 +26,17 @@ where: -1 OCPP v2.0.1 Security Profile 1 -2 OCPP v2.0.1 Security Profile 2 -3 OCPP v2.0.1 Security Profile 3 - -m MaEVe CSMS - -c CitrineOS CSMS + -c Use CitrineOS CSMS (default: MaEVe) -h Show this message" DEMO_VERSION= DEMO_COMPOSE_FILE_NAME= -DEMO_CSMS= +DEMO_CSMS=citrineos # loop through positional options/arguments -while getopts ':r:b:j123mch' option; do +while getopts ':r:b:j123ch' option; do case "$option" in r) DEMO_REPO="$OPTARG" ;; b) DEMO_BRANCH="$OPTARG" ;; @@ -45,7 +48,6 @@ while getopts ':r:b:j123mch' option; do DEMO_COMPOSE_FILE_NAME="docker-compose.ocpp201.yml" ;; 3) DEMO_VERSION="v2.0.1-sp3" DEMO_COMPOSE_FILE_NAME="docker-compose.ocpp201.yml" ;; - m) DEMO_CSMS="maeve" ;; c) DEMO_CSMS="citrineos" ;; h) echo -e "$usage"; exit ;; \?) echo -e "illegal option: -$OPTARG\n" >&2 @@ -94,7 +96,6 @@ echo "DEMO CSMS: $DEMO_CSMS" cd "${DEMO_DIR}" || exit 1 -ls -la echo "Cloning EVerest from ${DEMO_REPO} into ${DEMO_DIR}/everest-demo" git clone --branch "${DEMO_BRANCH}" "${DEMO_REPO}" everest-demo @@ -181,26 +182,58 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then popd || exit 1 fi -ls -la -pushd everest-demo || exit 1 -ls -la + if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then + echo "Cloning CitrineOS CSMS from ${CITRINEOS_REPO} into ${DEMO_DIR}/citrineos-csms and starting it" + git clone --branch "${CITRINEOS_BRANCH}" "${CITRINEOS_REPO}" citrineos-csms + + pushd citrineos-csms || exit 1 + + cp ../everest-demo/manager/cached_certs_correct_name_emaid.tar.gz . + + mkdir -p Server/data/certificates + + echo "Copying certs into ${DEMO_DIR}/citrineos-csms/Server/data/certificates" + tar xf cached_certs_correct_name_emaid.tar.gz + + # Leaf key + cp dist/etc/everest/certs/client/csms/CSMS_LEAF.key Server/data/certificates/csms.key + + #Cert chain + cat dist/etc/everest/certs/client/csms/CSMS_LEAF.pem \ + dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ + dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ + > Server/data/certificates/csms.pem + + # SubCA + cp dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.key Server/data/certificates/subCAKey.pem + + #RootCert + cp dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem Server/data/certificates/rootCertificate.pem + + echo "Copying patch and then patching docker compose to take certs from volume" + cp ../everest-demo/citrineos/add-certs-volumes.patch Server/data/certificates + + pushd Server || exit 1 + patch -p1 -i ./data/certificates/add-certs-volumes.patch echo "Starting the CitrineOS CSMS" - pushd citrineos || exit 1 - if ! docker compose --project-name citrineos-csms -f ./docker-compose.yml up -d --wait; then + + if ! docker compose -f ./docker-compose.yml build && docker compose --project-name citrineos-csms f ./docker-compose.yml up -d --wait; then echo "Failed to start CitrineOS." exit 1 fi - ./add-charger.sh - # TODO add SP2 and 3 support here + echo "Adding a charger to CitrineOS" + ../../everest-demo/citrineos/add-charger.sh + + popd || exit 1 popd || exit 1 fi - - +pushd everest-demo || exit 1 +echo "Starting everest" docker compose --project-name everest-ac-demo --file "${DEMO_COMPOSE_FILE_NAME}" up -d --wait docker cp config-sil-ocpp201-pnc.yaml everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then From b7e47c0a1a90f9c82f314cafb8de0b693f344401 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 29 May 2024 18:32:34 +0200 Subject: [PATCH 03/18] Add citrineos urls to sp2 and sp3 device models --- manager/device_model_storage_sp2.db | Bin 81920 -> 81920 bytes manager/device_model_storage_sp3.db | Bin 81920 -> 81920 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/manager/device_model_storage_sp2.db b/manager/device_model_storage_sp2.db index 9c193ce66520f7e62ff29f2c27c7e1a6d8635a6d..5ac7d34b164aee2ca2625b02fec1c654225c717e 100644 GIT binary patch delta 132 zcmV-~0DJ#{fCYen1&|v74v`!~1r7i%c8P&xwPXR#9|8smw=^IDtpNfADzT9!1Pp^k z76||W0SO2QhXI!wE&<*cEPEnjZ*FF3XLWL6bZKvHQ*3W^B03;4mozQ`J(qGW0T%^2 mI5adfmy9j}ZMV@U0U-qf4i2~UECCt;1ONa4>$egv0qzkhBO_@5 delta 68 zcmV-K0K5NyfCYen1&|v74Urr}1q}c$Q(%E)wPXR#9|8^zw=^IDtpNfB^0ATb1-H>B a0U-qf006i2ECCt;1c7K43AYk10qzl^h7)H1 diff --git a/manager/device_model_storage_sp3.db b/manager/device_model_storage_sp3.db index 9e10ad5b5e26e15e5849c8764ec5f0679bb80468..5ff3bdf43250af72994757a791b7c5e80d94eca4 100644 GIT binary patch delta 127 zcmV-_0D%91fCYen1&|v74v`!~1r7i%c8P&xwPXR#9|8slw=^IDtpNfADY20y1Pp^l z76||W0SO2QhXa=yE&<*cEPEnjZ*FF3XLWL6bZKvHQ*3W^B03;4mozQ`RRuaYG&D4q hj4lCfx6vm7Aq4^s4!86y0U7}W0002%w-PP^?h$=pA~OI0 delta 68 zcmV-K0K5NyfCYen1&|v74Urr}1q}c$Q(%E)wPXR#9|8^zw=^IDtpNfB^0ATb1-H>B a0U-qf006i2ECCt;1c7K43AYk10qzl^h7)H1 From f6a79afbe32001b80cedb528cb4be5598220bb93 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 29 May 2024 19:55:26 +0200 Subject: [PATCH 04/18] patch in local certificates --- citrineos/acme_account_key.pem | 27 +++++++++++++ citrineos/add-certs-volumes.patch | 65 ++++++++++++++++++++++++++----- demo-iso15118-2-ac-plus-ocpp.sh | 18 +++++---- 3 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 citrineos/acme_account_key.pem diff --git a/citrineos/acme_account_key.pem b/citrineos/acme_account_key.pem new file mode 100644 index 00000000..e8a259c1 --- /dev/null +++ b/citrineos/acme_account_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA8ul5QIk9qf+grKDCN1sKPPYsxT4HegfPOm4APr3pISo3rJNy +Ns8MfEryn58h8QJ8w7vSh0ZPlLpJq8oY8Y9ckaiJkNIWvRJYfFjwbMeWTLKteCOQ +lYTUzKEwxhRmQB1HlKPZYo1SFjgqF7ww4q98YFQQw67gzgs/rpLeEZ4pWzOVn4qM ++cBw2B0EgLFER6MI6dVja3t2NkNYRo6Jx0zs+UPKoYci7c9WETFcGOQwv2GjpOrm +ekkCLnp7/3/5tmkKmUFbkTZU8+Qoq+Hgj8pAqgRYik2dl9WyE21PHygL7a6psKZR +kjvOCPUqCkwjVdf/7oOfp8JAWSnWtyU4sKVU+wIDAQABAoIBAANTmjL9jighVZB3 +pSE/8Gx0TJmo505PBBH/RqaVUDeBjgChhktk231qQ1dXRQ45Y/8EN/ZdSqK1SGP/ +YQcR2Qkvny6qCeCt+yM8zpIWy6KiQcjm58h8aLOis3nK9rmDDSNmeQgl+k1OmJj5 +nUvFbnUdQZuEbhS0R7t6zGq+WT+j9uCIt0DV3m2+qWw0uN8ObZpr16GOWBp8yo6+ +3LBOwQ5+9/nqwTdOLMbpsZlJd/KOQikV9izOQkmL6tC2dxPXRqKPNST5987kYY37 +H+0iIfIyvFCx5gTKpoUy2JxGvXZOlKdibaav9b4P5P663YIb4sTUVPHi1cyZPYkc +pnoLSjkCgYEA+zAuQ5i5FTLry7f5iPjGNSdWSJ8Fb8RJ6dqTBP/PDezI6K48vJJ1 +gkll3JMyXfMBScd90qq1QVAUmb8Nz2mQXCIHsNBexjeuGNBnXxB21XSM3bA+1mL9 +zJ5eUnBUgih60CJE/8jdo9GNUY0Ce0XEOTpl1LKYPJc2uSXC1y6kLcMCgYEA95C0 +6c9hat9/VDRab+0VZrMb+FBj3f1XsHGRSWbQDuWuO7CfOEYhwTcLrE9WexTEjNL6 +6IVvN3CqhcxGTHD4fgW+9QFGAXC2SoNKCsPokzC1X1ikUusPtriyn/IvUP6qYHus +eB4xsCD5ulyGfJJRbBRa5dmzlqxnKyimPfC+MGkCgYEAxoibWHQifX3k3vyHb1pp +luODkByYOHGllf9bSo1BwxjO5xGoEceUtyh6KS/ylE0YTI8vhM3GO1wnHCnkqXYf +UqLW/0qCThr+MMCvo3So6CeZmzLNR7ewMAVQOcptEP8bqtwbOyww+mULVFSmjHZl +FHJyv/101BcUepw89sT3oO8CgYB4GQI63vkCcLQDdHZfD+Ou87rg5pbcDVfp5940 +fqT2ZSP2HwPOt+8OHZcTG1X31aZYLs272WePvJ9s0yFTWgailEUD9H8ymaxFT5Wu +zUVZimqie40UEKaJ3OYCw+mCYFjk/3o2t2cha43ag6JWcmD/joxeLxN5R9+wx0KG +j/Cj6QKBgF0WuXRkQwItF2F/swibuFcnqlGjz6I5k5wBuuZiRk8PcPgCPSyoWald +YzN6CLKfQSIZjO0fj7S329hc+CbKx1o+HNPjC72lP9fC/KCh8FAxMhUkcCwP7Bvt +fpRG66KTIz6EZtWWAI/VjWxUo9LOX4YVTBSVLeMI+bNmKHw4VLKI +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/citrineos/add-certs-volumes.patch b/citrineos/add-certs-volumes.patch index 7a3677a2..752b1380 100644 --- a/citrineos/add-certs-volumes.patch +++ b/citrineos/add-certs-volumes.patch @@ -1,13 +1,58 @@ ---- docker-compose.yml 2024-05-29 16:26:46 -+++ docker-compose-modified.yml 2024-05-29 16:34:45 -@@ -88,6 +88,10 @@ - - /usr/local/apps/citrineos/03_Modules/Reporting/dist/ - - /usr/local/apps/citrineos/03_Modules/SmartCharging/dist/ - - /usr/local/apps/citrineos/03_Modules/Transactions/dist/ -+ - ./data/certificates/leafKey.pem:/usr/local/apps/citrineos/Server/src/assets/certificates/leafKey.pem -+ - ./data/certificates/certChain.pem:/usr/local/apps/citrineos/Server/src/assets/certificates/certChain.pem -+ - ./data/certificates/subCAKey.pem:usr/local/apps/citrineos/Server/src/assets/certificates/subCAKey.pem -+ - ./data/certificates/rootCertificate.pem:/usr/local/apps/citrineos/Server/src/assets/certificates/rootCertificate.pem +--- docker-compose.yml 2024-05-29 19:10:43 ++++ docker-compose-modified.yml 2024-05-29 19:32:12 +@@ -41,52 +41,10 @@ + timeout: 5s + retries: 3 + citrine: +- build: +- context: .. +- dockerfile: ./Server/deploy.Dockerfile ++ image: server-citrine:pnc + volumes: +- - ../package-lock.json:/usr/local/apps/citrineos/package-lock-host.json +- - ../package.json:/usr/local/apps/citrineos/package.json +- - ../tsconfig.json:/usr/local/apps/citrineos/tsconfig.json +- - ../tsconfig.build.json:/usr/local/apps/citrineos/tsconfig.build.json +- - ../Server:/usr/local/apps/citrineos/Server +- - ../00_Base:/usr/local/apps/citrineos/00_Base +- - ../01_Data:/usr/local/apps/citrineos/01_Data +- - ../02_Util:/usr/local/apps/citrineos/02_Util +- - ../03_Modules/Certificates:/usr/local/apps/citrineos/03_Modules/Certificates +- - ../03_Modules/Configuration:/usr/local/apps/citrineos/03_Modules/Configuration +- - ../03_Modules/EVDriver:/usr/local/apps/citrineos/03_Modules/EVDriver +- - ../03_Modules/Monitoring:/usr/local/apps/citrineos/03_Modules/Monitoring +- - ../03_Modules/OcppRouter:/usr/local/apps/citrineos/03_Modules/OcppRouter +- - ../03_Modules/Reporting:/usr/local/apps/citrineos/03_Modules/Reporting +- - ../03_Modules/SmartCharging:/usr/local/apps/citrineos/03_Modules/SmartCharging +- - ../03_Modules/Transactions:/usr/local/apps/citrineos/03_Modules/Transactions +- - /usr/local/apps/citrineos/node_modules +- - /usr/local/apps/citrineos/Server/node_modules +- - /usr/local/apps/citrineos/00_Base/node_modules +- - /usr/local/apps/citrineos/01_Data/node_modules +- - /usr/local/apps/citrineos/02_Util/node_modules +- - /usr/local/apps/citrineos/03_Modules/Certificates/node_modules +- - /usr/local/apps/citrineos/03_Modules/Configuration/node_modules +- - /usr/local/apps/citrineos/03_Modules/EVDriver/node_modules +- - /usr/local/apps/citrineos/03_Modules/Monitoring/node_modules +- - /usr/local/apps/citrineos/03_Modules/OcppRouter/node_modules +- - /usr/local/apps/citrineos/03_Modules/Reporting/node_modules +- - /usr/local/apps/citrineos/03_Modules/SmartCharging/node_modules +- - /usr/local/apps/citrineos/03_Modules/Transactions/node_modules +- - /usr/local/apps/citrineos/dist/ +- - /usr/local/apps/citrineos/Server/dist/ +- - /usr/local/apps/citrineos/00_Base/dist/ +- - /usr/local/apps/citrineos/01_Data/dist/ +- - /usr/local/apps/citrineos/02_Util/dist/ +- - /usr/local/apps/citrineos/03_Modules/Certificates/dist/ +- - /usr/local/apps/citrineos/03_Modules/Configuration/dist/ +- - /usr/local/apps/citrineos/03_Modules/EVDriver/dist/ +- - /usr/local/apps/citrineos/03_Modules/Monitoring/dist/ +- - /usr/local/apps/citrineos/03_Modules/OcppRouter/dist/ +- - /usr/local/apps/citrineos/03_Modules/Reporting/dist/ +- - /usr/local/apps/citrineos/03_Modules/SmartCharging/dist/ +- - /usr/local/apps/citrineos/03_Modules/Transactions/dist/ ++ - ./data/certificates:/usr/local/apps/citrineos/Server/src/assets/certificates ++ environment: APP_NAME: 'all' APP_ENV: 'docker' diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 0c5230b0..457c2703 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -197,13 +197,13 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then tar xf cached_certs_correct_name_emaid.tar.gz # Leaf key - cp dist/etc/everest/certs/client/csms/CSMS_LEAF.key Server/data/certificates/csms.key + cp dist/etc/everest/certs/client/csms/CSMS_LEAF.key Server/data/certificates/leafKey.pem #Cert chain cat dist/etc/everest/certs/client/csms/CSMS_LEAF.pem \ dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ - > Server/data/certificates/csms.pem + > Server/data/certificates/certChain.pem # SubCA cp dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.key Server/data/certificates/subCAKey.pem @@ -211,14 +211,18 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then #RootCert cp dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem Server/data/certificates/rootCertificate.pem + #ACME key + cp ../everest-demo/citrineos/acme_account_key.pem Server/data/certificates/acme_account_key.pem + echo "Copying patch and then patching docker compose to take certs from volume" cp ../everest-demo/citrineos/add-certs-volumes.patch Server/data/certificates pushd Server || exit 1 patch -p1 -i ./data/certificates/add-certs-volumes.patch echo "Starting the CitrineOS CSMS" - - if ! docker compose -f ./docker-compose.yml build && docker compose --project-name citrineos-csms f ./docker-compose.yml up -d --wait; then + cat ./docker-compose.yml + docker compose -f ./docker-compose.yml build directus + if ! docker compose --project-name citrineos-csms -f ./docker-compose.yml up -d --wait; then echo "Failed to start CitrineOS." exit 1 fi @@ -246,15 +250,15 @@ fi if [[ "$DEMO_VERSION" =~ sp1 ]]; then echo "Copying device DB, configured to SecurityProfile: 1" - docker cp manager/device_model_storage_maeve_sp1.db \ + docker cp manager/device_model_storage_sp1.db \ everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db elif [[ "$DEMO_VERSION" =~ sp2 ]]; then echo "Copying device DB, configured to SecurityProfile: 2" - docker cp manager/device_model_storage_maeve_sp2.db \ + docker cp manager/device_model_storage_sp2.db \ everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db elif [[ "$DEMO_VERSION" =~ sp3 ]]; then echo "Copying device DB, configured to SecurityProfile: 3" - docker cp manager/device_model_storage_maeve_sp3.db \ + docker cp manager/device_model_storage_sp3.db \ everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db fi From ead6af5dd6ea3686a69d83b6ad72d3eb3836e751 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 29 May 2024 20:25:28 +0200 Subject: [PATCH 05/18] set citrine as first priority in the connection slots --- manager/device_model_storage_sp1.db | Bin 81920 -> 81920 bytes manager/device_model_storage_sp2.db | Bin 81920 -> 81920 bytes manager/device_model_storage_sp3.db | Bin 81920 -> 81920 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/manager/device_model_storage_sp1.db b/manager/device_model_storage_sp1.db index 5d39f3a83752b8f23f8acd295dd4d232f513fbbf..5e5db90360d842202df789d3fccaaf25ece4351b 100644 GIT binary patch delta 48 zcmZo@U~On%ogmG~KT*b+k-srvYXaj1)#=>ojG@yz^%(P~e^Fx;pKhSW7`i<{opFH# E0A`mCk^lez delta 48 zcmZo@U~On%ogmG~H&Mo!k*_gfYXaj1)#=>ojG@yz^%(P~e^Fx;pKhSW7`i<{opFH# E0A@}OkN^Mx diff --git a/manager/device_model_storage_sp2.db b/manager/device_model_storage_sp2.db index 5ac7d34b164aee2ca2625b02fec1c654225c717e..f529ed04da6c96406a014219d0f2cc0d51939fc1 100644 GIT binary patch delta 73 zcmV-P0Ji^tfCYen1&|v750M;00S|#-wO|3$9{~urG#~-40RbtoktGBVgGLq!0099B f2ndG*76MzB^d Date: Mon, 3 Jun 2024 14:02:11 -0400 Subject: [PATCH 06/18] adjusting for new citrineos branch --- demo-iso15118-2-ac-plus-ocpp.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 457c2703..af485778 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -8,7 +8,7 @@ MAEVE_REPO="https://github.com/thoughtworks/maeve-csms.git" MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit CITRINEOS_REPO="https://github.com/citrineos/citrineos-core.git" -CITRINEOS_BRANCH="feature/authorization-c07" +CITRINEOS_BRANCH="feature/everest-demo" @@ -208,8 +208,10 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then # SubCA cp dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.key Server/data/certificates/subCAKey.pem - #RootCert - cp dist/etc/everest/certs/ca/v2g/V2G_ROOT_CA.pem Server/data/certificates/rootCertificate.pem + #TrustedSubCAChain + cat dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ + dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ + > Server/data/certificates/rootCertificate.pem #ACME key cp ../everest-demo/citrineos/acme_account_key.pem Server/data/certificates/acme_account_key.pem @@ -218,7 +220,6 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then cp ../everest-demo/citrineos/add-certs-volumes.patch Server/data/certificates pushd Server || exit 1 - patch -p1 -i ./data/certificates/add-certs-volumes.patch echo "Starting the CitrineOS CSMS" cat ./docker-compose.yml docker compose -f ./docker-compose.yml build directus From 9c23e606bf9ea0dcf828a5c31754cb84f363ab3b Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Mon, 3 Jun 2024 23:54:06 +0000 Subject: [PATCH 07/18] building all citrineos images --- demo-iso15118-2-ac-plus-ocpp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index af485778..70027bf7 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -222,7 +222,7 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then pushd Server || exit 1 echo "Starting the CitrineOS CSMS" cat ./docker-compose.yml - docker compose -f ./docker-compose.yml build directus + docker compose -f ./docker-compose.yml build if ! docker compose --project-name citrineos-csms -f ./docker-compose.yml up -d --wait; then echo "Failed to start CitrineOS." exit 1 From 35cbf4446f79b7f4d609eb111b05da9f6651fda9 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Tue, 4 Jun 2024 03:04:41 +0000 Subject: [PATCH 08/18] explicitly setting version tag for EVerest dockercompose to 0.0.14; 0.0.15 is missing the build/run-scripts folder --- demo-iso15118-2-ac-plus-ocpp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 70027bf7..49b2395c 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -234,11 +234,11 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then popd || exit 1 popd || exit 1 - fi pushd everest-demo || exit 1 echo "Starting everest" +export TAG=0.0.14 docker compose --project-name everest-ac-demo --file "${DEMO_COMPOSE_FILE_NAME}" up -d --wait docker cp config-sil-ocpp201-pnc.yaml everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then From e86f47ddb88cf29f9dc08fec57310ef2eadac2ac Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Tue, 4 Jun 2024 03:46:25 +0000 Subject: [PATCH 09/18] updating demo repo & branch --- demo-iso15118-2-ac-plus-ocpp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 49b2395c..d4ed7ebb 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -DEMO_REPO="https://github.com/everest/everest-demo.git" -DEMO_BRANCH="main" +DEMO_REPO="https://github.com/ChrisWeissmann/everest-demo.git" +DEMO_BRANCH="feature/citrine-support" MAEVE_REPO="https://github.com/thoughtworks/maeve-csms.git" MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit From 9537d38fe0e356dab443791071bdd8d4824cff36 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Tue, 4 Jun 2024 03:48:53 +0000 Subject: [PATCH 10/18] making maeve the default again --- demo-iso15118-2-ac-plus-ocpp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index d4ed7ebb..de381e17 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -32,7 +32,7 @@ where: DEMO_VERSION= DEMO_COMPOSE_FILE_NAME= -DEMO_CSMS=citrineos +DEMO_CSMS=maeve # loop through positional options/arguments From f76d9035ebbc947be900183f67ce656d736bf6a2 Mon Sep 17 00:00:00 2001 From: thanaParis Date: Tue, 4 Jun 2024 11:34:46 -0400 Subject: [PATCH 11/18] updating with pr to adapt for 0.0.15 --- demo-iso15118-2-ac-plus-ocpp.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index de381e17..4469b6bd 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -DEMO_REPO="https://github.com/ChrisWeissmann/everest-demo.git" -DEMO_BRANCH="feature/citrine-support" +DEMO_REPO="https://github.com/everest/everest-demo.git" +DEMO_BRANCH="main" MAEVE_REPO="https://github.com/thoughtworks/maeve-csms.git" MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit @@ -238,32 +238,31 @@ fi pushd everest-demo || exit 1 echo "Starting everest" -export TAG=0.0.14 docker compose --project-name everest-ac-demo --file "${DEMO_COMPOSE_FILE_NAME}" up -d --wait docker cp config-sil-ocpp201-pnc.yaml everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then - docker cp manager/cached_certs_correct_name_emaid.tar.gz everest-ac-demo-manager-1:/workspace/ + 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 "tar xf cached_certs_correct_name_emaid.tar.gz" echo "Configured everest certs, validating that the chain is set up correctly" - docker exec everest-ac-demo-manager-1 /bin/bash -c "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" + 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 [[ "$DEMO_VERSION" =~ sp1 ]]; then echo "Copying device DB, configured to SecurityProfile: 1" docker cp manager/device_model_storage_sp1.db \ - everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db elif [[ "$DEMO_VERSION" =~ sp2 ]]; then echo "Copying device DB, configured to SecurityProfile: 2" docker cp manager/device_model_storage_sp2.db \ - everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db elif [[ "$DEMO_VERSION" =~ sp3 ]]; then echo "Copying device DB, configured to SecurityProfile: 3" docker cp manager/device_model_storage_sp3.db \ - everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db fi if [[ "$DEMO_VERSION" =~ v2.0.1 ]]; then echo "Starting software in the loop simulation" - docker exec everest-ac-demo-manager-1 sh /workspace/build/run-scripts/run-sil-ocpp201-pnc.sh + docker exec everest-ac-demo-manager-1 sh /ext/source/build/build/run-scripts/run-sil-ocpp201-pnc.sh fi From 825ff7f072cccce742c5b117f7268a4295d9a786 Mon Sep 17 00:00:00 2001 From: thanaParis Date: Tue, 4 Jun 2024 12:20:05 -0400 Subject: [PATCH 12/18] removing unneeded files & code --- citrineos/add-certs-volumes.patch | 58 ------------------- citrineos/directus-env-config.cjs | 13 ----- citrineos/docker-compose.yml | 95 ------------------------------- demo-iso15118-2-ac-plus-ocpp.sh | 3 - 4 files changed, 169 deletions(-) delete mode 100644 citrineos/add-certs-volumes.patch delete mode 100644 citrineos/directus-env-config.cjs delete mode 100644 citrineos/docker-compose.yml diff --git a/citrineos/add-certs-volumes.patch b/citrineos/add-certs-volumes.patch deleted file mode 100644 index 752b1380..00000000 --- a/citrineos/add-certs-volumes.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- docker-compose.yml 2024-05-29 19:10:43 -+++ docker-compose-modified.yml 2024-05-29 19:32:12 -@@ -41,52 +41,10 @@ - timeout: 5s - retries: 3 - citrine: -- build: -- context: .. -- dockerfile: ./Server/deploy.Dockerfile -+ image: server-citrine:pnc - volumes: -- - ../package-lock.json:/usr/local/apps/citrineos/package-lock-host.json -- - ../package.json:/usr/local/apps/citrineos/package.json -- - ../tsconfig.json:/usr/local/apps/citrineos/tsconfig.json -- - ../tsconfig.build.json:/usr/local/apps/citrineos/tsconfig.build.json -- - ../Server:/usr/local/apps/citrineos/Server -- - ../00_Base:/usr/local/apps/citrineos/00_Base -- - ../01_Data:/usr/local/apps/citrineos/01_Data -- - ../02_Util:/usr/local/apps/citrineos/02_Util -- - ../03_Modules/Certificates:/usr/local/apps/citrineos/03_Modules/Certificates -- - ../03_Modules/Configuration:/usr/local/apps/citrineos/03_Modules/Configuration -- - ../03_Modules/EVDriver:/usr/local/apps/citrineos/03_Modules/EVDriver -- - ../03_Modules/Monitoring:/usr/local/apps/citrineos/03_Modules/Monitoring -- - ../03_Modules/OcppRouter:/usr/local/apps/citrineos/03_Modules/OcppRouter -- - ../03_Modules/Reporting:/usr/local/apps/citrineos/03_Modules/Reporting -- - ../03_Modules/SmartCharging:/usr/local/apps/citrineos/03_Modules/SmartCharging -- - ../03_Modules/Transactions:/usr/local/apps/citrineos/03_Modules/Transactions -- - /usr/local/apps/citrineos/node_modules -- - /usr/local/apps/citrineos/Server/node_modules -- - /usr/local/apps/citrineos/00_Base/node_modules -- - /usr/local/apps/citrineos/01_Data/node_modules -- - /usr/local/apps/citrineos/02_Util/node_modules -- - /usr/local/apps/citrineos/03_Modules/Certificates/node_modules -- - /usr/local/apps/citrineos/03_Modules/Configuration/node_modules -- - /usr/local/apps/citrineos/03_Modules/EVDriver/node_modules -- - /usr/local/apps/citrineos/03_Modules/Monitoring/node_modules -- - /usr/local/apps/citrineos/03_Modules/OcppRouter/node_modules -- - /usr/local/apps/citrineos/03_Modules/Reporting/node_modules -- - /usr/local/apps/citrineos/03_Modules/SmartCharging/node_modules -- - /usr/local/apps/citrineos/03_Modules/Transactions/node_modules -- - /usr/local/apps/citrineos/dist/ -- - /usr/local/apps/citrineos/Server/dist/ -- - /usr/local/apps/citrineos/00_Base/dist/ -- - /usr/local/apps/citrineos/01_Data/dist/ -- - /usr/local/apps/citrineos/02_Util/dist/ -- - /usr/local/apps/citrineos/03_Modules/Certificates/dist/ -- - /usr/local/apps/citrineos/03_Modules/Configuration/dist/ -- - /usr/local/apps/citrineos/03_Modules/EVDriver/dist/ -- - /usr/local/apps/citrineos/03_Modules/Monitoring/dist/ -- - /usr/local/apps/citrineos/03_Modules/OcppRouter/dist/ -- - /usr/local/apps/citrineos/03_Modules/Reporting/dist/ -- - /usr/local/apps/citrineos/03_Modules/SmartCharging/dist/ -- - /usr/local/apps/citrineos/03_Modules/Transactions/dist/ -+ - ./data/certificates:/usr/local/apps/citrineos/Server/src/assets/certificates -+ - environment: - APP_NAME: 'all' - APP_ENV: 'docker' diff --git a/citrineos/directus-env-config.cjs b/citrineos/directus-env-config.cjs deleted file mode 100644 index 1e3882b9..00000000 --- a/citrineos/directus-env-config.cjs +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = function (env) { - const config = { - // API Paths - CITRINEOS_SUBSCRIPTION_API_PATH: '/data/ocpprouter/subscription', - DIRECTUS_CHARGING_STATION_UPDATE_STATUS_PATH: - '/charging-stations/update-station-status', - // Environment-specific urls - CITRINEOS_URL: 'http://citrine:8080', - DIRECTUS_URL: 'http://directus:8055', - }; - - return config; -}; \ No newline at end of file diff --git a/citrineos/docker-compose.yml b/citrineos/docker-compose.yml deleted file mode 100644 index 2b70f33f..00000000 --- a/citrineos/docker-compose.yml +++ /dev/null @@ -1,95 +0,0 @@ -services: - amqp-broker: - image: rabbitmq:3-management - ports: - - 15672:15672 - - 5672:5672 - environment: - RABBITMQ_DEFAULT_USER: 'guest' - RABBITMQ_DEFAULT_PASS: 'guest' - volumes: - - ./data/rabbitmq:/var/lib/rabbitmq - healthcheck: - test: rabbitmq-diagnostics -q ping - interval: 10s - timeout: 10s - retries: 3 - ocpp-db: - image: citrineos/postgis:v1.1.0 - ports: - - 5432:5432 - volumes: - - ./data/postgresql/pgdata:/var/lib/postgresql/data - environment: - POSTGRES_DB: citrine - POSTGRES_USER: citrine - POSTGRES_PASSWORD: 'citrine' - healthcheck: - test: 'pg_isready --username=citrine' - interval: 5s - timeout: 10s - retries: 5 - - redis: - image: redis:latest - ports: - - '6379:6379' - healthcheck: - test: ['CMD', 'redis-cli', 'ping'] - interval: 10s - timeout: 5s - retries: 3 - citrine: - image: ghcr.io/citrineos/citrineos-server:1.1.2 - environment: - APP_NAME: 'all' - APP_ENV: 'docker' - CITRINEOS_UTIL_DIRECTUS_USERNAME: 'admin@citrineos.com' - CITRINEOS_UTIL_DIRECTUS_PASSWORD: 'CitrineOS!' - depends_on: - ocpp-db: - condition: service_healthy - amqp-broker: - condition: service_healthy - directus: - condition: service_healthy - redis: - condition: service_healthy - ports: - - 8080:8080 - - 8081:8081 - - 8082:8082 - - 9229:9229 - - directus: - image: ghcr.io/chrisweissmann/everest-demo/citrineos-directus:1.1.0 - ports: - - 8055:8055 - volumes: - - ./directus-env-config.cjs:/directus/config.cjs - depends_on: - ocpp-db: - condition: service_healthy - environment: - APP_NAME: 'all' - KEY: '1234567890' - SECRET: '0987654321' - ADMIN_EMAIL: 'admin@citrineos.com' - ADMIN_PASSWORD: 'CitrineOS!' - CONFIG_PATH: '/directus/config.cjs' - EXTENSIONS_AUTO_RELOAD: 'true' - EXTENSIONS_CACHE_TTL: '1s' - DB_CLIENT: 'pg' - DB_HOST: ocpp-db - DB_PORT: 5432 - DB_DATABASE: 'citrine' - DB_USER: 'citrine' - DB_PASSWORD: 'citrine' - WEBSOCKETS_ENABLED: 'true' - healthcheck: - test: wget --no-verbose --tries=1 --spider http://127.0.0.1:8055/server/health || exit 1 - start_period: 15s - start_interval: 5s - interval: 15s - timeout: 15s - retries: 3 \ No newline at end of file diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 4469b6bd..9ed0190c 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -216,9 +216,6 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then #ACME key cp ../everest-demo/citrineos/acme_account_key.pem Server/data/certificates/acme_account_key.pem - echo "Copying patch and then patching docker compose to take certs from volume" - cp ../everest-demo/citrineos/add-certs-volumes.patch Server/data/certificates - pushd Server || exit 1 echo "Starting the CitrineOS CSMS" cat ./docker-compose.yml From 0e02b0388be8b9b3107a5d3f095a4adf0c32ffbc Mon Sep 17 00:00:00 2001 From: thanaParis Date: Tue, 4 Jun 2024 16:38:39 -0400 Subject: [PATCH 13/18] adding maeve db support --- demo-iso15118-2-ac-plus-ocpp.sh | 42 +++++++++++++++------- manager/device_model_storage_maeve_sp1.db | Bin 0 -> 81920 bytes manager/device_model_storage_maeve_sp2.db | Bin 0 -> 81920 bytes manager/device_model_storage_maeve_sp3.db | Bin 0 -> 81920 bytes 4 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 manager/device_model_storage_maeve_sp1.db create mode 100644 manager/device_model_storage_maeve_sp2.db create mode 100644 manager/device_model_storage_maeve_sp3.db diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 9ed0190c..b06d2238 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -245,18 +245,36 @@ 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 [[ "$DEMO_VERSION" =~ sp1 ]]; then - echo "Copying device DB, configured to SecurityProfile: 1" - docker cp manager/device_model_storage_sp1.db \ - everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db -elif [[ "$DEMO_VERSION" =~ sp2 ]]; then - echo "Copying device DB, configured to SecurityProfile: 2" - docker cp manager/device_model_storage_sp2.db \ - everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db -elif [[ "$DEMO_VERSION" =~ sp3 ]]; then - echo "Copying device DB, configured to SecurityProfile: 3" - docker cp manager/device_model_storage_sp3.db \ - everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db +if [[ "$DEMO_CSMS" == 'maeve' ]]; then + if [[ "$DEMO_VERSION" =~ sp1 ]]; then + echo "Copying device DB, configured to SecurityProfile: 1" + docker cp manager/device_model_storage_maeve_sp1.db \ + everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + elif [[ "$DEMO_VERSION" =~ sp2 ]]; then + echo "Copying device DB, configured to SecurityProfile: 2" + docker cp manager/device_model_storage_maeve_sp2.db \ + everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + elif [[ "$DEMO_VERSION" =~ sp3 ]]; then + echo "Copying device DB, configured to SecurityProfile: 3" + docker cp manager/device_model_storage_maeve_sp3.db \ + everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + fi +fi + +if [[ "$DEMO_CSMS" == 'citrineos' ]]; then + if [[ "$DEMO_VERSION" =~ sp1 ]]; then + echo "Copying device DB, configured to SecurityProfile: 1" + docker cp manager/device_model_storage_sp1.db \ + everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + elif [[ "$DEMO_VERSION" =~ sp2 ]]; then + echo "Copying device DB, configured to SecurityProfile: 2" + docker cp manager/device_model_storage_sp2.db \ + everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + elif [[ "$DEMO_VERSION" =~ sp3 ]]; then + echo "Copying device DB, configured to SecurityProfile: 3" + docker cp manager/device_model_storage_sp3.db \ + everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + fi fi if [[ "$DEMO_VERSION" =~ v2.0.1 ]]; then diff --git a/manager/device_model_storage_maeve_sp1.db b/manager/device_model_storage_maeve_sp1.db new file mode 100644 index 0000000000000000000000000000000000000000..7b96f36b8feeb74ead15f1d8987a757f5a46d981 GIT binary patch literal 81920 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 VN8F^5b2H?ezB)j)f(O?2{6F7=`mz83 literal 0 HcmV?d00001 diff --git a/manager/device_model_storage_maeve_sp3.db b/manager/device_model_storage_maeve_sp3.db new file mode 100644 index 0000000000000000000000000000000000000000..9e10ad5b5e26e15e5849c8764ec5f0679bb80468 GIT binary patch literal 81920 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 VN8F^5b2H?ezB)j)f(O?2{6FxH`m+E4 literal 0 HcmV?d00001 From 6f658e56f3cdeff388883eb448fd9c0cf7046643 Mon Sep 17 00:00:00 2001 From: thanaParis Date: Tue, 4 Jun 2024 16:40:32 -0400 Subject: [PATCH 14/18] making maeve default again --- manager/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/Dockerfile b/manager/Dockerfile index 7f681315..b1605f25 100644 --- a/manager/Dockerfile +++ b/manager/Dockerfile @@ -19,7 +19,7 @@ RUN git clone https://github.com/EVerest/everest-core.git \ # Copy over the custom config *after* compilation and installation COPY config-docker.json ./dist/share/everest/modules/OCPP/config-docker.json COPY config.json ./dist/share/everest/modules/OCPP201/config.json -COPY device_model_storage_sp1.db ./dist/share/everest/modules/OCPP201/device_model_storage.db +COPY device_model_storage_maeve_sp1.db ./dist/share/everest/modules/OCPP201/device_model_storage.db COPY run-test.sh /ext/source/tests/run-test.sh From 09a33c763da85f8237b8a52abc56641681b23884 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 5 Jun 2024 12:08:05 +0200 Subject: [PATCH 15/18] Rename device model to be explicit and small fixes based on PR feedback --- demo-iso15118-2-ac-plus-ocpp.sh | 28 +++++++----------- ... => device_model_storage_citrineos_sp1.db} | Bin 81920 -> 81920 bytes ... => device_model_storage_citrineos_sp2.db} | Bin 81920 -> 81920 bytes ... => device_model_storage_citrineos_sp3.db} | Bin 81920 -> 81920 bytes 4 files changed, 10 insertions(+), 18 deletions(-) rename manager/{device_model_storage_sp1.db => device_model_storage_citrineos_sp1.db} (99%) rename manager/{device_model_storage_sp2.db => device_model_storage_citrineos_sp2.db} (99%) rename manager/{device_model_storage_sp3.db => device_model_storage_citrineos_sp3.db} (99%) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 64df9eee..62fba40c 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -12,7 +12,7 @@ CITRINEOS_BRANCH="feature/everest-demo" -usage="usage: $(basename "$0") [-r ] [-b ] [-j|1|2|3|m|c] [-h] +usage="usage: $(basename "$0") [-r ] [-b ] [-j|1|2|3|c] [-h] This script will run EVerest ISO 15118-2 AC charging with OCPP demos. @@ -64,14 +64,6 @@ if [[ ! "${DEMO_VERSION}" ]]; then exit 1 fi -if [[ "${DEMO_VERSION}" != "v1.6j" && -z "${DEMO_CSMS}" ]]; then - echo 'Error: no 2.0.1 csms option provided.' - echo 'Use -c for CitrineOS or -m MaEVe' - echo - echo -e "$usage" - - exit 1 -fi DEMO_DIR="$(mktemp -d)" @@ -109,9 +101,8 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then git reset --hard ${MAEVE_BRANCH} 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 + echo "Patching the CSMS to disable load balancer" + patch -p1 -i ../everest-demo/maeve/maeve-csms-no-lb.patch # Set up certificates for SP2 and SP3 if [[ "$DEMO_VERSION" =~ sp2 || "$DEMO_VERSION" =~ sp3 ]]; then @@ -157,6 +148,7 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then popd || exit 1 fi + if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then echo "Cloning CitrineOS CSMS from ${CITRINEOS_REPO} into ${DEMO_DIR}/citrineos-csms and starting it" git clone --branch "${CITRINEOS_BRANCH}" "${CITRINEOS_REPO}" citrineos-csms @@ -238,16 +230,16 @@ fi if [[ "$DEMO_CSMS" == 'citrineos' ]]; then if [[ "$DEMO_VERSION" =~ sp1 ]]; then echo "Copying device DB, configured to SecurityProfile: 1" - docker cp manager/device_model_storage_sp1.db \ - everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + docker cp manager/device_model_storage_citrineos_sp1.db \ + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db elif [[ "$DEMO_VERSION" =~ sp2 ]]; then echo "Copying device DB, configured to SecurityProfile: 2" - docker cp manager/device_model_storage_sp2.db \ - everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + docker cp manager/device_model_storage_citrineos_sp2.db \ + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db elif [[ "$DEMO_VERSION" =~ sp3 ]]; then echo "Copying device DB, configured to SecurityProfile: 3" - docker cp manager/device_model_storage_sp3.db \ - everest-ac-demo-manager-1:/workspace/dist/share/everest/modules/OCPP201/device_model_storage.db + docker cp manager/device_model_storage_citrineos_sp3.db \ + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db fi fi diff --git a/manager/device_model_storage_sp1.db b/manager/device_model_storage_citrineos_sp1.db similarity index 99% rename from manager/device_model_storage_sp1.db rename to manager/device_model_storage_citrineos_sp1.db index 5e5db90360d842202df789d3fccaaf25ece4351b..dfdb6ff5828636eb4f8fc4252e23ac9a65450afd 100644 GIT binary patch delta 66 zcmZo@U~On%ogmF9Fj2;tQJ^tlYXakCdB$hkO%xc{F*32TZJemiGM!tE@itFmrWhv! WBO@mVN3-X2X+6fg?Fs6P3nTz?#}Tst delta 60 zcmV-C0K@-)fCYen1&|v750M;00S|#-wO|3$9{~%uG#~-40RjXov5_YPmkTBV+n4Gt S0S*BymmV$wYqwx00iYNN91!UM diff --git a/manager/device_model_storage_sp2.db b/manager/device_model_storage_citrineos_sp2.db similarity index 99% rename from manager/device_model_storage_sp2.db rename to manager/device_model_storage_citrineos_sp2.db index f529ed04da6c96406a014219d0f2cc0d51939fc1..bd0f04d9de21da60271b83b1644b64129e65200a 100644 GIT binary patch delta 66 zcmZo@U~On%ogmF9Fj2;tQJ^tlYXakCdB!K(O%xc{GBUBUZk(vfGMz(>@eWU8mKY}k WBO@mVN3-{IDLuyg?eXf23nc(?*b%M( delta 60 zcmV-C0K@-)fCYen1&|v750M;00S|#-wO|3$9{~urG#~-30RjXmv5_SNmk1^S+?VPu S0S*BymmMwvY`0%00ihTM?hxMq diff --git a/manager/device_model_storage_sp3.db b/manager/device_model_storage_citrineos_sp3.db similarity index 99% rename from manager/device_model_storage_sp3.db rename to manager/device_model_storage_citrineos_sp3.db index 3c9b7170fc9149da818a1930b932b368819bbb46..5500a73733052e27eca74e186debab61f37d4b59 100644 GIT binary patch delta 66 zcmZo@U~On%ogmF9Fj2;tQJ^tlYXakCdB!K(O%xc{GBUBUZk(vfGMz(>@eWU8mKY}k WBO@mVN3-{IDLuyg?eXf23nc(?*b%M( delta 60 zcmV-C0K@-)fCYen1&|v750M;00S|#-wO|3$9{~urG#~-30RjXmv5_SNmk1^S+?VPu S0S*BymmMwvY`0%00ihTM?hxMq From dd878837ce598fd9d351ecb8e42be069323aad3c Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Wed, 5 Jun 2024 13:16:23 +0200 Subject: [PATCH 16/18] fix: Slight adjustment for static code analysis --- citrineos/add-charger.sh | 12 ++++++------ demo-iso15118-2-ac-plus-ocpp.sh | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/citrineos/add-charger.sh b/citrineos/add-charger.sh index 5fe19f47..4671aeab 100755 --- a/citrineos/add-charger.sh +++ b/citrineos/add-charger.sh @@ -79,16 +79,16 @@ add_location() { # Function to add a charging station add_charging_station() { - local token=$1 - local location_id=$2 - local chargepointId=$3 + local token="$1" + local location_id="$2" + local chargepointId="$3" curl -s --request POST \ --url "${DIRECTUS_API_URL}/items/ChargingStations" \ --header "Authorization: Bearer $token" \ --header "Content-Type: application/json" \ --data '{ - "id": "'$chargepointId'", - "locationId": "'$location_id'" + "id": "'"$chargepointId"'", + "locationId": "'"$location_id"'" }' | tee /dev/tty && echo } @@ -112,7 +112,7 @@ add_cp001_password() { }, "variableAttribute": [ { - "value": "'$passwordString'" + "value": "'"$passwordString"'" } ], "variableCharacteristics": { diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 62fba40c..24fe15d5 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -94,11 +94,11 @@ git clone --branch "${DEMO_BRANCH}" "${DEMO_REPO}" everest-demo if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then echo "Cloning MaEVe CSMS from ${MAEVE_REPO} into ${DEMO_DIR}/maeve-csms and starting it" - git clone ${MAEVE_REPO} maeve-csms + git clone "${MAEVE_REPO}" maeve-csms pushd maeve-csms || exit 1 - git reset --hard ${MAEVE_BRANCH} + git reset --hard "${MAEVE_BRANCH}" cp ../everest-demo/manager/cached_certs_correct_name_emaid.tar.gz . echo "Patching the CSMS to disable load balancer" From f7604ba4d3ed4d73688ffb1cda8e3bdd9293bdbf Mon Sep 17 00:00:00 2001 From: thanaParis Date: Mon, 10 Jun 2024 10:17:49 -0400 Subject: [PATCH 17/18] fixing typo for variable naming --- demo-iso15118-2-ac-plus-ocpp.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 7639e795..5e000862 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -4,8 +4,8 @@ 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 +CSMMAEVEPO="https://github.com/thoughtworks/maeve-csms.git" +MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit CITRINEOS_REPO="https://github.com/citrineos/citrineos-core.git" CITRINEOS_BRANCH="feature/everest-demo" From d80abb2d6a6b8ae820ba98a7c808a61079e31c61 Mon Sep 17 00:00:00 2001 From: ChrisWeissmann Date: Mon, 10 Jun 2024 17:43:28 +0200 Subject: [PATCH 18/18] slight adjustment from static code analysis action to avoid globbing Signed-off-by: Christian Weissmann --- demo-iso15118-2-ac-plus-ocpp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index f1f7e697..8a816f2e 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -95,7 +95,7 @@ git clone --branch "${DEMO_BRANCH}" "${DEMO_REPO}" everest-demo if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then echo "Cloning ${DEMO_CSMS} CSMS from ${MAEVE_REPO} into ${DEMO_DIR}/${DEMO_CSMS}-csms and starting it" - git clone --branch "${MAEVE_BRANCH}" "${MAEVE_REPO}" ${CSMS}-csms + git clone --branch "${MAEVE_BRANCH}" "${MAEVE_REPO}" "${CSMS}-csms" pushd maeve-csms || exit 1