graph TD
A[Manager程序] --> B[配置加载]
B --> C[激活模块]
C --> D1[EvseManager模块]
C --> D2[OCPP201模块]
C --> D3[Auth模块]
C --> D4[EnergyManager模块]
C --> D5[其他模块...]
D1 --> E1[MQTT通信]
D2 --> E2[MQTT通信]
D3 --> E3[MQTT通信]
D4 --> E4[MQTT通信]
E1 <--> F1[外部MQTT服务器]
E2 <--> F1
E3 <--> F1
E4 <--> F1
D2 --> G1[OCPP数据库]
D3 --> G2[认证数据库]
D2 <--> H[SteVe OCPP中央系统]
D1 <--> I1[充电控制]
D2 <--> I2[会话管理]
D4 <--> I3[能源管理]
Everest管理器架构分析
Everest的manager程序是一个模块化的充电桩控制系统,它的核心特点是:
模块化架构
从配置文件config-sil-ocpp201.yaml中可以看到,系统由多个独立模块组成:
- EvseManager: 负责充电桩基本控制,管理单个充电连接器
- OCPP201: 实现OCPP 2.0.1协议通信
- Auth: 处理认证逻辑
- EnergyManager: 管理能源分配
- EnergyNode: 能源节点,用于限制和监控能源消耗
- YetiSimulator: 模拟硬件
每个模块有明确的职责,并通过定义的接口相互通信。
基于MQTT的通信架构
mqtt是系统内外部通信的核心机制:
// 从EvManager.hpp
class EvManager : public Everest::ModuleBase {
Everest::MqttProvider& mqtt;
// ...
}
// 从MicroMegaWattBSP.cpp,可以看到MQTT的使用
serial.signalTelemetry.connect([this](Telemetry t) {
mqtt.publish("everest_external/umwc/cp_hi", t.cp_hi);
mqtt.publish("everest_external/umwc/cp_lo", t.cp_lo);
mqtt.publish("everest_external/umwc/pwm_dc", t.pwm_dc);
mqtt.publish("everest_external/umwc/relais_on", t.relais_on);
mqtt.publish("everest_external/umwc/output_voltage", t.voltage);
});所有模块通过MQTT发布/订阅机制交换信息,这使得模块之间可以松耦合,而且可以与外部系统进行通信。MQTT话题采用层次结构,例如everest_external/umwc/cp_hi。
外部服务依赖
从docker-compose文件中可以看到系统依赖的外部服务:
- MQTT服务器(mqtt-server): 所有模块通过MQTT服务器通信
- OCPP数据库(ocpp-db): 存储OCPP相关数据
- SteVe服务器: 作为OCPP中央系统
在OCPP201模块中,可以看到对数据库的使用:
this->charge_point = std::make_unique<ocpp::v16::ChargePoint>(
json_config.dump(), this->ocpp_share_path, user_config_path,
std::filesystem::path(this->config.DatabasePath),
sql_init_path, std::filesystem::path(this->config.MessageLogPath),
std::make_shared<EvseSecurity>(*this->r_security));模块间通信机制
模块间通信主要通过两种方式:
- 直接调用接口: 模块可以通过定义的接口直接调用其他模块的方法
// 直接调用接口示例
this->r_evse_manager.at(this->connector_evse_index_map.at(connector))->call_pause_charging();- 通过MQTT的发布/订阅机制: 模块可以发布事件或状态变化,其他模块订阅这些事件
// MQTT订阅示例
this->mqtt.subscribe(cmd_enable, [this, &evse](const std::string& data) {
// 处理enable命令
});Manager程序的核心作用
manager程序是整个系统的入口点,它负责:
- 加载配置文件(例如
config-sil-ocpp201.yaml) - 初始化并激活所需的模块
- 建立模块间的连接关系
- 维护模块的生命周期
从run-sil-ocpp201.sh脚本可以看到它的调用方式:
LD_LIBRARY_PATH=/workspace/everest-core/build/dist/lib:$LD_LIBRARY_PATH \
PATH=/workspace/everest-core/build/dist/bin:$PATH \
manager \
--prefix /workspace/everest-core/build/dist \
--conf /workspace/everest-core/config/config-sil-ocpp201.yaml \
<br/>
$@具体工作流程
当run-sil-ocpp201.sh脚本执行时:
- 启动manager程序:加载配置文件
config-sil-ocpp201.yaml - 初始化模块:根据配置创建并初始化各个模块
- 建立连接:根据配置文件中的
connections部分建立模块间的连接关系 - 与外部服务通信:
- 通过MQTT与外部MQTT服务器通信
- OCPP201模块与SteVe服务器建立WebSocket连接
- 模块需要访问数据库时连接到外部数据库服务
因此,当你直接在WSL环境中运行脚本时,仍然需要先启动Docker Compose服务,因为manager程序需要连接到这些外部服务(MQTT、数据库和SteVe服务器)才能正常工作。即使不在容器中运行,这些依赖关系仍然存在。