From a49994748a3fead1f9dff2036e9c215a6baf35c3 Mon Sep 17 00:00:00 2001 From: ChrisWeissmann Date: Mon, 10 Jun 2024 17:07:04 +0200 Subject: [PATCH 1/6] feat: add general citrine support with own device-model. Run bash command with argument `-c`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Testing done: Used local branch to test before pushing to remote `./demo-iso15118-2-ac-plus-ocpp.sh -2 -c -r $(pwd) -b feature/add-citrine-support-signedoff` ``` [+] Running 5/5 ✔ Network citrineos-csms_default Created 0.0s ✔ Container citrineos-csms-ocpp-db-1 Healthy 22.6s ✔ Container citrineos-csms-amqp-broker-1 Healthy 22.6s ✔ Container citrineos-csms-directus-1 Healthy 22.6s ✔ Container citrineos-csms-citrine-1 Healthy 22.5s ``` Adding charger successfully: ``` Adding a charger to CitrineOS Adding new station... {"data":{"id":"cp001","isOnline":null,"locationId":2,"createdAt":"2024-06-10T15:10:18.175Z","updatedAt":"2024-06-10T15:10:18.176Z"}}{"data":{"id":"cp001","isOnline":null,"locationId":2,"createdAt":"2024-06-10T15:10:18.175Z","updatedAt":"2024-06-10T15:10:18.176Z"}} Add cp001 password to citrine... ``` ``` [+] Running 4/4 ✔ Network everest-ac-demo_default Created 0.0s ✔ Container everest-ac-demo-mqtt-server-1 Healthy 1.1s ✔ Container everest-ac-demo-nodered-1 Healthy 31.0s ✔ Container everest-ac-demo-manager-1 Healthy ``` ``` 2024-06-10 15:13:05.314829 [INFO] ocpp:OCPP201 :: Received BootNotificationResponse: { "currentTime": "2024-06-10T15:13:05.306Z", "interval": 60, "status": "Accepted" } ``` Signed-off-by: Christian Weissmann --- citrineos/acme_account_key.pem | 27 ++ citrineos/add-charger.sh | 176 +++++++++ demo-iso15118-2-ac-plus-ocpp.sh | 373 ++++++------------ manager/device_model_storage_citrineos_sp1.db | Bin 0 -> 81920 bytes manager/device_model_storage_citrineos_sp2.db | Bin 0 -> 81920 bytes manager/device_model_storage_citrineos_sp3.db | Bin 0 -> 81920 bytes 6 files changed, 320 insertions(+), 256 deletions(-) create mode 100644 citrineos/acme_account_key.pem create mode 100755 citrineos/add-charger.sh create mode 100644 manager/device_model_storage_citrineos_sp1.db create mode 100644 manager/device_model_storage_citrineos_sp2.db create mode 100644 manager/device_model_storage_citrineos_sp3.db 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-charger.sh b/citrineos/add-charger.sh new file mode 100755 index 00000000..4671aeab --- /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/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 6e054ddd..8e990320 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -4,14 +4,16 @@ DEMO_REPO="https://github.com/everest/everest-demo.git" DEMO_BRANCH="main" -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" +MAEVE_REPO="https://github.com/louisg1337/maeve-csms.git" +# MAEVE_BRANCH="b990d0eddf2bf80be8d9524a7b08029fbb305c7d" # patch files are based on this commit +MAEVE_BRANCH="set_charging_profile" +CITRINEOS_REPO="https://github.com/citrineos/citrineos-core.git" +CITRINEOS_BRANCH="feature/everest-demo" -usage="usage: $(basename "$0") [-r ] [-b ] [-c ] [-j|1|2|3] [-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. @@ -21,26 +23,24 @@ directory to the -r option (e.g., '-r \$(pwd)'). 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) -j OCPP v1.6j -1 OCPP v2.0.1 Security Profile 1 -2 OCPP v2.0.1 Security Profile 2 -3 OCPP v2.0.1 Security Profile 3 + -c Use CitrineOS CSMS (default: MaEVe) -h Show this message" DEMO_VERSION= DEMO_COMPOSE_FILE_NAME= +DEMO_CSMS=maeve # loop through positional options/arguments -while getopts ':r:b:cj123h' option; do +while getopts ':r:b:j123ch' 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" ;; j) DEMO_VERSION="v1.6j" DEMO_COMPOSE_FILE_NAME="docker-compose.ocpp16j.yml" ;; 1) DEMO_VERSION="v2.0.1-sp1" @@ -49,6 +49,7 @@ while getopts ':r:b:cj123h' 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" ;; + c) DEMO_CSMS="citrineos" ;; h) echo -e "$usage"; exit ;; \?) echo -e "illegal option: -$OPTARG\n" >&2 echo -e "$usage" >&2 @@ -65,7 +66,6 @@ if [[ ! "${DEMO_VERSION}" ]]; then exit 1 fi - DEMO_DIR="$(mktemp -d)" @@ -84,6 +84,7 @@ 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 @@ -91,271 +92,117 @@ 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 -if [[ "$DEMO_VERSION" != v1.6j ]]; then - echo "Cloning ${CSMS} CSMS from ${CSMS_REPO} into ${DEMO_DIR}/${CSMS}-csms and starting it" +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 - if [[ ${CSMS} == "maeve" ]]; then - git clone --branch "${CSMS_BRANCH}" "${CSMS_REPO}" ${CSMS}-csms - else - git clone ${CSMS_REPO} ${CSMS}-csms - fi + pushd maeve-csms || exit 1 - pushd ${CSMS}-csms || exit 1 + cp ../everest-demo/manager/cached_certs_correct_name_emaid.tar.gz . - git reset --hard ${CSMS_BRANCH} - - # Set up CSMS - echo "Setting up ${CSMS}" - if [[ "$CSMS" == "citrine" ]]; then - npm run install-all - if [[ "$?" != 0 ]]; then - echo 'Error: Failed to install dependencies.' - exit 1 - fi - npm run build - if [[ "$?" != 0 ]]; then - echo 'Error: Failed to build the project.' - exit 1 - fi - else - cp ../everest-demo/manager/cached_certs_correct_name_emaid.tar.gz . - 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 - if [[ "$CSMS" == "citrine" ]]; then - echo "Security profile 2/3 is not supported with Citrine yet!" - exit 1 - else - 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 \ - dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ - dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ - > config/certificates/csms.pem - cat dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ - dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ - > config/certificates/trust.pem - 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 - - 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 "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 \ + dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ + dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ + > config/certificates/csms.pem + cat dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.pem \ + dist/etc/everest/certs/ca/csms/CPO_SUB_CA1.pem \ + > config/certificates/trust.pem + 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 + + 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 + + else echo "Patching the CSMS to disable WSS" patch -p1 -i ../everest-demo/maeve/maeve-csms-no-wss.patch fi - # Start the CSMS - echo "Starting the CSMS" - if [[ ${CSMS} == "citrine" ]]; then - cd "Server" - # Remap the CitrineOS 8081 port (HTTP w/ no auth) to 80 port - CITRINE_DOCKER="docker-compose.yml" - - if [[ -f "$CITRINE_DOCKER" ]]; then - # Use sed to find and replace the string - sed -i '' 's/8082:8082/80:8082/g' "$CITRINE_DOCKER" - echo "Replaced mapping CitrineOS 8082 to 80 completed successfully." - else - echo "Error: File $CITRINE_DOCKER does not exist." - exit 1 - fi - fi - - docker compose build + docker compose build docker compose up -d - echo "Waiting 5s for CSMS to start..." + echo "Waiting 5s for MaEVe CSMS to start..." sleep 5 + popd || exit 1 +fi - if [[ ${CSMS} == "citrine" ]]; then - # Configuration - DIRECTUS_API_URL="http://localhost:8055" - CHARGEPOINT_ID="cp001" - CP_PASSWORD="DEADBEEFDEADBEEF" - DIRECTUS_EMAIL="admin@citrineos.com" - DIRECTUS_PASSWORD="CitrineOS!" - - # 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" - } - - # Create new charger 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 - - 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" - else - if [[ "$DEMO_VERSION" =~ sp1 ]]; then - echo "MaEVe CSMS started, adding charge station with Security Profile 1 (note: profiles in MaEVe start with 0 so SP-0 == OCPP SP-1)" - curl http://localhost:9410/api/v0/cs/cp001 -H 'content-type: application/json' \ - -d '{"securityProfile": 0, "base64SHA256Password": "3oGi4B5I+Y9iEkYtL7xvuUxrvGOXM/X2LQrsCwf/knA="}' - elif [[ "$DEMO_VERSION" =~ sp2 ]]; then - echo "MaEVe CSMS started, adding charge station with Security Profile 2 (note: profiles in MaEVe start with 0 so SP-1 == OCPP SP-2)" - curl http://localhost:9410/api/v0/cs/cp001 -H 'content-type: application/json' \ - -d '{"securityProfile": 1, "base64SHA256Password": "3oGi4B5I+Y9iEkYtL7xvuUxrvGOXM/X2LQrsCwf/knA="}' - elif [[ "$DEMO_VERSION" =~ sp3 ]]; then - echo "MaEVe CSMS started, adding charge station with Security Profile 3 (note: profiles in MaEVe start with 0 so SP-2 == OCPP SP-3)" - curl http://localhost:9410/api/v0/cs/cp001 -H 'content-type: application/json' -d '{"securityProfile": 2}' - fi - - echo "Charge station added, adding user token" - - curl http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{ - "countryCode": "GB", - "partyId": "TWK", - "type": "RFID", - "uid": "DEADBEEF", - "contractId": "GBTWK012345678V", - "issuer": "Thoughtworks", - "valid": true, - "cacheMode": "ALWAYS" - }' - - curl http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{"countryCode": "UK", "partyId": "Switch", "contractId": "UKSWI123456789G", "uid": "UKSWI123456789G", "issuer": "Switch", "valid": true, "cacheMode": "ALWAYS"}' - fi - - echo "API calls to CSMS finished, starting EVerest..." +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/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/certChain.pem + + # SubCA + cp dist/etc/everest/certs/ca/csms/CPO_SUB_CA2.key Server/data/certificates/subCAKey.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 + + pushd Server || exit 1 + echo "Starting the CitrineOS CSMS" + cat ./docker-compose.yml + 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 + fi + + echo "Adding a charger to CitrineOS" + ../../everest-demo/citrineos/add-charger.sh popd || exit 1 -fi + 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 - -# 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" @@ -364,9 +211,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" && ! ("$DEMO_VERSION" =~ sp1) ]]; then - echo "TODO: Set up device model correctly!" -else +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 \ @@ -382,7 +227,23 @@ else 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_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_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_citrineos_sp3.db \ + everest-ac-demo-manager-1:/ext/source/build/dist/share/everest/modules/OCPP201/device_model_storage.db + fi +fi + if [[ "$DEMO_VERSION" =~ v2.0.1 ]]; then echo "Starting software in the loop simulation" docker exec everest-ac-demo-manager-1 sh /ext/source/build/run-scripts/run-sil-ocpp201-pnc.sh -fi +fi \ No newline at end of file diff --git a/manager/device_model_storage_citrineos_sp1.db b/manager/device_model_storage_citrineos_sp1.db new file mode 100644 index 0000000000000000000000000000000000000000..67b9838d9f7c2cf01d0f8ad106320349cfd74428 GIT binary patch literal 81920 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 literal 0 HcmV?d00001 diff --git a/manager/device_model_storage_citrineos_sp2.db b/manager/device_model_storage_citrineos_sp2.db new file mode 100644 index 0000000000000000000000000000000000000000..6a9adf59e6bce0a6e1ab7bb57fe4d828269f3910 GIT binary patch literal 81920 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 literal 0 HcmV?d00001 diff --git a/manager/device_model_storage_citrineos_sp3.db b/manager/device_model_storage_citrineos_sp3.db new file mode 100644 index 0000000000000000000000000000000000000000..16c61d64319c053f9e7d7e4df4ad0ba1326cdbaf GIT binary patch literal 81920 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 literal 0 HcmV?d00001 From 17b26dd68fee45e8d52f3a78cd641e9600923c26 Mon Sep 17 00:00:00 2001 From: ChrisWeissmann Date: Mon, 10 Jun 2024 17:46:35 +0200 Subject: [PATCH 2/6] 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 8e990320..648a3f7b 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 From 35fb981513258c6ea6cbcf688f817ec474a2351b Mon Sep 17 00:00:00 2001 From: thanaParis Date: Tue, 18 Jun 2024 11:01:48 -0400 Subject: [PATCH 3/6] fixing issues from pr feedback preventing maeve from working Signed-off-by: thanaParis --- demo-iso15118-2-ac-plus-ocpp.sh | 34 ++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/demo-iso15118-2-ac-plus-ocpp.sh b/demo-iso15118-2-ac-plus-ocpp.sh index 648a3f7b..1daf436c 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -93,9 +93,9 @@ 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 -if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then +if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == maeve ]]; 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}" ${DEMO_CSMS}-csms pushd maeve-csms || exit 1 @@ -145,6 +145,34 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == meave ]]; then echo "Waiting 5s for MaEVe CSMS to start..." sleep 5 + if [[ "$DEMO_VERSION" =~ sp1 ]]; then + echo "MaEVe CSMS started, adding charge station with Security Profile 1 (note: profiles in MaEVe start with 0 so SP-0 == OCPP SP-1)" + curl http://localhost:9410/api/v0/cs/cp001 -H 'content-type: application/json' \ + -d '{"securityProfile": 0, "base64SHA256Password": "3oGi4B5I+Y9iEkYtL7xvuUxrvGOXM/X2LQrsCwf/knA="}' + elif [[ "$DEMO_VERSION" =~ sp2 ]]; then + echo "MaEVe CSMS started, adding charge station with Security Profile 2 (note: profiles in MaEVe start with 0 so SP-1 == OCPP SP-2)" + curl http://localhost:9410/api/v0/cs/cp001 -H 'content-type: application/json' \ + -d '{"securityProfile": 1, "base64SHA256Password": "3oGi4B5I+Y9iEkYtL7xvuUxrvGOXM/X2LQrsCwf/knA="}' + elif [[ "$DEMO_VERSION" =~ sp3 ]]; then + echo "MaEVe CSMS started, adding charge station with Security Profile 3 (note: profiles in MaEVe start with 0 so SP-2 == OCPP SP-3)" + curl http://localhost:9410/api/v0/cs/cp001 -H 'content-type: application/json' -d '{"securityProfile": 2}' + fi + + echo "Charge station added, adding user token" + + curl http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{ + "countryCode": "GB", + "partyId": "TWK", + "type": "RFID", + "uid": "DEADBEEF", + "contractId": "GBTWK012345678V", + "issuer": "Thoughtworks", + "valid": true, + "cacheMode": "ALWAYS" + }' + + curl http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{"countryCode": "UK", "partyId": "Switch", "contractId": "UKSWI123456789G", "uid": "UKSWI123456789G", "issuer": "Switch", "valid": true, "cacheMode": "ALWAYS"}' + popd || exit 1 fi @@ -200,7 +228,7 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then fi pushd everest-demo || exit 1 -echo "Starting everest" +echo "API calls to CSMS finished, 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 8563062ddd5c03d7c3fcdc7d38dbaf08876e7998 Mon Sep 17 00:00:00 2001 From: thanaParis Date: Tue, 18 Jun 2024 11:24:04 -0400 Subject: [PATCH 4/6] adding rfid token generation to script Signed-off-by: thanaParis --- citrineos/add-charger-and-rfid-card.sh | 215 +++++++++++++++++++++++++ demo-iso15118-2-ac-plus-ocpp.sh | 4 +- 2 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 citrineos/add-charger-and-rfid-card.sh diff --git a/citrineos/add-charger-and-rfid-card.sh b/citrineos/add-charger-and-rfid-card.sh new file mode 100644 index 00000000..1961779f --- /dev/null +++ b/citrineos/add-charger-and-rfid-card.sh @@ -0,0 +1,215 @@ +#!/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!" +ID_TOKEN="DEADBEEF" +ID_TOKEN_TYPE="ISO14443" + +#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 +} + +# Function to add new ev driver authorization information +add_evdriver_authorization() { + local response + local success=false + local attempt=1 + local idToken=$1 + local idTokenType=$2 + + until $success; do + echo "Attempt $attempt: Adding ev driver authorization..." + response=$(curl -s -o /dev/null -w "%{http_code}" --location --request PUT "http://localhost:8080/data/evdriver/authorization?idToken=${idToken}&type=${idTokenType}" \ + --header "Content-Type: application/json" \ + --data-raw '{ + "idToken": { + "idToken": "'"$idToken"'", + "type": "'"$idTokenType"'" + }, + "idTokenInfo": { + "status": "Accepted" + } + }' | tee /dev/tty) + + + if [[ $response -ge 200 && $response -lt 300 ]]; then + echo "Authorization update successful." + success=true + else + echo "Authorization 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" + +echo "Add ev driver rfid authorization to citrine..." +add_cp001_password "$ID_TOKEN" "$ID_TOKEN_TYPE" \ 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 1daf436c..684963da 100755 --- a/demo-iso15118-2-ac-plus-ocpp.sh +++ b/demo-iso15118-2-ac-plus-ocpp.sh @@ -219,8 +219,8 @@ if [[ "$DEMO_VERSION" != v1.6j && "$DEMO_CSMS" == 'citrineos' ]]; then exit 1 fi - echo "Adding a charger to CitrineOS" - ../../everest-demo/citrineos/add-charger.sh + echo "Adding a charger and RFID card to CitrineOS" + ../../everest-demo/citrineos/add-charger-and-rfid-card.sh popd || exit 1 popd || exit 1 From 0b1584a277127f69d77dff113cb3ba69dc06db93 Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Tue, 18 Jun 2024 18:21:34 +0000 Subject: [PATCH 5/6] adding execution permissions to add-charger-and-rfid-card.sh Signed-off-by: Christian Weissmann --- citrineos/add-charger-and-rfid-card.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 citrineos/add-charger-and-rfid-card.sh diff --git a/citrineos/add-charger-and-rfid-card.sh b/citrineos/add-charger-and-rfid-card.sh old mode 100644 new mode 100755 From 2f400af897d91273bdbfd9c9803f656cf413c4bc Mon Sep 17 00:00:00 2001 From: Christian Weissmann Date: Tue, 18 Jun 2024 18:52:36 +0000 Subject: [PATCH 6/6] fixing add rfid card call Signed-off-by: Christian Weissmann --- citrineos/add-charger-and-rfid-card.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/citrineos/add-charger-and-rfid-card.sh b/citrineos/add-charger-and-rfid-card.sh index 1961779f..e7d474e6 100755 --- a/citrineos/add-charger-and-rfid-card.sh +++ b/citrineos/add-charger-and-rfid-card.sh @@ -212,4 +212,4 @@ echo "Add cp001 password to citrine..." add_cp001_password "$CP_PASSWORD" echo "Add ev driver rfid authorization to citrine..." -add_cp001_password "$ID_TOKEN" "$ID_TOKEN_TYPE" \ No newline at end of file +add_evdriver_authorization "$ID_TOKEN" "$ID_TOKEN_TYPE" \ No newline at end of file