Backend API
Reference documentation for the V-Portal C++ backend SDK.
Core Interfaces
ModuleInterface
Base interface for all modules:
class ModuleInterface {
public:
virtual ~ModuleInterface() = default;
// Module metadata
virtual std::string name() const = 0;
virtual std::string version() const = 0;
virtual std::string description() const { return ""; }
// Lifecycle
virtual void initialize() = 0;
virtual void cleanup() = 0;
};Module Data Field Interface
For modules that use data fields:
class ModuleDataFieldInterface {
public:
virtual void onDataFieldChange(
const std::string& fieldName,
const DataVariant& value
) = 0;
virtual void onSubscriptionAdded(
const std::string& pattern
) {}
virtual void onSubscriptionRemoved(
const std::string& pattern
) {}
};Service Registry
Access V-Portal services:
#include "sdk/services/service_registry.h"
auto& registry = ServiceRegistry::instance();
// Get a service
auto& database = registry.getService<DatabaseService>();
auto& routes = registry.getService<RouteRegistry>();Route Registration
HTTP Routes
#include "sdk/services/route_registry.h"
void MyModule::registerRoutes() {
auto& routes = ServiceRegistry::instance()
.getService<RouteRegistry>();
// GET route
routes.registerRoute(
crow::HTTPMethod::GET,
"/api/mymodule/status",
[this](const crow::request& req) {
return crow::response(200, getStatus());
}
);
// POST route with JSON
routes.registerRoute(
crow::HTTPMethod::POST,
"/api/mymodule/command",
[this](const crow::request& req) {
auto body = crow::json::load(req.body);
if (!body) {
return crow::response(400, "Invalid JSON");
}
std::string cmd = body["command"].s();
executeCommand(cmd);
return crow::response(200, "OK");
}
);
}WebSocket Routes
routes.registerWebSocketRoute(
"/ws/mymodule",
[this](crow::websocket::connection& conn) {
// Connection opened
connections_.push_back(&conn);
},
[this](crow::websocket::connection& conn,
const std::string& data, bool is_binary) {
// Message received
handleMessage(conn, data);
},
[this](crow::websocket::connection& conn,
const std::string& reason) {
// Connection closed
removeConnection(&conn);
}
);Data Fields
Publishing Data
#include "sdk/services/data_field_service.h"
void publishData() {
auto& df = ServiceRegistry::instance()
.getService<DataFieldService>();
// Publish different types
df.publish("mymodule.status", std::string("RUNNING"));
df.publish("mymodule.value", 42);
df.publish("mymodule.temperature", 25.5);
df.publish("mymodule.enabled", true);
}Subscribing to Data
void MyModule::subscribe() {
auto& df = ServiceRegistry::instance()
.getService<DataFieldService>();
df.subscribe("robot.position.*",
[this](const std::string& name, const DataVariant& value) {
handlePositionUpdate(name, value);
}
);
}Database Access
#include "sdk/services/database_service/database_service.h"
void queryDatabase() {
auto& db = ServiceRegistry::instance()
.getService<DatabaseService>();
// Execute query
auto result = db.execute(
"SELECT * FROM users WHERE role = $1",
"admin"
);
// Process results
for (const auto& row : result) {
std::string username = row["username"].as<std::string>();
// ...
}
}File Operations
File Uploader Service
#include "sdk/services/file_uploader/file_uploader.h"
void handleFile(const std::string& filepath) {
auto& uploader = ServiceRegistry::instance()
.getService<FileUploader>();
// Get uploaded file
auto fileData = uploader.getFile(filepath);
// Process file
processFile(fileData);
}Python Integration
#include "sdk/services/python_runner/python_runner.h"
void runPythonScript() {
auto& python = ServiceRegistry::instance()
.getService<PythonRunner>();
std::string script = R"(
import vportal
vportal.log.info("Hello from Python")
)";
python.execute(script);
}Utilities
Data Variant
Type-safe data container:
#include "sdk/utils/data_variant.h"
DataVariant value;
// Set value
value = 42;
value = std::string("hello");
value = true;
// Get value
if (value.isInt()) {
int i = value.getInt();
}
if (value.isString()) {
std::string s = value.getString();
}Network Utilities
#include "sdk/utils/network.h"
// Get local IP
std::string ip = NetworkUtils::getLocalIP();
// Check port availability
bool available = NetworkUtils::isPortAvailable(8080);Checksums
#include "sdk/utils/checksum.h"
std::string data = "hello world";
std::string md5 = Checksum::md5(data);
std::string sha256 = Checksum::sha256(data);Threading
Realtime Thread
For time-critical operations:
#include "sdk/utils/realtime_thread.h"
class MyRealtimeTask : public RealtimeThread {
protected:
void run() override {
while (!shouldStop()) {
// Time-critical work
doWork();
// Sleep for precise timing
sleepFor(std::chrono::milliseconds(10));
}
}
};
// Usage
MyRealtimeTask task;
task.start();
// ...
task.stop();
task.join();Logging
#include "logging/logger.h"
LOG_INFO("Module initialized");
LOG_WARNING("Low memory: {} MB", availableMemory);
LOG_ERROR("Connection failed: {}", error);
LOG_DEBUG("Debug value: {}", debugValue);Module Export
#include "sdk/module_interface.h"
class MyModule : public ModuleInterface {
// Implementation
};
// Export macro
EXPORT_MODULE(MyModule)Next Steps
Last updated on