项目交接文档
FAAP/RTD 测试数据传输系统
一、系统整体架构
整个系统负责将无线基站生产测试数据从被测设备(DUT)实时采集并可靠传输到 RTD 云端中央数据库。
DUT(被测设备) FaapProxy(中间代理) PC客户端 MBS(消息缓冲服务) RTD云端
运行FAAP测试软件 协议转换+转发 FaapProxyClient 本地缓冲+可靠投递 中央数据库
│ │ │ │ │
│ gRPC 一元调用 │ gRPC Server Stream │ gRPC 一元调用 │ gRPC over HTTPS │
├─────────────────────►├──────────────────────►├─────────────────────►├───────────────────►│
│ │ │ │ │
│ AddTestPoint │ FaapProxyReturnMsg │ AddTestPointData │ AddTestPointData │
│ AddAuxiliaryData │ (oneof 消息流) │ InitiateTestSession │ 120秒超时 │
│ FinalizeSequence │ │ FinalizeTestSession │ 失败则缓存重发 │
关键特点:
- DUT 边测边发,整条链路是实时流式的
- FaapProxyClient → MBS 和 MBS → RTD 云端使用完全相同的 Proto 接口(MBS 是透明代理)
- MBS 提供断网保护:本地 SQLite 缓存 + 自动重发
二、代码仓库说明
按数据流顺序排列:DUT → FaapProxy → PC 客户端 → MBS → RTD 云端
2.1 Raptor2.MS.FaapProxy(FaapProxy 服务端)
位置:powerMeter/Raptor2.MS.FaapProxy/Source/
中间代理服务,接收 DUT 数据并通过 gRPC Server Streaming 推送给 PC 客户端。
Source/
├── Program.cs ← 入口
├── Startup.cs ← 服务启动配置
├── appsettings.json ← 配置
├── Services/
│ ├── FaapProxy.cs ← ★ 核心:队列 → gRPC 流推送给 PC(InitializeTestAsync)
│ ├── DutTestDataMessageProxy.cs ← V0:接收 DUT 测试数据(AddTestPointMessage 等)
│ ├── DutTestDataServiceV1.cs ← V1:接收 DUT 测试数据(AddTestPoint + 校验 + 版本兼容)
│ ├── ControlService.cs / V1 ← 测试流程控制
│ ├── SampleBasedTestServiceV1.cs ← SBT 采样测试
│ ├── DownloadFileServiceV1.cs ← DUT 文件下载
│ ├── DutCtrlServiceProxyV1.cs ← DUT 控制代理
│ ├── PsuServiceV1.cs ← 电源控制
│ ├── RxPwrServiceV1.cs ← 接收功率测量
│ └── ... (40+ 其他服务代理)
├── Clients/ ← gRPC 客户端(连接 DUT)
├── SupportComponents/
│ └── FaapProxyCache.cs ← DUT IP → 缓存项(SessionId、FilterAttributes等)
├── Interface/ ← 接口定义
└── Extensions/ ← 扩展方法
2.2 FaapProxyClient(PC 客户端)
位置:FaapProxyClient/Source/
WinForms 应用,接收 FaapProxy 推送的测试数据,转发到 MBS。
Source/
├── Program.cs ← 入口,DI 注册,gRPC 客户端配置
├── FaapProxyReturnMessageHandler.cs ← 核心:接收消息流 + 分发处理 + RTD转发
├── DataConversion.cs ← 数据解析(DataPoint → 可读字符串)
├── MainForm.cs ← WinForms UI
├── Handlers/
│ ├── ServiceHandler.cs ← 服务发现(查 MBS 地址)
│ └── PsuHandler.cs ← PSU 电源处理
├── Services/
│ └── SampleBaseTestService.cs ← SBT 采样测试服务
├── SupportComponents/
│ ├── SettingsForm.cs ← 设置界面
│ └── FactoryCodeHelper.cs ← 工厂代码帮助类
├── Models/ ← 数据模型
└── appsettings.json ← 客户端配置
2.3 Raptor2.RTDMessageBufferService(MBS)
位置:Raptor2.RTDMessageBufferService/Source/
消息缓冲服务,负责数据从 PC 客户端到 RTD 云端的可靠传输。
Source/
├── Program.cs ← 入口,配置 DI、gRPC 服务注册
├── Startup.cs ← 服务启动配置
├── appsettings.json ← 端点配置(地址、开关、缓存策略)
├── Services/
│ ├── TestResultMessageServiceImplV1.cs ← 接收 PC gRPC 调用(入口)
│ ├── RTDMessageHandlingService.cs ← 并发转发到云端(步骤 2)
│ ├── CacheMessageHandlingService.cs ← 缓存消息重发(断网恢复后)
│ ├── CacheMessagePersistenceService.cs ← 失败消息持久化到 SQLite
│ ├── CleaningService.cs ← 过期数据自动清理(8小时)
│ ├── HeaderMessageHandlingService.cs ← V0 Header 处理
│ ├── FooterMessageHandlingService.cs ← V0 Footer 处理
│ ├── TestPointMessageHandlingService.cs ← V0 TestPoint 处理
│ ├── AuxiliaryDataMessageHandlingService.cs ← V0 Auxiliary 处理
│ ├── V1/
│ │ ├── TestPointMessageHandlingServiceV1.cs ← V1 TestPoint(数据增强+持久化)
│ │ ├── AuxiliaryDataMessageHandlingServiceV1.cs ← V1 Auxiliary
│ │ └── FooterMessageHandlingServiceV1.cs ← V1 Footer
│ ├── Configuration/ ← 动态配置相关
│ ├── CalibrationData/ ← 校准数据服务
│ ├── TestEquipmentLog/ ← 测试设备日志
│ └── Opentelemetry/ ← 可观测性(指标/链路追踪/日志)
├── Helper/
│ ├── GRpcClientCall.cs ← gRPC 调用封装(路由+实际调用)
│ ├── EndPointOptions.cs ← 端点配置模型
│ ├── Configuration/ ← MBSConfigurationHistory 动态配置
│ ├── DBContextHelper.cs ← SQLite 重试帮助类
│ ├── MessageIndicator.cs ← 消息计数/seqid 管理
│ ├── RTDMessageConverter.cs ← V0/V1 消息转换
│ ├── ProductFamilyHelper.cs ← 产品族推断
│ └── TptagDuplicationHandler.cs ← 重复测试点处理
├── MessageChannel/ ← Channel 管道接口和实现
├── DBModels/ ← SQLite 数据模型(EF Core)
└── RTD2MI/ ← RTD 到 MI 的兼容层
2.4 Proto 接口定义(共享契约)
位置:production/(独立 git 仓库)
所有组件共享的 Proto 接口契约,不可随意修改。
production/
├── protos/ ← V0 版本(扁平结构)
│ ├── service_db_result.proto ← V0 测试结果服务
│ ├── service_db_logging.proto ← 日志服务
│ ├── calibration_data.proto ← 校准数据
│ └── ...
├── src/proto/production/ ← V1 版本(分层结构)
│ ├── db/result/v1/
│ │ └── service_db_result.proto ← ★ V1 测试结果服务(MBS→云端核心)
│ ├── db/result_query/v1/ ← 结果查询
│ ├── db/calibration_data/v1/ ← 校准数据
│ ├── db/test_equipment_log/v1/ ← 测试设备日志
│ ├── dut/result/v1/
│ │ └── result_service.proto ← ★ DUT → FaapProxy 接口
│ ├── test/data/v1/
│ │ └── data.proto ← ★ 数据消息定义(TestPointDataMessage等)
│ └── util/ ← 通用类型(SessionId、Data等)
└── third_party/ ← 第三方 proto(google/rpc 等)
2.5 tcpe_proto(Proto NuGet 包源码)
位置:powerMeter/tcpe_proto/Source/
C# 项目引用的 Proto 接口包的源码,包含 FaapProxy 的 proto 定义和 RTD 接口抽象。
tcpe_proto/Source/
├── Protos/
│ └── MeasurementServices/
│ ├── Services/
│ │ └── service_ms_faap_proxy.proto ← FaapProxy gRPC 服务定义
│ └── Messages/
│ └── faap_proxy.proto ← FaapProxyReturnMessage、InitializeTestRequest 等
├── TestData/
│ └── Interfaces/
│ ├── ITestDataResultV1.cs ← V1 RTD 接口(PC 调用 MBS 的抽象)
│ └── ITestDataResult.cs ← V0 RTD 接口
└── ...
2.6 Python gRPC 模拟环境
位置:python_grpc/strict_pipeline/
用 Python 模拟整条链路,方便独立测试(不需要实际 DUT 和硬件):
strict_pipeline/
├── dut_client.py ← 模拟 DUT 发送测试数据
├── faap_proxy_server.py ← 模拟 FaapProxy 代理
├── pc_client.py ← 模拟 PC 客户端
└── rtd_mbs_server.py ← 模拟 MBS 接收
三、第一段链路:DUT → FaapProxy(中间代理)
3.1 通信方式
DUT(被测设备)通过 gRPC 一元调用(Unary RPC)逐条发送测试数据到 FaapProxy。
Proto 定义:production/src/proto/production/dut/result/v1/result_service.proto
| RPC 方法 | 作用 |
|---|---|
AddTestPoint |
发送一个测试点数据(测量值 + Pass/Fail + 限值) |
AddAuxiliaryData |
发送辅助数据(温度/电压/电流等) |
AddDataPointGroup |
发送数据点分组 |
GetSeqIds |
批量预取序列号(V1 新增) |
3.2 FaapProxy 收到数据后做什么
- 通过 DUT IP 查缓存 — 从
context.Peer获取 DUT 的 IP 地址,查找对应的缓存项(SessionId、FilterAttributes、DutPosition 等) - 补充 FilterAttributes — 工厂代码、产品族等信息从缓存获取,附加到消息上
- V1 校验 SessionId — V1 版本增加了 SessionId 非空校验,为空返回 InvalidArgument
- 版本兼容处理 — 根据 PC 客户端声明的
SupportedMessages,决定发 V1 格式还是降级为 V0 - 写入消息队列 — 按 DutPosition 隔离的 Channel 队列(生产者-消费者模式)
3.3 关键设计
- DUT 边测边发,不是测完才传,整条链路实时流式
- FaapProxy 本质是透传代理,不做业务层面的数据校验
- 按 DutPosition 隔离队列,支持多 DUT 并行测试
- 用 DUT IP 作为缓存 key,缓存会话信息供后续 RPC 使用
四、第二段链路:FaapProxy → PC 客户端(FaapProxyClient)
4.1 通信方式
PC 客户端通过 gRPC Server Streaming(服务端流式)持续接收 FaapProxy 推送的数据。
Proto 定义:powerMeter/tcpe_proto/Source/Protos/MeasurementServices/Services/service_ms_faap_proxy.proto
| RPC 方法 | 类型 | 作用 |
|---|---|---|
InitializeTestAsync |
Server Streaming | PC 发起调用,FaapProxy 持续推送消息流 |
ReleaseResources |
Unary | 释放锁定的资源 |
GetSampleTestResults |
Unary | 获取 SBT 采样测试结果汇总 |
4.2 建立连接流程
PC 客户端调用 InitializeTestAsync 时发送 InitializeTestRequest,包含:
- SessionId(序列号 + UTC 时间戳)
- DUT IP、产品号、R-State
- FilterAttributes(工厂代码 + 产品族)
- FilesToDownload(最多 4 个数据库文件的字节内容)
- SupportedMessages(声明客户端能处理哪些消息类型)
- TestCategory、PowerCoupling、ExecutionMode 等
FaapProxy 收到后:
- 缓存 DUT 信息(IP、SessionId、支持的消息类型等)
- 发送
FaapProxyServerStarted通知 - 进入持续推送循环 — 从队列读取消息,通过 gRPC 流写给 PC
4.3 推送的消息类型(FaapProxyReturnMessage,oneof)
| 字段 | 消息类型 | 说明 |
|---|---|---|
test_point |
TestPointDataMessage (V0) | 旧版测试点数据 |
test_point_v1 |
TestPointDataMessage (V1) | 新版测试点数据 |
auxiliary |
AuxiliaryDataMessage (V0) | 旧版辅助数据 |
auxiliary_v1 |
AuxiliaryDataMessage (V1) | 新版辅助数据 |
data_point_group |
DataPointGroupMessage (V0) | 旧版数据点组 |
data_point_group_v1 |
DataPointGroupMessage (V1) | 新版数据点组 |
sequence_finalized |
TerminateTest | 测试序列完成 |
runtime_error |
ClientRuntimeError | 运行时错误 |
faap_still_alive |
FaapStillAlive | 心跳/看门狗 |
faap_proxy_server_started |
FaapProxyServerStarted | 服务端就绪通知 |
4.4 PC 客户端收到消息后做什么
收到消息 → 按 MsgCase 分发:
├── TestPoint/TestPointV1 → 解析数据 → 控制台输出(Pass绿/Fail红)→ 写本地文件 → 可选转发到 MBS
├── Auxiliary/AuxiliaryV1 → 解析数据 → 控制台输出 → 可选转发到 MBS
├── DataPointGroup/V1 → 日志记录 → 可选转发到 MBS
├── SequenceFinalized → 计数器 → 可选自动结束会话
├── RuntimeError → 仅日志
└── FaapStillAlive/ServerStarted → 仅日志
4.5 关键设计
- 底层基于 HTTP/2 长连接,服务端有数据就推,PC 端实时收到,无轮询
- PC 客户端用异步队列(
System.Threading.Channels)解耦数据接收和 RTD 转发 - 主线程收消息放队列(不阻塞),后台 Task 从队列消费并转发到 MBS
- 会话遵循 Header → Data Stream → Footer 三段式协议
五、第三段链路:PC 客户端 → MBS(本地 gRPC 调用)
5.1 通信方式
PC 客户端通过 gRPC 一元调用发送到本地 MBS(localhost:58766),使用的接口和 MBS → 云端完全相同。
Proto 定义:production/src/proto/production/db/result/v1/service_db_result.proto(同一套)
5.2 调用时序
测试开始 → InitiateTestSession(发送 HeaderMessage)
测试进行 → AddTestPointData / AddAuxiliaryData / AddDataPointGroup(从队列逐条消费)
测试结束 → FinalizeTestSession(发送 FooterMessage,先等队列排空最多 10 秒)
5.3 服务发现
PC 客户端不硬编码 MBS 端口,而是通过 ServiceManager 动态查询 "TestResultMessageService" 的实际运行地址。
5.4 重试策略
- 最多重试 5 次
- 指数退避:1s → 1.5s → 2.25s → 3.375s → 5s(最大)
- 仅对
StatusCode.Unavailable重试
六、第四段链路:MBS 内部处理 + 转发到 RTD 云端(三步)
6.1 MBS 接收入口
TestResultMessageServiceImplV1 接收 PC 客户端的 gRPC 调用,将消息写入对应的 Channel:
| PC 调用的 RPC | MBS 写入的 Channel |
|---|---|
| InitiateTestSession | _initiateTestSessionChannel |
| AddTestPointData | _testPointDataChannel |
| AddAuxiliaryData | _auxiliaryDataChannel |
| AddDataPointGroup | _dataPointGroupChannel |
| FinalizeTestSession | _footerChannel |
6.2 三步转发流程
步骤 1: TestPointMessageHandlingServiceV1(数据增强 + 持久化)
- 从输入 Channel 读取
- 补充 seqid、Duration、FilterAttributes、Repetition、Property、Tcnr
- 持久化到本地 SQLite(断网保护)
- 包装为 Request 写入输出 Channel
↓
步骤 2: RTDMessageHandlingService(并发转发)
- 从输出 Channel 读取,最多 20 并发发送
- 为每个请求创建 DI Scope(资源隔离)
- 调用 GRpcClientCall.PerformGRpcCall
- 失败 → 序列化为 byte[] → 写入缓存 Channel
↓
步骤 3: GRpcClientCall(实际 gRPC 调用)
- 根据消息类型查字典找到对应处理函数
- GetTransportConfigurationPerSession 获取端点配置 + headers
- 遍历所有启用的端点
- 用 GrpcClientFactory 创建 gRPC Stub
- 调用云端 RPC(带 120 秒超时 + 自定义 headers)
- 返回状态码:0=成功,非0=失败
↓
RTD 云端 (https://apigw.radiounits-realtimetestdata.ericsson.net:9443)
6.3 失败重发路径
步骤 2 发送失败
→ sendtoCache = true
→ 序列化为 RTDMessage(messageType, byte[])
→ 写入 CacheRTDMessageChannel
↓
CacheMessagePersistenceService(后台服务)
→ 从缓存 Channel 读取
→ 持久化到 SQLite 的 rtd_messages 表
↓
SQLite(本地持久化)
↓ (网络恢复后)
CacheMessageHandlingService(后台服务)
→ 定期扫描 SQLite 中未发送的消息
→ 反序列化 byte[] → protobuf 对象
→ 调用 GRpcClientCall.PerformGRpcCall(byte[] 版本)
→ 成功后从 SQLite 删除
↓
RTD 云端 → 成功
6.4 GRpcClientCall 两个重载
PerformGRpcCall(string, IMessage, sp) |
PerformGRpcCall(string, byte[], sp) |
|
|---|---|---|
| 输入 | protobuf 对象(活对象) | byte[] 字节(从 SQLite 读出) |
| 谁调用 | RTDMessageHandlingService(实时) | CacheMessageHandlingService(重发) |
| 反序列化 | 不需要,直接 as 强转 | 需要 Parser.ParseFrom(bytes) |
| 端点过滤 | 检查 Enabled |
检查 CacheEnabled |
七、关键配置
7.1 MBS 端点配置(appsettings.json)
文件:Raptor2.RTDMessageBufferService/Source/appsettings.json
{
"EndPointInfos": [
{
"Enabled": true, // 是否启用
"CacheEnabled": true, // 失败是否缓存重发
"EndPointName": "TestDataV1Endpoint",
"gRpcClient": "Proto.Production.Db.Result.V1.TestResultMessageService.TestResultMessageServiceClient",
"Url": "https://apigw.radiounits-realtimetestdata.ericsson.net:9443"
}
]
}
7.2 重要地址
| 地址 | 用途 | 状态 |
|---|---|---|
https://apigw.radiounits-realtimetestdata.ericsson.net:9443 |
RTD 生产环境 | 启用 |
https://apigw-dev.radiounits-realtimetestdata.ericsson.net:9443 |
RTD 开发环境 | 注释掉 |
http://rtd-u.kroto075.rnd.gic.ericsson.se:31103 |
沙箱环境 | Enabled=false |
http://kroto075.rnd.gic.ericsson.se:4317 |
OpenTelemetry 收集器 | 启用 |
localhost:58766 |
MBS 本地 gRPC 监听端口 | — |
7.3 关键参数
- gRPC 调用超时:120 秒
- 并发发送上限:20 路
- 客户端重试策略:5 次,指数退避 1s→5s,仅 Unavailable 状态码
- 过期数据清理:8 小时
- SQLite 模式:WAL(高并发写入不阻塞)
八、云端 gRPC 接口(Proto 定义)
MBS 调用 RTD 云端的核心 RPC(定义在 service_db_result.proto V1):
| RPC 方法 | 作用 | 调用时机 |
|---|---|---|
InitiateTestSession |
开始测试会话 | 测试开始时发一次 |
AddTestPointData |
发送测试点数据 | 每个测试点发一次 |
AddAuxiliaryData |
发送辅助数据 | 有辅助数据时发 |
AddDataPointGroup |
发送数据点组 | 批量数据时发 |
FinalizeTestSession |
结束测试会话 | 测试结束时发一次 |
每个 RPC 的返回都是 google.rpc.Status:Code=0 成功,非0 失败。 |
九、GRpcClientCall.cs 两个重载的区别(补充)
PerformGRpcCall(string, IMessage, sp) |
PerformGRpcCall(string, byte[], sp) |
|
|---|---|---|
| 输入 | protobuf 对象(活对象) | byte[] 字节数组(从数据库读出) |
| 谁调用 | RTDMessageHandlingService(实时发送) | CacheMessageHandlingService(缓存重发) |
| 反序列化 | 不需要 | 内部 Parser.ParseFrom(bytes) |
| 端点过滤 | 检查 endPoint.Enabled |
检查 endPoint.CacheEnabled |
十、各后台服务职责速查
| 服务 | 职责 |
|---|---|
TestResultMessageServiceImplV1 |
接收 PC 的 gRPC 调用,写入对应 Channel |
TestPointMessageHandlingServiceV1 |
从 Channel 读取 → 数据增强 → SQLite 持久化 → 写入输出 Channel |
AuxiliaryDataMessageHandlingServiceV1 |
同上,处理辅助数据 |
FooterMessageHandlingServiceV1 |
同上,处理 Footer |
RTDMessageHandlingService |
从输出 Channel 读取 → 20 并发转发到云端 → 失败写缓存 |
CacheMessagePersistenceService |
从缓存 Channel 读取 → 持久化到 SQLite |
CacheMessageHandlingService |
定期扫描 SQLite 未发送消息 → 反序列化 → 重新发送 |
CleaningService |
定期清理超过 8 小时的过期会话数据 |
LocalMessagePersistenceService |
本地消息存储管理 |
十一、FaapProxyClient 数据处理流程
11.1 会话生命周期
启动 → 服务发现(查 MBS 地址)→ 建立 gRPC 连接
→ 发送 RTD Header(InitiateTestSession)
→ 发起 Server Streaming 调用(InitializeTestAsync)
→ 持续接收消息流 → 按类型分发处理 → 可选转发到 MBS
→ 测试结束 → 发送 RTD Footer(FinalizeTestSession)
11.2 数据的三个输出去向
- 控制台:始终输出,Pass 绿色 / Fail 红色
- 本地文件:JSON 序列化 + TXT 追加
- RTD 云端:通过异步队列 → MBS 本地代理 → 云端
11.3 RTD 转发机制
主线程收到消息 → 写入 _rtdMessageQueue(不阻塞)→ 后台 Task 消费 → 调用 ITestDataResultV1 的对应方法 → MBS 接收
十二、常见问题排查
问题 1:数据没发到云端
排查步骤:
- 检查 MBS 进程是否在运行(
Ericsson.Raptor2.RTDMessageBufferService) - 检查
appsettings.json中对应端点的Enabled是否为true - 检查网络是否能访问
apigw.radiounits-realtimetestdata.ericsson.net:9443 - 查看 MBS 日志,搜索 "status code" 或 "exception"
- 检查 SQLite 缓存中是否有堆积的未发送消息
问题 2:数据发了但云端查不到
排查步骤:
- 确认 Header 中的
FilterAttributes非空(产品族、工厂代码) - 确认没有 "NOT_INTENDED_FOR_RTD" 标记
- 检查是否发了 Footer(FinalizeTestSession),云端可能要等 Footer 才可查询
- 确认 SessionId 格式正确(序列号 + UTC 时间戳)
问题 3:MBS 日志报 gRPC 超时
可能原因:
- 网络不稳定或 VPN 问题
- 云端负载高导致响应慢
- 当前超时设置为 120 秒,如果一直超时说明网络有问题
- 失败的消息会自动缓存,网络恢复后自动重发,不会丢
问题 4:切换到沙箱环境测试
修改 appsettings.json:
- 把生产端点的
Enabled设为false - 把沙箱端点(
TestDataEndpointSandbox)的Enabled设为true - 或直接修改
Url字段指向沙箱地址
十三、开发环境信息
- IDE:Visual Studio / VS Code
- 语言:C# (.NET 6+)
- 构建:
dotnet build - 解决方案文件:
- MBS:
Raptor2.RTDMessageBufferService/Source/Ericsson.Raptor2.RTDMessageBufferService.sln - PC Client:
FaapProxyClient/Source/FaapProxyClient.sln
- MBS:
- NuGet 源:见各项目的
nuget.config - Proto 编译:Proto 文件由 NuGet 包提供编译后的 C# 代码,不需要本地 protoc 编译
- 部署路径(测试站):
C:\TestStation\Raptor2RTDMessageBufferService\
十四、相关文档索引
| 文档 | 内容 |
|---|---|
MBS到RTD_三步链路代码详解.md |
MBS 内部三步转发的详细代码分析 |
MBS到RTD云端_完整流程图.md |
完整的架构图和流程图 |
FAAP_Report_数据处理流程学习汇报.md |
DUT → FaapProxy → PC 的完整数据流分析 |
FaapProxyClient到RTD数据传输详解.md |
PC 客户端到 RTD 的两跳传输详解 |
工作总结_求职简历参考.md |
个人工作总结(非交接用) |
十五、注意事项
- Proto 文件不要随意修改 — 它是多方共享的接口契约,修改需要协调 DUT 端、FaapProxy、PC 客户端、MBS、RTD 云端等多方
- appsettings.json 改完注意重启 MBS — 虽然有动态配置(MBSConfigurationHistory),但端点配置的变更通常需要重启
- SQLite 数据库文件 — 在
./temp/testrtd.db,如果磁盘满了可以手动清理 - V0 和 V1 同时存在 — 系统同时支持旧版(V0)和新版(V1)协议,新开发优先用 V1
- Python 模拟环境 —
python_grpc/strict_pipeline/可以不连实际设备,独立模拟测试整条链路

浙公网安备 33010602011771号