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
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,181 @@
.. _htg_bring_up_ac:
###########
AC BringUp
###########
Make sure to have completed the bring up of the CP signaling as
described in :ref:`htg_basic_bringup`.
It may be a good idea to verify the powermeter functionality now as
well - even though it is not strictly necessary for charging.
Please refer to :ref:`htg_bring_up_powermeter` for the bring-up of
the powermeter.
Once the CP signaling has been verified, most of the work for AC is
done. Let's verify the AC-specific components:
- RCD
- Connector Lock
You can continue to use your bringup config you used for the bring up
of CP, PP and relays, which includes the
:ref:`BSP BringUp module <everest_modules_BUEvseBoardSupport>`.
RCD
===
Residual current monitoring is mandatory in most countries, but the
exact regulations differ in different regions. Typically, both AC and DC
residual current faults need to be detected. If the RCD is part of your
charger setup (it may also be in the installation instead) it is a good
idea to test it now.
Connect an RCD test device, and verify it triggers both on AC and DC
faults within the correct timings and levels according to your region.
Connector Lock
==============
A connector lock is required for AC charging in case your charging station
has a socket outlet. Verify that the lock is working correctly by
commanding it to lock and unlock via your BSP driver.
Milestone: First Charging of a Real Car
=======================================
Now that all individual components have been verified, it is time to
assemble all pieces and charge a real car.
Start by creating a simple AC basic charging configuration file for
EVerest with a minimum amount of components - e.g. with one ModBus
power meter and your board support driver for CP/PP/Relays. You can set
“disable_authentication: true” in the configuration of EvseManager, then
no Auth manager is needed.
.. image:: images/basic-ac-charging-config.png
:alt: AC Basic Charging Configuration
:width: 550px
Copy the config file to your charger prototype. Make sure EVerest is
not running as a *systemd* service as we will start it manually in the
beginning. So in case of doubt, try to shutdown the *everest* system
service:
.. code-block:: bash
systemctl stop everest
Then start EVerest with the following command:
.. code-block:: bash
manager /path/to/simple_ac_config.yaml
It should look similar to the following:
.. image:: images/everest-manager-start.png
:alt: EVerest Manager start
Watch out for the log line “Ready to start charging”. Once that appears,
you can plug in the EV simulator.
Simulate a simple charging session by going to state B. Wait for PWM to
appear, then switch to state C. The relay should click and charging
should work.
Now, switch back to state B to pause charging. The relay should open and
EVerest will wait in state “ChargingPausedByEV”. Go back to state C to
close relay again.
Now, stop charging by first switching to state B followed by state A
(unplug). PWM should stop and the relay should open.
**Congratulations, you now simulated a full AC charging session on your
prototype!**
Two more things that should be tested before trying a real car:
Stop EVerest with ``Ctrl+C``. Switch the EV simulator to state B and
start EVerest again. Ideally, the plug-in should be detected right
after “Ready for charging” and PWM should be enabled. Switch to state C
after PWM is on and the relay should close.
.. tip::
If this does not work, your BSP driver needs to publish the current state
when the “enable” command is called.
This test is important as it simulates the behavior of a power
loss while a charging session is running. Especially in a home
environment, it is expected that the charging continues once the grid is
back.
Now you are ready to connect your first real EV. Here are a few things
you should also try with real EVs:
- Try pause/resume from EVSE side if you have some sort of human
interface (you will need to call the pause/resume charging commands
on EvseManager). If the EV supports it, also triggered by EV side.
- Unplug power input to the charger while a charging session is active
and replug it to verify it starts charging again (simulate grid black
out).
- Try different amperage limits.
Here is a (non-complete) list of things you should test as well in the
full setup:
- Try over-current shutdown (draw more amperage than the PWM allows,
e.g. set PWM to 6 A / 10% but connect a heater to the output of the
EV tester that draws much more than 6A).
- Test under-/over-voltage behavior (different countries have different
requirements).
- Test over-/under-temperature scenarios.
EVerest BringUp for AC ISO 15118-2
==================================
If basic AC charging is fully working, it is time for the ISO 15118-2
charging bring-up. You can use a simulator for this, but unlike for
basic charging, ISO 15118 simulators are quite complex and expensive.
You could use a real car for this.
.. note::
At the time of writing, most cars do not support ISO 15118 for AC - they do
so only on DC. Refer to https://github.com/EVerest/logfiles
to get a better idea which car brands / models can be used for testing.
As with basic charging, we first create a new configuration file by
extending the one we just used for basic charging.
We add an :ref:`ISO 15118 stack <everest_modules_EvseV2G>` as well as a
:ref:`SLAC module <everest_modules_EvseSlac>`:
.. image:: images/iso-15118-stack.png
:alt: ISO 15118 Stack
Start EVerest the same as we did for the basic charging test.
Now connect a real car and watch the output. Explaining the actual ISO
15118 protocol is beyond the scope of this document.
For more information on how to debug ISO communication, refer to
:doc:`Debugging ISO15118 </how-to-guides/debug-iso15118>`.
Now we have the charging functionality up and running for the most
important paths.
.. tip::
A lot of error cases should be tested now as well as we mostly covered the
happy paths - but this goes beyond the scope of this how-to-guide.
----
**Authors**: Cornelius Claussen

View File

@@ -0,0 +1,396 @@
.. _htg_basic_bringup:
################
Basic BringUp
################
This chapter guides you through the basic bring-up of the control pilot (CP),
proximity pilot (PP), and relays for both AC and DC chargers. It is a
prerequisite to the more specific bring-up guides for AC and DC charging.
Control Pilot
=============
The first step - both for AC and DC - is to verify the control pilot
(CP) signal functionality and stability. A lot of problems we have seen
in the field are related to unstable CP signals. So, this step is key
for a stable product.
The normative requirements are described in IEC 61815-1. This section
will guide you through the most important requirements specified in the
norm to be tested at bring-up. It is not complete, IEC gives more
requirements that should be followed at design time.
.. warning::
For all parameters: Ensure that the limits are guaranteed over the complete
temperature and input voltage ranges as well as all other environmental
factors over the complete lifetime of the product.
Being on the edge of the range during bring-up already, will most likely
result in out-of-spec performance in production due to part tolerance,
component aging etc.
First, verify PWM output with no car / nothing connected to it.
You should have an EVSE board support driver for your hardware already.
In this how-to-guide, we will use the BringUp & Qualification tool from
EVerest to select the different CP states manually. This ensures that
(a) the CP signal is correct and (b) the wiring up to the EVerest HW
driver is also correct.
You can find an example configuration file in EVerest for the BelayBox
that you can modify to use the correct BSP driver for your hardware:
.. code-block:: bash
config/bringup/config-bringup-yetidriver.yaml
Before you start the bring-up, make sure there is no other EVerest
instance running (e.g. do a ``systemctl stop everest``).
On the target, start it the following way:
.. code-block:: bash
/etc/everest/run_tmux_helper.sh /etc/everest/bringup/config-bringup-yetidriver.yaml /usr
Now, connect an EV simulator where you can set the states A/B/C/E and
simulate a diode failure / loss of PE connection between EV and EVSE
failure.
State D is not really used anymore nowadays; it dates back to the times
when lead-acid batteries were used that leak hydrogen gas during
charging.
Connect your EVSE, the simulator and a scope similar to this:
.. image:: images/cp-scope.png
:alt: CP Scope
:width: 600px
Now go through the following checklist step by step:
.. tip::
Select PWM off / X1, switch EV simulator to state A.
This should output constant +12 V on the CP line.
- Select AC coupling on the scope and verify the ripple noise. There
is no hard limit, but we recommend keeping it below 100 mV VPP.
.. image:: images/constant-cp-line.png
:alt: Constant CP Line
:width: 560px
- Switch to DC coupling, measure DC voltage range. It must be +12 V
+/- 5% (11.4 V to 12.6 V). Use a multimeter if your scope does not
provide sufficient DC accuracy.
Now select PWM State F. This outputs constant -12 V on the CP line.
- Select AC coupling on the scope and verify the ripple noise. There
is no hard limit, but we recommend keeping it below 100 mV.
- Switch back to DC coupling, measure DC voltage range. It must be
-12 V +/- 5% (-12.6 V to -11.4 V). Use a multimeter if your scope
does not provide sufficient DC accuracy.
Select *PWM on* with a duty cycle of 5%, and connect the EV on the
simulator (State B). Note that the images below were done in state A,
but you should use state B.
- PWM frequency: Must be in the range 980 Hz - 1020 Hz. It should be
1000 Hz.
.. image:: images/pwm-freq-1.png
:alt: PWM Frequency
:width: 560px
- Measure the (high) pulse length for the 5% duty cycle. Measure the
time between the zero crossings. It should be 50 µs.
.. image:: images/pwm-freq-2.png
:alt: PWM Frequency
:width: 560px
- Equivalent source resistance: 970 - 1030 Ohm. Using a 1% 1-kOhm
resistor should be sufficient to fulfill this requirement if the
output of the PWM generator is low impedance.
- Set state B and verify that the PWM duty cycle can be set to any
value between 5% (HLC) and the maximum current value your EVSE
supports (e.g. 53.3% for 32 A for AC). For AC, the maximum PWM for
your application can be calculated with:
.. math::
dutycyclePercent = maxAmpere / (0.6 * 100)
For DC, it is always 5%. The range from 5% to
10% is not used and it is ok to not support PWM in that range.
- Set state B, which will have a PWM voltage range from +9 V to -12
V. Verify rise time is below 10 µs from 10% (-9.9 V) to 90% (6.9 V)
of the signal. The example has a rise time of 4.3 µs.
.. image:: images/pwm-freq-3.png
:alt: PWM Frequency
:width: 560px
- State B: Verify fall time is less than 13 µs. As you can see in the
screenshot, the fall time is 10.68 µs, which is longer than the open
circuit time due to the diode in the EV simulator.
.. image:: images/pwm-freq-4.png
:alt: PWM Frequency
:width: 560px
- Set state C. Verify rise time is below 7 µs from 10% (-10.2 V) to
90% (4.2 V) of the signal. The example has a rise time of 3.08 µs.
.. image:: images/pwm-freq-5.png
:alt: PWM Frequency
:width: 560px
- State C: Fall time must be less than 13 µs from 90% (4.2 V) to 10%
(-10.2 V) of the signal. The example has a fall time of 12 µs which
is in range.
.. image:: images/pwm-freq-6.png
:alt: PWM Frequency
:width: 560px
- Set State E (sometimes called *CP Error* or so). The CP signal
should be at 0 V constantly according to the norm. Some EV simulators
only short after the diode as seen in the screenshot. Make sure that
your CP detection circuitry also treats that as state E.
.. image:: images/pwm-freq-7.png
:alt: PWM Frequency
:width: 560px
- Test diode failure detection: Short the diode on the EV side. Many
off-the-shelf EV simulators can be easily modified with an extra push
button if it is not included already. Verify that the BSP throws an
error (DiodeFault)
- Test short state changes: Toggle between states B, C, B quickly to
produce a short time in state C (about 200 ms or less). The short
state C should be reliably reported to EVerest. It is a common issue
that the safety MCU filters out state durations that are too short.
This will cause issues with the BCB toggle wakeup sequence detection
of ISO 15118-3.
- Disconnect PE between EV and EVSE. This should be detected as an
error or state A.
Now that the basic functionality is working, test stability of the state
detection. Most cheap EV simulators only use the nominal resistor values
to test the states, but ideally you have a simulator that can use the
minimum and maximum values for each state.
Ensure that the following states are detected correctly over the
complete range:
+-----------------+-----------------+-----------------+-----------------+
| State | Minimum R | Nominal R | Maximum R |
| | applied by EV | | applied by EV |
+=================+=================+=================+=================+
| B | 1870 Ω | 2740 Ω | 4610 Ω |
+-----------------+-----------------+-----------------+-----------------+
| C | 909 Ω | 1300 Ω | 1723 Ω |
+-----------------+-----------------+-----------------+-----------------+
If possible, use a debug GPIO, that shows the exact timing of the ADC
sampling and connect it to the second channel of your scope like this:
.. image:: images/pwm-freq-8.png
:alt: PWM Frequency
:width: 560px
In the screenshot, two PWM signals are shown. The cyan one is 5% duty
cycle and the yellow one is 95% duty cycle. The magenta signal shows the
time the ADC reads the signal. As you can see, the first magenta pulse
is nicely aligned with the end of the low part of the PWM, so it will
read the -12 V reliably even at 95% duty cycle.
The second magenta pulse is nicely aligned with the high part of the PWM
providing stable readings even at just 5% PWM. The 5% case is the more
critical one, as very high duty cycles are not typically used.
The most common problem for unstable CP detection (which results in
charging sessions breaking and potentially leads to relays opening under
full load) is that the ADC sampling time starts too early or ends too
late. In both cases it will capture part of the edge of the high part of
the signal, resulting in a lower measured value. This can lead to e.g. a
state C detection while it is state B in reality.
Make sure to observe the correct timing under real conditions with a car
attached. With an open circuit and the 2 µs rise time, timing may be
perfect, but with a car attached and a 10 µs rise time it may not work
correctly.
This is especially critical at the 5% duty cycle as the high part is
only 50 µs long. Never sample in the first 10 µs. When using the MCU to
synchronize ADC and PWM, make sure that interrupt priorities are set
correctly so that additional (interrupt) load on the MCU does not lead
to delayed ADC triggers *sometimes*.
This needs to be 100% stable over long periods of time (hours/days !).
Some MCU (especially those made for motor control) can trigger the ADC
synchronously with the PWM generation without involving an interrupt
routine.
Apply some filtering and averaging in software (e.g. average over 10
pulses, filter out the highest and the lowest value or similar). It
should not detect a wrong state, not even a single time.
Do not filter too much though. This is another common flaw that should
be tested at this stage: IEC 61851-1 requires switching off power when
the EV transitions from C2 to B2 within 100 ms. As the relays also take
some time to open, do not delay the detection of the state change by
more than 50 ms due to filtering. Report all state changes to EVerest,
also those that are short-lived. Otherwise, some features will not work
correctly, e.g. ISO 15118 resume after pause.
Now test with several different real cars as well, as the implementation
on the EV side differs a bit across vendors and models.
Relays
======
The AC output contactor bring-up is the same as for the DC output relay.
Verify the correct function of the relay. Command the MCU to close the
relay (use the BringUp tools *Allow power on* button) and verify it
closes the relay in a timely manner (given that there is no RCD error
etc).
EVerest will issue the *allow_power_on/force_power_off* commands to the
BSP driver just like you can do it in the BringUp module. It is
important to understand the logic:
If the safety MCU receives an *“Allow power on”*, it may switch on the
relay if all other requirements are met (e.g. CP in state C, RCD current
ok, temperature in range etc). The MCU may decide to not switch on the
relay if some other local requirements are not met. It is just important
to always report the actual relay state with the PowerOn/PowerOff
events.
The following checklist tests if the safety MCU behaves correctly in
regard to the CP state C2. It does not test for other requirements such
as over-temperature etc.
If the safety MCU receives a force power off from EVerest, it shall
open the relay immediately.
Complete the following checklist:
- State A, PWM off, force power off. Set State B then enable PWM 5%
and then C.
Then allow power on. Relays should switch on within a short period
of time after sending allow power on. You should see a “Power On”
event (the time between “Allow power on” and the “Power On”
feedback event should be short, e.g. less than 300 ms or so, no
hard limit here). Click on “Force power off”. You should see a
“Power Off” (same timings as above). These timings should be short
- see below. You can click “Power On/Off” a couple of times and
verify the timing of the feedback.
- Toggle the relay on and off a couple of times and observe the
PowerOn/PowerOff events. There should be exactly one event for each
on or off switching of the relay. Make sure that there are not
multiple PowerOn/PowerOff/PowerOn events being generated because the
relay is bouncing.
- State A, PWM off, state State B. Then enable PWM 5%, allow *power on*.
Relay should not close. Wait a few seconds, then set state C.
Relay should close immediately after entering state C. Ignore the
time shown on the “Power On” event. It measures the time from the
last “Allow power on” command to feedback.
- State C, PWM 5%, Relay closed. Then set state B. Relay should open
immediately (max 100 ms). Go back to state C. Relay should close
again. (IEC 61851-1:2017 Table A.6: Sequence 8.1)
- State C, PWM 5%, Relay closed. Then stop PWM but stay in state C.
Relay should open after a minimum of 6 seconds. (IEC 61851-1:2017
Table A.6: Sequence 10.2)
Timing on closing relays is quite relaxed, but ISO 15118 has a limit of
one second from the ISO command to switch on to the ISO feedback that it
was done. As most of the time is spent in the ISO communication stacks,
the MCU should ensure that the time from commanding the relays to close
to receiving the feedback that it was closed correctly should be in the
order of 100 ms in the MCU.
Timing on opening the relays is more critical and a good value is
opening within 50 ms after the command arrives at the latest. IEC
61851-1 requires the relay to be open after a maximum of 100 ms after
state C->B (or A etc) transition.
Verify that the feedback is reported correctly. A typical error during
bring-up with EVerest is missing relay feedback. Make sure they are
always reported to represent the relay state correctly. Send the events
on any change, regardless of the cause of switch on or off in the MCU.
Proximity Pilot
===============
This section is for Type 2 CCS Chargers. PP works a little different for
Type 1 Chargers.
For AC chargers with a type 2 socket, PP needs to be verified as well.
AC Chargers with a permanently attached cable do not use the PP signal.
DC chargers normally do not use PP as they have an attached cable,
however it may be used in some configurations to e.g. detect a cut
cable.
Most of the EV simulators can only switch the nominal resistor values
for 13 A/20 A/32 A. To test the PP functionality, you could e.g. use
small wired resistors and connect them manually between PP and PE or
build yourself a small tester that can do the minimum/nominal and
maximum resistor values.
Verify that the BSP reports the correct cable ampacity for all values in
this table:
================= ========= ========= =========
Cable ampacity Minimal R Nominal R Maximal R
================= ========= ========= =========
13 A 1100 Ω 1500 Ω 2460 Ω
20 A 400 Ω 680 Ω 936 Ω
32 A 164 Ω 220 Ω 308 Ω
63 A 3ph/70 A 1ph 80 Ω 100 Ω 140 Ω
================= ========= ========= =========
Values below 60 Ω above 4500 Ω should be treated as errors and the BSP
should report “None” as PP ampacity. Resistor values in between the
defined ranges in the table should be treated as the lower ampacity
value.
Ensure that PP is measured quickly after plug-in of the vehicle. The MCU
should also monitor PP throughout the complete charging session and
report an error if PP connection breaks.
With CP/PP and relays, the minimal setup for AC charging has already
been verified.
.. tip::
In addition, you may want to verify a few more components before charging a
real car.
But you can also do this later on.
Once the CP signaling has been verified you can continue with the bring up of
the powermeter and the bringup for AC or DC, depending on your use case.
- :doc:`AC BringUp </how-to-guides/bringup/ac>`
- :doc:`DC BringUp </how-to-guides/bringup/dc>`
- :doc:`BringUp Powermeter </how-to-guides/bringup/powermeter>`
----
**Authors**: Cornelius Claussen

View File

@@ -0,0 +1,386 @@
.. _htg_bring_up_dc:
##########
DC BringUp
##########
Make sure to have completed the bring up of the CP signaling as
described in :ref:`htg_basic_bringup`.
For a DC charger, CP is essential. Several other pieces of hardware need
to be brought to life as well, though. This gives you a minimal setup
before testing the complete setup:
- The DC power supply that delivers the charging current to the car
- Isolation monitoring device
- Optional: Proximity pilot
Let's start with the DC power supply as this is the most important one.
DC Power Supply
===============
Make sure the high voltage output of the DC power supply is isolated and
nothing is attached to it that could draw current or get destroyed by
high voltages. Make sure it is safe to set the maximum voltage.
.. warning::
Follow all relevant safety precautions.
Only trained personnel may execute this step.
High voltages may cause severe injury including death.
We will only check the most important features required for a minimal
CCS charger setup. Check IEC 61851-23 for a full set of requirements.
We will manually set voltages up to the maximum voltage and verify the
driver functionality and the performance of the power supply under
no-load conditions.
Create a simple BringUp configuration file that contains only the
BUPowerSupplyDC module and the actual driver module / bridge module to
your external driver. There are a couple of examples that you can
modify: ``config-bringup-huawei.yaml``, ``config-bringup-uugreen.yaml``,
``config-bringup-api-powersupply.yaml``.
Start the BringUp & Qualification session with the following command in
the build folder:
.. code-block:: bash
/etc/everest/run_tmux_helper.sh /etc/everest/bringup/config-bringup-mypowersupply.yaml /usr
Now make sure to complete the checklist:
Start with the power supply being switched off. Set the maximum output
voltage (e.g. 1000 V) and then switch the power supply to export mode
(rectifier mode, power supply outputs power to the car). Make sure to do
it in exactly this order:
- Verify that the reported capabilities are matching the
manufacturer's specifications for the power supply.
- Verify that the output voltage is reached within 6 seconds. If it
stays on a lower voltage, the power supply driver may “forget” the
voltage setting when being switched on or off. This needs to be
fixed. The driver should work independently of the order of setting
output voltage and switching on/off.
- Verify the output voltage and current is measured accurately.
Compare against an external voltage meter and a current meter (IEC
61851-1:2023 CC.6.3 requires +- 10 V for voltage and +-1.5% for
current or 0.5 A - whichever is more).
- Verify that there is no overshoot when changing voltage from lowest
to highest output voltage. This may cause problems in CableCheck
phase on some EVs.
- Verify the measured output voltage is correctly reported back to
EVerest (see measured output voltage in the BringUp module).
- Verify the measured voltage is reported frequently (e.g. every
second or more often).
- Optional: Measure the power factor. Some power supplies have
problems with power factor correction under no / light load
conditions. When charging a real car, no load happens during
*CableCheck* and *PreCharge* phases.
Now, set the minimum output voltage that the power supply supports
(e.g. 150 V). On power supplies that have high/low mode switching,
choose the minimum voltage that the high mode supports. Otherwise, it
will take quite long to switch from highest to lowest voltage, since the
power supply will need to change its mode configuration.
- Switch the power supply off and verify that the output voltage
drops to 0 V more or less immediately.
- On power supplies with automatic high/low voltage mode switching:
Switch manually between the highest and lowest voltage setting to
trigger mode switches. They should be reasonably fast, e.g. < 5
seconds. Should switching between the modes be necessary during
charging, it is ok to have a small pause in *CurrentDemand*.
- Switch on the power supply at e.g. 500 V and exit the bring up
setup, so EVerest is no longer communicating with the power supply.
It should switch off after a timeout. (Most power supplies switch off
within 10-20 seconds after communication loss.)
Isolation monitor device
========================
The isolation monitor needs to comply with IEC 61557-8 or equivalent.
EVerest will use the isolation resistance values as reported by the
driver module and decide whether to stop the charging session or not. It
is a good idea to have a redundant switch-off by e.g. using the IMDs
built in relay to directly switch the emergency off input of the PSU.
To test the correct functionality within EVerest, use the
BUIsolationMonitor BringUp module and connect it to the driver module.
An example can be found here:
.. code-block:: bash
config/config-bringup-isolation-monitor-sil.yaml
.. image:: images/bring-up-split-screen.png
:alt: BUIsolationMonitor Bring-Up
Ideally, the BringUp configuration loads both the isolation monitor and
DC Power supply modules as both are needed to run all tests.
- Switch on the “Power supply” at 500 V. Click on “Start
measurements”. Verify the isolation monitor sees the 500 V output
voltage. This is to ensure it is actually connected to the correct
wires. Verify that new measurements are coming in regularly
(e.g. every second).
- Verify that the measured resistance is very high (e.g. 1 MOhm or
so).
- Connect a 100 kOhm (or other value) resistor from the minus wire to
protective earth. Check how long it takes until the value changes on
the screen. This should be inline with the specs from the datasheet
(e.g. <10 seconds for Bender).
- Test the same with the plus wire.
- Stop the measurements and verify no more measurements are coming
in.
- Start the self-test of the IMD and wait for the result (with the
power supply still being on). It should take no more than 10 s or so
to do the self-testing. Many isolation monitors take a long time to
complete the self-testing. This may cause time-out problems in
*CableCheck* with some cars.
The time it takes until the IMD detects the isolation fault will need to
be set in the final configuration file.
Over-voltage monitor device
===========================
IEC 61851-23:2023 requires a fast over-voltage protection (OVM)
(6.3.1.106.2). For a minimal proof-of-concept setup in a lab
environment, you may want to skip this as it is not functionally needed
for charging. It will be required for certification though.
The OVM shall switch off if the DC voltage is above the required limit
for 9 ms. For bring-up purposes, we want to test if limit is transported
correctly and if the start and stop commands from EVerest are
implemented correctly in the driver.
An example bring-up configuration using APIs can be found here:
.. code-block:: bash
config/config-bringup-api-over-voltage-monitor.yaml
Add two things to this bring-up configuration:
1) A power supply driver connected to a BringUp module
2) An evse_board_support driver connected to a BringUp module
Test setup:
- Connect a CP tester to the control pilot and set state C.
- Set “Allow power on” in the evse_board_support BringUp. The relays
should close now.
- Connect a scope with one channel to the high voltage (use a 1000 V
probe!) and one channel to coil voltage of the relays. Instead of the
coil voltage, any other signal that triggers when the emergency
shutdown starts can be used.
To test the basic functionality, use the check list below. Start each
test with a fresh test setup (relays closed).
.. note::
There are more requirements in the standard - especially regarding timing.
- Switch on power supply at 500 V. Set the OVM limit to 550 V and
start the monitoring. Then, set the power supply to 565 V. The relays
should open immediately. The point in time when the voltage rises
above 550 V is t_1 - the time where the coil voltage indicates a
start of emergency shutdown. Verify with the scope that the time
between t_1 and t_2 is a maximum of 10 ms (9 ms for detection of
over-voltage and 1 ms to initate the shutdown.)
- Repeat for 825 V (limit) and 840 V (DC output voltage).
- Repeat for 935 V (limit) and 950 V (DC output voltage).
- Repeat for 1100 V (limit) and 1115 V (DC output voltage). This
measurement is probably not possible as the power supply is limited
to 1000 V. It is a test case in table 103 of IEC 61851-23:2023.
- Set a limit of 550 V. Switch on the power supply at 500 V. Start
monitoring. Stop monitoring. Set the DC output voltage to 565 V. The
relays shall remain closed as the over-voltage monitoring is not
active.
More IEC 61851-23 test cases for DC
===================================
For a minimum proof-of-concept setup, it should be enough already.
IEC 61851-23 has several more requirements (check the norm for a
complete list) that need to be fulfilled for a real product. Here is the
list of mandatory functions from IEC 61851-23:2023 6.3.1.1 that should
be tested early on as they may influence the final design:
- Verify the timing of the CableCheck phase. EVerest will print some
timing hints on the console. Several cars will timeout and not charge
if the Cable check takes more than 30 s. Recommendation is to stay
below 25 s for the complete phase. This may not be achievable with
off-the-shelf components. It is however crucial to be compatible with
all EVs. Use e.g. BYD EVs to test for the 30 s timeout in
*CableCheck*.
- Continuous continuity checking of the protective conductor
according to 6.3.1.2: This can be usually fulfilled by opening the
relays (potentially under load), but you should consider ramping down
the DC power supply before opening the relays to protect them.
- Verification that the EV is properly connected to the EV supply
equipment according to 6.3.1.3: This should be compliant
automatically if the *evse_board_support* and the safety MCU passed
the BringUp checks.
- Energization of the power supply to the EV according to 6.3.1.4:
This should be compliant if the BringUp checks are passed.
- De-energization of the power supply to the EV according to 6.3.1.5:
Similar to “Continuous continuity checking of the protective
conductor”.
- Maximum allowable current according to 6.3.1.6: This should be
compliant if the BringUp checks are passed.
- DC supply for EV according to 6.3.1.101: This should be compliant
if the BringUp checks are passed.
- Measuring current and voltage according to 6.3.1.102: For charging,
EVerest uses the voltage and current measurements as reported by the
power supply (not the power meter). This should be compliant if the
BringUp checks passed for the DC power supply.
- Latching of the vehicle coupler according to 6.3.1.103: This should
be compliant if the BringUp checks are passed.
- Compatibility check according to 6.3.1.104: This should be
compliant if the BringUp checks are passed.
- Insulation resistance check before energy transfer according to
6.3.1.105: This should be compliant if the BringUp checks are passed.
- Protection against over-voltage between DC+ and DC according to
6.3.1.106: This is a quite hard requirement (trigger shut-down in 1
ms after voltage is above limits for 9 ms). It requires both an
accurate and fast measurement. This needs to be implemented in the
safety MCU independently of EVerest.
- Verification of vehicle connector latching according to 6.3.1.107:
Not applicable for CCS.
- Control circuit supply integrity according to 6.3.1.108: Hardware
requirement.
- Short-circuit check before energy transfer according to 6.3.1.109:
Test with a 100 Ohm load resistor connected in *CableCheck* as per
the norm.
- User initiated shutdown according to 6.3.1.110: This can be
implemented either in the BSP (publish var *request_stop_transaction*
in interface *evse_board_support*) or use *stop_transaction* command
in *evse_manager* interface. Both are available via the EVerest API
modules.
- Overload protection for parallel conductors (conditional function)
according to 6.3.1.111: Pure hardware requirement.
- Voltage limitation between side B live parts (DC+ and DC) and
protective conductor according to 6.3.1.112: Hardware requirement -
choose especially the IMD wisely.
- Shutdown of EV supply equipment according to 6.3.1.113: This should
be compliant if the BringUp checks are passed.
First milestone: Connect a real car, zero power charging
========================================================
Now that all individual components are verified, start EVerest with the
full configuration that you created earlier.
Disconnect the plus wire between your prototype and the cable to the EV.
On the first tests, no power should be flowing.
Start EVerest and wait for the message “Ready for charging”. Then plug
in the vehicle. Watch the ISO traffic. It should be successful until the
*PreCharge* phase. Then the EV should stop as it cannot see the voltage.
During the start up of the session, monitor the voltage of the DC power
supply. It should be 500 V in *CableCheck* (or whatever you set in the
config) and then switch to the EV batteries voltage.
Verify that in precharge the output voltage is within +/-20 V of the
EV's battery voltage.
Second milestone: Connect a real car, limited power charging
============================================================
Connect a 5 kOhm resistor in the plus wire between EVSE output and
connector to EV. This will limit the current flow into the EV, but
allows voltages to be seen by the EV. Plug in a vehicle. You should now
get all the way to the *CurrentDemand* phase.
Some EVs will stop after some seconds as no current is flowing.
Verify all communications are correct. Use Wireshark to verify each step
of the ISO communication (see Debug chapter).
Third milestone: Connect a real car, full power charging
========================================================
If everything was correct in the previous step, remove the resistor and
connect the plug normally to the EVSE. Start a charging session.
Power should now be delivered to the EV in *CurrentDemand*.
Verify that the current delivered is what the EV requested and that it
is also reported correctly in the *CurrentDemandRes* messages. Verify it
is shown correctly on the in-vehicle display.
Verify the AC side is not getting overloaded.
.. tip::
A good habit is to monitor your prototype with a small thermal camera to
see if any component overheats.
If that works: **Congratulations!** You have successfully charged an EV
with DC for the first time.
Error cases
===========
There are many error cases that should be tested now. Listing all goes
beyond the scope of this manual. A few examples that should be tested:
- Place a 100 kOhm resistor from minus wire to PE. Start a charging
session. It should also fail in *CableCheck* state.
- Test short circuit under full load.
- Test load dump: Charge at maximum power and open the relays to zero
load. Watch the voltage overshoot. The power supplies need to survive
that multiple times. This does happen in the field with some EVs that
open their contactors during charging when the onboard controller
firmware resets.
- AC under-/over-voltage input
- Over-temperature shutdown
- On three-phase AC/DC converters, switch off one phase on the input
at full load.
----
**Authors**: Cornelius Claussen

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -0,0 +1,147 @@
.. _htg_bring_up:
########################
BringUp & Qualification
########################
This chapter introduces the EVerest BringUp & Qualification process.
This process is all about bringing up the individual hardware components
step by step by verifying their functionality and performance in
isolated test cases. In the end, the whole charger will be brought to
life and we'll hit the most important milestone: A first complete
charging session of a real car.
.. tip::
EVerest HW Drivers should be available for all required hardware
components and a prototype hardware should be in place.
Many sections are written like a checklist that you can follow step by step.
Before we start, we recommend to set up the following development
environment:
- Working cross compiler on your PC to do fast updates of your code
(e.g. with *rsync* to the target). On Yocto, use ``bitbake -c
populate_sdk my-image`` to generate the SDK.
- SSH to the target
- Ensure the hardware interfaces to all components are up and running
- Include “tmux” in your image
- Recommended: Unicode support should work on the target terminal
BringUp modules
================
The following chapters use EVerest's BringUp helper modules.
These modules allow manual control of one or several hardware drivers.
We will use them to verify correct functionality and timing of all
components individually before assembling the complete configuration
file.
The BringUp modules should be included in the system image initially,
but later in production they should not be installed.
To get familiar with this method, you can use a pure SIL version on your
development PC. This step is optional. From the *build* folder, start
the following run script:
.. code-block:: bash
./dist/etc/everest/run_tmux_helper.sh ../config/bringup/config-bringup-isolation-monitor-sil.yaml ./dist
The first parameter specifies the config file to load, the second
parameter points to the EVerest installation to use.
Later, on the embedded target, it can be used like this:
.. code-block:: bash
/etc/everest/run_tmux_helper.sh /etc/everest/bringup/myconf.yaml /usr
The second argument now points to the EVerest version installed in the
base Yocto system. If you use a cross-compiled development version
installed under ``/var/everest``, simply set the second argument to
``/var/everest``.
You should see a split-screen setup (using tmux) similar to this:
.. image:: images/bring-up-split-screen.png
:alt: Bring-Up Split-Screen
In the left pane, EVerest is running all modules except for the two
BringUp modules. They are running in their own shell. Mouse support
should be working and you can click on the buttons.
E.g., click on “Start Measurements” and check that new isolation
measurements are coming in roughly every second.
To exit the tmux session, press ``Ctrl+B`` and then ``d``. Normally with
tmux, this puts the session running into the background but it keeps
running. The ``run_tmux_helper.sh`` script will take care of ending the
session properly here and cleaning up.
Have a look at the config file that it is using
(``config/bringup/config-bringup-isolation-monitor-sil.yaml``):
.. code-block:: yaml
active_modules:
bsp_ui:
standalone: true
module: BUIsolationMonitor
connections:
imd:
- implementation_id: main
module_id: iso_monitor
powersupply_ui:
connections:
psu:
- implementation_id: main
module_id: powersupply
module: BUPowerSupplyDC
standalone: true
iso_monitor:
module: IMDSimulator
powersupply:
module: DCSupplySimulator
The configuration file loads the two BringUp modules you saw on the
right as well as the two driver modules for isolation monitor and DC
power supply. Since it is a SIL config, both hardware drivers are
simulated only.
.. tip::
Have a look at the attribute “standalone: true” in both BringUp modules.
This tells the manager and the tmux script that these two modules should be
run in a separate tmux window.
For your hardware, you will need to create configuration files that use
the real hardware instead of the simulated ones. There are example files
for each of the following steps - just adapt them to your needs.
Now, lets use this on real hardware.
.. warning::
During the hardware bring-up, you will switch on high voltages that can
cause severe injury including death.
It must only be done by trained personnel.
Make sure to follow all necessary safety procedures.
The following chapters will guide you through the individual steps of
bringing up the hardware components one by one.
.. toctree::
:maxdepth: 1
basic
powermeter
ac
dc
----
**Authors**: Cornelius Claussen

View File

@@ -0,0 +1,44 @@
.. _htg_bring_up_powermeter:
##################
BringUp Powermeter
##################
In case your charger prototype has a power meter, it may be a good time
to verify its functionality as well now - even though it is not strictly
necessary for charging.
Write a bring-up config for your power meter and start it the same way
as described in :ref:`htg_bring_up`. There are a few examples you can copy
and modify, e.g. ``config-bringup-DZG.yaml`` or ``config-bringup-LEM.yaml``.
.. code-block:: bash
/etc/everest/run_tmux_helper.sh /etc/everest/bringup/config-bringup-mypowermeter.yaml /usr
Your setup should look like this:
.. image:: images/bring-up-powermeter.png
:alt: Bring-Up Powermeter
Complete the following steps:
- Verify that the measurements come in regularly (e.g. every second).
- Imported energy in Wh and timestamp are the only required values.
Verify they are correct. For bidirectional metering, also verify the
exported energy values.
- Validate the other reported measurements.
- If supported by the power meter (e.g. for
:doc:`German Eichrecht </how-to-guides/eichrecht>`), click
on “Start Transaction”. Verify that it replies correctly, and verify
the time to reply is less than a few seconds.
- Click on “Stop Transaction” and verify the reply. The reply should
not take more than a few seconds.
- Apply some test load if possible, and verify that the flow
direction of energy is correct. A common mistake is to swap input and
output of the meter. If you dont have a test load, you can also test
this when doing the first charging tests with a real car.
----
**Authors**: Cornelius Claussen

View File

@@ -0,0 +1,65 @@
.. _htg-choosing-version:
###########################
Choosing an EVerest Version
###########################
This guide helps you choose the right EVerest version for your use case.
Please refer to our :ref:`versioning policy <project-release-and-versioning>` for detailed information on
versioning and release cycles.
.. note::
This guide provides general guidance but is not exhaustive. Actual version and upgrade
requirements depend on your specific deployment, integrations, and customizations.
Always thoroughly review release notes and test upgrades in non-production environments.
Production Deployments
======================
For production systems, use the latest stable release (``yyyy.mm.x``). These versions provide:
- Tested and verified functionality
- Ongoing maintenance and security updates
- Stable public APIs
- Community support
Development and Testing
=======================
For development of new features or testing upcoming changes, you may use the ``main`` branch. Be aware that:
- Breaking changes may occur at any time
- APIs may be unstable
- This is not suitable for production deployments
Upgrade Planning
================
Within Stable Lines
-------------------
Upgrading within a stable release line (e.g., ``2026.01.0`` to ``2026.01.3``) should be straightforward:
- Review the release notes for the target version
- Test the upgrade in a non-production environment
- Deploy the new version
No configuration or integration changes should be required.
Across Major Releases
---------------------
Upgrading to a new stable release line (e.g., ``2026.01.x`` to ``2026.07.0``) requires more careful planning:
- Review the release notes and potential migration documentation
- Identify any breaking changes affecting your integration
- Update configurations and integrations as needed
- Thoroughly test in a non-production environment
- Plan a maintenance window for production deployment
Migration guides may be provided by the community for each major release documenting known breaking changes and upgrade paths.
Different major releases may be fully backwards compatible, partially compatible, or incompatible depending on the changes introduced.
It is recommended to review the release notes as well as versions of the public API components when upgrading across major releases.

View File

@@ -0,0 +1,111 @@
.. _howto-configure-pnc:
Configure Plug&Charge in EVerest
================================
This is a goal-oriented how-to-guide on how to configure Plug&Charge in EVerest.
To learn how Plug&Charge is implemented in EVerest, please refer to the
:doc:`Explanation of the Plug&Charge process </explanation/pnc-process>`.
The following two configuration files are relevant and require a correct setup and activation for Plug&Charge:
* EVerest configuration file (yaml)
* OCPP configuration file(s) (json) for OCPP 1.6 or OCPP 2.x
Let's start with the EVerest configuration file. If you haven't read
:ref:`Explaining the YAML files <exp-yaml-files>`,
now it's the right time to do it before you go on!
It's a good idea to start with a base of a configuration file and talk about the changes required to enable
Plug&Charge. The base config we use is the "config-sil-ocpp201.yaml", which already contains the configuration
for OCPP2.x.
Module Configurations
---------------------
We need to take a closer look at the configuration of the following modules:
* EvseManager
* EvseV2G
* Auth
* EvseSecurity
EvseManager
~~~~~~~~~~~
* In case of AC, make sure that `ac_hlc_enabled` is set to `true` in order to allow ISO15118 communication.
* Make sure `payment_enable_contract` is set to `true`.
EvseV2G
~~~~~~~~~~~
* Make sure `tls_security` is set to `allow` or `force`.
* Make sure `verify_contract_cert_chain` is set to `true`.
Auth
~~~~~~~~~~~
* Make sure the EvseManager module is listed as a connection of `token_provider`. This is important, because only
in this case the authorization request including the contract certificate is actually received by the Auth module.
* Make sure the OCPP module is configured as the single `token_validator`.
EvseSecurity
~~~~~~~~~~~~
Please refer to :ref:`Documentation of the EvseSecurity module <everest_modules_handwritten_EvseSecurity>`
for information on the ISO15118 configuration. It describes how to configure the paths to the required certificates and keys.
.. _how-to-configure-pnc-ocpp-configuration:
OCPP 1.6 and OCPP 2.x configuration
-----------------------------------
For a general introduction to how to configure OCPP in EVerest, please refer to :ref:`the OCPP1.6 tutorial <tutorial-ocpp16>`
or :ref:`the OCPP2.x tutorial <tutorial-ocpp2>`.
Since Plug&Charge has been backported from OCPP 2.x to OCPP 1.6, the
configuration options to control the process are mostly identical.
These options are described in the following section, where differences
between OCPP 1.6 and OCPP 2.x are marked.
These OCPP configuration options are relevant for the Plug&Charge process:
* ISO15118CertificateManagementEnabled (bool): Global feature flag to enable
certificate management using ISO15118. This enables the ISO15118 message handling
via the DataTransfer mechanism according the the OCPP1.6 Plug&Charge Whitepaper.
(only required for OCPP1.6, OCPP2.x does not require this option). This option
should be set to `true` in order to allow certificate management for Plug&Charge.
* ISO15118PnCEnabled (bool): Global feature flag to enable authorization using
contract certificates. This option should be set to `true`.
* CentralContractValidationAllowed (bool): If enabled and charging station can
not validate the contract locally (e.g. because no MO root certificate is
installed), the charging station provides the contract certificate as part
of the Authorize.req so that the CSMS can verfiy the contract instead.
* ContractValidationOffline (bool): If enabled, the charging station will try
to validate a contract certificate when it is offline using the authorization
cache or the local authorization list. If this is set to `false`, Plug&Charge
will fail if the charging station is offline.
* ISO15118Ctrlr::V2GCertificateInstallationEnabled (bool, only OCPP2.x):
Allows the CSMS to install an SECC leaf certificate on the charging station.
This must be enabled in case the charging station shall receive the SECC leaf
certificate from the CSMS.
* ISO15118Ctrlr::ContractCertificateInstallationEnabled (bool, only OCPP2.x):
Allows contract certificate installation installtion/update in the EV
via ISO15118.
The following configuration options control parameters of the certificate
signing request that is initiated by the charging station automatically in case
Plug&Charge is enabled and no (valid) SECC Leaf Certificate is currently installed.
* SeccLeafSubjectCommonName (string, ISO15118Ctrlr::SeccId in OCPP 2.x)
* SeccLeafSubjectCountry (string, ISO15118Ctrlr::CountryName in OCPP 2.x)
* SeccLeafSubjectOrganization (string, ISO15118Ctrlr::OrganizationName in OCPP 2.x)
These configuration keys can be configured manually or controlled by the CSMS according to its needs. If the CSMS rejects the CSR
from the charging station or does not return a certificate after the specified timeouts and retries, it is likely that the values
of these configuration keys do not match the expectations of the CSMS. Contact your CSMS partner in this case.
----
**Authors**: Piet Gömpel

View File

@@ -0,0 +1,138 @@
.. _htg_debug_iso15118:
#################
Debug ISO 15118
#################
This how-to-guide will show you how to debug ISO15118 communication
of EVerest using Wireshark.
.. _htg_wireshark:
Wireshark plugin
=================
Using the Wireshark plugin from *dspace*, it is possible to decode the
EXI messages sent over the interface of the PLC modem. The plugin uses
the same EXI decoder as EVerest.
It does even decrypt TLS-encrypted communication as EVerest sends the
keys to decrypt the packages as UDP broadcast, so the plugin can make
use of it. It is possible to live-view traffic between EV and EVSE and
to decrypt captured traffic after the fact.
Install
-------
Follow the steps in this
`README <https://github.com/dspace-group/dsV2Gshark?tab=readme-ov-file#requirements>`_
to install the plugin:
.. tip::
Make sure to copy the **whole** content of the zipped archive to the
corresponding folder!
.. _remotelivecapture:
Remote live capture
--------------------
In order to view live traffic, an *ssh* connection between the system(s)
running Wireshark and the target is required.
Making use of a VPN connection enables remote live capture from around
the globe, e.g. developers in the backoffice observing live traffic on
chargers during testivals.
To start a remote live capture session in Wireshark, click on the small
gear symbol next to:
.. figure:: images/sshdumpsetupsymbol.png
:alt: SSH remote capture: sshdump
:width: 600px
This should open a setup window. Enter the target IP address and SSH
port.
.. figure:: images/sshdumpsetup.png
:alt: Setup Window
:width: 600px
Select ``Authentication`` and enter the SSH credentials for the target.
.. figure:: images/authentication.png
:alt: Authentication
:width: 600px
Next, select ``Capture`` and type in the network interface on the target
that is used by the PLC modem. In the case of the YAK board, it is
``eth1``.
.. figure:: images/capture.png
:alt: Setup Window
:width: 600px
To start the live capture session, click on ``Start``.
.. tip::
It is recommended to establish a passwordless SSH connection, as the
password must be typed in every time a remote capture session is started.
After setting this up e.g. via `ssh-copy-id`, select the path to your
private key.
SSH credentials with an empty password are not supported for the steps
above.
However, in order to start a live capture session without any prior GUI
setup using an empty or passwordless SSH connection, simply execute:
.. code-block:: bash
wireshark -k -i <( ssh <user>@<target_ip> tcpdump -s 0 -U -n -w - -i <device to listen on>)
The remote live session should look like this:
.. figure:: images/traffic.gif
:alt: wireshark_traffic
.. _decodingafterthefact:
Decoding captured traffic after the fact
-----------------------------------------
To activate the local capturing of traffic between EV and EVSE, you need
to include the ``PacketSniffer`` module in your EVerest config:
.. code-block:: yaml
packet_sniffer:
config_module:
session_logging_path: <your desired path>
connections:
evse_manager:
- implementation_id: evse
module_id: evse_manager
module: PacketSniffer
In case you want to keep the capture files after a reboot, you need to
set the logging path, e.g. ``/var/everest-logs/sessions``; otherwise
the default logging path is ``tmp``, which will be empty on each boot.
To view the captured traffic, you can either download the ``.dump``
files via SCP and use the Wireshark GUI to open the files or in case a
passwordless *ssh* is set up (``ssh-copy-id``), you can directly open
the file using:
.. code-block:: bash
wireshark -k -i <(ssh <user>@<target ip> cat <logging path on target>/ethernet-traffic.dump)
You can now view the decoded messages, e.g.
.. figure:: images/wireshark_decoded.png
:alt: wireshark_decoded_message
----
**Authors**: Cornelius Claussen

View File

@@ -0,0 +1,94 @@
.. _htg_debug_modules:
#####################
Debug EVerest Modules
#####################
Preparation
===========
Obvious prerequisite for using a debugger is to compile the project with
debugging enabled. One easy way to achieve this is to call
.. code-block:: bash
cmake -B build -DCMAKE_BUILD_TYPE=Debug
from the root folder of EVerest, assuming you have already created the
``build`` directory.
Execution
=========
It is possible to use the GNU Debugger (GDB) to debug a single EVerest module.
The easiest way is to run the module in standalone mode. Say, for example, you
want to debug the Auth module for the SIL config (``config-sil.yaml``).
Let's assume you are in directory ``build/dist``.
Start the manager with
.. code-block:: bash
./bin/manager --config config-sil --standalone auth
This will start EVerest with the config-sil.yaml as configuration, but it
won't start the Auth module (note ``auth`` is written small because it is the
*module instance id* - this way there can be multiple Auth module instances
in your config).
Now you need to start the Auth module manual using gdb. When using
Visual Studio Code, the debug configuration (``launch.json``) looks like this:
.. code-block:: bash
{
"version": "0.2.0",
"configurations": [
{
"name": "AuthManager",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/dist/libexec/everest/modules/Auth/Auth",
"args": ["--config", "config-sil", "--module", "auth"],
"stopAtEntry": false,
"cwd": "/workspace/EVerest",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
]
}
This will then start the Auth module instance.
Also note the argument ``--module auth``, which again specifies the module
instance id and needs to match the one you've used for standalone.
Now, EVerest will continue to start and breakpoints set in the source file of
the Auth module should be taken.
.. note::
It is also possible to debug the whole manager process. This way, you will
have the disadvantage of possibly bad performance. The reason is that the
manager spawns/forks new processes, which then need to be attached to the
debugger too.
Just in case you want to go this direction, you need to
"set detach-on-fork off" and "follow-fork-mode" depending on what you want to
achieve.

View File

@@ -0,0 +1,310 @@
#####################################################
Use the EVerest Development Container (devrd managed)
#####################################################
The EVerest development container (devcontainer) provides
a consistent development environment for EVerest development
and sil testing.
With the devcontainer itself also service containers
are provided to run required services like databases,
message brokers, etc.
.. hint::
This guide describes the usage of the devcontainer
managed by the `devrd` cli tool.
For the variant using the VSCode Dev Containers extension
this is not required since everything is managed by VSCode
automatically.
Find further documentation on development containers here:
- :doc:`Tutorial: Setup the EVerest Development Container </tutorials/setup-devcontainer/index>`
- :doc:`Internals of the EVerest Development Container </explanation/devcontainer-internal/index>`
***************************
Provided Service Containers
***************************
Services are organized into logical profiles for easier management:
.. _table_of_devcontainer_services:
.. list-table::
:header-rows: 1
:widths: 20 20 20 20 20
* - Profiles
- Services
- Container Name
- URL
- Purpose
* - ``mqtt/ocpp/sil/all``
- **MQTT Server**
- `<prefix>_devcontainer-mqtt-server-1`
- localhost:1883
- Basic MQTT broker
* - ``ocpp/all``
- **OCPP DB**
- `<prefix>_devcontainer-ocpp-db-1`
- Internal
- OCPP database
* - ``ocpp/all``
- **SteVe (HTTP)**
- `<prefix>_devcontainer-steve-1`
- <http://localhost:8180>
- OCPP backend management
* - ``sil/all``
- **Node-RED UI**
- `<prefix>_devcontainer-nodered-1`
- <http://localhost:1880/ui>
- SIL simulation interface
* - ``sil/all``
- **MQTT Explorer**
- `<prefix>_devcontainer-mqtt-explorer-1`
- <http://localhost:4000>
- MQTT topic browser
* - ``ocpp/sil/all``
- **Dev Container**
- `<prefix>_devcontainer-devcontainer-1`
- Command line
- The development container
* - ``ocpp/sil/all``
- **Docker Proxy**
- `<prefix>_devcontainer-docker-proxy-1`
- Internal
- Secure Docker API access
.. note::
the ``all`` profile is a synthetic profile that includes all
services. Use ``./applications/devrd/devrd start all`` or ``./devrd start`` (default)
to start all services.
Where ``<prefix>`` is the docker compose project name prefix.
***********************************
Starting/Stopping Services/Profiles
***********************************
To start/stop service containers use the ``devrd`` cli tool,
with ``./applications/devrd/devrd start`` and ``./devrd stop`` commands.
Usage examples:
.. code-block:: bash
# Start profiles
./applications/devrd/devrd start # Start all services (generates .env if missing)
./applications/devrd/devrd start all # Start all services (same as above)
./applications/devrd/devrd start sil # Start SIL simulation tools
./applications/devrd/devrd start ocpp # Start OCPP backend
./applications/devrd/devrd start mqtt # Start only MQTT server
# Stop services
./applications/devrd/devrd stop # Stop all services
./applications/devrd/devrd stop all # Stop all services (same as above)
./applications/devrd/devrd stop sil # Stop SIL profile only
./applications/devrd/devrd stop ev-ws # Stop all containers matching pattern 'ev-ws'
*******************
Devcontainer Access
*******************
There are two ways to access the devcontainer:
1. **Open an interactive shell in the devcontainer**
To run commands inside the devcontainer, open an interactive shell
with the devrd cli:
.. code-block:: bash
./applications/devrd/devrd prompt
This will open an interactive shell inside the devcontainer.
The contents of the EVerest repository are mapped
to the ``/workspace`` directory inside the container.
You can now run all development commands inside this shell.
2. **Run a single command in the devcontainer**
To run a single command inside the devcontainer, use the
``devrd exec`` command:
.. code-block:: bash
./applications/devrd/devrd exec <command> [args...]
This will run the specified command with optional arguments
inside the devcontainer and return the output to the host terminal.
Example:
.. code-block:: bash
./applications/devrd/devrd exec ls /workspace
This will list the contents of the ``/workspace`` directory
inside the devcontainer.
********************************************
Clean Up Devcontainer and Service Containers
********************************************
To clean up the devcontainer and all service containers,
use the ``./applications/devrd/devrd stop`` and ``./devrd purge`` command:
.. code-block:: bash
./applications/devrd/devrd stop # Stop all service containers
./applications/devrd/devrd purge # Remove all service containers, images and volumes
***********************************
Manage Flows for Node-RED Container
***********************************
There are two commands one should know when working with Node-RED flows:
1. **List available flows**
To list all available flows in the Node-RED container use the command:
.. code-block:: bash
./applications/devrd/devrd flows
2. **Switch to specific flow file**
To switch to a specific flow file in the Node-RED container use the command:
.. code-block:: bash
./applications/devrd/devrd flow path/to/flow/file.json
Where ``path/to/flow/file.json`` is the path to the flow file.
**********************************
Modify Workspace Directory Mapping
**********************************
While the default mapping of the EVerest repository
is to the ``/workspace`` directory inside the devcontainer,
this can be modified by using the ``./applications/devrd/devrd env`` command:
.. code-block:: bash
./applications/devrd/devrd env -w /path/to/workspace
This will mount the EVerest repository to the specified
``/path/to/workspace`` directory inside the devcontainer.
Where ``/path/to/workspace`` is the desired path inside the container.
*********************
Example SIL Execution
*********************
Simple SIL
==========
**Prerequisites:**
- Containers are up and running
- EVerest has been build (``cmake --build ...``) + installed (``cmake --install ...``)
**Inside the devcontainer:**
Change to the build directory and run the config in question, e.g.:
.. code-block:: bash
# get a prompt inside the container:
./applications/devrd/devrd prompt
# run EVerest:
./run-scripts/run-sil.sh
.. warning::
If aiming to test OCPP, i.e. connect to the SteVe backend, further preparation
is required, see the next example, below.
**Outside the devcontainer:**
Run a NodeRED flow that matches your EVerest config:
.. code-block:: bash
# switch to basic SIL flow:
./applications/devrd/devrd flow config/nodered/config-sil-flow.json
**In your Webbrowser:**
See the :ref:`table above <table_of_devcontainer_services>` to
- open the Node-RED UI to start/stop charging.
- open the MQTT Explorer topic browser to analyse MQTT traffic between modules.
SIL with OCPP
=============
**Prerequisites:**
Similar to the simple setup above + choose a similar NodeRED flow.
In the OCPP config file: Find the key ``"CentralSystemURI"``. Change ``127.0.0.1:8180``
to ``steve:8180``. This allows EVerest's OCPP module to connect to the SteVe
instance running in its own separate container (``"steve"`` is the name of the service
defined in the ``docker-compose.yaml``).
.. hint::
Identify EVerest's OCPP config file: For the given example of ``run-sil-ocpp.sh``,
the underlying config ``config-sil-ocpp.yaml`` sets ``ChargePointConfigPath`` as
``lib/everest/ocpp/config/v16/config-docker.json``.
.. important::
When running a OCPP SIL in this containerized setup, the SteVe CMSM will
be available on ``127.0.0.1::8180`` on your host, but not from within the
container that runs EVerest! This is simply how docker/docker-compose work.
Therefore, the OCPP module will not successfully connect to the CSMS if
configured to this address.
**In your Webbrowser:**
- Login to the SteVe web UI (see :ref:`table above <table_of_devcontainer_services>`)
(default credentials are ``admin`` / ``1234``).
- Add the charger:
- choose ``DATA MANAGEMENT``/``CHARGE POINTS`` and ``Add New``
- Set ``ChargeBox ID`` to match the ``"ChargePointId"`` from EVerest's OCPP config file
- ``Add`` the charge point.
**Inside the devcontainer:**
Using the terminal, change to the build directory.
Run an OCPP-enabled config, e.g.:
.. code-block:: bash
# get a prompt inside the container:
./applications/devrd/devrd prompt
# run an OCPP enabled config:
./run-scripts/run-sil-ocpp.sh
Now you can use your webbrowser again to control the charger (NodeRED UI), analyze
MQTT traffic and control the charger via the SteVe CSMS.
***************
Troubleshooting
***************
See the :doc:`separate troubleshooting section </tutorials/setup-devcontainer/troubleshooting>` for help
on devcontainer-specific issues.
----
**Authors:** Florian Mihut, Andreas Heinrich

View File

@@ -0,0 +1,65 @@
.. _howto_document:
######################
Documenting Quickstart
######################
This is a short how-to for writing documentation in EVerest. Please refer to the
`Documentation README <https://github.com/EVerest/EVerest/blob/main/docs/README.md>`_
for build instructions for the documentation.
To get more detailed information, see
:ref:`Documenting EVerest <documenting_everest>`.
1. Decide which type of documentation you want to create:
a. If you are not familiar with the Diátaxis way of organizing documentation,
read the subsection :ref:`Structure of the Documentation <exp_the_everest_documentation_structure_of_doc>`.
b. If you cannot clearly decide which category your contribution belongs to,
consider splitting it up to align with the Diátaxis philosophy.
2. Decide where to place the documentation
a. Module documentation goes into the modules ``docs`` directory. Provide
at least an index.rst file in this directory.
b. If you want to document some partial aspects of your code (like a
specific algorithm you use), you can add a section in the ``README.md``
close to the source code. That could for example be in the ``lib/everest/...``
directory of the EVerest repository or in the corresponding GitHub repository
if the code is not part of EVerest.
c. For documentation that is required to understand an important part or
concept of EVerest, place the new documentation in a proper location in
the ``docs`` directory of the
`EVerest main repository <https://github.com/EVerest/EVerest>`_.
d. When in doubt, use the EVerest main repository.
3. Create an issue (in case of bigger documentation changes).
Consider to create a documentation issue inside of the
EVerest GitHub repository you just have chosen.
Describe the most important aspects of the topic to be documented.
4. Create a Git branch like ``docs/name-of-topic`` in the EVerest main
repository.
Put a note in the issue to inform the community that you start working on
new documentation to solve that issue.
5. Create the documentation.
You can use existing ``.rst`` files as template for creating new
documentation pages. See this page for getting an idea how to use
reStructuredText:
https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html
Also have a look at our
:ref:`best practices page for using Sphinx in EVerest <everest_doc_sphinx_style_code>`.
6. Create pull request (PR).
After having finished your work, create a PR and set a reference to the
originating issue (if existing).
The maintainers of the repository will get informed automatically.
Alternatively, you can try to find people who have the required knowledge in
and also have the time to review your PR.
You might find them via Zulip or the working groups.

View File

@@ -0,0 +1,143 @@
.. _extending_everest_documentation:
###################################
Extending the EVerest Documentation
###################################
If you want to start documenting quickly without the need of reading through
all the theory about current documentation structure and best practices, have
a look at our :ref:`How to write EVerest documentation <howto_document>`.
.. note::
For doing quick changes in existing documentation pages, the "How to" might
be a good choice. You also can use the "How to" for creating completely new
pages. But doing this, prepare for getting more change requests by other
community members during the review process. To avoid this, read through
the page you are currently reading to get more theory.
********************************
Process of EVerest documentation
********************************
Preparing a new documentation page
==================================
Let's suppose, you are aware of a brand-new EVerest feature that is still not
documented. Or you found some aspect of EVerest that still lacks a
corresponding documentation page.
This is what to do:
1. Check the existing documentation for similar sections.
a. Search https://everest.github.io/nightly/index.html
b. Is it a module that you want to add documentation to? Then have a look
at the ``EVerest`` repository in the ``modules`` directory and check
if any documentation pages already do exist there.
c. Use GitHub search with ``org:EVerest`` and your keywords to check if you
can find existing documentation snippets near the source code of the
feature.
If you can find something that is related to the topic on your mind, please
decide, whether a new documentation section should be added or the existing
page should be updated.
2. Create a GitHub issue
a. In the repository https://github.com/EVerest/EVerest, click on ``Issues``
and then ``New issue``.
b. Choose ``Feature Request`` and fill out the title and
the description fields. Answer the templated questions, which have already
been added to the description text area.
c. Also add a reference to any related documentation pages and describe how
the new documentation parts shall relate to that (new section, change of
docs, new page with reference to existing ones etc.).
3. Optionally: Inform others about the issue
Especially if you do not want to create documentation on your own (due to
lack of time or knowledge), you can inform others about this new
documentation requirement (the issue). This is optional as the maintainers
of the EVerest documentation will get informed about the newly created issue.
But by taking the topic into an appropriate working group or into the EVerest
Zulip channels, you could find the right people who have time and knowledge
to create such a new section in the documentation.
Creating a new documentation page
=================================
Creating a Git branch
---------------------
As with source code feature development, documentation is also organized with
Git branches. The scheme to name a branch should be adhered to
.. code-block:: bash
docs/name-of-topic
Optionally, to better find your own branches in a list, you could also add
your name initials.
In case your name is Abraham Braveman and you are creating a documentation
about Plug'n'Charge, you could name your branch
.. code-block:: bash
docs/ab-plug-n-charge
Choosing the type of documentation
----------------------------------
The EVerest documentation follows the Diátaxis philosphy. Find an explanation in
the :ref:`Structure of the Documentation <exp_the_everest_documentation_structure_of_doc>`
section.
Choosing a place to store the docs
----------------------------------
If you want to create a new documentation page, you should first check if
pages with similar topics are already existing. It is a good idea to place
your new page in the same location.
In general, you can decide where to put your documentation pages:
* The repository for the main documentation:
https://github.com/EVerest/EVerest in directory ``docs/sources/``
* Directly inside of the ``docs`` directory in your modules directory structure.
The ``index.rst`` in this location will be included into the auto-generated
``reference`` documentation page of this module.
* Near the source code which implements the feature that is to be documented.
.. note::
Don't be afraid to put your documentation at a "wrong" location. It is more
important that documentation does exist. The maintainers of the EVerest
documentation will help you to move your docs to a suitable place during the
PR review phase.
Writing
-------
Best practice is to look at existing documentation sources to get an idea about
how headlines or bullet points are to be handled.
You can create a ``Draft pull request`` on GitHub at an early stage of your
work to let others already get an idea how the new documentation part will look
like and give them the opportunity to comment on your work already.
.. note::
Consider referencing to existing docs with the same topic and vice versa.
Test the generated html to be correct in formatting an test all the links you
included in your text. Build instructions can be found in `docs/README.md`.
Creating a PR and merge
-----------------------
If you have finished your documentation work, you can create a pull request
for your branch. Don't forget to reference the originating issue (if existing).
The maintainers of the corresponding repository will get informed and will try
to invest time to review your work.
After merging the PR, don't forget to also close the issue and eventually
inform the community about your newly created documentation work.

View File

@@ -0,0 +1,38 @@
.. _documenting_everest:
###################
Documenting EVerest
###################
Documentation helps beginners to start with EVerest and advanced users to
be effective by quickly having required information had hand. Find out how
to help writing and keeping documentation up to date.
.. grid:: 1 2 2 3
:gutter: 2
.. grid-item-card:: Write Documentation
:link: extending-everest-documentation
:link-type: doc
How to write documentation for EVerest. A detailed description.
.. grid-item-card:: Documenting Quickstart
:link: change-documentation-quickstart
:link-type: doc
Short description with the most important steps required to change the EVerest documentation.
.. grid-item-card:: Sphinx Style Guide
:link: sphinx-style-guide
:link-type: doc
How to achieve the desired formatting with Sphinx.
.. toctree::
:hidden:
:maxdepth: 1
extending-everest-documentation
change-documentation-quickstart
sphinx-style-guide

View File

@@ -0,0 +1,656 @@
.. _everest_doc_sphinx_style_code:
##################
Sphinx Style Guide
##################
*********
Headlines
*********
Example:
.. code-block:: rst
###################
How To: Sphinx (h1)
###################
**************
Headlines (h2)
**************
Headline (h3)
=============
Headline (h4)
-------------
Headline (h5)
^^^^^^^^^^^^^
Headline (h6)
"""""""""""""
Result:
.. raw:: html
<div class="highlight-rst"><pre>
<h1>How To: Sphinx (h1)</h1>
<h2>Headlines (h2)</h2>
<h3>Headline (h3)</h3>
<h4>Headline (h4)</h4>
<h5>Headline (h5)</h5>
<h6>Headline (h6)</h6>
</pre></div>
******
Styles
******
.. code-block:: rst
**Bold text**
*Italic text*
``Inline literal/code``
:sup:`super`\ Script
:sub:`sub`\ Script
.. line-block::
**Bold text**
*Italic text*
``Inline literal/code``
:sup:`super`\ Script
:sub:`sub`\ Script
************
Bullet Lists
************
.. code-blocK:: rst
* Unordered item
* Unordered item
#. Nestes ordered item
#. Nestes ordered item
#. Nested ordered item
* Unordered item
* Unordered item
* Unordered item
#. Nestes ordered item
#. Nestes ordered item
#. Nested ordered item
* Unordered item
*****************
Targets and Links
*****************
.. code-block:: rst
.. Anchor target
.. _anchorbyref:
.. _Anchor link by text:
.. External target
.. _external_link_ref: https://example.com
.. _External link name: https://example.com
.. Footnote target
.. [1] footnote text
.. Citation target
.. [cit1] A global citation
.. External links
`External link <https://example.com>`_
`External link name`_
`Example Text <External link name>`_
`External link by ref <external_link_ref>`_
.. Internal links
`Anchor link by text`_
`Anchor <Anchor link by text>`_
`Anchor by ref <anchorbyref>`_
:ref:`Anchor <anchorbyref>`
.. Footnote
Reference a footnote [1]_
.. Citation
Reference a global citation [cit1]_
.. Section Link
Section Heading
===============
`Link <Section Heading>`_
.. anchor target
.. _anchorbyref:
.. _Anchor link by text:
.. external target
.. _external_link_ref: https://example.com
.. _External link name: https://example.com
.. footnote target
.. [1] footnote text
.. citation target
.. [cit1] A global citation
.. External links
| `External link <https://example.com>`_
| `External link name`_
| `Example Text <External link name>`_
| `External link by ref <external_link_ref>`_
.. Internal links
| `Anchor link by text`_
| `Anchor <Anchor link by text>`_
| `Anchor by ref <anchorbyref>`_
| :ref:`Anchor <anchorbyref>`
.. Footnote
Reference a footnote [1]_
.. Citation
Reference a global citation [cit1]_
.. Section Link
Section Heading
===============
`Link <Section Heading_>`_
******
Tables
******
.. code-block:: rst
+-----------------+-----------------+-----------------+
| Grid table | Header 2 | Header 3 |
| | | |
+=================+=================+=================+
| Column 1 | Column 2 | Vertical |
+-----------------+-----------------+ column +
| Horizontal span | span |
+-----------------+-----------------+-----------------+
============ ======== ========
Simple table Header 2 Header 3
============ ======== ========
Column 1 Column 2 Column 3
Horizontal column span ...
---------------------- --------
... ... ...
============ ======== ========
.. csv-table:: table title
:header: "Header 1", "Header 2", "Header 3"
:widths: 20, 20, 20
:encoding: utf-8
:header-rows: 1
"Row 1, Column 1", "Row 1, Column 2", "Row 1, Column 3"
"Row 2, Column 1", "Row 2, Column 2", "Row 2, Column 3"
The ``csv-table`` directive can be used to create tables from CSV files:
.. code-block:: rst
.. csv-table:: table title
:header: "Header 1", "Header 2", "Header 3"
:widths: 20, 20, 20
:encoding: utf-8
:header-rows: 1
:file: table.csv
Grid table
==========
+-----------------+-----------------+-----------------+
| Grid table | Header 2 | Header 3 |
| | | |
+=================+=================+=================+
| Column 1 | Column 2 | Vertical |
+-----------------+-----------------+ column +
| Horizontal span | span |
+-----------------+-----------------+-----------------+
Simple table
============
============ ======== ========
Simple table Header 2 Header 3
============ ======== ========
Column 1 Column 2 Column 3
Horizontal column span ...
---------------------- --------
... ... ...
============ ======== ========
CSV table
=========
.. csv-table:: table title
:header: "Header 1", "Header 2", "Header 3"
:widths: 20, 20, 20
:encoding: utf-8
:header-rows: 1
"Row 1, Column 1", "Row 1, Column 2", "Row 1, Column 3"
"Row 2, Column 1", "Row 2, Column 2", "Row 2, Column 3"
******************
Images and Figures
******************
Figures are images with captions. They support all image options.
.. code-block:: rst
.. image:: image.png
:alt: Image alt text
:width: 150px
:height: 150px
:align: center
:target: target_
.. figure:: image.png
:align: center
:height: 150px
:name: figure-name
Figure caption :figure:`figure-name` or `Example <figure-name>`_
Image
=====
.. image:: https://via.placeholder.com/150
:alt: Image alt text
:width: 150px
:height: 150px
:align: center
:target: https://example.com
Figure
======
.. figure:: https://via.placeholder.com/150
:alt: Figure alt text
:align: center
:target: https://example.com
:name: figure-name
Figure caption `figure-name`_ or `Example <figure-name_>`_
********
Comments
********
.. code-block:: rst
.. comment
This is a comment
**********
Directives
**********
.. code-block:: rst
.. directive:: argument
:option: value
Directive content
*****************
Table of Contents
*****************
.. code-block:: rst
.. local table of contents. The ``:local:`` option is optional.
.. contents:: Table of Contents
:local:
:depth: 2
.. defines global structure and includes all sub toc-trees and tocs
Can also be set to visible by omitting the ``:hidden:`` option
.. toc-tree:: Table of Contents
:maxdepth: 2
:numbered:
:hidden:
file.rst
second_file
directory/file
Table of Contents (this document)
=================================
.. contents:: Table of Contents
:depth: 2
:class: this-will-duplicate-information-and-it-is-still-useful-here
:backlinks: none
************************
Content Block Directives
************************
.. contents:: Content Block Directives
:depth: 1
:class: this-will-duplicate-information-and-it-is-still-useful-here
:backlinks: none
:local:
``.. topic::`` *[title]*
=========================
.. code-block:: rst
.. topic:: Topic title
Topic content
.. topic:: Topic
Topic content
``.. sidebar::`` *[title]*
===========================
.. code-block:: rst
.. sidebar:: Sidebar title
Sidebar content
.. sidebar:: Sidebar
Sidebar content
``.. admonition::`` *[title]*
=============================
.. code-block:: rst
.. admonition:: Admonition title
Admonition content
.. admonition:: Admonition title
Admonition content
``.. attention::``
==================
.. code-block:: rst
.. attention::
Attention content
.. attention::
Attention content
``.. caution::``
================
.. code-block:: rst
.. caution::
Caution content
.. caution::
Caution content
``.. danger::``
===============
.. code-block:: rst
.. danger::
Danger content
.. danger::
Danger content
``.. error::``
==============
.. code-block:: rst
.. error::
Error content
.. error::
Error content
``.. hint::``
=============
.. code-block:: rst
.. hint::
Hint content
.. hint::
Hint content
``.. important::``
==================
.. code-block:: rst
.. important::
Important content
.. important::
Important content
``.. note::``
=============
.. code-block:: rst
.. note::
Note content
.. note::
Note content
``.. tip::``
============
.. code-block:: rst
.. tip::
Tip content
.. tip::
Tip content
``.. warning::``
================
.. code-block:: rst
.. warning::
Warning content
.. warning::
Warning content
``.. seealso::``
================
.. code-block:: rst
.. seealso::
See also content
.. seealso::
See also content
``.. versionadded::`` *[version]*
==================================
.. code-block:: rst
.. versionadded:: 1.0
Version added content
.. versionadded:: 1.0
Version added content
``.. versionchanged::`` *[version]*
====================================
.. code-block:: rst
.. versionchanged:: 1.0
Version changed content
.. versionchanged:: 1.0
Version changed content
``.. deprecated::`` *[version]*
===============================
.. code-block:: rst
.. deprecated:: 1.0
Deprecated content
.. deprecated:: 1.0
Deprecated content
``.. math::``
=============
.. code-block:: rst
.. math::
\int_{-\infty}^\infty g(x) dx = 1
.. math::
\int_{-\infty}^\infty g(x) dx = 1
``.. raw::`` *output format*
============================
.. code-block:: rst
.. raw:: html
<div>Raw HTML content</div>
.. raw:: html
<div>Raw HTML content</div>
*************
Code Examples
*************
.. code-block:: rst
.. code-block:: python
:linenos:
:emphasize-lines: 2,3
:caption: Code caption
:name: code-name
// Code example
some_function();
any_var = 42;
// Do another thing
another_function();
.. literalinclude:: index.rst
:language: rst
:linenos:
:emphasize-lines: 2-5
:dedent: 4
.. code-block:: python
:linenos:
:emphasize-lines: 2,3
:caption: Code caption
:name: code-name
// Code example
some_function();
any_var = 42;
// Do another thing
another_function();
.. literalinclude:: index.rst
:language: rst
:linenos:
:emphasize-lines: 2-5
:dedent: 0

View File

@@ -0,0 +1,43 @@
.. _htg_eichrecht:
#########
Eichrecht
#########
It is recommended to use a power meter that has field-proven support for
Eichrecht implementation. The power meter should support tracking of the
transactions and signing of the OCMF packets.
EVerest transports the signed meter values from the power meter to the
OCPP CSMS and triggers the start and stop of a transaction. It does not
create, store or modify the signed meter values.
Requirements for power meter hardware and EVerest driver:
- EVerest provides information according to OCMF standard in the
*start_transaction* and *stop_transaction* commands as described
here: https://github.com/SAFE-eV/OCMF-Open-Charge-Metering-Format
- After power failure of the complete system, an ongoing transaction
before power failure shall be closed properly (including the signed
meter value) in the CSMS. For this to work, the *stop_transaction*
needs to be implemented correctly. On startup, the EvseManager will
call *stop_transaction(last_uuid)* to try to close the ongoing
transaction. The power meter driver shall return the signed meter
value for the transaction and close it. After that, it will call
*stop_transaction("")* with an empty argument. Then, the power meter
driver shall clear all pending transactions in the power meter, if
any.
- If the communication between EVerest driver and the power meter is
lost and re-established during a charging session, the charging
session shall still receive the signed meter value normally at the
end of the session.
- EvseManager should be configured to stop the charging session on
power meter failures (ensure that fail_on_powermeter_errors is set to
``true``).
----
**Authors**: Cornelius Claussen, Manuel Ziegler

View File

@@ -0,0 +1,384 @@
.. _htg_error_framework:
#########################
Using the Error Framework
#########################
Syntax in a C++ module
======================
You can find two example modules written in C++ in the `examples` folder:
`ExampleErrorRaiser` and `ExampleErrorSubscriber`.
Raise an error
--------------
Can be done in the implementation of an interface.
.. code-block:: cpp
// Create an error object
Error error_object = this->error_factory->create_error(
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
"This is an example error" // message
);
// Raise the error
raise_error(error_object);
Clear an error
--------------
Can be done in the implementation of an interface.
.. code-block:: cpp
// Clear all errors of the ErrorType "example/ExampleErrorA"
clear_error(
"example/ExampleErrorA", // ErrorType
true // clear_all
);
// Clear the error with ErrorType "example/ExampleErrorA" and ErrorSubType ""
clear_error(
"example/ExampleErrorA", // ErrorType
"" // ErrorSubType
);
clear_error(
"example/ExampleErrorA", // ErrorType
false // clear_all
);
clear_error(
"example/ExampleErrorA" // ErrorType
); // clear_all defaults to false
// Clear all errors of the current implementation
clear_all_errors_of_impl();
Subscribe to an error
---------------------
May be done in the `init` function of the implementation.
.. code-block:: cpp
// Subscribe to an error of the ErrorType "example/ExampleErrorA"
subscribe_error(
"example/ExampleErrorA", // ErrorType
[](Error error) { // callback
// Do something when the error is raised
},
[](Error error) { // clear_callback
// Do something when the error is cleared
}
);
// Subscribe to all errors of the requirement
subscribe_all_errors(
[](Error error) { // callback
// Do something when an error is raised
},
[](Error error) { // clear_callback
// Do something when an error is cleared
}
);
Subscribe to global all errors
------------------------------
Needs to be enabled in the manifest file of the module. May be done in the
`init` function of the implementation.
.. code-block:: cpp
// Subscribe to global all errors
subscribe_global_all_errors(
[](Error error) { // callback
// Do something when an error is raised
},
[](Error error) { // clear_callback
// Do something when an error is cleared
}
);
The ErrorFactory
----------------
Is used to create an error object.
.. code-block:: cpp
Error error_object_0 = this->error_factory->create_error();
Error error_object_1 = this->error_factory->create_error(
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
"This is an example error" // message
);
Error error_object_2 = this->error_factory->create_error(
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
"This is an example error", // message
Everest::error::Severity::High // severity
);
Error error_object_3 = this->error_factory->create_error(
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
"This is an example error", // message
Everest::error::State::Active // state
);
Error error_object_4 = this->error_factory->create_error(
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
"This is an example error", // message
Everest::error::Severity::High, // severity
Everest::error::State::Active // state
);
The ErrorStateMonitor
---------------------
Is used to monitor the error state of implementations and requirements.
Can be accessed in the implementation of an interface / anytime for
requirements.
Get the `ErrorStateMonitor`:
.. code-block:: cpp
// Get the ErrorStateMonitor of an implementation
std::shared_ptr<ErrorStateMonitor>& monitor = this->error_state_monitor;
// Get the ErrorStateMonitor of a requirement
std::shared_ptr<ErrorStateMonitor>& monitor = this->mod->r_example_raiser->error_state_monitor;
Check if an error is active:
.. code-block:: cpp
// Check if an error of the ErrorType "example/ExampleErrorA" is active
bool is_active = monitor->is_error_active(
"example/ExampleErrorA", // ErrorType
"" // ErrorSubType
);
Check if a specific set of errors is in a specific state:
.. code-block:: cpp
// Check if an error of the ErrorType "example/ExampleErrorA" is active
StateCondition condition = {
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
true // active
};
bool is_satisfied = monitor->is_condition_satisfied(condition);
// Check if multiple errors are active
std::list<StateCondition> conditions = {
{
"example/ExampleErrorA", // ErrorType
"", // ErrorSubType
true // active
},
{
"example/ExampleErrorB", // ErrorType
"", // ErrorSubType
true // active
}
};
bool are_satisfied = monitor->is_condition_satisfied(conditions);
Syntax in a Python module
=========================
You can find two example modules written in Python in the `examples` folder:
`PyExampleErrorRaiser` and `PyExampleErrorSubscriber`.
The error related classes need to be imported from the `everest` module.
.. code-block:: python
from everest.framework import error
Raise an error
--------------
Can be done in the implementation of an interface after initializing.
In opposite to the C++ implementation, the raise function is called on the
module object and takes additionally the `implementation_id` as argument.
.. code-block:: python
# Create an error object
error_object = self._mod.get_error_factory("example_raiser").create_error(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
"This is an example error" # message
)
# Raise the error
self._mod.raise_error(
"example_raiser", # implementation_id
error_object # error
)
Clear an error
--------------
Can be done in the implementation of an interface after raising.
In opposite to the C++ implementation, the clear function is called on the
module object and takes additionally the `implementation_id` as argument.
.. code-block:: python
# Clear all errors of the ErrorType "example/ExampleErrorA"
self._mod.clear_error(
"example_raiser", # implementation_id
"example/ExampleErrorA", # ErrorType
True # clear_all
)
# Clear the error with ErrorType "example/ExampleErrorA" and ErrorSubType ""
self._mod.clear_error(
"example_raiser", # implementation_id
"example/ExampleErrorA", # ErrorType
"" # ErrorSubType
)
self._mod.clear_error(
"example_raiser", # implementation_id
"example/ExampleErrorA", # ErrorType
False # clear_all
)
self._mod.clear_error(
"example_raiser", # implementation_id
"example/ExampleErrorA" # ErrorType
) # clear_all defaults to false
# Clear all errors of the current implementation
self._mod.clear_all_errors_of_impl(
"example_raiser" # implementation_id
)
Subscribe to an error
---------------------
Can be done in the `init` function of the implementation.
In opposite to the C++ implementation, the subscribe function is called on the
module object and takes additionally the `requirement` as argument.
.. code-block:: python
# Subscribe to an error of the ErrorType "example/ExampleErrorA"
self._mod.subscribe_error(
self._setup.connections["example_raiser"][0], # requirement
"example/ExampleErrorA", # ErrorType
lambda error: print("Error raised: ", error), # callback
lambda error: print("Error cleared: ", error) # clear_callback
)
# Subscribe to all errors of the requirement
self._mod.subscribe_all_errors(
self._setup.connections["example_raiser"][0], # implementation_id
lambda error: print("Error raised: ", error), # callback
lambda error: print("Error cleared: ", error) # clear_callback
)
Subscribe to global all errors
------------------------------
This feature is currently only available for C++ modules.
The ErrorFactory
----------------
Is used to create an error object.
.. code-block:: python
error_object_0 = self._mod.get_error_factory("example_raiser").create_error()
error_object_1 = self._mod.get_error_factory("example_raiser").create_error(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
"This is an example error" # message
)
error_object_2 = self._mod.get_error_factory("example_raiser").create_error(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
"This is an example error", # message
error.Severity.High # severity
)
error_object_3 = self._mod.get_error_factory("example_raiser").create_error(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
"This is an example error", # message
error.State.Active # state
)
error_object_4 = self._mod.get_error_factory("example_raiser").create_error(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
"This is an example error", # message
error.Severity.High, # severity
error.State.Active # state
)
The ErrorStateMonitor
---------------------
Get the `ErrorStateMonitor`:
.. code-block:: python
# Get the ErrorStateMonitor of an implementation
monitor = self._mod.get_error_state_monitor_impl(
"example_raiser" # implementation_id
)
# Get the ErrorStateMonitor of a requirement
monitor = self._mod.get_error_state_monitor_req(
self._setup.connections["example_raiser"][0] # requirement
)
Check if an error is active:
.. code-block:: python
# Check if an error of the ErrorType "example/ExampleErrorA" is active
is_active = monitor.is_error_active(
"example/ExampleErrorA", # ErrorType
"" # ErrorSubType
)
Check if a specific set of errors is in a specific state:
.. code-block:: python
# Check if an error of the ErrorType "example/ExampleErrorA" is active
condition = error.StateCondition(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
True # active
)
is_satisfied = monitor.is_condition_satisfied(condition)
# Check if multiple errors are active
conditions = [
error.StateCondition(
"example/ExampleErrorA", # ErrorType
"", # ErrorSubType
True # active
),
error.StateCondition(
"example/ExampleErrorB", # ErrorType
"", # ErrorSubType
True # active
)
]
are_satisfied = monitor.is_condition_satisfied(conditions)

View File

@@ -0,0 +1,104 @@
.. _htg_getting_started_hw:
#########################
Get started with Hardware
#########################
There are different approaches for getting started with running EVerest
on hardware. For each approach we have collected some starting points
and best practices to help you get up and running with EVerest.
For each of the following starting scenarios, you can find more detail
in the sections below:
- **Using an EVerest-compatible development kit and add the BSP.** This
is a great path to start learning about the benefits of EVerest. A
device including a deployed EVerest image can let you experience
charging in a more practical manner moving beyond software simulation.
- **Start with your own hardware.** This is a less out-of-the-box
start, but a more direct path to your own system environment. We will
explain how to get there below.
Using an EVerest-compatible development kit
===========================================
The easiest way to get started with hardware is to use one of the development kits.
They can charge a real car out of the box and you can evaluate all features of
EVerest before building your own product.
Additionally, they come with a ready-to-use Yocto image with RAUC OTA updates, OCPP,
ISO 15118 and all other features of EVerest.
They will help you to:
* parallelize HW and SW developments for new charger projects,
* test OCPP backends (CSMS) against EVerest,
* explore new charging algorithms without the need of doing all the groundwork and
* rapidly integrate EV charging with other applications.
Currently, there are three development kits available. Choose the one that matches
your product the closest:
1. **AC all-integrated PCB development kit: The BelayBox.**
It is available at https://shop.pionix.com with a touch screen display,
up to 22 kW 3ph AC charging, RCD, PCB-integrated power meter, RFID reader and
a Raspberry Pi CM4 compute module.
Schematics and MCU firmware are open source:
https://github.com/PionixPublic/reference-hardware
Yocto for the BelayBox is available at:
https://github.com/PionixPublic/dev-hardware-yocto
Find the manual here: https://pionix.com/user-manual-belaybox
2. **AC DIN Rail / Dual public charging**
Dual socket AC charging with DIN rail contactors and power meters can be realized
with the phyVERSO available from Phytec:
https://www.phytec.de/ladeelektronik/komplettloesung
The advantage of this solution is the seamless transition to production: The phyVERSO
is production-ready and can be used as is in volume production. Customization service
is also available from Phytec to build custom derivatives with different interfaces
and form factors to perfectly meet your requirements.
3. **DC DIN Rail / Dual public charging**
Similar to (2), the phyVERSO can be used in a DC configuration (both ports can be
configured for AC or DC; also a mixed configuration is possible). Phytec offers a
DC development kit as well, which includes a 40 kW DC power supply, isolation monitor,
power meter and everything else needed to make it a complete charger ready for
evaluation.
.. note::
Keep in mind that the development kits were not designed to be a certifiable product.
They are optimized to be easily accessible for developers.
Start with your own hardware
----------------------------
If you already want to start integrating EVerest with
your existing charger hardware, we recommend to start reading through
the sections about setting up your Linux/Yocto and cross-compiling.
You will find these sections in the :doc:`Linux / Yocto overview </explanation/linux-yocto/index>`.
.. note::
This is not the easiest way to start.
But should you choose this mission, you will go the most direct way to use
EVerest for production-ready charger development.
Tell us about your experience and where you get stuck on the way.
The mountain top can best be reached together.
We recommend to start your journey by copying an already existing image
(like the phyVERSO or Yeti/Yak ones) and change this according to your
needs and HW setup.
This will give you an overview on which in- and outputs are required,
the dependencies per module and how to set up the MQTT communication
accordingly.
-----------------------------------
**Authors**: Cornelius Claussen, Manuel Ziegler

View File

@@ -0,0 +1,548 @@
.. _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

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View File

@@ -0,0 +1,46 @@
.. exp_quick_start_guides:
############################
Getting Started with EVerest
############################
We provide several entry points for a fast start with EVerest.
Whether you want to do a software-based simulation or start
working with existing hardware, you will find your way here.
.. grid:: 1 2 2 2
:gutter: 3
:margin: 2 0 2 0
.. grid-item-card:: 🧩 Get started in Software
:link: get-started-sw
:link-type: doc
A big advantage of EVerest is the ability to simulate
complete EV charging stations in software without the need
for any hardware. This guide will help you to install EVerest
on your development machine and get started with a software-based
simulation.
.. grid-item-card:: ⚙️ Get started with Hardware
:link: get-started-hw
:link-type: doc
Want to get EVerest running on real hardware right away?
This guide presents several options to get started with existing
hardware components. You will find the right approach for your
specific use case here.
.. grid-item-card:: 🔌 EVerest APIs
:link: /explanation/adapt-everest/apis
:link-type: doc
Learn about the APIs provided by EVerest that help you integrating
EVerest into your system and adapting it to your needs.
.. toctree::
:maxdepth: 1
:hidden:
get-started-sw
get-started-hw

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -0,0 +1,131 @@
#############
How To Guides
#############
How-to guides are practical guides to solve dedicated problems.
If you already have some experience with EVerest, those guides might be for
you.
Find a fast way into a topic without going through all the basic details.
Have a look at this categorized list of all guides:
.. grid:: 1 2 2 3
:gutter: 2
.. grid-item-card:: Documenting EVerest
:link: documenting-everest/index
:link-type: doc
How to write documentation for EVerest.
.. grid-item-card:: Getting started with EVerest
:link: getting-started/index
:link-type: doc
Hands-on getting started with or without hardware.
.. grid-item-card:: Use the Error Framework
:link: error-framework-howto
:link-type: doc
How to use the error framework to raise/clear errors and listen to these events.
.. grid-item-card:: Configure Plug&Charge
:link: configure-pnc
:link-type: doc
How to enable Plug&Charge in a EVerest configuration.
.. grid-item-card:: Debug ISO 15118
:link: debug-iso15118
:link-type: doc
How to debug ISO15118 communication of EVerest using Wireshark.
.. grid-item-card:: Debug Modules
:link: debug-modules
:link-type: doc
How to debug a single EVerest module.
.. grid-item-card:: Cross-compile of EVerest
:link: yocto-cross-compilation
:link-type: doc
How to cross-compile EVerest for your Yocto image using a Yocto SDK.
.. grid-item-card:: Comply with Eichrecht
:link: eichrecht
:link-type: doc
How to be compliant with German Eichrecht.
.. grid-item-card:: Comply with UK Smart Charging Regulations
:link: uk-smart-charging-regulations
:link-type: doc
How to be compliant with UK Smart Charging Regulations.
.. grid-item-card:: Use Renesas MPU
:link: renesas-mpu/index
:link-type: doc
How to use EVerest on Renesas RZ/G2L-MPU microprocessors.
.. grid-item-card:: Apply Security Best Practices
:link: security-best-practices
:link-type: doc
How to apply security best practices when deploying EVerest in a production environment.
.. grid-item-card:: Bring up a Charger Setup
:link: bringup/index
:link-type: doc
How to bring up all hard and software components of a charger in isolated test cases.
.. grid-item-card:: Use the EVerest Development Container
:link: devcontainer-usage/index
:link-type: doc
How to use a development container for EVerest development and sil testing.
.. grid-item-card:: Choosing EVerest Version and Upgrading
:link: choosing-version-and-upgrading
:link-type: doc
How to choose the right EVerest version and plan upgrades.
.. grid-item-card:: Pionix Belay Box
:link: pionix-belay-box
:link-type: doc
How to get started with the Pionix Belay Box, an AC charging station dev kit based on EVerest.
.. grid-item-card:: Integrate Tariff and Cost
:link: integrate-tariff-and-cost
:link-type: doc
How to subscribe to tariff and session cost updates from the consumer APIs, including OCPP-specific configuration.
.. toctree::
:maxdepth: 1
:hidden:
documenting-everest/index
getting-started/index
error-framework-howto
configure-pnc
debug-iso15118
debug-modules
yocto-cross-compilation
eichrecht
uk-smart-charging-regulations
renesas-mpu/index
security-best-practices
bringup/index
choosing-version-and-upgrading
pionix-belay-box
integrate-tariff-and-cost
devcontainer-usage/index

View File

@@ -0,0 +1,370 @@
.. _htg_integrate_tariff_and_cost:
#########################
Integrate Tariff and Cost
#########################
This guide explains how to subscribe to tariff and session cost updates
published by EVerest, and how the data flow differs between OCPP 1.6 and
OCPP 2.x.
*************
Prerequisites
*************
- An EVerest deployment with an OCPP module (``OCPP`` for 1.6 or ``OCPP201``
for 2.x) and the ``Auth`` module and the relevant API modules (see next section).
- An API client that connects via MQTT and subscribes to the relevant
consumer API topics.
**********************
Relevant Consumer APIs
**********************
Two consumer APIs carry tariff and cost information:
- **Session cost consumer API** — provides the ``tariff_message``,
``session_cost``, and ``default_price`` variables on the ``session_cost``
interface.
- **Auth consumer API** — provides ``token_validation_status``, which may
include tariff messages received at authorization time.
At least the session cost consumer API must be subscribed to receive tariff and cost
updates.
See the AsyncAPI reference for the `auth_consumer_API <../reference/api/auth_consumer_API/index.html>`_
and the `session_cost_consumer_API <../reference/api/session_cost_consumer_API/index.html>`_ for message schemas.
.. note::
The OCPP implementations follow the requirements of the OCA California
Pricing Whitepaper. Note that this whitepaper contains requirements for
displaying pricing information to the user, so in order to comply with it,
the tariff and session cost messages must be used to show the required
information on a charger display. The APIs only provide the necessary data.
*************************
No local cost calculation
*************************
EVerest does not calculate session costs locally. All cost figures
published on the session cost consumer API originate exclusively from the
CSMS:
- In OCPP 2.x, cost values come from the ``totalCost`` field in
``TransactionEventResponse`` or from a ``CostUpdated`` message.
- In OCPP 1.6, cost values come from ``RunningCost`` and ``FinalCost``
DataTransfer messages sent by the CSMS.
EVerest only formats these values (e.g. applying the configured number of
decimal places) before forwarding them. No energy-based or time-based
cost computation is performed on the charging station.
When the charging station is offline, no cost figures are available at
all. The session cost consumer API will only receive human-readable tariff
text messages (from the locally configured fallback variables), never
computed cost amounts. The actual session cost is only published once the
CSMS responds after the connection is restored.
In addition to CSMS-provided cost data, the locally configured fallback
messages (``TariffFallbackMessage``, ``OfflineTariffFallbackMessage``,
``TotalCostFallbackMessage`` in OCPP 2.x; ``DefaultPriceText`` in OCPP 1.6)
are also published via the session cost consumer API as ``tariff_message``
publications. These contain human-readable pricing text only — they carry
no cost figures and are not derived from any local computation.
******************
OCPP configuration
******************
If you plan to use session cost information from OCPP (e.g. according to the California
Pricing requirements), you need to configure the OCPP modules to receive tariff and
cost information from the CSMS.
OCPP 1.6
=========
Enable the ``CostAndPrice`` profile in the OCPP 1.6 module configuration.
Once enabled, the OCPP module registers the tariff message and session cost
callbacks. The relevant configuration keys are:
- **DefaultPriceText** — the tariff fallback message shown when no
``SetUserPrice`` DataTransfer is received within the timeout. This is the
OCPP 1.6 equivalent of ``TariffFallbackMessage`` in OCPP 2.x.
- **WaitForSetUserPriceTimeout** — how long to wait for a ``SetUserPrice``
DataTransfer before publishing the ``DefaultPriceText`` fallback.
There is no OCPP 1.6 equivalent of ``TotalCostFallbackMessage``: no
fallback cost message is published when a transaction ends while offline.
OCPP 2.x
========
Enable the ``TariffCostCtrlr`` in the OCPP 2.x device model. The
component variables ``TariffEnabled`` and ``CostEnabled`` control which
features are active:
- **TariffEnabled** — publishes tariff / pricing messages via the
``tariff_message`` variable.
- **CostEnabled** — publishes running and final session cost via the
``session_cost`` variable.
Both can be enabled independently. Also configure other variables of the
``TariffCostCtrlr`` as needed.
Fallback messages
-----------------
When the CSMS provides no tariff information, the charging station
displays locally configured fallback messages. The following
``TariffCostCtrlr`` variables control this:
- **TariffFallbackMessage** — published when tariff is enabled but the
CSMS provides no ``personalMessage`` in the ``AuthorizeResponse``.
- **OfflineTariffFallbackMessage** — used instead of
``TariffFallbackMessage`` when the charging station is offline. If not
configured, ``TariffFallbackMessage`` is used as a fallback.
- **TotalCostFallbackMessage** — published when a transaction ends while
the charging station is offline and no CSMS ``totalCost`` response can
be received.
For multi-language deployments, add a language-specific instance of
``TariffFallbackMessage`` for each supported language (e.g. instance
``de`` for German, ``nl`` for Dutch). The supported languages are derived
from ``DisplayMessageCtrlr.Language.valuesList``. The default-language
text goes into ``personalMessage``; up to four additional language
entries go into ``customData.personalMessageExtra`` per California
Pricing spec 4.3.4. All languages are forwarded together as entries
in the ``messages`` field of the ``tariff_message`` publication.
.. note::
Additional requirements of the OCPP 2.1 specification with respect to
tariff and costs have not yet been implemented. The implemented features
can still be used with OCPP 2.1.
*******************
Tariff message flow
*******************
Tariff messages contain human-readable pricing text in one or more
languages. They are published on the ``tariff_message`` variable of the
session cost consumer API.
OCPP 1.6
=========
Tariff messages originate from a ``SetUserPrice`` DataTransfer message sent
by the CSMS. The CSMS typically sends this message shortly after the
``Authorize.conf``, so the tariff message is available close to
authorization time.
If the ``SetUserPrice`` DataTransfer is not received within the
``WaitForSetUserPriceTimeout``, the ``DefaultPriceText`` fallback (if
configured) is published. The ``identifier_type`` is ``IdToken`` at
authorization time, and ``TransactionId`` once a transaction has started.
OCPP 2.x
========
Tariff messages are published at two points:
1. **Authorization time** — from the ``personalMessage`` field in the
``AuthorizeResponse``. The tariff message is also included in the
``messages`` field of the ``token_validation_status`` on the auth
consumer API. At this point the ``identifier_type`` is ``IdToken`` and
the ``identifier_id`` is the token value, since no transaction exists
yet.
If the CSMS does not provide a ``personalMessage``, the charging
station automatically injects the configured ``TariffFallbackMessage``
(or ``OfflineTariffFallbackMessage`` when offline) so that a tariff
message is always published when tariff is enabled and a fallback is
configured.
2. **During the session** — from the ``updatedPersonalMessage`` field in
``TransactionEventResponse`` messages. At this point the
``identifier_type`` is ``TransactionId`` and the ``identifier_id`` is
the OCPP transaction ID.
.. note::
To correlate auth-time tariff messages (keyed by ``IdToken``) with
in-session updates (keyed by ``TransactionId``), use the
``token_validation_status`` message on the auth consumer API to capture
the token, then match it against the session information from the EVSE
manager consumer API.
*****************
Session cost flow
*****************
Session cost messages contain the accumulated cost of a charging session,
broken down into cost chunks (energy, time, flat fees), with current and
next-period pricing. They are published on the ``session_cost`` variable of
the session cost consumer API.
OCPP 1.6
=========
Session cost updates are triggered by ``RunningCost`` and ``FinalCost``
DataTransfer messages from the CSMS.
When a transaction ends while the charging station is offline, the queued
``StopTransaction`` is sent to the CSMS once the connection is
re-established. The ``StopTransactionResponse`` carries no cost data. No
fallback cost message is published. If the CSMS sends a ``FinalCost``
DataTransfer after reconnect, a ``session_cost`` will be published at
that point — but this is entirely at the CSMS's discretion and may not
happen at all.
OCPP 2.x
========
Session cost updates are triggered by:
- ``totalCost`` in a ``TransactionEventResponse`` — publishes a running
cost update with status ``Running`` or ``Idle``.
- ``CostUpdated`` message — publishes a final cost update with status
``Finished``.
When both ``totalCost`` and ``updatedPersonalMessage`` are present in the
same ``TransactionEventResponse``, the personal message appears in both the
``tariff_message`` variable and the ``message`` field of the
``session_cost`` record.
When a transaction ends while the charging station is offline, the CSMS
``totalCost`` response will never arrive. In this case, if
``TotalCostFallbackMessage`` is configured, a ``tariff_message`` is
published with ``identifier_type = TransactionId``. This message contains
human-readable text only — no actual cost figures are available.
Consumers should display this text as a notification that the session
cost is unavailable, rather than as a cost breakdown.
Once the OCPP connection is re-established, the queued
``TransactionEvent(Ended)`` is sent to the CSMS. If the CSMS responds
with a ``totalCost``, a ``session_cost`` with status ``Finished`` is
published for the same transaction ID.
****************************
Station default price
****************************
The ``default_price`` variable on the session cost consumer API carries the
currently applicable station-wide fallback tariff text. Unlike
``tariff_message``, it is not bound to a specific session or token — it
represents the price a customer can expect to pay at this station when no
personalised tariff has been provided by the CSMS.
It is published in the following situations:
- **On startup** — once before the first connection attempt, using the
offline fallback text (if configured).
- **On connect / reconnect** — with the online fallback text.
- **On disconnect** — with the offline fallback text (if configured);
falls back to the online text if no offline text is configured.
- **On configuration change** — immediately after the relevant fallback
variable is updated via ``ChangeConfiguration`` (OCPP 1.6) or
``SetVariables`` (OCPP 2.x)
OCPP 1.6
=========
The ``default_price`` variable is populated from the ``DefaultPrice``
configuration key (``CostAndPrice`` section). It contains both a
``priceText`` (online) and a ``priceTextOffline`` field. The relevant
configuration key changes that trigger a re-publication are ``DefaultPrice``
and ``DefaultPriceText,<language>``.
OCPP 2.x
=========
The ``default_price`` variable is populated from the
``TariffFallbackMessage`` (online) and ``OfflineTariffFallbackMessage``
(offline) variables of the ``TariffCostCtrlr`` component. If no offline
message is configured, ``TariffFallbackMessage`` is used in both states.
A change to either variable via ``SetVariables`` triggers an immediate
re-publication.
If neither variable is configured, no ``default_price`` publication occurs.
*****************************
Relationship between the APIs
*****************************
OCPP 2.x
=========
.. list-table::
:header-rows: 1
:widths: 30 35 35
* - Event
- Auth consumer API
- Session cost consumer API
* - Token authorized, CSMS provides tariff
- ``token_validation_status`` includes ``messages``
- ``tariff_message`` published (``identifier_type = IdToken``)
* - Token authorized, no CSMS tariff, fallback configured
- ``token_validation_status`` includes ``messages``
- ``tariff_message`` published from ``TariffFallbackMessage`` (``identifier_type = IdToken``)
* - In-session tariff update
- —
- ``tariff_message`` published (``identifier_type = TransactionId``)
* - Running / final cost (online)
- —
- ``session_cost`` published (may include ``message``)
* - Transaction ended offline, fallback configured
- —
- ``tariff_message`` published from ``TotalCostFallbackMessage`` (``identifier_type = TransactionId``); no ``session_cost``
* - Reconnected, CSMS sends ``totalCost`` for offline transaction
- —
- ``session_cost`` with status ``Finished`` published; supersedes the earlier fallback text
* - Connected / reconnected
- —
- ``default_price`` published with online ``TariffFallbackMessage`` (if configured)
* - Disconnected
- —
- ``default_price`` published with ``OfflineTariffFallbackMessage``, or ``TariffFallbackMessage`` if not configured
* - ``TariffFallbackMessage`` or ``OfflineTariffFallbackMessage`` changed via ``SetVariables``
- —
- ``default_price`` re-published with new online text
OCPP 1.6
=========
.. list-table::
:header-rows: 1
:widths: 30 35 35
* - Event
- Auth consumer API
- Session cost consumer API
* - Token authorized, CSMS sends ``SetUserPrice``
- ``token_validation_status`` includes ``messages``
- ``tariff_message`` published (``identifier_type = IdToken``)
* - ``SetUserPrice`` timeout, ``DefaultPriceText`` configured
- ``token_validation_status`` includes ``messages``
- ``tariff_message`` published from ``DefaultPriceText`` (``identifier_type = IdToken``)
* - In-session ``SetUserPrice`` DataTransfer
- —
- ``tariff_message`` published (``identifier_type = TransactionId``)
* - ``RunningCost`` / ``FinalCost`` DataTransfer (online)
- —
- ``session_cost`` published (may include ``message``)
* - Transaction ended offline
- —
- nothing published
* - Reconnected, CSMS sends ``FinalCost`` DataTransfer
- —
- ``session_cost`` with status ``Finished`` published
* - Connected / reconnected
- —
- ``default_price`` published with online ``DefaultPrice.priceText`` (if configured)
* - Disconnected
- —
- ``default_price`` published with ``DefaultPrice.priceTextOffline`` (if configured)
* - ``DefaultPrice`` changed via ``ChangeConfiguration``
- —
- ``default_price`` re-published with new online text

View File

@@ -0,0 +1,709 @@
.. doc_pionix_belay-box:
Pionix BelayBox
###############
Introduction
************
The BelayBox is a reference platform specifically designed for development and
testing of the open source software EVerest. More details about how EVerest is
embedded on the hardware can be found in the dedicated sections about EVerest
cross-compilation in the section :ref:`BelayBox use cases <belaybox_furtherinfo>`.
The BelayBox is delivered as a development kit, which has to be assembled
following the instructions in this documentation. Part of the kit is a
Raspberry Pi CM4 compute module. PIONIX is officially part of the "Powered by
Raspberry Pi" scheme:
.. image:: images/powered-by-pi.png
:width: 300
:alt: Logo Powered by Raspberry Pi for Charging Development Kit BelayBox
:align: center
BelayBox can be utilized by individuals, research facilities and companies
alike to
* parallelize HW and SW developments for new charger projects,
* explore new charging algorithms without the need do all the groundwork,
* rapid integration of EV charging with other applications
and anything else you want to quickly do without building your own EVerest
compatible charger first.
The BelayBox is not meant to be used for private usage or outdoor charging.
The BelayBox hardware
=====================
The BelayBox consists mainly of the Yeti board - an AC charger for
electric vehicles (EV) supporting IEC-61851-1 and SAE J1772 - and the Yak
board, which is a high-level control board for EV charging stations supporting
ISO 15118-2 (with ISO 15118-20 on its way) and DIN SPEC70121.
As both - Yeti and Yak board - are released as Open Hardware under CERN
Open Hardware Licence Version 2 (Permissive), we are very happy to point you
to the schematics and design files and also the firmware:
* `Yeti and Yak Hardware Reference Design <https://github.com/PionixPublic/reference-hardware>`_
* `Yeti Firmware <https://github.com/PionixPublic/yeti-firmware>`_
The 3D files of the BelayBox case components can be downloaded here:
`BelayBox 3D files <https://a360.co/45erK90>`_.
For more information about vendors working with EVerest,
contact us via
the `EVerest mailing list <https://lists.lfenergy.org/g/everest>`_.
Getting support
===============
See also the `BelayBox manual <https://pionix.com/user-manual-belaybox>`_.
If you already have purchased a BelayBox kit and you have hardware related
questions, you can get support by creating an issue via our
`support page <http://support.pionix.com>`_.
.. important::
This is only for hardware-related support. For all software-related
questions, you can find help in the wonderful EVerest community via
`Zulip <https://lfenergy.zulipchat.com/>`_ or the
`EVerest mailinglist <https://lists.lfenergy.org/g/everest>`_.
If you need additional parts for your BelayBox, see the
`Pionix Online Shop <https://shop.pionix.com>`_.
Setting up Hardware and Software
********************************
The Yeti board is delivered with a firmware already flashed on it.
The Yak board does not have any software flashed on it.
In the following sections, we will show how to assemble the hardware parts and
also how to do the flashing of the Yak board. The Yocto image for the Yak
board includes binaries and services to run EVerest.
.. note::
In case you need to build a custom Yeti firmware, have a look at this repo:
`Yeti firmware GitHub repository here <https://github.com/PionixPublic/yeti-firmware>`_
.
Also see the :ref:`section about how to flash the Yeti board <belaybox_yeti_flash>`.
Assembling the Yak Board
========================
Starting assembling the Yak Board, you should have the following parts
available:
.. image:: images/yak-assembly-1-overview-w600.png
And you will need the following tools:
* ESD safe environment, e.g. ESD wrist band
* ESD underlay mat
* Linux host system, Ubuntu >18 recommended
* 1x Micro USB cable
* 12 V DC power supply with minimum 30 W to connect to “12 V IN” pins on
Yak board. A lab power supply is sufficient.
Needed software:
* `Raspberry PI USB Boot <https://github.com/raspberrypi/usbboot/blob/master/Readme.md#building>`_
* bmaptool - `see here <https://docs.yoctoproject.org/dev-manual/bmaptool.html>`_
* Internet access from host system
.. warning::
Before working with any open PCB make sure to work in an ESD safe
environment using ESD safe equipment only.
Glue on the heatsinks as shown in the following image using the double
sided tape that comes with the heatsinks. Plug in the small clips into
the mounting holes of the CM4 board as shown.
.. image:: images/yak-assembly-2-w500.png
Turn around the CM4 and put on the gray spacers as shown here:
.. image:: images/yak-assembly-3-w500.png
Plug the CM4 board in both connectors and make sure the clips go all the way
through the Yak board and hold the CM4 securely without any gaps between the
spacers and both boards. Make sure to remove the metal part (if there is one)
out of the board-to-board connector as shown in the upper left corner in the
following image:
.. image:: images/yak-assembly-4-w600.png
This is how it looks from the top side:
.. image:: images/yak-assembly-5-w600.png
.. _belaybox_flashing_yak_board:
Flashing the Yak Board
======================
In this section, we will walk you through the process of deploying the
Yocto-based image including EVerest.
.. note::
You will only have to do this flashing procedure once. After that, you can
use the RAUC updates, which are hosted on PIONIX update servers.
In case you need to reflash the whole image, we will inform you in the
public support channels.
If you want to create your own custom yocto image with EVerest, you can
have a look at
`Pionix Dev Hardware Yocto repository <https://github.com/PionixPublic/dev-hardware-yocto>`_.
STEP 1: Downloading
-------------------
Download the latest stable image and the matching .bmap file.
You will find the required files (.bz2 and .bmap) here:
`PIONIX update files <https://pionix-update.de/releases/index.php>`_
.. warning::
Make sure to download the correct files (.bz2 and .bmap) from the BelayBox
section.
STEP 2: Set boot jumper and connect Micro-USB
---------------------------------------------
Place the small jumper onto the "BOOT" pins.
This is needed to be able to make the eMMC flash accessible to the host system.
After that, connect the Yak board via Micro-USB to the host system.
STEP 3: Powering up
-------------------
Power up the BelayBox or - if the Yak is used alone - apply 12 V to
the "12 IN" pins.
The red power LED on the Yak should light up constantly now.
STEP 4: Enabling CM4 storage mode
---------------------------------
Enable the CM4 storage mode so that the eMMC becomes available to
the host system:
.. code-block:: bash
sudo rpiboot
The green LED on the Yak board should light up constantly now.
STEP 5: Finding the eMMC device
-------------------------------
To find the eMMC device, do:
.. code-block:: bash
lsblk
Check the output and look for a approximately 16 GB device called /dev/sdX -
where X can be any letter.
.. warning::
Make sure to select the correct device as data loss can occure if the wrong
device is selected!
STEP 6: Flash the eMMC
----------------------
Make sure the .wic.bz2 file and the .bmap file are in the same directory
and flash the eMMC. In the command below, replace <image file>.bz2 with your
downloaded image file and replace "X" according to your eMMC device.
.. code-block:: bash
sudo bmaptool copy <image file>.bz2 /dev/sdX
After roughly nine minutes the flashing should have finished.
.. caution::
Make sure to connect the WiFi antenna to the CM4 after flashing. The image
activates the external antenna support. Running a flashed Yak without the
WiFi antenna mounted can result in **damage of the WiFi chip**.
STEP 7: Finishing
-----------------
Disconnect the eMMC device, power off and unplug the "boot" jumper from the
Yak board.
.. image:: images/yak-assembly-9.jpg
With the Raspberry Pi CM4, it can be that the overlay filesystem sometimes does
not get mounted in the right order; so you might have to reboot twice if some
files are missing after flashing.
Assembling the Yeti Board
=========================
Here's what you should have:
.. image:: images/yeti-assembly-1-overview-w550.png
Tools needed:
* ESD safe environment, e.g. ESD wrist band
* ESD underlay mat
Clip on the touch protection cage and make sure all clips are correctly seated
as shown here:
.. image:: images/yeti-assembly-2-w500.png
Clip in the smaller part of the touch protection and make sure all clips are
correctly seated as shown here:
.. image:: images/yeti-assembly-3-w500.png
Clip in the bigger part of the touch protection and make sure all clips are
correctly seated as shown in the following image:
.. image:: images/yeti-assembly-4-w425.png
Your mission can be seen as accomplished if your Yeti looks like that:
.. image:: images/yeti-assembly-5-w500.png
Preparing the cable set
=======================
That's how we start:
.. image:: images/cable-set-1-overview-w500.png
The **10-position cable between Yeti and Yak** is mandatory to connect Yak to
Yeti and to power the Yak board from the Yeti power supply.
.. image:: images/cable-set-2-w400.png
Plug in one of the crimped cables with one end into the 10-position plug. Make
sure to plug in the crimp in the exact same orientation as shown in the
picture above.
.. warning::
Be aware that the crimps cannot be unplugged again from the 10 position
plug. Make sure you plug in the crimps in the correct positions before
actually plugging them in.
Plug in the other crimped end of the cable into the second plug. It is very
important to plug in the crimps in the shown “1:1” fashion. Doing otherwise
important to plug in the crimps in the shown “1:1” fashion.
.. danger::
Doing otherwise will **permanently damage** the Yak and/or Yeti board.
.. image:: images/cable-set-3-w500.png
Continue with plugging in all ten cables one after the other as there is less
chance of getting it wrong this way.
This is how the cable looks when assembly is done:
.. image:: images/cable-set-4-w500.png
Let's continue with the **6-position CAN + RS485 cable**.
.. image:: images/cable-set-5-w550.png
Plug in a crimped cable with one end into the 6-position plug.
Make sure to plug in the crimp in the exact same orientation as shown in the
picture above. Continue with plugging in all needed cables.
Be aware that these cables have unisolated, open ends. In case you use the
6-position cable for e.g. using the CAN bus, make sure all other not used
cables are isolated to prevent damage to the Yak board.
This is how the assembled cable looks like:
.. image:: images/cable-set-6-w500.png
This is the pin description of the Yak board's 4-, 6- and 10-position sockets:
.. image:: images/cable-set-7-w550.png
Final Yak-Yeti-Cable-Setup
==========================
Tools needed:
* ESD safe environment, e.g. ESD wrist band
* ESD underlay mat
* Preassembled Yak, Yeti kits and cable-set as shown in sections above
.. image:: images/final-assembly-425.png
Plug in the 10-pin cable into the corresponding sockets on both ends.
Plug in the 4-pin RFID/NFC reader cable.
The assembly of Yak, Yet kit and cable set is completed.
When using the assembly in a "desk" environment, it is recommended to apply
power through the 12 V DC barrel connector shown in the upper right corner of
the Yeti board in the image above. Make sure the WiFi antenna does not touch
any other open PCB parts to prevent damage to the boards.
.. _belaybox_furtherinfo:
BelayBox Use Cases
******************
.. _belaybox_rauc:
How to install updates via RAUC bundles
=======================================
To enable the seamless updating via RAUC, ensure your configuration file
includes the :ref:`Linux_Systemd_Rauc module <everest_modules_Linux_Systemd_Rauc>`.
Add the following snippet to your config file (if it does not exist):
.. code-block:: bash
system:
module: Linux_Systemd_Rauc
config_module:
RebootCommand: "reboot '0 tryboot'"
connections:
store:
- module_id: persistent_store
implementation_id: main
Verify that the module ID of your store module is named correctly.
After modifying the configuration, restart the everest service.
Next, connect via SSH into your Yak board. The credentials are:
* User: root
* Password: belaybox
Check the currently booted slot:
.. code-block:: bash
rauc status
Remember the slot for comparison afterwards.
Download the RAUC bundle from the PIONIX update server. You can find the
latest file here:
`PIONIX update files <https://pionix-update.de/releases/index.php>`_
.. warning::
Make sure to download the correct file (.raucb) from the BelayBox
section.
Execute the following:
.. code-block:: bash
rauc install <path_to_rauc_bundle.raucb>
Cross-compile toolchain
=======================
If you want to cross-compile your EVerest version, get the toolchain from the
PIONIX update page here (file extension is .sh):
`PIONIX update files <https://pionix-update.de/releases/index.php>`_
.. warning::
Make sure to download the correct file (.sh) from the BelayBox
section.
First of all, you need to install it. It is a shell script, so just do a
``chmod +x name_of_toolchain.sh`` and then run it with
.. code-block:: bash
./name_of_toolchain.sh
You will be asked where to install it. You can e.g. install it in your home
directory - somewhere like ``/home/myuser/toolchain-belaybox``
Then you need to source the environment variables (it tells you how to do it
at the end of the installation).
Once they are sourced, this terminal will cross compile.
In ``EVerest/``, create a folder called "build-cross". Change into it.
There, run cmake as follows:
.. code-block:: bash
cmake .. -GNinja -DCMAKE_INSTALL_PREFIX=/var/everest -DEVEREST_ENABLE_PY_SUPPORT=OFF -DEVEREST_ENABLE_JS_SUPPORT=OFF -Deverest-core_USE_PYTHON_VENV=OFF
In this case, the PY/JS support flags are set to ``OFF``. You may need to set them
to ``ON`` if you are using simulation. The last option
``-Deverest-core_USE_PYTHON_VENV`` is only a temporarily needed directive that
will probably be obsolete in future release candidates.
The ``-GNinja`` can also be left out, then it will use make.
After that you can build with
.. code-block:: bash
make -j10
or
.. code-block:: bash
ninja
depending on what you configured.
Once the build is complete, you can rsync directly to belaybox like this:
.. code-block:: bash
DESTDIR=dist ninja install/strip && rsync -av dist/var/everest root@the.ip.add.ress:/var
Replace the IP address placeholder with the correct one.
Then log into the BelayBox and stop the systemd service:
.. code-block:: bash
systemctl stop everest
Then you can run your self-compiled version like this:
.. code-block:: bash
/var/everest/bin/manager --conf /path/to/my/configfile
.. _belaybox_yeti_flash:
How to flash the Yeti board
===========================
Connect via SSH into the Yak board and run these two commands (the first one
is very important - do not update while everest is running!):
.. code-block:: bash
systemctl stop everest
yeti_fwupdate /dev/serial0 /usr/share/everest/modules/YetiDriver/firmware/yetiR1_2.1_firmware.bin
.. important::
In case you use a fullsize Raspberry Pi 4B, use the following command
instead of the above one:
systemctl stop everest-rpi
After that, restart the everest or everest-rpi service:
.. code-block:: bash
systemctl restart everest
or (respectively)
.. code-block:: bash
systemctl restart everest-rpi
How to activate OCPP
====================
Please refer to the :ref:`OCPP1.6 <everest_modules_OCPP>` and :ref:`OCPP2.0.1 <everest_modules_OCPP201>` module
documentation for the general information about how to activate OCPP 1.6 or OCPP 2.x in EVerest.
For OCPP2.x the configuration files are located in ``/usr/share/everest/modules/OCPP201/component_config``.
You can configure the CSMS endpoint and edit the files according to your needs.
For OCPP1.6 the configuration files are located in ``/usr/share/everest/modules/OCPP/``.
You can use the following commands to stop the everest service, update to an EVerest config that includes OCPP
and restart the service:
.. code-block:: bash
systemctl stop everest
manager --config config-belaybox-pwm-ocpp.yaml
.. note::
Running the manager process for the first time, you can get a warning that
no key pair could be found for v2g ocsp request. As after the first startup,
a key pair is generated, this message should not be shown next time.
Factory reset
=============
.. note::
We are preparing a new factory reset howto for the updated Yocto-image.
Further information
===================
RS-485 Modbus config for Yak board
----------------------------------
If you want to use the RS-485 Modbus device on the Yak board, here is how you configure it in the
config.yaml for the SerialCommunicationHub:
.. code-block:: bash
comm_hub:
config_implementation:
main:
serial_port: /dev/ttyAMA3
baudrate: 19200
parity: 2
rxtx_gpio_chip: gpiochip0
rxtx_gpio_line: 16
rxtx_gpio_tx_high: true
module: SerialCommHub
Setup static IP address for the Yak board
-----------------------------------------
Should there be any problems with receiving an IP address via DHCP, you can
setup a static IP address for the Yak board. That's how you do it:
**Mount eMMC**
Mount the eMMC as in steps 2-5 known from the
:ref:`YAK flashing procedure <belaybox_flashing_yak_board>`.
**Create network config file**
Create a file similar to the example file here:
.. code-block:: bash
[Match]
Name=eth0
[Network]
Address=192.168.0.110/24
Gateway=192.168.0.1
DNS=192.168.0.1
Copy this file to
.. code-block:: bash
<your-mount-folder>/root_A/usr/lib/systemd/network/79-eth0.network
and
.. code-block:: bash
<your-mount-folder>/root_B/usr/lib/systemd/network/79-eth0.network
**Re-booting procedure**
As a last step, power down the board, unplug the boot jumper and the
Micro-USB cable and power up again.
**Connect to the Yak board**
After booting, you should be able to connect to the YAK board via the address
specified in the network config file. In the example above, this would be the
192.168.0.110.
Troubleshooting
***************
Yeti errors or EVerest not starting
===================================
Should your log output tell you something about "Yeti reset not successful"
or the EVerest modules get terminated right after EVerest started, it could
be due to the Yeti interface not being connected properly.
In this case, check the connections and the cable harness.
Should everything look fine, check if the Yeti firmware is running properly
by looking at the Yeti LED. If you are running firmware version 1, it should
flash one time. If you are running version 2, it should flash two times.
If it is on or off without flashing, the firmware could not be started or is
not installed.
No reboot after RAUC update
===========================
.. note::
Before doing further troubleshooting, please make sure to have the necessary
configuration in place.
See :ref:`the section about RAUC updates <belaybox_rauc>` for the snippet you
will need.
After that, restart the EVerest service and try to do the RAUC update again.
If you have done a RAUC udpate and the Linux system does not reboot after some
seconds, execute:
.. code-block:: bash
tryboot
After the next boot, connect via SSH again and check the currently booted slot
again. It should have switched to the other slot.
If it did not switch to the other slot and the slot is marked as "bad", you
could try to re-flash the Yeti board with an up-to-date firmware version.
If this does not help, please find support in
`the mailing list or Zulip channels <https://everest.github.io/nightly/#everest-compass>`_
.
Short cheat sheet
=================
The new ssh login credentials for the Yocto image are:
.. code-block:: bash
user: root
pw: belaybox
The default config file being used by the everest.service is the symlink
in
.. code-block:: bash
/etc/everest/everest.yaml
It points to the config to be used. This can be
changed to a config to your liking:
.. code-block:: bash
ln -sf /etc/everest/<your-custom-config> /etc/everest/everest.yaml
After this, restart the EVerest service or reboot.
Should you see any "Unknown config entry" errors when starting the manager
process, delete the corresponding config entries from the yaml file you are
using for startup.

View File

@@ -0,0 +1,67 @@
.. _how_to_renesas_mpu:
##############################################
How to for Renesas MPU (RZ/G2L family)
##############################################
To get more information on EVerest and Renesas hardware, see here:
https://www.renesas.com/en/products/microcontrollers-microprocessors/rz-mpus/rz-partner-solutions/pionix-basecamp
Here is how to set it up and run an EVerest simulation:
1. Clone the ``rz-community-bsp`` repo:
https://github.com/renesas-rz/rz-community-bsp.git
2. Apply the patch necessary to build ``EVerest``.
You can find the patch here: :ref:`Patch file <how_to_renesas_mpu_patch>`
3. Start the ``kas-container`` menu to configure the environment:
a. Run ``./kas-container menu``
b. Select the device **RZ/G2L**
c. Save & Exit
4. Start ``kas-shell`` with ``./kas-container shell`` and install dependencies:
a. Run ``sudo apt-get update``
b. Run ``sudo apt-get install -y python3.11 python3.11-dev``
5. Edit the file
``/work/poky/meta/recipes-devtools/elfutils/elfutils_0.186.bb``
to add the following line:
.. code-block:: bash
CFLAGS:append = " -Wno-error=deprecated-declarations"
6. Start the build using:
``bitbake renesas-image-minimal``
Once the build is complete, exit the shell.
7. Flash the hardware with the instructions in the RZ/G2L startup guide:
`Evaluation Board Kit Quick Start Guide <https://www.renesas.com/us/en/document/qsg/rzg2l-evaluation-board-kit-quick-start-guide>`_
The generated images/binaries will be present in:
.. code-block:: bash
built/tmp/deploy/images/smarc-rzg2l
8. Start EVerest with:
.. code-block:: bash
/usr/bin/manager --conf /etc/everest/config-sil.yaml
If everything has been set up correctly, you will now be able to run simulation
steps with EVerest. See the :ref:`Quick Start Guide <htg_getting_started_sw>`
for more information.
To go further and implement your own customized EVerest modules, have a look at
the :doc:`EVerest module concept documentation </explanation/detail-module-concept>`.
----
**Authors:** Manuel Ziegler

View File

@@ -0,0 +1,57 @@
:orphan:
.. _how_to_renesas_mpu_patch:
#####################################
Patch for Renesas MPU (RZ/G2L family)
#####################################
Save this content here as a file with the extension ``.patch``. Then apply it to the
``kas/yocto/kirkstone.yml`` file in the ``rz-community-bsp`` repository:
.. code-block:: bash
From 0af5946f55b746a6e436c45249f559866fcaa848 Mon Sep 17 00:00:00 2001
From: sach1n1 <sachin.s.dominic@gmail.com>
Date: Wed, 28 Aug 2024 12:44:51 +0200
Subject: [PATCH] Signed-off-by: <sachin.dominic.zn@renesas.com>
Changes for everest.
---
kas/yocto/kirkstone.yml | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/kas/yocto/kirkstone.yml b/kas/yocto/kirkstone.yml
index b2a1470..c80dd34 100644
--- a/kas/yocto/kirkstone.yml
+++ b/kas/yocto/kirkstone.yml
@@ -24,3 +24,27 @@ repos:
layers:
meta-arm-toolchain:
meta-arm:
+ meta-openembedded:
+ url: https://github.com/openembedded/meta-openembedded
+ commit: 52ecd66835dcfd8b4e55c9cb6325908ccea6a4e7
+ layers:
+ meta-oe:
+ meta-networking:
+ meta-python:
+ meta-multimedia:
+ meta-filesystems:
+ meta-perl:
+ meta-everest:
+ url: https://github.com/EVerest/meta-everest.git
+ commit: f9273939088db91a5699c07e512ddd7981e5637a
+
+
+local_conf_header:
+ systemd: |
+ DISTRO_FEATURES:append = " systemd"
+ VIRTUAL-RUNTIME_init_manager = "systemd"
+ VIRTUAL-RUNTIME_initscripts = "systemd-compat-units"
+
+ everest-core: |
+ IMAGE_INSTALL:append = " systemd systemd-analyze everest-core mosquitto"
+ IMAGE_INSTALL:remove = "busybox-syslog"
--
2.25.1

View File

@@ -0,0 +1,156 @@
##################################
Security Best Practices
##################################
This how-to-guide describes security best practices for deploying
EVerest in a production environment. It provides checklists with
items to consider for securing the system.
EVerest-related security aspects
================================
- Do not expose the main MQTT broker on any interface (e.g. PLC,
Ethernet, ...). We recommend using a unix domain socket between
EVerest and Mosquitto.
In Mosquitto, config file add the line:
.. code-block::
listener 0 /tmp/mosquitto.socket
In the EVerest config file, add the following to the settings section:
.. code-block:: yaml
settings:
mqtt_broker_socket_path: /tmp/mosquitto.socket
- If a part of an MQTT API should be exposed, e.g. to a mobile app on
the same wireless LAN, use mutually authenticated TLS for the MQTT
connection and run a separate Mosquitto instance. Bridge only those
API topics strictly needed (and nothing from the “everest” topic)
between the two Mosquitto instances. Shutdown the public Mosquitto
whenever it is not needed.
- Use OCPP security level 3 for the CSMS connection.
- Use a hardware security module, e.g. TPM2 for generating and
securing private keys.
- Don't use the *admin-panel* on the product and ensure EVerest does
not listen on port 8849. In the Yocto recipes, this is disabled by
default. Take special care if you use another build system. Set
"EVEREST_ENABLE_ADMIN_PANEL_BACKEND=OFF" in cmake.
- Do not run EVerest modules as root user. Create a low privilege
user, that has access only to what is needed (via filesystem
permissions, group memberships, ...). In Yocto, you can do this in your
image file similar to this:
.. code-block::
inherit useradd
USERADD_PACKAGES = "${PN}"
USERADD_PARAM:${PN} = "-u 1500 -d /home/everest -g everest -G systemd-journal,dialout,tty,gpio,tss,mosquitto -r -s /bin/false everest"
GROUPADD_PARAM:${PN} = "-g 1500 everest; -g 1501 gpio; -r systemd-journal; -r tss"
GROUPMEMS_PARAM:${PN} = ""
.. note::
Make sure to use the correct groups and settings for your system.
Specify this user in the EVerest config file in the settings section:
.. code-block:: yaml
settings:
run_as_user: everest
Some modules need elevated privileges, e.g. SLAC module. Those modules
should be given individual Linux capabilities like this:
.. code-block:: yaml
slac:
config_implementation:
main:
device: seth0
link_status_detection: true
module: EvseSlac
capabilities:
- CAP_NET_RAW
Here is a list of capabilities required by the EVerest modules:
================= ============================================
Module name Capabilities
================= ============================================
EvseSlac / EvSlac CAP_NET_RAW
Setup CAP_NET_ADMIN, CAP_NET_RAW, CAP_DAC_OVERRIDE
PacketSniffer CAP_NET_RAW
================= ============================================
The systemd service should start the manager process as root. It will
then change the user for the child processes it forks (the modules) and
set the capabilities as needed.
- To ensure that internal services cannot be accessed via the powerline connection,
iptables can be used with the following rules. In this example the powerline module
is on device seth0.
.. code-block::
ip6tables -S | grep seth0
-A INPUT -i seth0 -p ipv6-icmp -j ACCEPT
-A INPUT -i seth0 -p udp -m udp --dport 15118 -j ACCEPT
-A INPUT -i seth0 -p tcp -m tcp --dport 50000 -j ACCEPT
-A INPUT -i seth0 -p tcp -m tcp --dport 61341 -j ACCEPT
-A INPUT -i seth0 -p tcp -m tcp --dport 64109 -j ACCEPT
-A OUTPUT -o seth0 -p ipv6-icmp -j ACCEPT
-A OUTPUT -o seth0 -p udp -m udp --sport 15118 -j ACCEPT
-A OUTPUT -o seth0 -p tcp -m tcp --sport 50000 -j ACCEPT
-A OUTPUT -o seth0 -p tcp -m tcp --sport 61341 -j ACCEPT
-A OUTPUT -o seth0 -p tcp -m tcp --sport 64109 -j ACCEPT
According to the standard, port 15118 is used for SDP messages.
:ref:`EvseV2G <everest_modules_EvseV2G>` uses the following ports: TCP (61341), TLS (64109).
:ref:`Evse15118D20 <everest_modules_Evse15118D20>` integrates libiso15118 which uses port 50000 for TCP and TLS1.2/1.3.
General (non-EVerest-related) security aspects
====================================================================
Reaching complete system-level security is a complex topic, that should
be handled by experts. This manual cannot give real advice here.
Following, we created an unordered and incomplete list of things that
you should consider during the development process:
- Use secure boot and make sure that you do a full lock-down on
production units that prevents any unsigned code to boot.
- Disable *bootloader* console on production units.
- Disable any UART console login.
- Disable or lock down all programmer interfaces such as SWD or JTAG
in production units.
- Don't expose USB ports unless you really know what you are doing. A
quite common attack vector for charging stations is to plug in a USB
dongle and reconfigure / update the firmware - or attach a keyboard …
- Evaluate if the rootfs or special partitions need encryption.
- Use a secure vault for all private keys on the device
(e.g. TPM2.0).
- Make sure your PKI for secure boot and OTA is properly maintained.
If you loose the private root key, the hardware in the field is lost.
- Use signed updates. Evaluate if encryption is needed.
- Use signed updates also for all other components, such as the
safety MCU.
- Be able to OTA-update all components in the charger through the
normal OTA package - also third party components if they have a
firmware update feature.
- Network interfaces: Verify that only services being absolutely
necessary are accessible on a network interface.
- Use mTLS with TPM if you have a custom cloud connection.
- Lock down all maintenance / service / repair ports.
- Maintain the complete Linux system and provide regular updates.
- Don't use default passwords for anything - or better: Don't use
passwords at all.
- Use software and hardware watchdogs.
----
**Authors**: Cornelius Claussen

View File

@@ -0,0 +1,90 @@
.. _htg_uk_smart_charging_regulations:
#############################
UK Smart Charging Regulations
#############################
The UK imposes additional requirements that may apply to your product if
it is sold in the UK:
https://www.legislation.gov.uk/uksi/2021/1467/contents/made
There are several key requirements in this regulation such as:
- measuring system and historic logs for 12 months
- off-peak charging (schedules) pre-set defaults security
- no default passwords
- no hard coded credentials
- encrypted communication (TLS …)
- checks for updates
- secure boot
- check / detect unauthorized software change
- tamper protection
- security log (you can use the OCPP security log from EVerest)
- randomized delays
Charger deployment can also impact the requirements. For example,
randomized delays are disabled when a charger is operating under Demand
Side Response service.
Most of the requirements are not in the EVerest domain and will need to
be implemented by the hardware or non-EVerest software.
Regarding EVerest integration, "Part 2 11 Randomized delays" is
particularly important. EVerest has support for that feature by
enabling the following config option in the
:ref:`EvseManager module <everest_modules_EvseManager>`:
.. code-block:: yaml
uk_smartcharging_random_delay_enable: true
By setting the config option, EVerest will be compliant with the
regulations by adding a randomized delay of up to ten minutes on any
change of current flow (both increasing and decreasing current).
The delay may be adjusted by the following config option:
.. code-block:: yaml
uk_smartcharging_random_delay_max_duration: 600
While it is compliant, it is quite annoying to use. The regulation
basically states that a random delay needs to be added if the underlying
reason for the power change is not sufficiently randomized already.
As an example, think about a price signal that is the same for the whole
UK. At 5pm, all EVs will stop charging precisely at the same time
because the prices per kwh increases a lot.
Similarly, if prices drop significantly, all EVs connected will suddenly
start charging.
This is a change in power that definitely shall be randomized to spread
over ten minutes.
Another example would be that the power is driven by the excess energy
from the solar inverter. A small cloud reduces the availability power
and the EV stops charging. As this is a quite local event, it is already
random on a bigger scale. The same applies to users plugging in and out.
EVerest does not know about the nature of the power change, if it is
requested from an external entity (e.g. through OCPP, or a local energy
management system) and hence always applies the delay, even if
unnecessary.
To improve user experience, EVerest supports the
:doc:`uk_random_delay API </reference/interfaces/uk_random_delay>`.
It offers three commands: enable, disable and cancel.
Enable and disable can be used to switch the feature on/off completely
during runtime (e.g. due to user choice).
“Cancel” command can be used to cancel a currently ongoing delay. It has
no effect on the next delay. This should be used to cancel any delay if
the external source of the change knows that it is sufficiently
randomized already.
----
**Authors**: Manuel Ziegler

View File

@@ -0,0 +1,134 @@
.. _howto_yocto_cross_compilation:
############################
Cross-compilation of EVerest
############################
This is a how-to-guide on cross-compiling EVerest for a Yocto-based
Linux system.
For in-depth explanations about using EVerest with Linux and Yocto, please
refer to the :doc:`Linux / Yocto explanations </explanation/linux-yocto/index>`.
.. _exp_cross_compilation_building_an_sdk:
Building a Yocto SDK
=====================
A Yocto SDK can be built once you have a working image. The SDK uses the information
from your image to determine what is needed to build a cross compilation tool chain.
The SDK can be built once and the generated file made available to developers.
To build an SDK that can be used for cross-compilation, after sourcing
your Yocto environment you will just have to run
.. code-block:: bash
bitbake IMAGE_NAME -c populate_sdk
After that you will be able to find the installer of your
newly-generated SDK under ``deploy*/sdk/``.
Cross-compiling EVerest using a Yocto SDK
=========================================
Before you can cross-compile EVerest for your target system, you will
have to acquire a Yocto SDK that is based on the Yocto image that is
currently running on the target you want to cross-compile for.
You can either :ref:`build one yourself <exp_cross_compilation_building_an_sdk>` or be supplied
with one by the organization that is building and maintaining the Yocto
image you are using.
.. tip::
You can download an SDK for the phyVERSO board here:
http://pionix-update.de/phyverso/1.0.0/phytec-ampliphy-rauc-glibc-x86_64-phyverso-basecamp-image-aarch64-toolchain-BSP-Yocto-Ampliphy-AM62x-PD23.2.1-phyVERSO-EVCS.sh
To install the SDK, follow the steps below.
Whether you have created an SDK by yourself or are supplied with one,
the first step you will have to do will be to install the SDK on your
development machine. For that, you will first have to make the SDK
installer file executable and execute it.
.. code-block:: bash
chmod +x name_of_sdk_installer.sh
./name_of_sdk_installer.sh
After that, the installer will ask you for the path in which you want to
install the SDK in.
You are free to install it in your preferred directory.
Whenever you want to do any compilations using this SDK/cross-toolchain,
you will have to source the respective environment-setup file of the
given SDK, which resides in the SDK's install location.
To source the cross-toolchain environment use the following syntax:
.. code-block:: bash
source /path/to/sdk/environment-setup-XYZ.sh
``XYZ`` depends on the architecture and distribution name of your Yocto
image/SDK.
Use ``ls`` or tab-completion to find the full name of the
``environment-setup-\*.sh`` you want to use.
Now that the SDK is installed on your development machine and you know
how to source the cross-toolchain, we can start fetch the EVerest
sources and cross-compile them using the SDK-supplied toolchain.
Clone the ``EVerest`` repository and checkout the branch/tag/commit you
want to cross-compile.
.. code-block:: bash
git clone git@github.com:EVerest/EVerest.git
cd EVerest
git checkout TAG
.. warning::
Make sure to source the SDK's toolchain first before continuing!
You can now create a ``build-cross`` directory, where you will do your
cross-compilation and run cmake with your desired additional flags.
.. code-block:: bash
cmake -S. -Bbuild-cross -DCMAKE_INSTALL_PREFIX=/var/everest
cd build-cross
make -j16
DESTDIR=dist make install
rsync -av dist/ root@192.168.3.11:/var/everest
This will cross-compile and “install” EVerest into
``EVerest/build-cross/dist/`` and ``rsync`` the cross-compiled
EVerest to your target (the next command assumes that your target is
accessible at 192.168.3.11):
You can now SSH into your target and stop the normally running
``everest`` process:
.. code-block::
systemctl stop everest
After that, you can start your cross-compiled EVerest via:
.. code-block::
LD_LIBRARY_PATH=/var/everest/lib:$LD_LIBRARY_PATH /var/everest/bin/manager --prefix /var/everest/ --config /path/to/your/config
.. note::
With ``--prefix`` you specify the path of the EVerest installation. Some modules
may use this path to find their resources (e.g. certificates, config files, etc.).
----
**Authors**: Cornelius Claussen, James Chapman