4. System Architecture

ChargEval is based on the model-view-controller (MVC) architecture. In the MVC architecture, the model represents the data, the view refers to the interface(s) exposed to the user and the controller handles the user requests. The architecture of ChargEval is as shown in Fig. 4.1.

ChargEval System Architecture

Fig. 4.1 ChargEval System Architecture

4.1. Model

The model refers to the data in the application. A relational database management system, PostgreSQL (v12.0.0) has been used as it provides geospatial capabilities through its extensions PostGIS (v 3.0) and pgRouting (v 3.0.0-alpha). The benefit of a database over files is that it enforces strict rules on data. This can help when as the complexity of the application increases and several layers depend on the same data.

Read Database for details about the database.

4.2. View

The view refers to the interface exposed to the users of ChargEval. The users interact with the views. ChargEval has two views - the EV Infrastructure Designer (evides) can be used to select the locations of prospective charging stations and configure the details for the charging stations placed; and the Results Viewer (resview) can be used to view to the results of the simulation for the current EV infrastructure, which is the combination of built as well as proposed charging stations.

4.3. Controller

The controller is the application that manages the execution of a simulation process when a new analysis request is made. Due to the multi-user nature of ChargEval, many users may simultaneously submit analysis execution requests. The controller queues the analysis requests and allocates the available resources.

Read Simulation Manager (simman) for more details about the controller.

4.4. Benefits of MVC Architecture

MVC is a popular architecture for complex applications. The benefit in our case, is that we can deploy all the component applications of ChargEval namely the database, the EV Infrastructure Designer, the Results Viewer and Simuilation Manager on one machine, or we can deploy it across several machines allowing to scale the application as needed. Modular nature of ChargEval allows us to maintain the application with ease, and a develop can work on one component without affecting the others. This also makes deployment easier, as the components can all be containerized.

4.5. System Diagram

Fig. 4.2 shows the ChargEval System Diagram.

ChargEval System Diagram

Fig. 4.2 ChargEval System Diagram

4.6. Deployment

ChargEval can be readily deployed on an AWS EC2 instance using docker-compose. The docker-compose script is located here.

4.6.1. Services

  • nginx: The Nginx webserver is used as a reverse proxy for the R Shiny applications evides and resview.
  • evides: EV Infrastructure Designer (evides) is the R Shiny app with authentication for submitting new EVSE deplopyment scenarios. These scenarios get recorded in a database.
  • simman: This micro-service, the Simulation Manager (simman) is the NodeJS application responsible for managing the submitted analysis requests.
  • redis: The Redis server is used to as the storage for analysis request queue, used by simman.
  • resview: The Results Viewer (resview) is the R Shiny application for viewing the results of the simulation. It shows summary statistics as well as agent states at every minute of the simulation.
  • flyway: This service can be executed to implement database migrations.

To start a docker container after making a change, use the following command to recreate the container (will take some time to execute):

$ docker-compose up -d --build --force-recreate <container-name(s)>

Replace <container-name(s)> with the name(s) of the docker container you wish to start, for example, evides, nginx etc.

To start a stopped container, or restart a container without re-building it, but update environment variables, use the following command:

$ docker-compose up -d <container-name>

To log into a specific container for debugging etc. use the following command:

$ docker exec -it <container-id> /bin/bash

4.6.1.1. AWS-Specific Settings

It is suggested that the script be launched in an instance of type t3a.medium (2 vCPUs, 4 GB RAM) or larger. Other AWS-sepcific settings include:

  • IAM Policies: A new IAM role can be created by attaching the following policies to the EC2 instance with the docker-stack:
    • Send logs to CloudWatch: To be able to send logs from the instance using the AWS CloudWatch agent, attach the pre-existing IAM policy: CloudWatchAgentServerPolicy.
    • Send emails using Amazon SES: To be able to send emails using the Amazon Simple Email Service (SES), attach the pre-existing policy: AmazonSESFullAccess.
    • Create EC2 Instances (of certains types only): This can be achieved by attaching an IAM policy like one shown below (detailed explanation):
{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Sid": "VisualEditor0",
          "Effect": "Allow",
          "Action": [
              "ec2:Describe*",
              "ec2:GetConsole*"
          ],
          "Resource": "*"
      },
      {
          "Sid": "VisualEditor1",
          "Effect": "Allow",
          "Action": [
              "ec2:TerminateInstances",
              "ec2:DeleteTags",
              "ec2:CreateTags",
              "ec2:RunInstances",
              "ec2:StopInstances"
          ],
          "Resource": [
              "arn:aws:ec2:*:*:key-pair/*",
              "arn:aws:ec2:*:*:instance/*",
              "arn:aws:ec2:*:*:subnet/*",
              "arn:aws:ec2:*:*:volume/*",
              "arn:aws:ec2:*:*:security-group/*",
              "arn:aws:ec2:*:*:network-interface/*",
              "arn:aws:ec2:*::image/*"
          ]
      },
      {
          "Sid": "VisualEditor2",
          "Effect": "Deny",
          "Action": "ec2:RunInstances",
          "Resource": [
              "arn:aws:ec2:*:*:subnet/*",
              "arn:aws:ec2:*:*:instance/*",
              "arn:aws:ec2:*:*:volume/*",
              "arn:aws:ec2:*:*:security-group/*",
              "arn:aws:ec2:*:*:network-interface/*",
              "arn:aws:ec2:*::image/*"
          ],
          "Condition": {
              "ForAnyValue:StringNotLike": {
                  "ec2:InstanceType": [
                      "t2.nano",
                      "t2.small",
                      "t2.micro",
                      "t2.medium",
                      "t2.large"
                  ]
              }
          }
      },
      {
          "Effect": "Allow",
          "Action": "iam:PassRole",
          "Resource": "*"
      }
  ]
}

4.6.2. Observability

Observability is the capability to be aware of the system and take quick remedial action in case of failures, errors etc. and is critical for distributed, scalable applications. The three main pillars of observability include:

4.6.2.1. Logging

ChargEval uses AWS CloudWatch as centralized log destination for all systems. Logs are sent from docker containers (evides, simman, resview, redis, nginx, flyway, tripgen) as well as from the launched EC2 instances tripgen and eviabm. Using a centralized log destination allows for log persistance and long term analytical capabilities. The tripgen logging allows for debugging, using queries. For example, the query below shows results in the log entry for origin = 98108, and destination = 98624, shown in Fig. 4.3.The factors that affect the vehicle choice can be examined to verify their validity.

fields @timestamp, @message
| sort @timestamp desc
| filter @@fields.origin_zip = '98108'
| filter @@fields.destination_zip = '98624'
| limit 20
CloudWatch Logs Insight Example

Fig. 4.3 CloudWatch Logs Insight Example

4.6.2.2. Monitoring

  • AWS CloudWatch Dashboard - evi_dss_sys_diagram shows the ChargEval CloudWatch Dashboard. The dashboard shows the plot of average CPU utilization of the main EC2 instance, status of alarms, plot of database metrics like CPU utilization, number of database connections, free storage space, as well as logs from evides, nginx and simman.
ChargEval CloudWatch Dashboard

Fig. 4.4 ChargEval CloudWatch Dashboard

  • dockprom: dockprom gives fine grained statistics for all the docker containers on the system.
  • pgAdmin: pgAdmin’s in-built dashboard allows insight into the database and can be used to see the number of active connections as well as transaction metrics.
  • AWS EC2 Dashboard: The AWS EC2 dashboard provides basic monitoring capabilities on the launched EC2 instances, namely the number and specification of the launched instances as well as coarse system metrics like CPU and memory utilization.
  • ssh: All the EC2 instances have ssh access which means a user can log in and view the system state and debug it as needed.

4.6.2.3. Distributed Tracing

Currently, no instrumentation exists in the system that directly shows the trace of an analysis request, i.e. which step of the process is currently executing. But since, the simulation manager is controlled by the three triggers, namely, notify_new_order(), notify_trips_generated() and notify_solved(), observing the database for status changes alongwith the audit trigger on the analysis_record table gives us an indication of the step.

4.6.3. New Deployment

To create a new deployment, start with an Ubuntu EC2 instance of type T3a.medium or larger and follow the following steps:

  • Install docker, and docker-compose.
  • Clone the repo, initiate the submodules, and update them to the latest commit.
  • Update the services in docker-compose-prod.yml as per the requirement. Create a new log group to send the container logs to, and comment out services not required.
  • Purchase a domain name and update the environment variables appropriately.
  • For a new database, perform the database migrations by running the flyway container like so:
$ docker-compose -f docker-compose-prod.yml up -d flyway
  • Update the EVSE and EV population, using tripgen::update_evses() and tripgen::update_wa_bevs().
  • Add _auth0.yml file at the required location.
  • Generate SSL certificate and copy it to the SSL folder. Also, add the required entries in Route 52 for the new domain related to the SSL certificate authentication. To renew the SSL certificate run:
$ certbot certonly --manual --preferred-challenges=dns --email cp84@uw.edu --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d evidss.org -d www.evidss.org