Constructing an OCPP-compliant electrical car cost level operator answer utilizing AWS IoT Core

Spread the love

The shift from fossil fuels to electrical powered automobiles is a key part of presidency and business commitments to attain net-zero emissions by 2050. It’s projected that america alone would require a nationwide community of a minimum of 500,000 electrical car (EV) chargers by 2030 to assist the projected variety of EVs on the street [1][2]. Globally, governments and industries are partnering to construct tens of millions of public charging and personal fleet charging networks [3].

Putting in and powering the bodily charging infrastructure is simply step one — chargers (Cost Factors or “CP”) have to be constantly monitored and managed by their operators (Cost Level Operators or “CPO”). CPOs are liable for common distant and on-site upkeep, accumulating well being metrics, and managing operational configurations. CPOs are additionally liable for guaranteeing that the CPs are suitable with the most recent business requirements and protocols, like Open Cost Level Protocol (OCPP) and ISO 15118. And all this have to be applied with safety measures that may assist CPs at scale.

This publish demonstrates how AWS providers like AWS IoT Core, Amazon Elastic Container Service (Amazon ECS), and AWS Lambda can be utilized to construct a highly-scalable, low-latency electrical car cost level operator system based mostly on the EV business customary, OCPP.

About AWS IoT Core

AWS IoT Core helps you to join billions of gadgets and route trillions of messages to and from AWS providers with out managing infrastructure. AWS IoT Core handles the heavy-lifting of scaling and message routing—making it simpler for purchasers needing to assist massive fleets of distant gadgets, like CPs, speaking by publish-and-subscribe patterns. AWS IoT Core natively implements MQTT, HTTPS, and MQTT over WebSockets, and could be tailored to assist different protocols, like OCPP.


Most commercially out there CPs implement OCPP as a method of bi-directional publish-and-subscribe communication with a CPO. Working a CPO on AWS requires the introduction of an OCPP WebSocket endpoint, with which CPs talk. That endpoint, described right here because the OCPP Gateway, acts as a proxy between OCPP and MQTT, enabling integration with AWS IoT Core and downstream CPO providers constructed on AWS.

The next structure diagram illustrates the high-level end-to-end answer you’ll construct on this weblog publish.

Figure 1: Charge Point OCPP message proxied to CPO Service via one-to-one relationship between WebSocket connection and MQTT topic
Determine 1: Cost Level OCPP message proxied to CPO Service through one-to-one relationship between WebSocket connection and MQTT matter


The structure diagram beneath depicts the assets that this answer will deploy into your account.

Figure 2: OCPP Gateway solution stack architecture
Determine 2: OCPP Gateway answer stack structure

The OCPP Gateway is deployed as an Amazon ECS software which might run on both AWS Fargate or Amazon Elastic Compute Cloud (EC2). AWS Fargate eliminates the necessity for infrastructure administration and is the popular choice for this answer. Containerized functions could be scaled horizontally, permitting the OCPP Gateway to routinely scale up or down because the variety of related CPs adjustments. The lengthy working nature of ECS duties permits for WebSockets connections to be maintained for prolonged durations, decreasing community site visitors and connection overheads.

A Community Load Balancer (NLB) fronts a number of OCPP Gateway containers. The NLB supplies a single, absolutely certified area title (FQDN) that serves because the OCPP endpoint to which CPs provoke connection. Upon connection initiation, the NLB will route the cost level connection to one of many OCPP Gateway cases, which is able to set up the WebSocket connection between itself and the CP.

When a CP establishes a socket reference to an occasion of the OCPP Gateway, that Handler units up an MQTT connection to AWS IoT Core utilizing the CP’s distinctive identifier because the Factor ID. That consumer subscribes to MQTT message subjects related to that CP.

The MQTT consumer applied by the OCPP Gateway is socket conscious, thereby offering a one-to-one affiliation between the MQTT subscription and the CP. Any messages initiated by the CPO shall be delivered to the MQTT consumer related to the vacation spot CP and forwarded over the socket to that CP. AWS IoT Core is very elastic and can readily scale as extra CPs are on-boarded.

Resolution walk-through

This answer demonstrates how you need to use AWS to construct a scalable CPO by deploying the OCPP Gateway to combine with AWS IoT Core. The steps beneath will stroll you thru the deployment of an OCPP Gateway into your AWS account, will display how one can simulate CP message, and can present examples of you ways can act on these message utilizing AWS assets.


Confirm that your atmosphere satisfies the next conditions:

You could have:

  1. An AWS account
  2. AdministratorAccess coverage granted to your AWS account (for manufacturing, we suggest limiting entry as wanted)
  3. Each console and programmatic entry
  4. AWS CLI put in and configured to make use of together with your AWS account
  5. NodeJS 12+ put in
  6. Typescript 3.8+ put in
  7. AWS CDK CLI put in
  8. Docker put in
  9. Python 3+ put in

Put together the CDK

The answer shall be deployed into your AWS account utilizing infrastructure-as-code wih the AWS Cloud Improvement Equipment (CDK).

  1. Clone the repository:
git clone
  1. Navigate to this challenge in your laptop utilizing your terminal:
cd aws-ocpp-gateway
  1. Set up the challenge dependencies by working this command:
npm set up
  1. Set atmosphere variables for CDK to the goal AWS account ID and area the place you want to deploy this stack

Word: AWS IoT Core is out there in these AWS areas.

export CDK_DEPLOY_ACCOUNT=targetAccountId (e.g. 12345678910)
export CDK_DEPLOY_REGION=targetRegion (e.g. eu-west-1)
  1. (Non-obligatory) Bootstrap AWS CDK on the goal account and regioon

Word: That is required if in case you have by no means used AWS CDK earlier than on this account and area mixture. (Extra info on CDK bootstrapping).

npx cdk bootstrap aws://{targetAccountId}/{targetRegion}

(Non-obligatory) Allow WebSockets utilizing TLS with your personal area title

When you have an Amazon Route 53 hosted zone in your account, this answer can routinely:

  • Create subdomain (A Document)
  • Create an AWS Certificates Supervisor (ACM) SSL certificates for it
  • Allow TLS in your gateway wss://
  • Uncomment this line in /bin/aws-ocpp-gateway.ts and change with your personal area title (i.e.
  // domainName: '',

Deploy the answer to your AWS Account

  1. Confirm that Docker is working with the next command:
docker model

Word: If you happen to get an error just like the one beneath, then Docker shouldn’t be working and have to be restarted:

Can't hook up with the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon working?
  1. Deploy the OCPP Gateway utilizing the next CDK command:
npx cdk deploy

Word: This step can take about 10 minutes, relying in your laptop and community pace.

  1. You’ll be able to view the progress of your CDK deployment within the CloudFormation console within the chosen area.
Screenshot: CloudFormation stack resources
Screenshot: AWS CloudFormation stack assets
  1. As soon as deployed, be aware of the AwsOcppGatewayStack.websocketURL worth

Word: This WebSocket URL is the entry level that shall be set in your CP configurations or within the
EV Cost Level simulator described beneath.

If you happen to used your personal area, your output will seem like:

AwsOcppGatewayStack.loadBalancerDnsName =
👉 AwsOcppGatewayStack.websocketURL = wss://

In any other case, like this:

AwsOcppGatewayStack.loadBalancerDnsName =
👉 AwsOcppGatewayStack.websocketURL = ws://

Simulating CP connectivity

We’ve offered the Python script that can assist you check and discover the aptitude of the OCPP Gateway and AWS IoT Core with out the necessity for a bodily CP. Different OCPP simulators, like OCPP-2.0-CP-Simulator, may also be used.

Simulation setup

  1. In AWS Explorer, choose your area and open AWS IoT Core, All gadgets, Issues. On the Issues tab select Create a issues.
  2. Choose Create single factor and select Subsequent
  3. Enter a Factor title

Word: Every EV Cost Level should map to a single IoT Factor. For our check, we’ll set the Factor title as CP1

Screenshot: Creating an IoT Thing
Screenshot: Creating an IoT Factor
  1. Select Subsequent
  2. For Gadget certificates, choose Skip making a certificates at the moment, and select Create factor
Screenshot: Skip the certification creation
Screenshot: Skip the certification creation
  1. Navigate to this folder together with your terminal:
cd ev-charge-point-simulator
  1. Create a Python digital atmosphere and activate it by working this command:
python3 -m venv venv && supply venv/bin/activate
  1. Set up the Python dependencies by working:
pip3 set up -r necessities.txt

Simulate an EV cost level boot and heartbeat notification

The Python script simulates some primary performance of an EV cost level:

  • Sending a BootNotification, together with attributes in regards to the CP {hardware}
  • Sending Heartbeat messages based mostly on a frequency instructed by the CPO (that is outlined by the interval parameter returned within the response to the BootNotification)
  1. Run the Python script utilizing the next command, ensuring to switch the --url worth with the AwsOcppGatewayStack.websocketURL returned from the cdk deployment:
python3 --url {websocket URL generated from the AWS OCPP Stack} --cp-id CP1 

Word: we’re utilizing --cp-id CP1 which should match the worth of the IoT Factor created above. If the --cp-id doesn’t match the IoT Factor title, the connection shall be rejected by the OCPP Gateway.

A profitable output ought to seem like this:

(venv) ev-charge-point-simulator % python3 --url {websocket URL generated from the AWS OCPP Stack} --cp-id CP1 
INFO:ocpp:CP1: ship [2,"0678cb2a-a7a2-42bc-8037-d01164e77ac6","BootNotification",{"chargingStation":{"model":"ABC 123 XYZ","vendorName":"Acme Electrical Systems","firmwareVersion":"10.9.8.ABC","serialNumber":"CP1234567890A01","modem":{"iccid":"891004234814455936F","imsi":"310410123456789"}},"reason":"PowerUp"}]
INFO:ocpp:CP1: obtain message [3,"0678cb2a-a7a2-42bc-8037-d01164e77ac6",{"currentTime":"2023-02-16T19:00:18.630818","interval":10,"status":"Accepted"}]
INFO:root:CP1: related to central system
INFO:root:CP1: heartbeat interval set to 10
INFO:ocpp:CP1: ship [2,"9b7933a7-5216-496d-9bb0-dae45014bb98","Heartbeat",{}]
INFO:ocpp:CP1: obtain message [3,"9b7933a7-5216-496d-9bb0-dae45014bb98",{"currentTime":"2023-02-16T19:00:19.073675"}]

This change represents a profitable simulation of a CP, first sending a BootNotification, adopted by subsequent Heartbeat on the specified interval. The output consists of each the simulated OCPP message despatched from the CP to AWS IoT (prefixed ship) and the response acquired from AWS (prefixed acquired message).

  1. To simulate with a distinct CP, set a distinct worth for the --cp-id argument.

Word: if the --cp-id worth doesn’t have a correspondent IoT Factor the OCPP Gateway will reject the connection. Right here is an unsuccessful instance passing --cp-id CP2, which is not registered as a Factor in IoT:

(venv) ev-charge-point-simulator % python3 --url {websocket URL generated from the AWS OCPP Stack} --cp-id CP2 
INFO:ocpp:CP2: ship [2,"32dc5b6e-77b0-4105-b217-28e20b579ecc","BootNotification",{"chargingStation":{"model":"ABC 123 XYZ","vendorName":"Acme Electrical Systems","firmwareVersion":"10.9.8.ABC","serialNumber":"CP1234567890A01","modem":{"iccid":"891004234814455936F","imsi":"310410123456789"}},"reason":"PowerUp"}]
ERROR:root:CP2: acquired 1008 (coverage violation) Cost Level CP2 not registered as an IoT Factor; then despatched 1008 (coverage violation) Cost Level CP2 not registered as an IoT Factor

Monitor OCPP exercise within the AWS Console

Messages from and to the CP are brokered by AWS IoT Core. These messages make the most of the MQTT publish-and-subscribe protocol. You’ll be able to see these messages within the console.

    1. In AWS Explorer, choose your area and open AWS IoT Core, MQTT check consumer
    2. Within the check consumer, choose the Subscribe to a subject tab, and subscribe to those two subjects by getting into these values within the Matter filter:

a. To view all messages from CP to AWS


b. To view all messages from AWS to CP

Screenshot: Subscribe to Topics
Screenshot: Subscribe to Subjects
  1. Run the Python script to simulate a CP and watch the messages within the MQTT check consumer

Monitor EV Cost Level {hardware} attributes in machine shadows

When a CP sends a BootNotification, its {hardware} attributes are saved in a Gadget Shadow related to the IoT Factor. You’ll be able to see these attributes within the console.

  1. In AWS Explorer, choose your area and open AWS IoT Core, All gadgets, Issues
  2. Toggle the verify field towards the Factor created beforehand
  3. Choose the Gadget Shadows tab.
  4. Choose the Basic Shadow machine shadow title hyperlink to see the Gadget Shadow doc and the {hardware} attributes reported by the EV Cost Level:
  "state": {
    "reported": {
      "chargingStation": {
        "mannequin": "ABC 123 XYZ",
        "vendorName": "Acme Electrical Programs",
        "firmwareVersion": "10.9.8.ABC",
        "serialNumber": "CP1234567890A01",
        "modem": {
          "iccid": "891004234814455936F",
          "imsi": "310410123456789"
      "purpose": "PowerUp"
Screenshot: IoT Thing shadow document
Screenshot: IoT Factor shadow doc
  1. Simulate totally different CP {hardware} attributes by passing these arguments into the script and confirm their have an effect on on the Gadget Shadow:
  • --cp-serial – to set the serial quantity
  • --cp-model – to set the mannequin identification
  • --cp-version – to set the firmware model
  • --cp-vendor – to set the seller title


On this publish, you discovered how AWS Companies can be utilized to construct a highly-scalable, low-latency CPO. Utilizing AWS Fargate, you deployed the OCPP Gateway, an OCPP-to-MQTT proxy, which allowed you to benefit from AWS IoT Core’s managed routing and scaling performance to deploy and function your Cost Level Operator answer on AWS. You discovered how Guidelines for AWS IoT can be utilized to filter and route messages from the EV cost level to downstream AWS providers like Amazon DynamoDB and AWS Lambda to create customized reporting and automatic workflows.

The answer and the pattern code have been made out there as open-source and could be readily tailored to your particular enterprise wants.

We hope you discovered this publish informative and the walk-through useful. As all the time, AWS welcomes suggestions. Please be at liberty to attach/message the authors by their LinkedIn profiles embody beneath.

(Non-obligatory) Extra issues to attempt your self

This part supplies some advised simulations and exams you possibly can attempt your self to higher respect the artwork of the doable because it pertains to constructing an OCPP-compliant CPO on AWS.

Load testing

AWS IoT Core is a totally managed, extremely elastic service that scales to assist tens of millions of Issues. The OCPP Gateway makes use of auto-scaling to routinely scale-up as your fleet of CPs grows.

  1. Utilizing a load testing software or the included Apache JMeter configuration, simulate a load of hundreds of CPs
  2. In AWS Explorer, choose your area and open Elastic Container Service
  3. Underneath Clusters open the hyperlink of the cluster created by the OCPP Gateway stack (shall be prefixed AwsOcppGatewayStack)
  4. Choose the Metrics tab
  5. Watch how the variety of duties will increase from one to 2, and so on. as your load will increase.

Auto-scaling is configured to set off when the common CPU utilization exceeds 60% — you possibly can drive extra load or lower this threshold to check the have an effect on.

In case you are utilizing JMeter or comparable load tester be cautious of the variety of threads (Issues) you create and period you run your check for. The answer will readily scale to many hundreds of Issues and can run for indefinite durations of time, which can end in surprising fees in your AWS account. We propose utilizing the load check to check scalability, however to halt the check shortly to cut back prices.

Guidelines for AWS IoT

Guidelines for AWS IoT can be utilized to filter MQTT messages and route them to different providers in AWS. Create a brand new rule to seize Heartbeat messages and file them in a DynamoDB desk for a final recognized occasion.

  1. In AWS Explorer, choose your area and open DynamoDB
  2. Choose Create desk
  3. Present the Desk title chargePointHeartbeat and set the Partition key to chargePointId
  4. Select Create desk
  5. In AWS Explorer, choose your area and open AWS IoT Core, Message routing, Guidelines
  6. Choose Create Rule
  7. Present the Rule title chargePointHeartbeat and select Subsequent
  8. Enter the next into the SQL assertion and select Subsequent
  matter(1) AS chargePointId,
  timestamp() AS lastTimestamp
FROM '+/in'
WHERE get(*, 2) = 'Heartbeat'
  1. For Motion 1, select DynamoDBv2
Screenshot: IoT Rule SQL statement
Screenshot: IoT Rule SQL assertion
  1. Choose the Amazon DynamoDB desk created above for Desk title
Screenshot: IoT Rule action
Screenshot: IoT Rule motion
  1. Choose Create new function, present the Position title
    chargePointHeartbeat, select Create
  2. Select Subsequent and Create
  3. Navigate again to DynamoBD and choose Tables, Discover Gadgets
  4. For Tables, select the DynamoDB desk created beforehand
  5. Run the Python script to simulate a CP and watch as heartbeat are added and replace within the DynamoDB desk

Connection dealing with

A single CP ought to solely preserve one connection to 1 OCPP Gateway, in any other case routing of responses from the CPO to the best connection could also be affected. You’ll be able to simulate a reconnection try.

  1. (Non-obligatory) If you happen to don’t have already got it, obtain and set up the wscat utility
  2. Open a terminal home windows and set up a WebSocket connection:
wscat -c {AwsOcppGatewayStack.websocketURL}/CP1 -s ocpp2.0.1
Related (press CTRL+C to give up)
  1. In a second terminal window run the identical command, trying to create one other connection utilizing the identical CP, e.g.
  2. As soon as this new connection is established you’ll see that the prior connection is routinely closed:
Disconnected (code: 1000, purpose: "")
  1. Testing a reference to a CP that’s not configured as an IoT Factor will end result within the connection try being rejected:
wscat -c {AwsOcppGatewayStack.websocketURL}/CPX -s ocpp2.0.1
Related (press CTRL+C to give up)
Disconnected (code: 1008, purpose: "Cost Level CPX not registered as an IoT Factor")

Clear up

When you find yourself carried out working simulations, deactivate the Python digital atmosphere (venv) by executing this command in your terminal:


You’ll be able to take away the OCPP Gateway Stack and all of the related assets created in your AWS account by working the next command:

npx cdk destroy

In regards to the authors

Garry Galinsky

Garry Galinsky

Garry Galinsky is a Principal Options Architect supporting Amazon on AWS. He’s a part of the hassle to affect Amazon’s Final Mile supply fleets throughout North America and Europe. LinkedIn

Bigad Soleiman

Bigad Soleiman

Bigad Soleiman is a Sr. Lead Prototyping Engineer on the AWS Prototyping Staff. Main largest and strategic AWS prospects navigating advanced core enterprise issues from idea to manufacturing throughout a number of domains. LinkedIn

This publish is part of a broader effort to assist the OCPP protocol on AWS. Particular due to David Goehrig, Sergey Pugachev, Clement Rey, and Ozan Cihangir for his or her contributions to this effort.

Leave a Reply

Your email address will not be published. Required fields are marked *