- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
549 lines
19 KiB
ReStructuredText
549 lines
19 KiB
ReStructuredText
.. _htg_getting_started_sw:
|
|
|
|
#######################
|
|
Get started in Software
|
|
#######################
|
|
|
|
Prepare Your Development Environment
|
|
====================================
|
|
|
|
This guide will help you to set up a development environment for EVerest on
|
|
your local machine.
|
|
|
|
For a native build, EVerest requires a Linux based system.
|
|
|
|
To build on a Windows or Mac system, you can use WSL2 (Windows) or
|
|
Docker / Podman (Mac).
|
|
|
|
System Requirements and Dependencies
|
|
====================================
|
|
|
|
This section lists all dependencies and supported environments required to set up
|
|
your development environment and build EVerest.
|
|
|
|
.. attention::
|
|
|
|
As an alternative approach you can make use of development containers.
|
|
EVerest comes with a ready to use configuration. Consult the associated
|
|
:doc:`tutorial </tutorials/setup-devcontainer/index>` to find out how.
|
|
|
|
General Requirements
|
|
--------------------
|
|
|
|
* Python (greater than 3.6)
|
|
* Jinja2
|
|
* PyYAML
|
|
* Compiler:
|
|
|
|
* GCC 9 (lower versions could work with some tweaking but are not
|
|
recommended)
|
|
* Clang (starting with version 12) has been used with EVerest but is not
|
|
officially supported.
|
|
|
|
Tested Linux Distributions
|
|
--------------------------
|
|
|
|
**Ubuntu**:
|
|
|
|
.. warning::
|
|
|
|
Ubuntu 20.04 and 22.04 may not be supported anymore.
|
|
|
|
Tested with Ubuntu 24.04 or newer.
|
|
|
|
Use `apt` to get your needed libraries installed:
|
|
|
|
.. code-block:: bash
|
|
|
|
sudo apt update
|
|
sudo apt install -y python3-pip python3-venv git rsync wget cmake doxygen \
|
|
graphviz build-essential clang-tidy cppcheck openjdk-17-jdk npm docker.io \
|
|
docker-compose libboost-all-dev nodejs libssl-dev libsqlite3-dev \
|
|
clang-format curl rfkill libpcap-dev libevent-dev pkg-config libcap-dev \
|
|
libsystemd-dev
|
|
|
|
**OpenSUSE**:
|
|
|
|
Use `zypper` to get your needed libraries installed:
|
|
|
|
.. code-block:: bash
|
|
|
|
zypper update && zypper install -y sudo shadow
|
|
zypper install -y --type pattern devel_basis
|
|
zypper install -y git rsync wget cmake doxygen graphviz clang-tools cppcheck \
|
|
boost-devel libboost_filesystem-devel libboost_log-devel \
|
|
libboost_program_options-devel libboost_system-devel libboost_thread-devel \
|
|
java-17-openjdk java-17-openjdk-devel nodejs nodejs-devel npm python3-devel \
|
|
python3-pip gcc-c++ libopenssl-devel sqlite3-devel libpcap-devel \
|
|
libevent-devel libcap-devel
|
|
|
|
**Fedora**:
|
|
|
|
Tested with Fedora 40, 41 and 42. Here is how to get your needed libraries with
|
|
`dnf`.
|
|
|
|
.. code-block:: bash
|
|
|
|
sudo dnf update
|
|
sudo dnf install make automake gcc gcc-c++ kernel-devel python3-pip python3-devel \
|
|
git rsync wget cmake doxygen graphviz clang-tools-extra cppcheck java-21-openjdk \
|
|
java-21-openjdk-devel boost-devel nodejs nodejs-devel npm openssl openssl-devel \
|
|
libsqlite3x-devel curl rfkill libpcap-devel libevent-devel libcap-devel
|
|
|
|
.. _htg_getting_started_sw_download_install:
|
|
|
|
Download And Install EVerest
|
|
=============================
|
|
|
|
EVerest's main application code is located in `EVerest <https://github.com/EVerest/EVerest>`_. It makes use of various
|
|
libraries which are included in the same repository for the most part. External dependencies
|
|
are dynamically loaded via `CPM <https://github.com/cpm-cmake/CPM.cmake>`_.
|
|
|
|
This means you can and should set the ``CPM_SOURCE_CACHE`` environment
|
|
variable. This makes sure that dependencies that you do not manage in the workspace
|
|
are not re-downloaded multiple times. For detailed information and other useful
|
|
environment variables please refer to the
|
|
`CPM Documentation <https://github.com/cpm-cmake/CPM.cmake/blob/master/README.md#CPM_SOURCE_CACHE>`_.
|
|
|
|
Make sure to set the ``PATH`` and the ``CPM_SOURCE_CACHE`` variable in your shell profile:
|
|
|
|
.. code-block:: bash
|
|
|
|
export CPM_SOURCE_CACHE=$HOME/.cache/CPM
|
|
export PATH=$PATH:/home/$(whoami)/.local/bin
|
|
|
|
.. note::
|
|
In the past the EVerest Dependency Manager - short ``edm`` - helped you with orchestrating
|
|
and pulling in the dependencies in the build process of ``EVerest``. Since EVerest has
|
|
been restructered into a (quasi)-mono-repository, manual installation of ``edm`` is no longer
|
|
recommended for building recent releases of EVerest (2026 and later).
|
|
For more details about ``edm``, see the dedicated :doc:`edm documentation </explanation/dev-tools/edm>`.
|
|
|
|
We can now continue to build ``EVerest``.
|
|
|
|
.. code-block:: bash
|
|
|
|
git clone https://github.com/EVerest/EVerest
|
|
mkdir build && cd build
|
|
cmake ../EVerest/
|
|
make -j$(nproc) install
|
|
|
|
.. _htg_getting_started_sw_simulate:
|
|
|
|
Simulating EVerest
|
|
==================
|
|
|
|
The following sections explains how to get EVerest running in a software-in-the-loop.
|
|
|
|
.. _htg_getting_started_sw_helpers:
|
|
|
|
Prepare The Helpers
|
|
-------------------
|
|
|
|
EVerest provides some Docker containers that help with the simulation.
|
|
One container is used to run an MQTT Broker (mosquitto), which is required to run EVerest.
|
|
This documentation section shows the necessary steps to start the simulation and get a
|
|
simple Node-RED user interface running.
|
|
|
|
.. hint::
|
|
To get all this working, make sure you have docker and docker-compose installed during the previous install phase.
|
|
If not, see install instructions for `docker <https://docs.docker.com/engine/install/#server>`_ and
|
|
`docker-compose <https://docs.docker.com/compose/install/#install-compose>`_.
|
|
|
|
In order for custom or local containers being able to talk to the services,
|
|
provided by the docker-compose containers, we need to create a common docker
|
|
network. It is called ``infranet_network`` and needs to be created by the
|
|
following command (IPv6 is enabled for containers which might need it):
|
|
|
|
.. code-block:: bash
|
|
|
|
docker network create --driver bridge --ipv6 --subnet fd00::/80 infranet_network --attachable
|
|
|
|
Now, start the mosquitto broker, which is deployed as built docker image.
|
|
It is used for the communication between the EVerest modules:
|
|
|
|
.. code-block:: bash
|
|
|
|
docker run -d --name mqtt-server --network infranet_network -p 1883:1883 -p 9001:9001 ghcr.io/everest/containers/mosquitto:docker-images-v0.1.0
|
|
|
|
|
|
That makes us ready for entering the simulation phase described in the next
|
|
chapter.
|
|
|
|
Software in a loop
|
|
------------------
|
|
|
|
In the following, we will start EVerest as a simple AC charging station with
|
|
software-in-the-loop configuration. This means that all hardware related
|
|
parts like Powermeter, RFID-Reader are loaded as simulated modules.
|
|
Also the Electric Vehicle simulations run as part of EVerest.
|
|
|
|
Change to the directory ``EVerest/build``, which has been created during
|
|
EVerest install.
|
|
|
|
Since the EVerest config we are going to use includes ISO15118 functionality on the EV
|
|
side, we need to source the preinstalled virtual environment and install the respective
|
|
python requirements for ISO15118 using a make target:
|
|
|
|
.. code-block:: bash
|
|
|
|
source venv/bin/activate
|
|
make iso15118_pip_install_dist
|
|
|
|
Now we can start EVerest with a software-in-the-loop configuration via script.
|
|
|
|
.. code-block:: bash
|
|
|
|
./run-scripts/run-sil.sh
|
|
|
|
This script starts EVerest with EVerest with a pre-defined
|
|
configuration for software-in-the-loop simulation. Every module specified in
|
|
that configuration is started as an independent process.
|
|
|
|
In a new terminal window, run the following Node-RED script:
|
|
|
|
.. code-block:: bash
|
|
|
|
./run-scripts/nodered-sil.sh
|
|
|
|
For a user interface, just direct your browser to `<http://localhost:1880/ui>`_
|
|
- the required web-server has already been started via the shell scripts.
|
|
|
|
This will let us control the simulation in a very simple GUI.
|
|
|
|
You can analyse the output of the two shell scripts in the terminal windows to
|
|
get a little bit of insights about what is going on and which ports are used
|
|
etc.
|
|
|
|
In the GUI, you can simulate car charging sessions using the available buttons,
|
|
e.g. `CAR PLUGIN`, `PAUSE`, `RESUME` and so on:
|
|
|
|
.. image:: images/quick-start-sil-gui.png
|
|
:width: 200px
|
|
|
|
Having a very first basic feeling for that will be enough for now.
|
|
|
|
.. _htg_getting_started_sw_admin_panel:
|
|
|
|
Admin panel and simulations
|
|
===========================
|
|
|
|
.. important::
|
|
|
|
Be aware, that the Admin Panel is currently under development.
|
|
The former version of the Admin Panel, which was integrated in EVerest,
|
|
will be removed. See the new standalone version which runs without an
|
|
EVerest instance here:
|
|
`Admin Panel GitHub repository <https://github.com/EVerest/everest-admin-panel>`_
|
|
.
|
|
|
|
You can glue together the modules of EVerest (and also your custom ones) with
|
|
the help of EVerest's framework mechanisms. This way, you define simulation
|
|
flows with which you can test and analyze complicated systems.
|
|
|
|
As EVerest is a modular framework, you can define connections and data flows
|
|
in a nice network of modules. As it would be a little bit exhausting to
|
|
configure everything via code or config files, there is a nice helper: The
|
|
admin panel.
|
|
|
|
It gives you an overview of modules and connections between them. In a
|
|
diagram, you can see and understand the simulation with all interfaces,
|
|
configs, data flows and so on.
|
|
|
|
.. note::
|
|
|
|
See
|
|
`Admin Panel GitHub repository <https://github.com/EVerest/everest-admin-panel>`_
|
|
for information about how to start the Admin Panel. The screenshots and the
|
|
documentation in this subsection might be different than what you see on
|
|
your screen. This is due to the currently ongoing changes in the Admin
|
|
Panel. This will be updated soon.
|
|
|
|
You should see a rather empty page like that:
|
|
|
|
.. image:: images/quick-start-admin-panel-1.png
|
|
:width: 360px
|
|
|
|
Click on the menu symbol on the upper left corner of the page, then click on
|
|
config. A left side column with further menu items opens. Choose `Available
|
|
configs`:
|
|
|
|
.. image:: images/quick-start-admin-panel-2.png
|
|
:width: 360px
|
|
|
|
If you are here for the first time, you will see all pre-configured Node-RED
|
|
flows here. For a first intro, you may want to take a look at *config-sil*.
|
|
|
|
After opening it, you can see a diagram representation of some modules with
|
|
connections between them.
|
|
|
|
Next, let's see how fast we can create a new module in EVerest.
|
|
|
|
.. _htg_getting_started_sw_understand_modules:
|
|
|
|
Understanding EVerest Modules
|
|
=============================
|
|
|
|
You reached the phase of writing a new EVerest module. Congrats!
|
|
|
|
For this Quick Start Guide, we will give you a rocket start of understanding
|
|
the basic elements of the EVerest module concept.
|
|
|
|
.. note::
|
|
|
|
Modules can be implemented in C++, Python or Rust.
|
|
We will stick to C++ in the examples below.
|
|
|
|
So, let's dig into the overview:
|
|
|
|
EVerest is a modular framework. So, there are lots of modules for different
|
|
entities in ``EVerest/modules``:
|
|
|
|
- EvseManager (a charging port as part of a charging station)
|
|
- Hardware driver modules
|
|
- Protocol implementations
|
|
- Car simulation modules
|
|
- Authentication modules
|
|
- Energy management modules
|
|
|
|
and so on.
|
|
|
|
Of course, you can change the functionality of those modules or add your
|
|
custom ones to the whole module stack.
|
|
|
|
In simple terms, a new module can be created by describing its structure
|
|
via a manifest file and interface files. After that, an EVerest helper tool (:ref:`ev-cli <exp_dev_tools_evcli>`)
|
|
will create the necessary files as stub files, so that you can implement the
|
|
details. The EVerest framework will also know how the modules can be connected
|
|
by the restrictions you set in the manifest.
|
|
|
|
How does all that look like? Read the next section!
|
|
|
|
.. _htg_getting_started_sw_basic_elements:
|
|
|
|
Basic elements of a module
|
|
---------------------------
|
|
|
|
Module manifest
|
|
^^^^^^^^^^^^^^^
|
|
|
|
Let's look at the first step: Describing the structure of a new module.
|
|
Starting with the manifest file, which could look like this:
|
|
|
|
.. code-block:: yaml
|
|
:linenos:
|
|
|
|
description: Describing what this module does.
|
|
config:
|
|
some_key:
|
|
description: Describe the effect of this config key.
|
|
type: boolean
|
|
default: false
|
|
provides:
|
|
main:
|
|
interface: myinterface
|
|
description: Describe what the implementation of this interface does.
|
|
requires:
|
|
some_implementation:
|
|
interface: externalinterface
|
|
min_connections: 0
|
|
max_connections: 2
|
|
enable_external_mqtt: true
|
|
metadata:
|
|
license: https://spdx.org/licenses/Apache-2.0.html
|
|
authors:
|
|
- Your name, your company
|
|
|
|
Most of this should be self-explanatory. Just a few words:
|
|
|
|
The config section gives you the possbility to define some config keys for the
|
|
module to re-use it for different scenarios in your workspace.
|
|
|
|
In line 7, the *provides* section let's you tell other modules what your
|
|
module is able to do. You tell the EVerest module framework which interfaces
|
|
have been implemented - for example, a power meter. Of course, you can
|
|
implement more than one interface and list all of that in the *provides*
|
|
section.
|
|
|
|
Line 11 starts with the requirements of your own module. This is the other
|
|
side: Your module tells the EVerest module framework which implementations it
|
|
will require to work.
|
|
|
|
With the ``min_connections`` and ``max_connections`` keys you can configure how
|
|
many connections are required or allowed for your module.
|
|
|
|
In EVerest, you find a manifest file for each module. See the module
|
|
directories in *EVerest/modules*.
|
|
|
|
Interfaces
|
|
^^^^^^^^^^^^^^^
|
|
|
|
An interface describes - like a kind of construction manual - which information
|
|
it delivers and which functionality it provides for other modules to use.
|
|
|
|
A module, that implements an interface, publishes information via **VARs** (short
|
|
for variables). **VARs** can be consumed by connected modules. Functionality is
|
|
provided by **CMDs** (commands, that can be called from other modules).
|
|
|
|
VARs and CMDs are defined in the interface files. Remember the manifest file?
|
|
The previous section showed that the manifest file defines which interfaces your
|
|
module implements. Those interfaces could already exist. If not, you would have
|
|
to create a new one. EVerest contains a rich set of interfaces defining common
|
|
functionality of a charging station software stack.
|
|
|
|
You can find all interface source files in the directory
|
|
*EVerest/interfaces* as yaml files or their
|
|
respective documentation in the :doc:`EVerest Reference Documentation </reference/types_index>`.
|
|
|
|
This is an easy interface as an example:
|
|
|
|
.. code-block:: yaml
|
|
:linenos:
|
|
|
|
description: Describe why we need this interface.
|
|
cmds:
|
|
get_id:
|
|
description: Describe what this command does when called.
|
|
arguments:
|
|
verbose:
|
|
description: An example for a method argument.
|
|
type: boolean
|
|
result:
|
|
description: Explain the return value.
|
|
type: integer
|
|
vars:
|
|
temperature:
|
|
description: Describe this value that gets published.
|
|
type: integer
|
|
limits:
|
|
description: Describe this struct that gets published.
|
|
$ref: /typedef#/Limits
|
|
|
|
A short interface file, but lots to learn here:
|
|
|
|
You can see one CMD defined, which has the name *get_id*. If you want to
|
|
implement this interface (and *provide* the functionality of the interface
|
|
to other modules), this is the method you will have to fill with code in your
|
|
implementation later.
|
|
|
|
There is one argument defined for the method called *verbose*. A return value
|
|
of type *integer* rounds things up for the one CMD of this interface.
|
|
|
|
VARs are pieces of information which get published for the network of
|
|
listening modules regularly. We have two VARs in this example. The first one
|
|
is of type *integer*, the second one is a reference to a type definition.
|
|
|
|
This way, you can create structs or classes (however you would call a bunch
|
|
of simple data-types grouped inside of one logical unit) for publishing.
|
|
|
|
.. note::
|
|
|
|
In some yaml interface files in the EVerest GitHub project, you will still
|
|
find an additional type attribute besides a ``$ref`` attribute. In most cases,
|
|
the type will be of value ``object``. This is considered bad practice and will
|
|
be deprecated in future versions.
|
|
|
|
Let's have a look at a type definition in the next section.
|
|
|
|
Types
|
|
^^^^^^^^^^^^^^^
|
|
|
|
As you have seen in the example interface yaml, you can use *types* instead
|
|
of primitive data types (like boolean, integer, string).
|
|
|
|
In the interface, you saw a reference to an EVerest type definition.
|
|
|
|
You can find the type definitions as yaml files in the following directory:
|
|
|
|
*EVerest/types* or their respective
|
|
documentation in the :doc:`EVerest Reference Documentation </reference/index>`.
|
|
|
|
An easy definition of a type could look like this:
|
|
|
|
.. code-block:: yaml
|
|
:linenos:
|
|
|
|
description: Describe which group of types will follow.
|
|
types:
|
|
SomeType:
|
|
description: Describe this type.
|
|
type: object
|
|
additionalProperties: false
|
|
properties:
|
|
property_1:
|
|
description: Describe the first property.
|
|
type: boolean
|
|
property_2:
|
|
description: Describe the second property.
|
|
type: number
|
|
|
|
You can see one defined type here. It has two properties. A property could
|
|
again be another type reference.
|
|
|
|
Now, as we have defined everything, it is time to let the EVerest command line
|
|
interface - the :ref:`ev-cli tool <exp_dev_tools_evcli>` - generate the implementation stubs.
|
|
|
|
Generate the stub files
|
|
---------------------------
|
|
|
|
You can use ``ev-cli`` to generate stub files for a module. Everything that you need
|
|
is a module directory within ``EVerest/modules`` containing a ``manifest.yaml`` file
|
|
described above.
|
|
|
|
Assuming the module is defined inside the ``EVSE`` directory you can use :ref:`ev-cli <exp_dev_tools_evcli>` to create
|
|
the module skeleton like this:
|
|
|
|
.. code-block:: bash
|
|
|
|
ev-cli mod create EVSE/MyModuleName
|
|
|
|
Your main cpp file will have two special functions:
|
|
|
|
.. code-block:: c++
|
|
|
|
void MyModuleName::init() {}
|
|
void MyModuleName::ready() {}
|
|
|
|
When initialising, the EVerest framework will call all ``init()`` functions of all
|
|
modules one after the other. After having initialised all modules in that way,
|
|
the framework calls the ``ready()`` functions.
|
|
|
|
This allows you to do setup things that relate only to your current module in
|
|
the ``init()`` function and all stuff requiring other modules being initialised in
|
|
your ``ready()`` function.
|
|
|
|
Furthermore, you will get generated files for all interfaces that you
|
|
declared to be implemented in your module. Those interface files will contain
|
|
handler methods for the CMDs you have declared in the interface files.
|
|
|
|
You can walk through the generated files in your new module directory and
|
|
have a look at the prepared classes.
|
|
|
|
Please see the documentation about :ref:`exp_dev_tools_evcli` for further documentation.
|
|
|
|
Or - if you rather would like to have more theoretical input about EVerest
|
|
modules - continue with the
|
|
:doc:`EVerest Module Concept page </explanation/detail-module-concept>`.
|
|
|
|
One Deep Breath And Next Steps
|
|
===============================
|
|
|
|
You made it. Great!
|
|
|
|
Probably, now is a good time to take a deep breath and review what you have
|
|
learnt about EVerest.
|
|
|
|
You might have generated stub files now but still are not sure how to procede
|
|
with implementing your specific scenarios?
|
|
|
|
Good news: A tutorial about developing EVerest modules is waiting for you.
|
|
|
|
:ref:`Continue with the tutorial here! <tutorial_develop_new_everest_module>`
|
|
|
|
See you in our :ref:`weekly tech meetings <project-community>` and thanks for
|
|
being a part of the EVerest community!
|
|
|
|
----
|
|
|
|
**Authors**: Manuel Ziegler, Piet Gömpel, Dominik Kolmann, Andreas Heinrich, Philip Molares, Tobias Marzell
|