# 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 { 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 Parse(string line, int lineNumber, Guid logFileId) { var match = PlossPattern.Match(line); if (!match.Success) { return ParseResult.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.Success(record); } catch (Exception ex) { return ParseResult.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 | 高功率允许更多损耗 |