Documentation Index Fetch the complete documentation index at: https://mintlify.com/EVerest/everest-core/llms.txt
Use this file to discover all available pages before exploring further.
EVerest modules are the fundamental building blocks of the charging system. Each module implements specific functionality and communicates with other modules through well-defined interfaces.
Module Structure
Every EVerest module follows a standard directory structure:
MyModule/
├── manifest.yaml # Module metadata and configuration
├── CMakeLists.txt # Build configuration
├── MyModule.hpp # Module header file
├── MyModule.cpp # Module implementation
└── main/ # Interface implementations
├── InterfaceImpl.hpp
└── InterfaceImpl.cpp
Example: Store Module
Let’s examine the simple Store module from modules/Misc/Store/:
Store/
├── manifest.yaml
├── CMakeLists.txt
├── Store.hpp
├── Store.cpp
└── main/
├── kvsImpl.hpp
└── kvsImpl.cpp
Creating a Module with ev-cli
The recommended way to create a new module is using the ev-cli tool:
ev-cli module create MyModule
This generates the complete module skeleton including:
CMakeLists.txt : Build instructions for CMake
ld-ev.hpp/ld-ev.cpp : Framework glue code
MyModule.hpp/MyModule.cpp : Main module files
Interface implementations : One subdirectory per provided interface
Make sure you have created the manifest.yaml file first, as ev-cli generates code based on the manifest.
Module Implementation Basics
The module header defines the module class structure:
#ifndef MYMODULE_HPP
#define MYMODULE_HPP
#include "ld-ev.hpp"
#include <generated/interfaces/my_interface/Implementation.hpp>
namespace module {
struct Conf {
// Configuration parameters from manifest
};
class MyModule : public Everest :: ModuleBase {
public:
MyModule () = delete ;
MyModule ( const ModuleInfo & info ,
std :: unique_ptr < my_interfaceImplBase > p_main ,
Conf & config ) :
ModuleBase (info), p_main ( std :: move (p_main)), config (config) {};
const std ::unique_ptr < my_interfaceImplBase > p_main;
const Conf & config;
protected:
void init ();
void ready ();
};
} // namespace module
#endif // MYMODULE_HPP
Module Implementation (MyModule.cpp)
The implementation file defines the lifecycle methods:
#include "MyModule.hpp"
namespace module {
void MyModule :: init () {
// Called during module initialization
// Setup resources, initialize member variables
invoke_init ( * p_main);
}
void MyModule :: ready () {
// Called when all modules are initialized
// Start processing, subscribe to events
invoke_ready ( * p_main);
}
} // namespace module
Interface Implementation
Each interface your module provides requires an implementation:
// main/kvsImpl.hpp
#ifndef MAIN_KVS_IMPL_HPP
#define MAIN_KVS_IMPL_HPP
#include <generated/interfaces/kvs/Implementation.hpp>
#include <map>
namespace module {
namespace main {
struct Conf {};
class kvsImpl : public kvsImplBase {
public:
kvsImpl () : kvsImplBase ( nullptr , "main" ) {};
virtual void init () override ;
virtual void ready () override ;
// Command handlers
virtual void handle_store ( std :: string & key ,
std :: variant <...> & value ) override ;
virtual std :: variant <...> handle_load ( std :: string & key ) override ;
private:
std ::map < std ::string, std ::variant < ... >> kvs;
};
} // namespace main
} // namespace module
#endif
// main/kvsImpl.cpp
#include "kvsImpl.hpp"
namespace module {
namespace main {
void kvsImpl :: init () {
// Initialize interface
}
void kvsImpl :: ready () {
// Interface is ready
}
void kvsImpl :: handle_store ( std :: string & key ,
std :: variant <...> & value ) {
kvs [key] = value;
}
std :: variant <...> kvsImpl :: handle_load ( std :: string & key ) {
return kvs [key];
}
} // namespace main
} // namespace module
CMakeLists.txt Integration
The module’s CMakeLists.txt is auto-generated but can be customized:
# Module setup
ev_setup_cpp_module()
# Add source files
target_sources ( ${MODULE_NAME}
PRIVATE
"main/kvsImpl.cpp"
)
# Link additional libraries if needed
# target_link_libraries(${MODULE_NAME} PRIVATE my_library)
# Add custom targets
# install(...)
Keep code within the marked regions (between ev@... comments) when updating modules with ev-cli, as these sections are preserved during updates.
Logging in Modules
Use the EVLOG macros for logging:
#include <everest/logging.hpp>
EVLOG_info << "Module initialized" ;
EVLOG_debug << "Processing value: " << value;
EVLOG_warning << "Unusual condition detected" ;
EVLOG_error << "Failed to process: " << error;
Log levels:
EVLOG_debug: Detailed debugging information
EVLOG_info: General informational messages
EVLOG_warning: Warning messages for unusual conditions
EVLOG_error: Error messages for failures
Updating Modules
When you modify the manifest or interface definitions:
ev-cli module update MyModule
This updates:
Header files (preserving marked sections)
CMakeLists.txt (preserving marked sections)
Interface implementation headers
Use --diff to preview changes without modifying files: ev-cli module update MyModule --diff
Next Steps
Module Manifest Learn about the manifest.yaml format and configuration options
Testing Write tests for your custom modules
Debugging Debug your modules effectively
Interfaces Explore available EVerest interfaces