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:
609
tools/EVerest-main/docs/source/tutorials/develop-new-module.rst
Normal file
609
tools/EVerest-main/docs/source/tutorials/develop-new-module.rst
Normal file
@@ -0,0 +1,609 @@
|
||||
.. _tutorial_develop_new_everest_module:
|
||||
|
||||
Develop New Modules
|
||||
*******************
|
||||
|
||||
.. hint::
|
||||
|
||||
The module concept will be improved in the next couple of months with
|
||||
new or changed features. We will reflect those changes in the documentation,
|
||||
but be aware that there might be some fragments that still show some "old
|
||||
style". We would be happy if you drop us a line via the
|
||||
`EVerest mailing list <https://lists.lfenergy.org/g/everest>`_ in this case.
|
||||
|
||||
This tutorial is meant to show how to develop your own module for the EVerest
|
||||
framework. This tutorial builds on knowledge that is explained in the
|
||||
:ref:`Quick Start Guide <htg_getting_started_sw>`, which is a good starting
|
||||
point for understanding the central concepts of modules.
|
||||
|
||||
Goal Of This Tutorial
|
||||
=====================
|
||||
|
||||
In this tutorial, we will keep everything as simple as possible. You will
|
||||
learn the following:
|
||||
|
||||
1. Create an EVerest module that implements an interface.
|
||||
2. Define an interface containing a simple command with parameter and return
|
||||
value.
|
||||
3. Define a configuration parameter for the new module.
|
||||
4. Configure required dependencies of the EVerest framework and modules.
|
||||
5. Build and run.
|
||||
|
||||
Install Prerequisites
|
||||
=====================
|
||||
|
||||
Please follow the :ref:`Quick Start Guide <htg_getting_started_sw>` to install
|
||||
all prerequisites into your environment.
|
||||
|
||||
After that, you should in particular have:
|
||||
|
||||
- *optional:* The EVerest dependency manager (check via ``edm --version``)
|
||||
- The EVerest cli utility (check via ``ev-cli --version``)
|
||||
- A running MQTT broker (e.g. started as container as described in the setup
|
||||
guide; per default expected on localhost on port 1883)
|
||||
|
||||
Workspace Setup
|
||||
===============
|
||||
|
||||
This section describes how to setup an EVerest workspace (or at least the
|
||||
necessary parts of it) to develop EVerest modules.
|
||||
|
||||
First, create a directory for your workspace. In the following, we will assume
|
||||
the environment variable ``EVEREST_WORKSPACE`` to hold this directory::
|
||||
|
||||
export EVEREST_WORKSPACE=~/ev-workspace
|
||||
mkdir -p $EVEREST_WORKSPACE
|
||||
|
||||
|
||||
Now you have two options:
|
||||
|
||||
Alternative 1: Clone required repositories (recommended for recent versions)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Just clone this, to get the required dependencies::
|
||||
|
||||
git clone https://github.com/EVerest/everest-cmake.git ${EVEREST_WORKSPACE}/everest-cmake
|
||||
git clone https://github.com/EVerest/EVerest.git ${EVEREST_WORKSPACE}/EVerest
|
||||
|
||||
Alternative 2: Setup Workspace via EVerest Dependency Manager (recommended for pre-2026 version)
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
Use the EVerest dependency manager to setup your workspace. This has the
|
||||
benefit of allowing your to select a specific snapshot (see the corresponding
|
||||
:ref:`docs <exp_dev_tools_edm>` for details), as well as it is a single command::
|
||||
|
||||
edm init --workspace $EVEREST_WORKSPACE
|
||||
cd $EVEREST_WORKSPACE
|
||||
|
||||
As of 2026 the EVerest dependency manager layouts the workspace to be compatible with
|
||||
older non-mono-repository versions of EVerest (or, as formerly called, `everest-core`). Assuming you want to build a recent
|
||||
version of everest, you can delete the dependencies which are part of the mono-repo today.
|
||||
|
||||
**Remove everything except** ``EVerest/`` **and** ``everest-cmake/`` **.**
|
||||
|
||||
The result should look like::
|
||||
|
||||
$ ls
|
||||
EVerest everest-cmake
|
||||
|
||||
|
||||
Create Module Skeleton
|
||||
======================
|
||||
|
||||
The following describes how to define the fundamental skeleton of a module.
|
||||
This includes configuration files and the auto-generation of source files.
|
||||
|
||||
First, create an empty folder that is to contain your module. In the
|
||||
following, we assume the environment variable ``EVEREST_TUTORIAL_DIR`` to hold
|
||||
this directory, for example::
|
||||
|
||||
export EVEREST_TUTORIAL_DIR=~/everest-tutorial-module
|
||||
git clone https://github.com/EVerest/everest-template.git $EVEREST_TUTORIAL_DIR
|
||||
|
||||
This provides you in particular with the ``.clang-format`` and ``.eslintrc.json``
|
||||
files.
|
||||
|
||||
.. note::
|
||||
|
||||
You may want to change the origin remote in this git repository if you are
|
||||
going to use it further on. See suitable Git documentation how to do that.
|
||||
You might also want to check that you do not take the Git history of the
|
||||
`everest-template` repository with you.
|
||||
|
||||
|
||||
Interface Configuration
|
||||
-----------------------
|
||||
|
||||
First, we define an interface that the module provides.
|
||||
In this very first minimal version, the interface shall provide a single
|
||||
command `command_tutorial` that can be called by another module and will
|
||||
just always return the string "everest" as result. We will later give some
|
||||
ideas how to extend this minimal example.
|
||||
|
||||
We store the following interface configuration in form of a .yaml file in
|
||||
``$EVEREST_TUTORIAL_DIR/interfaces/interface_tutorial_module.yaml``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
description: The interface of the tutorial module.
|
||||
cmds:
|
||||
command_tutorial:
|
||||
description: A command the tutorial module's interface provides. It receives a simple string.
|
||||
arguments:
|
||||
payload:
|
||||
description: An arbitrary string that can be sent to the module.
|
||||
type: string
|
||||
result:
|
||||
description: The answer of the module (which per default will just be "everest").
|
||||
type: string
|
||||
|
||||
Second, we use the ``ev-cli`` tool to auto-generate header files for this
|
||||
interface::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR && ev-cli interface generate-headers --everest-dir . --schemas-dir $EVEREST_WORKSPACE/EVerest/lib/everest/framework/schemas interface_tutorial_module
|
||||
|
||||
|
||||
After this, you should find the following file tree structure in your module::
|
||||
|
||||
.
|
||||
├── build
|
||||
│ └── generated
|
||||
│ └── include
|
||||
│ └── generated
|
||||
│ └── interfaces
|
||||
│ └── interface_tutorial_module
|
||||
│ ├── Implementation.hpp
|
||||
│ ├── Interface.hpp
|
||||
│ └── Types.hpp
|
||||
└── interfaces
|
||||
└── interface_tutorial_module.yaml
|
||||
|
||||
|
||||
These auto-generated header files in particular provide you with static type
|
||||
checks when developing against your individual interface.
|
||||
|
||||
.. hint::
|
||||
It is also possible to work with Python or Rust. At this point
|
||||
we will focus on C++.
|
||||
|
||||
|
||||
Module Configuration
|
||||
--------------------
|
||||
|
||||
Next, we will define our module's manifest.
|
||||
|
||||
For this, we create a module directory::
|
||||
|
||||
mkdir -p $EVEREST_TUTORIAL_DIR/modules/TutorialModule
|
||||
|
||||
and in it, create file
|
||||
``$EVEREST_TUTORIAL_DIR/modules/TutorialModule/manifest.yaml`` with the
|
||||
following content:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
description: The EVerest Tutorial Module
|
||||
config:
|
||||
config_tutorial_switch:
|
||||
description: A boolean configuration parameter.
|
||||
type: boolean
|
||||
default: false
|
||||
provides:
|
||||
interface_impl_tutorial_module:
|
||||
interface: interface_tutorial_module
|
||||
description: An actual implementation in your module of "interface_tutorial_module" interface.
|
||||
metadata:
|
||||
license: https://opensource.org/licenses/Apache-2.0
|
||||
authors:
|
||||
- <Your Name>, <Your Organization>
|
||||
|
||||
|
||||
In particular, this manifest declares the following:
|
||||
|
||||
- A boolean configuration parameter `config_tutorial_switch` of the module we
|
||||
can define later at runtime.
|
||||
- The module will implement the `interface_tutorial_module` interface (that
|
||||
we have defined before). We give this implementation the name `interface_impl_tutorial_module`.
|
||||
|
||||
|
||||
Again, we use the EVerest cli tool to auto-generate code from this
|
||||
configuration::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR && ev-cli module create --everest-dir . --schemas-dir $EVEREST_WORKSPACE/EVerest/lib/everest/framework/schemas TutorialModule --licenses $EVEREST_WORKSPACE/EVerest/applications/utils/ev-dev-tools/src/ev_cli/licenses
|
||||
|
||||
|
||||
After that, you should have the following file structure::
|
||||
|
||||
.
|
||||
├── build
|
||||
│ └── generated
|
||||
│ (...)
|
||||
├── config
|
||||
├── interfaces
|
||||
│ └── interface_tutorial_module.yaml
|
||||
└── modules
|
||||
└── TutorialModule
|
||||
├── CMakeLists.txt
|
||||
├── TutorialModule.cpp
|
||||
├── TutorialModule.hpp
|
||||
├── doc.rst
|
||||
├── docs
|
||||
│ └── index.rst
|
||||
├── interface_impl_tutorial_module
|
||||
│ ├── interface_tutorial_moduleImpl.cpp
|
||||
│ └── interface_tutorial_moduleImpl.hpp
|
||||
└── manifest.yaml
|
||||
|
||||
|
||||
Let us point out a few particularly important files:
|
||||
|
||||
**TutorialModule{.hpp,.cpp}:**
|
||||
|
||||
This provides the module's callbacks called by the EVerest framework at
|
||||
startup, more precisely in initialization and system-ready state. Here,
|
||||
the auto-generated implementation already calls the respective callbacks of
|
||||
its interface implementations.
|
||||
|
||||
Among others, you'll furthermore find the module's configuration and a pointer
|
||||
to the interface implementations.
|
||||
|
||||
**interface_impl_tutorial_module/interface_tutorial_moduleImpl{.hpp,.cpp}:**
|
||||
For each interface implementation (here, only a single one is defined), the
|
||||
respective header and source files are generated.
|
||||
|
||||
The header file declares particular spots for non-auto-generated code.
|
||||
|
||||
Observe that the default implementation of the handler of the
|
||||
`command_tutorial` coincidentally already satisfies this tutorial's needs:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::string interface_tutorial_moduleImpl::handle_command_tutorial(std::string& payload) {
|
||||
// your code for cmd command_tutorial goes here
|
||||
return "everest";
|
||||
}
|
||||
|
||||
|
||||
Build Configuration & Build
|
||||
===========================
|
||||
|
||||
This section describes the additional steps needed to build your project and
|
||||
install it.
|
||||
|
||||
Adding CMakeLists.txt in the root directory
|
||||
-------------------------------------------
|
||||
The ``$EVEREST_TUTORIAL_DIR/CMakeLists.txt`` file in the root of your project
|
||||
repository will need to import some build commands from the framework, as well
|
||||
as link to its dependencies. A fairly simple file that includes
|
||||
``everest-core`` into the build would look as follows::
|
||||
|
||||
cmake_minimum_required(VERSION 3.14.7)
|
||||
project(everest-tutorial VERSION 0.1
|
||||
DESCRIPTION "EVerest tutorial modules"
|
||||
LANGUAGES CXX C)
|
||||
find_package(everest-cmake 0.1 REQUIRED
|
||||
COMPONENTS bundling
|
||||
PATHS ../everest-cmake
|
||||
)
|
||||
# options
|
||||
option(BUILD_TESTING "Run unit tests" OFF)
|
||||
option(CMAKE_RUN_CLANG_TIDY "Run clang-tidy" OFF)
|
||||
# dependencies
|
||||
if (NOT DISABLE_EDM)
|
||||
evc_setup_edm()
|
||||
else()
|
||||
find_package(everest-core)
|
||||
# InfyPowerACDC uses pal-sigslot
|
||||
find_package(PalSigslot REQUIRED)
|
||||
endif()
|
||||
ev_add_project()
|
||||
|
||||
# config (not needed if you do not need a run script for your configuration)
|
||||
# add_subdirectory(config)
|
||||
|
||||
# configure clang-tidy if requested
|
||||
if(CMAKE_RUN_CLANG_TIDY)
|
||||
message("Enabling clang-tidy")
|
||||
set(CMAKE_CXX_CLANG_TIDY clang-tidy)
|
||||
endif()
|
||||
# testing
|
||||
if(BUILD_TESTING)
|
||||
include(CTest)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
|
||||
evc_include(CodeCoverage)
|
||||
append_coverage_compiler_flags()
|
||||
add_subdirectory(tests)
|
||||
setup_target_for_coverage_gcovr_html(
|
||||
NAME gcovr_coverage
|
||||
EXECUTABLE test_config
|
||||
DEPENDENCIES test_config everest
|
||||
)
|
||||
setup_target_for_coverage_lcov(
|
||||
NAME lcov_coverage
|
||||
EXECUTABLE test_config
|
||||
DEPENDENCIES test_config everest
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
Adding ``modules/CMakeLists.txt``
|
||||
---------------------------------
|
||||
|
||||
Next, ``$EVEREST_TUTORIAL_DIR/modules/CMakeLists.txt`` essentially tells CMake
|
||||
where to look for modules, in order to add them to the build.
|
||||
|
||||
It contains a single line per module. To proceed, create the file and then add the following line, as per our example::
|
||||
|
||||
ev_add_module(TutorialModule)
|
||||
|
||||
|
||||
Note that you could also develop several modules at once in your repository.
|
||||
In that case you would add a respective ``ev_add_module(<MODULE_NAME>)`` line
|
||||
for each of those.
|
||||
|
||||
|
||||
Adding ``dependencies.yaml``
|
||||
----------------------------
|
||||
|
||||
The ``find-package()`` CMake directive found in the previous sections is
|
||||
handled by EDM.
|
||||
|
||||
In order for this to work, you need to add a dependency file for EDM, called
|
||||
``dependencies.yaml``, in the project root directory. For example, listing
|
||||
only ``EVerest`` as a dependency looks like this::
|
||||
|
||||
---
|
||||
EVerest:
|
||||
git: https://github.com/EVerest/EVerest.git
|
||||
git_tag: main
|
||||
|
||||
With the above setup taken care of, you are now ready to build the project.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
When you auto-generated the code for the interfaces and modules, a ``build/``
|
||||
directory should have appeared.
|
||||
|
||||
You can also build the project there - go to it, and configure the build::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR/build
|
||||
CMAKE_PREFIX_PATH=$EVEREST_WORKSPACE cmake --install-prefix $EVEREST_TUTORIAL_DIR/dist ..
|
||||
|
||||
Here, we added two instructions to cmake:
|
||||
|
||||
- Setting ``CMAKE_PREFIX_PATH=$EVEREST_WORKSPACE`` allows cmake to find the
|
||||
``everest-cmake`` repository in the workspace.
|
||||
- Specifying the ``--install-prefix`` allows you to specify where the finished
|
||||
binaries will be placed, e.g. into the ``dist/`` folder in the modules repository.
|
||||
EVerest can be installed system wide (e.g. into ``users/local/bin``), but this
|
||||
usually requires ``sudo`` permissions.
|
||||
|
||||
|
||||
Then, build and install the project::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR/build
|
||||
make -j <number of parallel jobs>
|
||||
|
||||
And finally, install the binaries::
|
||||
|
||||
make install -j <number of parallel jobs>
|
||||
|
||||
|
||||
If everything worked smoothly so far, your modules are installed and ready to
|
||||
run.
|
||||
|
||||
Run Configuration & Run
|
||||
=======================
|
||||
|
||||
EVerest configuration
|
||||
---------------------
|
||||
|
||||
The final step to run EVerest and testing the new module is to define an
|
||||
EVerest run configuration. For this, create a file
|
||||
``$EVEREST_TUTORIAL_DIR/config/config-modules-tutorial.yaml`` with the following
|
||||
content:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
active_modules:
|
||||
tutorial_module_instance:
|
||||
module: TutorialModule
|
||||
|
||||
This provides a very minimalistic run configuration for EVerest telling to run
|
||||
with a single module, namely the newly created one.
|
||||
|
||||
|
||||
Adding and activating ``config/CMakeLists.txt``
|
||||
-----------------------------------------------
|
||||
|
||||
The EVerest cmake utils provide a function to auto-generate run scripts for
|
||||
your configurations.
|
||||
|
||||
In order to achieve this, create the file ``$EVEREST_TUTORIAL_DIR/config/CMakeLists.txt`` with content::
|
||||
|
||||
generate_config_run_script(CONFIG modules-tutorial)
|
||||
|
||||
|
||||
Here, the ``generate_config_run_script(<CONFIG_NAME>)`` expects the existence of
|
||||
a file ``config-<CONFIG_NAME>.yaml``.
|
||||
|
||||
It will then generate a run script for this configuration.
|
||||
|
||||
You must then "activate" this configuraton by adapting the
|
||||
``$EVEREST_TUTORIAL_DIR/CMakeLists.txt`` file removing the commenting ``#``
|
||||
before the ``add_subdirectory(config)`` instruction, i.e.::
|
||||
|
||||
# config
|
||||
# (not needed if you do not need a run script for your configuration)
|
||||
add_subdirectory(config)
|
||||
|
||||
After that, once more run cmake::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR/build
|
||||
CMAKE_PREFIX_PATH=$EVEREST_WORKSPACE cmake --install-prefix $EVEREST_TUTORIAL_DIR/dist ..
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
Running EVerest
|
||||
---------------
|
||||
|
||||
The step before should have created a file
|
||||
``$EVEREST_TUTORIAL_DIR/build/run-scripts/run-modules-tutorial.sh``.
|
||||
|
||||
Up to path substitution this will have the following content::
|
||||
|
||||
LD_LIBRARY_PATH=$EVEREST_TUTORIAL_DIR/dist/lib:$LD_LIBRARY_PATH \
|
||||
PATH=$EVEREST_TUTORIAL_DIR/dist/bin:$PATH \
|
||||
manager \
|
||||
--prefix $EVEREST_TUTORIAL_DIR/dist \
|
||||
--conf $EVEREST_TUTORIAL_DIR/config/config-modules-tutorial.yaml
|
||||
|
||||
It puts the compiled libraries and binaries into the respective paths, and
|
||||
then runs EVerest by calling the `manager` binary with the respective
|
||||
configuration.
|
||||
|
||||
Importantly, the configuration must not be known before runtime (since also in
|
||||
our example it was only used to generate the run script, not to build the
|
||||
project!).
|
||||
|
||||
Executing ``run-modules-tutorial.sh`` then should start EVerest, and provide
|
||||
an output similar to::
|
||||
|
||||
YYYY-MM-DD 00:00:12.500139 [INFO] manager :: 8< 8< 8< ------------------------------------------------------------------------------ 8< 8< 8<
|
||||
YYYY-MM-DD 00:00:12.500327 [INFO] manager :: EVerest manager starting using /home/everest/everest-module-tutorial/config/config-modules-tutorial.yaml
|
||||
YYYY-MM-DD 00:00:12.500354 [INFO] manager :: EVerest using MQTT broker localhost:1883
|
||||
YYYY-MM-DD 00:00:12.799618 [INFO] everest_ctrl :: everest controller process started ...
|
||||
YYYY-MM-DD 00:00:12.799822 [INFO] everest_ctrl :: Launching controller service on port 8849
|
||||
YYYY-MM-DD 00:00:13.120267 [INFO] tutorial_module :: Module tutorial_module_instance initialized.
|
||||
YYYY-MM-DD 00:00:13.149934 [INFO] manager :: >>> All modules are initialized. EVerest up and running <<<
|
||||
|
||||
If your socket can't be connected, make sure that your MQTT brocker is running.
|
||||
|
||||
|
||||
Observing the System
|
||||
====================
|
||||
|
||||
In this final section we describe how to observe the behavior of your module
|
||||
and debug it.
|
||||
|
||||
Exploring with MQTT Explorer
|
||||
----------------------------
|
||||
The open-source tool `MQTT Explorer <https://github.com/thomasnordquist/MQTT-Explorer>`_ can be utilized to
|
||||
observe the module communication in EVerest.
|
||||
|
||||
With your MQTT broker running on localhost:1883, you should be able to connect
|
||||
right away when opening MQTT explorer.
|
||||
|
||||
Then start (or re-start) the EVerest manager (as described above). You should
|
||||
notice an `everest` topic popping up.
|
||||
|
||||
We can now publish a command to our self-written module. For this, choose the topic::
|
||||
|
||||
everest/modules/tutorial_module_instance/impl/interface_impl_tutorial_module/cmd/command_tutorial
|
||||
|
||||
and publish the JSON::
|
||||
|
||||
{
|
||||
"msg_type": "Cmd",
|
||||
"data": {
|
||||
"args": {
|
||||
"payload": "Hello World!"
|
||||
},
|
||||
"id": "00000000-0000-0000-0000-000000000042",
|
||||
"origin": "manual_test"
|
||||
}
|
||||
}
|
||||
|
||||
Our module should return with a "everest" response (you may have to reselect
|
||||
the ``everest/tutorial_module_instance/interface_impl_tutorial_module/cmd``
|
||||
on the left to refresh this view.
|
||||
|
||||
The response should be on topic::
|
||||
|
||||
everest/modules/tutorial_module_instance/impl/interface_impl_tutorial_module/cmd/command_tutorial/response/manual_test
|
||||
|
||||
.. image:: images/mqtt_explorer_example.png
|
||||
|
||||
.. _tutorials_develop_new_module_debugging:
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
At the latest when you start developing an actual module, it might come handy
|
||||
to be able to debug your code. Thus, the following shall provide some
|
||||
rudimentary steps to do so.
|
||||
|
||||
*1) Rebuild with debug flags enabled*
|
||||
|
||||
Rerun Cmake, this time with `-DCMAKE_BUILD_TYPE=Debug`, and rebuild::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR/build
|
||||
CMAKE_PREFIX_PATH=$EVEREST_WORKSPACE cmake --install-prefix $EVEREST_TUTORIAL_DIR/dist -DCMAKE_BUILD_TYPE=Debug ..
|
||||
make -j <number of parallel jobs>
|
||||
|
||||
*2) Start EVerest with your module with your module marked as "standalone"*
|
||||
|
||||
With EVerest built as described before, but with the additonal option
|
||||
``--standalone tutorial_module_instance``::
|
||||
|
||||
LD_LIBRARY_PATH=$EVEREST_TUTORIAL_DIR/dist/lib:$LD_LIBRARY_PATH \
|
||||
PATH=$EVEREST_TUTORIAL_DIR/dist/bin:$PATH \
|
||||
manager --prefix $EVEREST_TUTORIAL_DIR/dist --conf $EVEREST_TUTORIAL_DIR/config/config-modules-tutorial.yaml --standalone tutorial_module_instance
|
||||
|
||||
This starts EVerest, but without your module. Instead, the output contains a
|
||||
line::
|
||||
|
||||
manager :: Not starting standalone module: tutorial_module_instance
|
||||
|
||||
Also, so far the output should be missing the ``All modules are initialized. EVerest up and running``
|
||||
notification, since it keeps waiting for your module
|
||||
to spin up.
|
||||
|
||||
*3) Start your module with a debugger*:
|
||||
|
||||
Now open a second terminal (while keeping EVerest running in the frist
|
||||
terminal), and start your module via ``gdb``::
|
||||
|
||||
cd $EVEREST_TUTORIAL_DIR/build
|
||||
gdb --args ./modules/TutorialModule/TutorialModule --module tutorial_module_instance --conf $EVEREST_TUTORIAL_DIR/config/config-modules-tutorial.yaml --prefix $EVEREST_TUTORIAL_DIR/dist
|
||||
|
||||
|
||||
In gdb, we set a break in the line that returns the payload when your test
|
||||
command is hit.
|
||||
We then run the program (you might need to adjust the line number)::
|
||||
|
||||
break modules/TutorialModule/interface_impl_tutorial_module/interface_tutorial_moduleImpl.cpp:17
|
||||
run
|
||||
|
||||
After the ``run`` command, you should notify in your EVerest terminal that all
|
||||
modules have now started. You may now again use MQTT Explorer as before and
|
||||
send a command call via MQTT, this should hit your set breakpoint with a
|
||||
output similar to::
|
||||
|
||||
Thread 4 "tutorial_module" hit Breakpoint 1, module::interface_impl_tutorial_module::interface_tutorial_moduleImpl::handle_command_tutorial (this=0xaaaaaad24fc0, payload="mock_transaction_id") at /tmp/everest-tutorial-verify/modules/TutorialModule/interface_impl_tutorial_module/interface_tutorial_moduleImpl.cpp:17
|
||||
17 return "everest";
|
||||
|
||||
|
||||
Of course, you might setup your favorite IDE in a similar way for a nicer
|
||||
debugging experience.
|
||||
|
||||
Exemplary Module Customizations
|
||||
===============================
|
||||
|
||||
Having prepared a buildable and runnable module, we can now extend the logic
|
||||
of our implementation:
|
||||
|
||||
- Add a variable to your interface, and publish it;
|
||||
- Add a second module which requires the ``interface_tutorial_module`` interface and sends commands or subscribes to variables.
|
||||
- ...
|
||||
|
||||
.. hint::
|
||||
This section is yet to come. Want to help us with that? Feel free and create
|
||||
a suggestion for this.
|
||||
|
||||
--------------------------------
|
||||
|
||||
**Authors**: Valentin Dimov, Manuel Ziegler, Andreas Heinrich, Lukas Mertens, Martin Litre, Piet Gömpel, Christoph Burandt
|
||||
|
||||
Reference in New Issue
Block a user