Post

My SWE Internship Experience @ SP Group

A brief overview of my software engineering internship working with electric vehicle charging infrastructure at SP Group that I undertook during my 3rd year of university during the semester (Jan 2023). Unfortunately, I'm writing this a little over a year too late so my memory might not be all there.

Legend

Throughout this post I will probably reference a lot of the below abbreviations.

AbbreviationExpanded / Explanation
CSMSCharging Station Management System (Software)
CPOCharge Point Operator. Responsible for managing and setting up the charging infrastructure and charging stations.
EMSPE-Mobility Service Provider. Responsible for offering the set-up charging infrastructure to customers and handling billing.
CosmosThe CSMS product offering by SP Digital (Acts as a CPO).
EVAThe EMSP product offering by SP Digital (Acts as an EMSP).
SPMSP Mobility. The business-facing unit of SP Digital’s EV product solutions.
InfinitySPM’s customer-facing app to manage EV charging and handle billing.
OCAOpen Charge Alliance. A global consortium of public and private electric vehicle infrastructure leaders that aims to promote open charging standards.
OCPPOpen Charge Point Protocol (A charging station AND CPO WebSocket communication specification by OCA).
OCPIOpen Charge Point Interface. A CPO and EMSP RESTful communication specification by the EVRoaming Foundation.

Introduction

SP Group was a company that I applied to for a 6-month internship as part of NUS’s Advanced Technology Attachment Programme (ATAP). This internship took place during my university’s 3rd year school semester, so I did some night classes concurrently for a few school modules. I applied for the Product Engineering Intern role in the electric vehicle Charging Station Management System (CSMS) team. What stood out to me with regards to this internship was how nice my team was. I bonded with my internship supervisor over anime, exchanged doggo pictures with my PM, and even composed 3-4 songs together with a songwriter colleague to enter them in competitions. I rate this internship 10/10 👍.

About SP Digital

SP Digital Logo

SP Group (Singapore Power) is a government-owned utilities provider in Singapore, and is the sole electrical and gas grid operator in the country. I was posted to SP Digital, the EnergyTech branch of the company focused on digital transformation and driving innovation in energy management, sustainability, and smart grid technologies. Unlike its parent organization, SP Digital was described to me as having a more start-up-like culture, flatter organizational structure, faster-paced work, and a more collaborative atmosphere geared towards problem-solving in the tech space.

As mentioned, I joined the EV CSMS team. Under the Singapore Green Plan 2030 by LTA, Singapore is slated to grow its adoption of EV technology with the goal of reducing land transport emissions. For example, LTA has set a target of Singapore having 60,000 EV charging points by 2030. SP Group is one of the players in the EV space here in Singapore, and the CSMS team focuses on building and maintaining backend and frontend systems for SP Group’s EV charging products.

Project Background

My full internship report can be downloaded here if you have spare time and want to read 4000 words for some reason 💪.

My Team

As mentioned before, I am part of the CSMS team. The name of the project that this team manages is called Cosmos, whereas CSMS is more of an industry term. The more specific responsibility of this team includes engineering and development of 2 main items. One is the Cosmos central OCPP server, which is the backend system for which charging stations can connect to. This server acts as a platform to monitor and manage charge station information, infrastructure stability, energy, tariffs, authentication tokens, maintenance, billing information, and more. The other item is called Cosmos Web, which is the frontend dashboard where users can interact with Cosmos.

Technology Overview

Charge stations currently connect to Cosmos following the OCPP 1.6 specification using the WebSocket protocol. Once connected, Cosmos is able to send and receive WebSocket messages to and from the charging stations. This allows the charging stations to validate any necessary information with Cosmos, such as authentication and billing information. The general flow of operations when a customer attempts to start EV charging can be seen below.

High Level System Diagram High Level System Diagram

Cosmos interfaces with other systems to provide a full EV charging solution, where the customer manages charging via the Infinity app, which communicates with EVA for payments and subscriptions, and EVA exchanges information with Cosmos via OCPI (REST), while Cosmos manages charging stations through OCPP (WebSocket).

Open Charge Point Protocol (OCPP)

OCPP is designed to enable communication between EV charging stations and a central management system, typically a CSMS. The full specifications can be found here.

Key features

  1. Open Standard: It is an open protocol, meaning it’s publicly available and free to use, promoting wide adoption and compatibility.
  2. Versions: The most widely used versions are OCPP 1.6 and OCPP 2.0.1, with the latter offering more features such as enhanced security, support for smart charging, and better handling of different charging profiles.
  3. Two-Way Communication: It allows two-way communication, meaning the charging station can send data to the CSMS, such as charging session details, status updates, and diagnostics, while the CSMS can send commands like starting/stopping a session or setting charging limits.

How it works

In the specifications for OCPP 1.6, operations are divided into logical sections, such as Core, Firmware Management, Local Auth List Management, Reservation, Smart Charging, and Remote Trigger. For each logical section, the OCPP specification provides the conventions, operation requirements, and message payload details. A proper implementation of this specification requires that each message follows exactly the specified JSON schema in the specification. The below example details the flow of messages during the most basic of charging transactions, without any messages to ship info on regular electricity meter values, smart charging configurations or charger reservations.

Sequence diagram of a simple Charging Transaction Sequence diagram of a simple Charging Transaction, a message under the core logical section

How is the Authorize or StartTransaction request and response WebSocket message formatted? A request and response to and from the central server and the charging station contain the following structure respectively:

Request: [<MessageTypeId>, “<UniqueId>”, “<Action>”, {<Payload>}]

Response: [<MessageTypeId>, “<UniqueId>”, {<Payload>}]

where MessageTypeId, UniqueId, Action and Payload indicates whether it is a request or response, a unique identifier, the name of the operation (for example StartTransaction), and finally a JSON object containing the arguments relevant to the Action. As seen below, the specification also provides the relevant datatypes for each Payload.

Data Type Specification for the `StartTransaction` request Data Type Specification for the StartTransaction request

Problems

  1. Manual Testing Limitation: The current system lacks automated testing capabilities for OCPP 1.6 messages, requiring manual validation with hardware or limited simulators that don’t maintain charger state or support serverless HTTP triggers, making them unsuitable for complex operations.

  2. Load Testing Need: With the growing number of charging stations, Cosmos must be tested for its maximum load handling capacity (e.g., mass reconnections after outages) to optimize Kubernetes pod configurations for efficient resource use.

  3. OCPP 2.0.1 Migration: With near-future plans to migrate to OCPP 2.0.1, a simulated charger is needed for future testing to accommodate new security features and smart charging improvements in the updated protocol.

Project Details

To address the above pain points, there is a requirement for an overall project consisting of 4 sub project modules:

  1. An OCPP 1.6 Charger Simulator that is HTTP triggerable and can be hosted both locally and serverless
  2. An OCPP 2.0.1 Charger Simulator that is HTTP triggerable and can be hosted both locally and serverless.
  3. A Locust application for load testing.
  4. A web platform to manage simulated chargers and facilitate OCPP message exchange with a central server for the OCPP 1.6 Charger Simulator module.

Both the OCPP 1.6 and 2.0.1 charger simulator must be able to be hosted both locally and serverless for the purpose of load testing and automated testing respectively. These 2 simulators are meant to be built with the viewpoint of a charging station manufacturer. This means that the systems must be able to maintain state as well as communicate in a (specification accurate) manner with the central server, which is Cosmos.

The 3rd module (Locust) is meant to compliment the 1st module (OCPP 1.6 simulator). As a load testing framework, locust can simulate a large number of concurrent requests to HTTP endpoint URLs. The URLs that will be used for this module will be exposed by the 1st module. The 4th module is meant to be used for ad-hoc testing by the developer team.

Technology Stack

  • Python
  • ocpp release 0.16.0 by mobilityhouse (MIT licensed)
  • FastAPI for client applications
  • Azure Functions
  • Azure Cosmos DB
  • Docker
  • Jenkins for CI/CD
  • Next.js for the web platform
  • Locust for load testing

High-Level Application Architecture

High-Level Application Architecture Diagram High-Level Application Architecture Diagram

HTTP requests can be made by the user either through the locally hosted FastAPI application itself, or through the serverless hosted Azure Functions provided ASGI wrapper (that allows the endpoints to be hosted on an Azure Functions App which forwards requests to the same FastAPI layer through an ASGI communication interface). The FastAPI application can communicate with Azure Cosmos DB through its SDK for the purpose of storing charger information and maintaining charger state. The FastAPI application then communicates with the central server over OCPP (WebSocket) and change charger state or return a response to the caller based on the operation.

Deliverables

Towards the end of my internship, I:

  1. Recorded and shared a demo video of the process flow when using the Web UI module.
  2. Demo-ed the application modules to both my internship supervisor and the Head of Product Engineering, including the simulation of 500 to 2000 concurrent charging transactions with Locust via the charger simulator API, demonstrating its impact on Cosmos server resources.
  3. Gave a presentation of what I did, faced (in terms of challenges), and learned to the rest of the interns I came in with, as well as to my school’s ATAP supervisor.
  4. Wrote an internship report documenting my project and journey.

Challenges Faced

  1. Adapting to New Development Processes

    This was my first experience with processes like test-driven development, robust code review processes, CI strategies and pipelines and other development best practices. I needed some ramp up time for research.

  2. Unfamiliarity with Domain and Technology Stack

    The project involved a stack I hadn’t fully worked with before, requiring me to spend a little extra time self-learning some new frameworks and tools. For example, I had to design and develop a Next.js web application from scratch to support the OCPP 1.6 simulator module, handling charger CRUD, OCPP operation facilitation, and log management. This process involved frequent research and refactoring to ensure adherence to best practices and language conventions.

  3. Limited Resources for Niche Technologies

    Implementing a serverless OCPP state-maintaining solution presented a unique challenge due to the scarcity of online resources for this very domain-specific technology. There were times where I had to rely on self-guided experimentation trial and error.

What I’ve Learned

  • Technical:

    • Conducting in-depth research to identify tools and technologies that fit project requirements, since I was given some freedom of choice.
    • Gaining proficiency in Python and experience with Azure products like Azure Functions, CosmosDB, Vault and AKS.
    • Working with CI/CD pipelines with Jenkins, GitHub webhooks, and Azure services, learning best practices at each stage.
    • Understanding the basics of good software development, including tools and best practices.
    • Gaining hands-on knowledge about the EV charging industry and how OCPP is implemented in real-world scenarios.
  • Non-technical:

    • The importance of effective communication in a collaborative manner, even across teams.
    • Gaining insight into how large software teams operate, including Agile development processes, and the communication between infrastructure and development teams.
    • Observing the hierarchical decision-making process in a big organization.

Key Takeaways

  • The importance of thorough research and design before starting a project to ensure the right tools and technologies are selected. Proper planning prevents future roadblocks and ensures a smoother development process when the right tools are chosen upfront.

  • Insight into how a proper Agile team functions and the common tools used for maintaining clean code and automating processes. Working in an Agile environment has given me an understanding of how sprints, standups, and retrospectives drive productivity, while tools like linters, CI/CD pipelines, and testing frameworks ensure code quality.

  • Exposure to the electric vehicle industry, its emerging technologies, and the specific implementation of charging processes, which sparked my interest in the sector.

Comments powered by Disqus.