165 lines
4.9 KiB
Markdown
165 lines
4.9 KiB
Markdown
|
|
# Ploss 解析器
|
|||
|
|
|
|||
|
|
> 所属模块:[解析器设计](./概览.md)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 日志格式
|
|||
|
|
|
|||
|
|
**格式:** `FOD-> (1) X X X (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)`
|
|||
|
|
|
|||
|
|
**示例:** `FOD-> 4 2 1 127 10690 12013 35377 9904 1213 -2882 750 0 0 1 500 1`
|
|||
|
|
|
|||
|
|
> 括号数字表示有效字段编号,X 表示忽略该位置数据
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 字段定义
|
|||
|
|
|
|||
|
|
| 编号 | 字段名称 | 数据类型 | 说明 |
|
|||
|
|
|------|----------|----------|------|
|
|||
|
|
| (1) | RxType | byte | 接收端类型标识 |
|
|||
|
|
| (2) | RxPower | short | 接收端功率(mW) |
|
|||
|
|
| (3) | TxPower | short | 发射端功率(mW) |
|
|||
|
|
| (4) | Vcoil | short | 发射线圈电压 |
|
|||
|
|
| (5) | Vin | short | 输入电压 |
|
|||
|
|
| (6) | Isns | short | 输入电流采样值 |
|
|||
|
|
| (7) | Ploss | int | **核心值**:计算损耗(负数表示安全) |
|
|||
|
|
| (8) | Threshold | int | **安全红线**:当前功率段阈值 |
|
|||
|
|
| (9) | TriggerCount | short | 触发计数器 |
|
|||
|
|
| (10) | FodResult | short | FOD判定结果状态 |
|
|||
|
|
| (11) | ProtocolType | byte | 充电协议类型 |
|
|||
|
|
| (12) | PwmDuty | short | PWM控制占空比 |
|
|||
|
|
| (13) | CoilIndex | byte | 充电线圈索引 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 正则表达式
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Parsers/PlossParser.cs
|
|||
|
|
private static readonly Regex PlossPattern = new(
|
|||
|
|
@"^FOD->\s+(\d+)\s+\d+\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(-?\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$",
|
|||
|
|
RegexOptions.Compiled
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**捕获组映射:**
|
|||
|
|
|
|||
|
|
| 捕获组 | 字段 | 类型转换 |
|
|||
|
|
|--------|------|----------|
|
|||
|
|
| Group 1 | RxType | byte.Parse() |
|
|||
|
|
| Group 2 | RxPower | short.Parse() |
|
|||
|
|
| Group 3 | TxPower | short.Parse() |
|
|||
|
|
| Group 4 | Vcoil | short.Parse() |
|
|||
|
|
| Group 5 | Vin | short.Parse() |
|
|||
|
|
| Group 6 | Isns | short.Parse() |
|
|||
|
|
| Group 7 | Ploss | int.Parse() |
|
|||
|
|
| Group 8 | Threshold | int.Parse() |
|
|||
|
|
| Group 9 | TriggerCount | short.Parse() |
|
|||
|
|
| Group 10 | FodResult | short.Parse() |
|
|||
|
|
| Group 11 | ProtocolType | byte.Parse() |
|
|||
|
|
| Group 12 | PwmDuty | short.Parse() |
|
|||
|
|
| Group 13 | CoilIndex | byte.Parse() |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 解析器实现
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Parsers/PlossParser.cs
|
|||
|
|
using System.Text.RegularExpressions;
|
|||
|
|
using WCTDataMiner.Models;
|
|||
|
|
|
|||
|
|
namespace WCTDataMiner.Parsers;
|
|||
|
|
|
|||
|
|
public class PlossParser : IParser<PlossRecord>
|
|||
|
|
{
|
|||
|
|
private static readonly Regex PlossPattern = new(
|
|||
|
|
@"^FOD->\s+(\d+)\s+\d+\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(-?\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$",
|
|||
|
|
RegexOptions.Compiled
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
public bool CanParse(string line) => PlossPattern.IsMatch(line);
|
|||
|
|
|
|||
|
|
public ParseResult<PlossRecord> Parse(string line, int lineNumber, Guid logFileId)
|
|||
|
|
{
|
|||
|
|
var match = PlossPattern.Match(line);
|
|||
|
|
if (!match.Success)
|
|||
|
|
{
|
|||
|
|
return ParseResult<PlossRecord>.Failure(
|
|||
|
|
"FORMAT_MISMATCH",
|
|||
|
|
"Line does not match Ploss pattern"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var record = new PlossRecord
|
|||
|
|
{
|
|||
|
|
LogFileId = logFileId,
|
|||
|
|
LineNumber = lineNumber,
|
|||
|
|
RxType = byte.Parse(match.Groups[1].Value),
|
|||
|
|
RxPower = short.Parse(match.Groups[2].Value),
|
|||
|
|
TxPower = short.Parse(match.Groups[3].Value),
|
|||
|
|
Vcoil = short.Parse(match.Groups[4].Value),
|
|||
|
|
Vin = short.Parse(match.Groups[5].Value),
|
|||
|
|
Isns = short.Parse(match.Groups[6].Value),
|
|||
|
|
Ploss = int.Parse(match.Groups[7].Value),
|
|||
|
|
Threshold = int.Parse(match.Groups[8].Value),
|
|||
|
|
TriggerCount = short.Parse(match.Groups[9].Value),
|
|||
|
|
FodResult = short.Parse(match.Groups[10].Value),
|
|||
|
|
ProtocolType = byte.Parse(match.Groups[11].Value),
|
|||
|
|
PwmDuty = short.Parse(match.Groups[12].Value),
|
|||
|
|
CoilIndex = byte.Parse(match.Groups[13].Value)
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return ParseResult<PlossRecord>.Success(record);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
return ParseResult<PlossRecord>.Failure(
|
|||
|
|
"TYPE_CONVERSION",
|
|||
|
|
$"Failed to convert field: {ex.Message}"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 核心判定逻辑
|
|||
|
|
|
|||
|
|
### 5.1 FOD 触发条件
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
if (Ploss > Threshold) → 计数器累积
|
|||
|
|
if (Count > Limit) → 触发 FOD 报警,停止充电
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 安全余量计算
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 派生属性(不落库)
|
|||
|
|
Margin = Threshold - Ploss
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
| Margin 状态 | 含义 |
|
|||
|
|
|-------------|------|
|
|||
|
|
| Margin > 0 | 安全,损耗低于阈值 |
|
|||
|
|
| Margin < 0 | 危险,损耗超过阈值,可能触发 FOD |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. 动态阈值表
|
|||
|
|
|
|||
|
|
阈值根据接收功率动态查表:
|
|||
|
|
|
|||
|
|
| 接收功率区间 (Rx Power) | 阈值 (Threshold) | 备注 |
|
|||
|
|
|------------------------|------------------|------|
|
|||
|
|
| 0 ~ 5W (0-5000 mW) | 350 mW | 低功率最敏感 |
|
|||
|
|
| 5 ~ 10W (5000-10000 mW) | 500 mW | |
|
|||
|
|
| 10 ~ 15W (10000-15000 mW) | 750 mW | |
|
|||
|
|
| 15 ~ 30W (15000-30000 mW) | 1000 mW | 示例 Log 处于此区间 |
|
|||
|
|
| 30 ~ 50W (30000-50000 mW) | 1250 mW | 高功率允许更多损耗 |
|