Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- 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
@@ -0,0 +1,277 @@
|
||||
############
|
||||
EVerest APIs
|
||||
############
|
||||
|
||||
.. tip::
|
||||
|
||||
You can find the API reference documentation here:
|
||||
:doc:`EVerest API Reference </reference/api/autogenerated_api_index>` .
|
||||
|
||||
EVerest can be extended and adapted to specific needs via two sets of
|
||||
APIs: The internal interfaces and the EVerest API.
|
||||
|
||||
The EVerest API are versioned and guaranteed to not introduce breaking
|
||||
changes for the same major version of the API, while the internal
|
||||
interfaces may change between versions. Therefore, the EVerest API
|
||||
is the preferred way to implement custom integrations,
|
||||
extensions and adaptations.
|
||||
|
||||
.. tip::
|
||||
|
||||
If you plan to integrate EVerest on your charging station hardware we
|
||||
strongly recommend to use the EVerest APIs for this purpose, since these
|
||||
interfaces are the ones that are supposed to be kept stable and maintained.
|
||||
over time.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The EVerest API is the interface for hardware integration,
|
||||
custom extensions and adaptations.
|
||||
It is provided via a public MQTT interface, and the format for data
|
||||
exchange is plain text JSON. The API is defined in AsyncAPI 3.
|
||||
|
||||
Custom client software using the EVerest API is therefore only loosely
|
||||
coupled to the EVerest application and its internal interfaces.
|
||||
There are no obligatory binary or link time dependencies of any kind.
|
||||
As a result, the clients can be built individually and without
|
||||
reference to the EVerest application at all.
|
||||
|
||||
This also implies that the programming language used for implementing
|
||||
the client can be chosen freely. Typically a compiled language is
|
||||
preferable for an embedded target, but it is not strictly required at
|
||||
all.
|
||||
|
||||
The EVerest API is implemented in terms of EVerest modules, and every
|
||||
API module implements one or more of EVerest's internal interfaces.
|
||||
There are two distinct versions of API modules, either to implement
|
||||
an interface (e.g. a driver for a DC power supply) or to consume it
|
||||
(e.g. to check for the validation status of a token).
|
||||
|
||||
They can be included in the configuration file just like any other
|
||||
module. E.g. - in this example -, a EVerest API module was loaded to
|
||||
fulfill the power meter requirement of the EvseManager. The actual code
|
||||
that talks to the power meter hardware to fetch the measurements can now
|
||||
be implemented in a process running outside of EVerest (and is started
|
||||
e.g. by a separate *systemd* unit). It just needs to feed the measured
|
||||
values via MQTT into the
|
||||
:ref:`Powermeter API module <everest_modules_powermeter_API>`.
|
||||
|
||||
.. figure:: images/everest-api-1.png
|
||||
:alt: EVerest API - Image 1
|
||||
:width: 450px
|
||||
|
||||
For a better understanding of how the EVerest API works, let us have an
|
||||
exemplary closer look at the
|
||||
:ref:`Power Supply DC API module <everest_modules_power_supply_DC_API>`.
|
||||
|
||||
The manifest can be reduced to this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
config:
|
||||
cfg_communication_check_to_s:
|
||||
type: integer
|
||||
default: 5
|
||||
cfg_heartbeat_interval_ms:
|
||||
type: integer
|
||||
default: 1000
|
||||
|
||||
provides:
|
||||
if_power_supply_DC:
|
||||
interface: power_supply_DC
|
||||
|
||||
There are two configuration variables which are common for every API
|
||||
module. Both are related to communication checks between EVerest and
|
||||
the client module.
|
||||
|
||||
Below, there is the *provides* section, which states that this API
|
||||
module *is* a :doc:`DC power supply </reference/interfaces/power_supply_DC>`.
|
||||
This implies that it can be used in the configuration file for EVerest
|
||||
wherever a DC power supply is expected.
|
||||
|
||||
In a product, this would be the :ref:`EvseManager <everest_modules_EvseManager>`
|
||||
requiring a DC power supply. During development or validation it could also be a
|
||||
BringUp module.
|
||||
|
||||
In contrast to an integrated driver for actual hardware, the API module
|
||||
creates MQTT topics according to its specification and by this provides
|
||||
hooks for the client to do the implementation work.
|
||||
|
||||
The documentation of the APIs can be found in the respective :doc:`reference
|
||||
pages </reference/api/autogenerated_api_index>`. Each API module has its own
|
||||
reference page describing the messages, topics and data structures used.
|
||||
|
||||
Let's take a look at an example configuration that uses the API module:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
active_modules:
|
||||
ps_dc_1:
|
||||
module: power_supply_DC_API
|
||||
config_module:
|
||||
cfg_communication_check_to_s: 60
|
||||
cfg_heartbeat_interval_ms: 1000
|
||||
cli:
|
||||
module: BUPowerSupplyDC
|
||||
standalone: true
|
||||
connections:
|
||||
psu:
|
||||
- module_id: ps_dc_1
|
||||
implementation_id: if_power_supply_DC
|
||||
|
||||
It loads two modules:
|
||||
The :ref:`power_supply_DC_API <everest_modules_power_supply_DC_API>`
|
||||
and the
|
||||
:ref:`BringUp module for DC power supplies <everest_modules_BUPowerSupplyDC>`.
|
||||
Starting EVerest with this configuration enables the API for DC power
|
||||
supplies and a BringUp module, that can send to and receive messages from the
|
||||
API. The actual topics on the MQTT will be available under
|
||||
*everest_api/1/power_supply_DC/ps_dc_1/*.
|
||||
|
||||
It is as simple as this.
|
||||
|
||||
As explained previously, the client is only loosely coupled to EVerest.
|
||||
As a consequence, EVerest cannot know by itself whether the client is
|
||||
available and in good working conditions. For this reason, a
|
||||
bidirectional communication check is available.
|
||||
|
||||
EVerest APIs sends *heartbeat* messages periodically
|
||||
(*cfg_heartbeat_interval_ms* - with negative values disabling heartbeat
|
||||
messages) and on the other hand requires the clients to send
|
||||
*communication_check* messages within the timeout interval specified
|
||||
(*cfg_communication_check_to_s* - with negative values disabling the
|
||||
requirement for these messages).
|
||||
|
||||
In situations where a request/reply pattern is implemented, the timeout
|
||||
for a response can be configured (*cfg_request_reply_to_s* - these timeouts
|
||||
cannot be disabled since internal EVerest timeouts apply) . In general it
|
||||
is advisable to respond as quickly as possible in to to prevent EVerest
|
||||
from blocking internally.
|
||||
|
||||
AsyncAPI
|
||||
========
|
||||
|
||||
The EVerest API is defined in terms of AsyncAPI 3.0.0.
|
||||
|
||||
For a thorough introduction and reference refer to
|
||||
https://www.asyncapi.com .
|
||||
|
||||
All EVerest API modules are located in *EVerest/modules/API* and each
|
||||
module contains the API definition in
|
||||
*EVerest/docs/source/reference/EVerest_API/<name-of-api>.yaml* file.
|
||||
These files are used to generate the
|
||||
:doc:`HTML-based documentation </reference/api/autogenerated_api_index>`.
|
||||
|
||||
In order to build the documentation including the API reference pages,
|
||||
run the following command in your *build* folder:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cmake -DEVEREST_BUILD_DOCS=ON .. && make trailbook_everest
|
||||
|
||||
Another possible way is to use the AsyncAPI yaml source file in
|
||||
`AsyncAPI Studio <https://https://studio.asyncapi.com/>`_.
|
||||
|
||||
The *<name-of-api>.yaml* is defined for the client implementing the API and
|
||||
reflects the client's point of view, when using the words *send* and
|
||||
*receive* in the context of actions and operations.
|
||||
|
||||
The MQTT topics of the EVerest API follow a fixed pattern. All topics
|
||||
are prefixed with *everest_api/1/{api_type}/{module_id}* - with *1*
|
||||
being the version and *{api_type}* the type of the API.
|
||||
|
||||
*{module_id}* is the *module id* of the API module as configured in the
|
||||
EVerest configuration file.
|
||||
|
||||
The prefix is followed by the direction of the message. There are two
|
||||
options:
|
||||
|
||||
- *m2e* for messages from the module (client) to EVerest and
|
||||
- *e2m* for messages from EVerest to the module (client).
|
||||
|
||||
This is finally followed by the name of the message. Here is a complete
|
||||
example:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
everest_api/1/power_supply_DC/ps_dc_1/m2e/voltage_current
|
||||
|
||||
In the example, *power_supply_DC* is the API type, *ps_dc_1* is the
|
||||
*module id* as configured in the EVerest configuration file, the
|
||||
message (*m2e*) originates from the client and is directed towards
|
||||
EVerest. The message name is *voltage_current*.
|
||||
|
||||
AsyncAPI defines channels which carry messages. A channel can be
|
||||
addressed via the topic as defined above. Each channel can in principle
|
||||
carry multiple messages, but concerning EVerest API, there is a
|
||||
one-to-one mapping between a message and a channel. A message carries
|
||||
content in the form of payload and possibly headers.
|
||||
|
||||
The content type for EVerest API is always JSON. The content is
|
||||
individual for each message and defined in *components:schemas* within
|
||||
the same file or sometimes in a referenced file.
|
||||
|
||||
AsyncAPI finally specifies operations on channels. The operations define
|
||||
the action on a specific channel (for EVerest API always from the
|
||||
client's point of view), which can be *send* or *receive*.
|
||||
|
||||
In many situations, the sender of a message is not interested in the
|
||||
receive status of a message, e.g. in a situation where a meter publishes
|
||||
its current values. Simple send and receive operations are used in this
|
||||
case.
|
||||
|
||||
There are situations however, where this is not the case, e.g. remote
|
||||
procedure calls or when a reply is requested. EVerest API handles this
|
||||
situation with the request/reply pattern offered by AsyncAPI.
|
||||
|
||||
The operations are then augmented with a reply property holding the
|
||||
reply channel and a dynamic reply address.
|
||||
|
||||
If the client receives a request, it has to reply to the topic provided
|
||||
in the header's *replyTo* property within *cfg_communication_check_to_s*
|
||||
seconds. If it does not, a default response is given by the API to
|
||||
EVerest and an error is raised.
|
||||
|
||||
If the client sends a request, it has to specify the reply topic, where
|
||||
it expects the answer. This information is communicated via the
|
||||
*replyTo* property of the headers object. It is the client's
|
||||
responsibility to ensure that the topic is unique in order to relate
|
||||
replies to requests.
|
||||
|
||||
Using the EVerest API
|
||||
======================
|
||||
|
||||
In order to use the EVerest API, load the required API modules in the
|
||||
EVerest configuration file and connect its interfaces as presented in
|
||||
the *Overview* section.
|
||||
|
||||
The chosen *module id* becomes part of the MQTT topic. EVerest API
|
||||
modules can be loaded multiple times, e.g. if two DC power supplies are
|
||||
connected.
|
||||
|
||||
If needed, adjust the heartbeat interval and communication check timeout
|
||||
via the *cfg_heartbeat_interval_ms* and *cfg_communication_check_to_s*
|
||||
configuration variables of the module.
|
||||
|
||||
Although communication check and heartbeat can be disabled with values
|
||||
smaller or equal to zero, this is not recommended in a production
|
||||
environment, since they are the only way to continuously check whether
|
||||
the client and EVerest are online and responsive.
|
||||
|
||||
EVerest API clients are completely independent applications. They have
|
||||
to be started independently of EVerest, possibly by their own *systemd*
|
||||
service.
|
||||
|
||||
EVerest cannot start them, since it is agnostic of them. On EVerest
|
||||
startup, the API modules raise an initial communication check error (if
|
||||
communication check is enabled). This error is cleared with the first
|
||||
communication check message sent from the client. It is raised again
|
||||
when a timeout occurs or a request is not answered. Sending a
|
||||
communication check message clears the error again.
|
||||
|
||||
It is the responsibility of the user to ensure that the client is and
|
||||
remains available. This includes potentially a *watchdog* that restarts
|
||||
the client in case of crash or deadlock. It is also the client's
|
||||
responsibility to ensure proper initialization, shutdown and
|
||||
surveillance of managed hardware, e.g. a DC power supply.
|
||||
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 163 KiB |
|
After Width: | Height: | Size: 286 KiB |
|
After Width: | Height: | Size: 231 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 308 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 438 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 258 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 402 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 166 KiB |
@@ -0,0 +1,14 @@
|
||||
#############
|
||||
Adapt EVerest
|
||||
#############
|
||||
|
||||
EVerest is designed to be easily adaptable to different use cases and
|
||||
environments. This section will guide you through the process of adapting
|
||||
EVerest to your specific needs by explaining the various sub-systems and APIs
|
||||
available.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
sub-systems
|
||||
apis
|
||||
@@ -0,0 +1,416 @@
|
||||
###########
|
||||
Sub-systems
|
||||
###########
|
||||
|
||||
The following sections are a functional description of the subsystems of
|
||||
EVerest. A subsystem is a group of modules that together implement a
|
||||
specific functionality. This documentation guides you through some of the
|
||||
most important subsystems step by step, showing how to build them up from
|
||||
individual modules. The following subsystems will be explained:
|
||||
|
||||
- Charging subsystem
|
||||
- Authentication subsystem
|
||||
- OCPP subsystem
|
||||
- Energy management subsystem
|
||||
|
||||
Charging subsystem
|
||||
==================
|
||||
|
||||
The charging subsystem contains all modules that are responsible for the
|
||||
charging logic, car communication and hardware drivers related to a
|
||||
single charging port. For multiple charging ports the whole subsystem
|
||||
can simply be duplicated.
|
||||
|
||||
It depends on the Authentication subsystem to authorize charging
|
||||
sessions and on the Energy management subsystem to allocate the energy
|
||||
budget for the charging process.
|
||||
|
||||
The main module of this subsystem is the
|
||||
:ref:`EvseManager <everest_modules_EvseManager>`.
|
||||
It contains all the logic and state machines for one CCS AC or DC charging
|
||||
port.
|
||||
|
||||
.. _ac-charging-port:
|
||||
|
||||
AC charging port
|
||||
------------------
|
||||
|
||||
Let's build an AC charging port step by step. Start with the EvseManager
|
||||
module. For a simple AC charger, the default configuration of the module
|
||||
is sufficient.
|
||||
|
||||
First, we add a board support module. This is the most important
|
||||
hardware driver.
|
||||
|
||||
In this example, we use the :ref:`YetiDriver <everest_modules_YetiDriver>`
|
||||
module which is the BSP driver for the BelayBox. Check the configuration of
|
||||
the module; it should be correct for the BelayBox. Click on the (i) button
|
||||
to learn more about each configuration setting.
|
||||
|
||||
.. figure:: images/yeti-driver-config.png
|
||||
:alt: Yeti Driver Configuration
|
||||
:width: 320px
|
||||
|
||||
The first connection is for the mandatory
|
||||
:doc:`evse_board_support interface </reference/interfaces/evse_board_support>`.
|
||||
|
||||
It implements the following functionality:
|
||||
|
||||
- Control Pilot Signal (CP): Set PWM duty cycle in X2, State X1/F,
|
||||
report states A-F
|
||||
- Set allow relays on/off flag
|
||||
- Report PP resistor (if used)
|
||||
- Report AC input current / phases capabilities of the system
|
||||
- Stop charging button input
|
||||
|
||||
.. figure:: images/yeti-evse-connection.png
|
||||
:alt: Yeti Driver connected to EVSE Manager
|
||||
:width: 360px
|
||||
|
||||
As you can see, there are two more connections between the
|
||||
YetiDriver and the EvseManager. Those are optional:
|
||||
|
||||
- :doc:`connector_lock </reference/interfaces/connector_lock>`
|
||||
(if used in the hardware): EvseManager requests
|
||||
locking/unlocking of the connector lock (for AC Type 2 Sockets)
|
||||
|
||||
- :doc:`ac_rcd </reference/interfaces/ac_rcd>` (optional):
|
||||
Reports information about the RCD module in an
|
||||
AC charger. This is only used for telemetry and error reporting,
|
||||
the actual shutdown needs to be handled in hardware.
|
||||
|
||||
These two modules already allow basic AC charging functionality. Next
|
||||
step is to add a power meter to allow for invoicing the charged amount
|
||||
of energy. It may not be needed e.g. in a private installation.
|
||||
|
||||
You can use any hardware driver module that provides a
|
||||
:doc:`powermeter interface </reference/interfaces/powermeter>`
|
||||
implementation. For the BelayBox, we could have used the
|
||||
*powermeter* implementation of the YetiDriver (which uses the Yeti
|
||||
onboard metering). In most configurations, an external DIN-rail power
|
||||
meter is used with an RS485/ModBus connection, so we use the
|
||||
:ref:`GenericPowermeter <everest_modules_GenericPowermeter>`
|
||||
module here:
|
||||
|
||||
.. figure:: images/powermeter-connection.png
|
||||
:alt: Power meter connection
|
||||
:width: 420px
|
||||
|
||||
:ref:`GenericPowermeter <everest_modules_GenericPowermeter>`
|
||||
is a module that can easily be adapted to most ModBus-based
|
||||
AC power meters by specifying the register mappings in the
|
||||
configuration of that module. It requires a
|
||||
:ref:`SerialCommHub <everest_modules_SerialCommHub>`
|
||||
module to do the actual read/write to the serial RS485 port of the system.
|
||||
This is a separate module as multiple device drivers may use the same
|
||||
serial bus, so they can all be connected to the same
|
||||
:ref:`SerialCommHub <everest_modules_SerialCommHub>` module.
|
||||
Make sure to configure the correct serial device and baud rate.
|
||||
|
||||
Note that there are two optional requirements for power meters in the
|
||||
EvseManager: *powermeter_grid_side* and *powermeter_car_side*. The first
|
||||
one should be used if the power meter is measuring on the AC input side,
|
||||
the second one should be used if it is measuring the output power to the
|
||||
vehicle. It is ok to connect both if you have two power meters. For AC,
|
||||
one is generally sufficient. For DC, two meters on AC and DC side may be
|
||||
useful.
|
||||
|
||||
Next step is to add ISO communication, if support for AC ISO15118-2 is
|
||||
desired:
|
||||
|
||||
.. figure:: images/iso-communication-connection.png
|
||||
:alt: ISO Communication Connection
|
||||
:width: 700px
|
||||
|
||||
Three modules have been added:
|
||||
|
||||
:ref:`EvseV2G <everest_modules_EvseV2G>`:
|
||||
Implementation of ISO15118-2(AC/DC) and DIN SPEC70121(DC).
|
||||
Connects to the *hlc/ISO15118_charger* requirement of EvseV2G. Make sure
|
||||
to set the “device” config option to the ethernet device of the PLC
|
||||
modem. Leave the other options on default for now.
|
||||
|
||||
:ref:`EvseSecurity <everest_modules_EvseSecurity>`:
|
||||
Handles certificates and private keys for TLS/PnC. We
|
||||
will connect it here even though PnC is not enabled yet.
|
||||
|
||||
:ref:`EvseSlac <everest_modules_EvseSlac>`:
|
||||
Implementation of ISO15118-3 (SLAC) to pair the PLC modems
|
||||
of the EV and the EVSE at the start of the session. Make sure to
|
||||
configure the same “device” as used for the EvseV2G. The two must point
|
||||
to the same PLC modem.
|
||||
|
||||
To actually enable ISO 15118, some settings in the EvseManager module
|
||||
need to be adjusted:
|
||||
|
||||
----
|
||||
|
||||
.. figure:: images/enable-iso15118.png
|
||||
:alt: Enable ISO 15118
|
||||
:width: 350px
|
||||
|
||||
----
|
||||
|
||||
The recommended setting is to use *ac_hlc_enable*, which allows ISO
|
||||
15118-2 sessions on AC. In this configuration, nominal PWM (>10% duty
|
||||
cycle) will be used the same way as it is used for basic charging
|
||||
(non-ISO) sessions. This is the most interoperable way that charges all
|
||||
cars, even if they do not support ISO 15118-2 on AC. All other options
|
||||
will only charge a subset of EVs out there.
|
||||
|
||||
Some cars however may not use ISO at all if they detect nominal PWM -
|
||||
even if they support ISO 15118-2. You enable set *ac_hlc_use_5percent*
|
||||
to start with 5% duty cycle PWM on CP similar to DC charging.
|
||||
|
||||
Several cars will now use ISO communication for AC. The downside is that
|
||||
there are cars that cannot be charged at all, because they allow only DC
|
||||
to be used when 5% signaling is enabled. (They violate the ISO 15118-3,
|
||||
but many car implementations do it that way.)
|
||||
|
||||
With this setting, EVerest may switch back to nominal PWM from 5% in
|
||||
accordance with the ISO 15118-3 regulations. Some EVs may cancel ISO
|
||||
communication in this case, even though the standard clearly states
|
||||
differently.
|
||||
|
||||
For those EVs, you can set the *ac_enforce_hlc* option to “true”. Then,
|
||||
the 5% PWM will be used throughout the complete charging session as it
|
||||
is done for DC. This is not allowed according to the standard though.
|
||||
|
||||
For completeness, we’ll also add a
|
||||
:ref:`PersistentStore <everest_modules_PersistentStore>`
|
||||
module to the *kvs/persistent_store* requirement of the
|
||||
:ref:`EvseManager <everest_modules_EvseManager>`.
|
||||
This is needed to persistently store charging session information e.g-
|
||||
for German Eichrecht requirements. It may not be needed in simple
|
||||
configurations.
|
||||
|
||||
.. figure:: images/persistent-store-connection.png
|
||||
:alt: Persistent Store Connection
|
||||
:width: 700px
|
||||
|
||||
For AC, we are complete now.
|
||||
|
||||
.. _dc-charging-port:
|
||||
|
||||
DC charging port
|
||||
------------------
|
||||
|
||||
Let's build a DC charging port using the phyVERSO board. Start with the
|
||||
:ref:`EvseManager <everest_modules_EvseManager>` again and adjust
|
||||
one setting to switch it to DC mode:
|
||||
|
||||
.. figure:: images/switch-to-dc-mode.png
|
||||
:alt: Switch to DC Mode
|
||||
:width: 320px
|
||||
|
||||
The basic configuration looks similar to the AC one. We just exchanged
|
||||
the :ref:`YetiDriver <everest_modules_YetiDriver>` with the
|
||||
:ref:`PhyVersoBSP <everest_modules_PhyVersoBSP>` driver and connected the
|
||||
*connector_1* interface for *evse_board_support* to EvseManager. Note
|
||||
that *connector_lock* and *ac_rcd* are no longer needed on DC.
|
||||
|
||||
The second port of the phyVERSO will not be used here but could be
|
||||
connected to a second EvseManager. Check the configuration options and
|
||||
especially verify serial port, baud rate, capabilities and reset GPIO.
|
||||
They should be correct on the default phyVERSO Board.
|
||||
|
||||
.. figure:: images/dc-basic-connection.png
|
||||
:alt: Basic DC Connection
|
||||
:width: 700px
|
||||
|
||||
The power meter has been replaced by a
|
||||
:ref:`LEM driver <everest_modules_LemDCBM400600>` , which is a power
|
||||
meter often used for public DC charging. It is connected via ethernet,
|
||||
so no SerialCommHub is needed. Verify the correct target IP is set.
|
||||
|
||||
Then, we will need to add the additional hardware drivers required for
|
||||
DC charging:
|
||||
|
||||
.. figure:: images/dc-additional-hardware-drivers.png
|
||||
:alt: Additional DC Hardware Drivers
|
||||
:width: 750px
|
||||
|
||||
For the DC power supply, a
|
||||
:ref:`Huawei driver <everest_modules_Huawei_R100040Gx>` was added here
|
||||
to the *power_supply_DC* requirement of EvseManager. Set the correct CAN
|
||||
device. As isolation monitor, the
|
||||
:ref:`Bender isoCHA driver <everest_modules_Bender_isoCHA425HV>` was added.
|
||||
As it is a modbus device, it requires a SerialCommHub again - the same way
|
||||
as the GenericPowermeter in the AC configuration. Make sure the settings
|
||||
for the serial port are correct.
|
||||
|
||||
Both of the AC and DC example configs will not yet charge a car. They
|
||||
still need two things from the other subsystems:
|
||||
|
||||
- Energy from the energy management system
|
||||
- Authorization from the Auth subsystem. If you don't need any
|
||||
Authorization, you can also disable this requirement by setting
|
||||
“disable_authentication: true” for EvseManager.
|
||||
|
||||
Authentication subsystem
|
||||
========================
|
||||
|
||||
Let's add a simple authentication subsystem to the charging part we just
|
||||
created. Start by adding the :ref:`Auth module <everest_modules_Auth>` .
|
||||
It is the central logic core of this subsystem and manages all incoming
|
||||
tokens, validations and reservations. Connect it to the *evse/evse_manager*
|
||||
implementation on EvseManager. Through this interface, it will authorize
|
||||
the charging sessions. If you have multiple charging ports (multiple EvseManagers)
|
||||
you can connect all of them to the same Auth module. The Auth module
|
||||
will then manage multiple ports.
|
||||
|
||||
.. figure:: images/multiple-connections.png
|
||||
:alt: Authentication Subsystem
|
||||
:width: 750px
|
||||
|
||||
To do anything useful, the Auth module requires two things:
|
||||
|
||||
1. :doc:`Auth token providers </reference/interfaces/auth_token_provider>`:
|
||||
They are sources of auth tokens, e.g. RFID readers etc that output tokens
|
||||
(but do not know whether they are valid or not).
|
||||
|
||||
2. :doc:`Auth token validators </reference/interfaces/auth_token_validator>`:
|
||||
They can tell whether a token is valid or not.
|
||||
|
||||
Move the *token_provider* requirement to the right. The first auth token
|
||||
provider that we will connect is the *auth_token_provider*
|
||||
implementation of the EvseManager. This is needed for features such as
|
||||
“Plug and Charge” and “Autocharge”, where the EV is used as a token to
|
||||
authenticate the charging session.
|
||||
|
||||
----
|
||||
|
||||
.. figure:: images/add-pnc-autocharge.png
|
||||
:alt: Add Plug-and-Charge and Autocharge Feature
|
||||
:width: 350px
|
||||
|
||||
----
|
||||
|
||||
Next, we can connect an RFID reader as a second auth token provider:
|
||||
|
||||
----
|
||||
|
||||
.. figure:: images/add-rfid-reader.png
|
||||
:alt: Add RFID Reader
|
||||
:width: 380px
|
||||
|
||||
--------------
|
||||
|
||||
Now, let's add a very simple token validator:
|
||||
|
||||
--------------
|
||||
|
||||
.. figure:: images/add-token-validator.png
|
||||
:alt: Add Token Validator
|
||||
:width: 500px
|
||||
|
||||
--------------
|
||||
|
||||
The :ref:`LocalAllowlistTokenValidator <everest_modules_LocalAllowlistTokenValidator>`
|
||||
module takes a simple ASCII file (see config) with one line per token.
|
||||
All tokens listed in this file are considered valid, all others are invalid.
|
||||
With this Auth system, we already have a very simple version that can be
|
||||
used to authenticate RFID tokens, that have been previously added to the
|
||||
local whitelist file.
|
||||
|
||||
OCPP sub-system
|
||||
==================
|
||||
|
||||
Especially for public charging stations, authentication is done via a
|
||||
cloud backend instead of a simple local whitelist. For this, we use OCPP
|
||||
1.6 in this example. OCPP 2.0.1 can be used in a similar way by using
|
||||
the OCPP201 module instead.
|
||||
|
||||
OCPP is both a token provider and a token validator.
|
||||
|
||||
It provides tokens when a *RemoteStart* /
|
||||
*RequestStartTransactionRequest* command is issued, and it is used as a
|
||||
token validator if e.g. an RFID or Plug&Charge contract should be
|
||||
validated in the CSMS. So we will connect both of those connections and
|
||||
remove the LocalWhiteListTokenValidator. OCPP has its own internal local whitelist
|
||||
and authorization cache implementation, that is according to the standard:
|
||||
|
||||
.. figure:: images/remove-whitelist.png
|
||||
:alt: Remove Whitelist
|
||||
:width: 650px
|
||||
|
||||
OCPP requires several connections. Let's go through them step by step:
|
||||
|
||||
- :doc:`Auth token providers </reference/interfaces/auth_token_provider>`
|
||||
and :doc:`Auth token validators </reference/interfaces/auth_token_validator>`
|
||||
are the main ones for remote start and token validation functionality.
|
||||
Connect them to the Auth module.
|
||||
- :doc:`auth interface </reference/interfaces/auth>` needs to be connected to
|
||||
the *Auth* module. This connection is mostly used to set the connection
|
||||
timeout setting via the OCPP protocol.
|
||||
- :doc:`reservation interface </reference/interfaces/reservation>` is used to
|
||||
reserve/cancel reservations of connectors via OCPP from the CSMS.
|
||||
- OCPP also requires a connection to the
|
||||
:ref:`EvseSecurity <everest_modules_EvseSecurity>` module, which
|
||||
is now shared between OCPP and EvseV2G. OCPP requires it to load the
|
||||
certificate / keys for TLS to the CSMS. OCPP can also update/install
|
||||
certificates for both OCPP and ISO 15118 from the CSMS.
|
||||
- OCPP requires a helper module for system-specific implementations
|
||||
(OTA update, logfile collection and upload). Here, we use
|
||||
:ref:`Linux_Systemd_Rauc <everest_modules_Linux_Systemd_Rauc>`
|
||||
from EVerest, which is the default implementation using systemd for
|
||||
log collection and RAUC for OTA updates. This in turn requires a
|
||||
:ref:`PersistentStore <everest_modules_PersistentStore>` module,
|
||||
which is shared here with the EvseManager.
|
||||
|
||||
For more detailed information about the OCPP configuration, check out the
|
||||
following resources:
|
||||
|
||||
- :ref:`OCPP1.6 module documentation <everest_modules_OCPP>`
|
||||
- :ref:`OCPP2.0.1 module documentation <everest_modules_OCPP201>`
|
||||
- :doc:`OCPP1.6 tutorial </tutorials/ocpp16>`
|
||||
- :doc:`OCPP2.0.1 tutorial </tutorials/ocpp2>`
|
||||
|
||||
Now, we have a configuration that can be used in public environments. It
|
||||
supports authentication via OCPP for RFID tags, and - since the LEM
|
||||
power supply is used on the DC port - German Eichrecht compliant
|
||||
metering with OCMF-signed meter values forwarding to the cloud.
|
||||
|
||||
Energy management subsystem
|
||||
====================================
|
||||
|
||||
The last subsystem missing is the Energy management. In EVerest, the
|
||||
energy management distributes energy between charging ports. It is also
|
||||
needed if only one charging port exists.
|
||||
|
||||
Please refer to the
|
||||
:doc:`Energy Management documentation </explanation/energymanagement/index>`
|
||||
for a detailed explanation of how to set up the energy management
|
||||
subsystem.
|
||||
|
||||
Multiple connectors
|
||||
===================
|
||||
|
||||
In order to support multiple charging ports, the charging subsystem will
|
||||
need to be loaded multiple times (also duplicating all direct
|
||||
dependencies), but Auth and Energy management subsystems are used only
|
||||
once.
|
||||
|
||||
Here is an example for two charging ports (leaving out the dependencies
|
||||
of each functional block / most connections for clarity):
|
||||
|
||||
.. figure:: images/multiple-connectors.png
|
||||
:alt: Multiple Connectors
|
||||
:width: 750px
|
||||
|
||||
Most drivers implement only a single instance. So e.g. drivers for
|
||||
isolation monitors, SLAC, ISO protocol etc all need to be duplicated
|
||||
when EvseManager is duplicated.
|
||||
|
||||
A few driver modules also have two implementations of one interface. A
|
||||
good example is the PhyVersoBSP, which is the driver for a dual port
|
||||
controller in one module - so it supplies two separate CP pins etc to
|
||||
two EvseManagers (again removing most other modules for clarity):
|
||||
|
||||
.. figure:: images/phyverso-bsp.png
|
||||
:alt: phyVERSO BSP
|
||||
:width: 600px
|
||||
|
||||
----
|
||||
|
||||
**Authors**: Cornelius Claussen, Piet Gömpel
|
||||