refactor(ploss): 统一字段语义 Field9=ploss Field10=threshold
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,34 +8,44 @@
|
||||
|
||||
**表名**:`ploss_record`
|
||||
|
||||
**描述**:存储 Ploss FOD 格式解析数据,对应日志格式 `FOD-> (1)...(13)`
|
||||
**描述**:存储 Ploss FOD 格式解析数据,对应两行日志格式:
|
||||
|
||||
```
|
||||
pow_loss = X, delta_p = Y
|
||||
FOD-> (1) (2) ... (16)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 字段定义
|
||||
|
||||
> **类型修正说明**:需求文档中 rx_power, tx_power, vcoil, vin, isns, pwm_duty 为 `uint16`(0-65535),但 SQLite 不支持无符号类型。实际数据如 vcoil=35377 超出了 SMALLINT(-32768~32767)范围,因此这些字段使用 INT 类型存储。
|
||||
|
||||
| 列名 | 类型 | 约束 | 说明 |
|
||||
|------|------|------|------|
|
||||
| id | UUID | PK, NOT NULL | 主键 |
|
||||
| scenario_id | UUID | FK, NOT NULL | 关联测试场景 |
|
||||
| rx_type | TINYINT | NOT NULL | 接收端类型标识 |
|
||||
| rx_power | INT | NOT NULL | 接收端功率(mW),原 uint16 |
|
||||
| tx_power | INT | NOT NULL | 发射端功率(mW),原 uint16 |
|
||||
| vcoil | INT | NOT NULL | 发射线圈电压,原 uint16 |
|
||||
| vin | INT | NOT NULL | 输入电压,原 uint16 |
|
||||
| isns | INT | NOT NULL | 输入电流采样值,原 uint16 |
|
||||
| ploss | INT | NOT NULL | **核心值**:计算损耗(负数=安全) |
|
||||
| threshold | INT | NOT NULL | **安全红线**:当前功率段阈值 |
|
||||
| trigger_count | INT | NOT NULL, DEFAULT 0 | 触发计数器 |
|
||||
| fod_result | INT | NOT NULL, DEFAULT 0 | FOD判定结果 |
|
||||
| protocol_type | TINYINT | NOT NULL | 充电协议类型 |
|
||||
| pwm_duty | INT | NOT NULL | PWM占空比,原 uint16 |
|
||||
| coil_index | TINYINT | NOT NULL | 充电线圈索引 |
|
||||
| pow_loss | INT | NULL | 第一行:功率损耗值 |
|
||||
| delta_p | INT | NULL | 第一行:功率差值 |
|
||||
| field_1 | INT | NOT NULL | Field1(语义待定义) |
|
||||
| field_2 | INT | NOT NULL | Field2(语义待定义) |
|
||||
| field_3 | INT | NOT NULL | Field3(语义待定义) |
|
||||
| field_4 | INT | NOT NULL | Field4: RX power - 接收端功率 |
|
||||
| field_5 | INT | NOT NULL | Field5: TX power - 发射端功率 |
|
||||
| field_6 | INT | NOT NULL | Field6(语义待定义) |
|
||||
| field_7 | INT | NOT NULL | Field7(语义待定义) |
|
||||
| field_8 | INT | NOT NULL | Field8(语义待定义) |
|
||||
| field_9 | INT | NOT NULL, DEFAULT 0 | Field9: ploss - 功率损耗计算值 |
|
||||
| field_10 | INT | NOT NULL, DEFAULT 0 | Field10: threshold - 阈值 |
|
||||
| field_11 | INT | NOT NULL | Field11: 触发次数 - 当 Field9 > Field10 时计数,超过5次触发FOD保护 |
|
||||
| field_12 | INT | NOT NULL | Field12: PFOD result 标志 - 触发时置位 |
|
||||
| field_13 | INT | NOT NULL, DEFAULT 0 | Field13(语义待定义) |
|
||||
| field_14 | INT | NOT NULL, DEFAULT 0 | Field14(语义待定义) |
|
||||
| field_15 | INT | NOT NULL, DEFAULT 0 | Field15(语义待定义) |
|
||||
| field_16 | INT | NOT NULL, DEFAULT 0 | Field16(语义待定义) |
|
||||
| is_deleted | BOOLEAN | NOT NULL, DEFAULT FALSE | 软删除标记 |
|
||||
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW() | 创建时间 |
|
||||
|
||||
> **字段语义**以 `PlossRecord` 实体注释为准。
|
||||
|
||||
---
|
||||
|
||||
## 3. 外键
|
||||
@@ -52,9 +62,9 @@
|
||||
|
||||
| 字段 | 计算公式 | 说明 |
|
||||
|------|----------|------|
|
||||
| margin | threshold - ploss | 安全余量(>0 安全,<0 危险) |
|
||||
| margin | field_10 - field_9 | 安全余量(>0 安全,<0 危险) |
|
||||
|
||||
> **使用限制**:`Margin` 属性通过 EF Core `Ignore()` 排除映射,仅用于内存计算。不可在数据库查询中直接使用(如 `WHERE Margin > 0`),需改用 `WHERE (threshold - ploss) > 0` 或先加载到内存再计算。
|
||||
> **使用限制**:`Margin` 属性通过 EF Core `Ignore()` 排除映射,仅用于内存计算。不可在数据库查询中直接使用(如 `WHERE Margin > 0`),需改用 `WHERE (field_10 - field_9) > 0` 或先加载到内存再计算。
|
||||
|
||||
---
|
||||
|
||||
@@ -63,10 +73,12 @@
|
||||
| 索引名 | 字段 | 用途 |
|
||||
|--------|------|------|
|
||||
| idx_ploss_scenario | scenario_id | 按测试场景查询 |
|
||||
| idx_ploss_rx_power | rx_power | 阈值表匹配 |
|
||||
| idx_ploss_ploss | ploss | 损耗值查询 |
|
||||
| idx_ploss_threshold | threshold | 阈值查询 |
|
||||
| idx_ploss_fod_result | fod_result | FOD结果筛选 |
|
||||
| idx_ploss_field_2 | field_2 | 字段查询 |
|
||||
| idx_ploss_field_7 | field_7 | 字段查询 |
|
||||
| idx_ploss_field_8 | field_8 | 字段查询 |
|
||||
| idx_ploss_field_10 | field_10 | 字段查询 |
|
||||
| idx_ploss_pow_loss | pow_loss | 第一行损耗值查询 |
|
||||
| idx_ploss_delta_p | delta_p | 第一行功率差值查询 |
|
||||
|
||||
---
|
||||
|
||||
@@ -75,51 +87,73 @@
|
||||
### 实体类
|
||||
|
||||
```csharp
|
||||
// Models/PlossRecord.cs
|
||||
namespace Gpulse.WCT.DataAnalyzer.Models;
|
||||
// Domain/Local/PlossRecord.cs
|
||||
namespace Gpulse.WCT.DataAnalyzer.Core.Domain.Local;
|
||||
|
||||
public class PlossRecord
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Guid ScenarioId { get; set; }
|
||||
public byte RxType { get; set; }
|
||||
public short RxPower { get; set; }
|
||||
public short TxPower { get; set; }
|
||||
public short Vcoil { get; set; }
|
||||
public short Vin { get; set; }
|
||||
public short Isns { get; set; }
|
||||
|
||||
/// <summary>核心判定值:负数表示安全</summary>
|
||||
public int Ploss { get; set; }
|
||||
// ===== 第一行字段(nullable,兼容旧数据) =====
|
||||
/// <summary>功率损耗值(来自第一行)</summary>
|
||||
public int? PowLoss { get; set; }
|
||||
|
||||
/// <summary>安全红线:当前功率段阈值</summary>
|
||||
public int Threshold { get; set; }
|
||||
/// <summary>功率差值(来自第一行)</summary>
|
||||
public int? DeltaP { get; set; }
|
||||
|
||||
// ===== 第二行字段(16个通用字段,均支持负数) =====
|
||||
public int Field1 { get; set; }
|
||||
public int Field2 { get; set; }
|
||||
public int Field3 { get; set; }
|
||||
|
||||
/// <summary>Field4: RX power - 接收端功率</summary>
|
||||
public int Field4 { get; set; }
|
||||
|
||||
/// <summary>Field5: TX power - 发射端功率</summary>
|
||||
public int Field5 { get; set; }
|
||||
|
||||
public int Field6 { get; set; }
|
||||
public int Field7 { get; set; }
|
||||
public int Field8 { get; set; }
|
||||
|
||||
/// <summary>Field9: ploss - 功率损耗计算值</summary>
|
||||
public int Field9 { get; set; }
|
||||
|
||||
/// <summary>Field10: threshold - 阈值</summary>
|
||||
public int Field10 { get; set; }
|
||||
|
||||
/// <summary>Field11: 触发次数 - 当 Field9 > Field10(ploss 大于阈值)时计数,超过5次触发FOD保护</summary>
|
||||
public int Field11 { get; set; }
|
||||
|
||||
/// <summary>Field12: PFOD result 标志 - 触发时置位</summary>
|
||||
public int Field12 { get; set; }
|
||||
|
||||
public int Field13 { get; set; }
|
||||
public int Field14 { get; set; }
|
||||
public int Field15 { get; set; }
|
||||
public int Field16 { get; set; }
|
||||
|
||||
public short TriggerCount { get; set; } = 0;
|
||||
public short FodResult { get; set; } = 0;
|
||||
public byte ProtocolType { get; set; }
|
||||
public short PwmDuty { get; set; }
|
||||
public byte CoilIndex { get; set; }
|
||||
public bool IsDeleted { get; set; } = false;
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Navigation Properties
|
||||
public TestScenario Scenario { get; set; } = null!;
|
||||
|
||||
/// <summary>派生属性:安全余量(不落库)</summary>
|
||||
public int Margin => Threshold - Ploss;
|
||||
/// <summary>派生属性:安全余量(不落库) = Field10 - Field9</summary>
|
||||
public int Margin => Field10 - Field9;
|
||||
}
|
||||
```
|
||||
|
||||
### 配置类
|
||||
|
||||
```csharp
|
||||
// Data/Configurations/PlossRecordConfiguration.cs
|
||||
// Infrastructure/LocalData/Configurations/PlossRecordConfiguration.cs
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Gpulse.WCT.DataAnalyzer.Models;
|
||||
using Gpulse.WCT.DataAnalyzer.Core.Domain.Local;
|
||||
|
||||
namespace Gpulse.WCT.DataAnalyzer.Data.Configurations;
|
||||
namespace Gpulse.WCT.DataAnalyzer.Core.Infrastructure.LocalData.Configurations;
|
||||
|
||||
public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||
{
|
||||
@@ -134,59 +168,27 @@ public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||
.IsRequired()
|
||||
.HasColumnName("scenario_id");
|
||||
|
||||
builder.Property(e => e.RxType)
|
||||
.IsRequired()
|
||||
.HasColumnName("rx_type");
|
||||
// ===== 第一行字段(nullable) =====
|
||||
builder.Property(e => e.PowLoss).IsRequired(false).HasColumnName("pow_loss");
|
||||
builder.Property(e => e.DeltaP).IsRequired(false).HasColumnName("delta_p");
|
||||
|
||||
builder.Property(e => e.RxPower)
|
||||
.IsRequired()
|
||||
.HasColumnName("rx_power");
|
||||
|
||||
builder.Property(e => e.TxPower)
|
||||
.IsRequired()
|
||||
.HasColumnName("tx_power");
|
||||
|
||||
builder.Property(e => e.Vcoil)
|
||||
.IsRequired()
|
||||
.HasColumnName("vcoil");
|
||||
|
||||
builder.Property(e => e.Vin)
|
||||
.IsRequired()
|
||||
.HasColumnName("vin");
|
||||
|
||||
builder.Property(e => e.Isns)
|
||||
.IsRequired()
|
||||
.HasColumnName("isns");
|
||||
|
||||
builder.Property(e => e.Ploss)
|
||||
.IsRequired()
|
||||
.HasColumnName("ploss");
|
||||
|
||||
builder.Property(e => e.Threshold)
|
||||
.IsRequired()
|
||||
.HasColumnName("threshold");
|
||||
|
||||
builder.Property(e => e.TriggerCount)
|
||||
.IsRequired()
|
||||
.HasDefaultValue((short)0)
|
||||
.HasColumnName("trigger_count");
|
||||
|
||||
builder.Property(e => e.FodResult)
|
||||
.IsRequired()
|
||||
.HasDefaultValue((short)0)
|
||||
.HasColumnName("fod_result");
|
||||
|
||||
builder.Property(e => e.ProtocolType)
|
||||
.IsRequired()
|
||||
.HasColumnName("protocol_type");
|
||||
|
||||
builder.Property(e => e.PwmDuty)
|
||||
.IsRequired()
|
||||
.HasColumnName("pwm_duty");
|
||||
|
||||
builder.Property(e => e.CoilIndex)
|
||||
.IsRequired()
|
||||
.HasColumnName("coil_index");
|
||||
// ===== 第二行字段(通用命名) =====
|
||||
builder.Property(e => e.Field1).IsRequired().HasColumnName("field_1");
|
||||
builder.Property(e => e.Field2).IsRequired().HasColumnName("field_2");
|
||||
builder.Property(e => e.Field3).IsRequired().HasColumnName("field_3");
|
||||
builder.Property(e => e.Field4).IsRequired().HasColumnName("field_4");
|
||||
builder.Property(e => e.Field5).IsRequired().HasColumnName("field_5");
|
||||
builder.Property(e => e.Field6).IsRequired().HasColumnName("field_6");
|
||||
builder.Property(e => e.Field7).IsRequired().HasColumnName("field_7");
|
||||
builder.Property(e => e.Field8).IsRequired().HasColumnName("field_8");
|
||||
builder.Property(e => e.Field9).IsRequired().HasDefaultValue(0).HasColumnName("field_9");
|
||||
builder.Property(e => e.Field10).IsRequired().HasDefaultValue(0).HasColumnName("field_10");
|
||||
builder.Property(e => e.Field11).IsRequired().HasColumnName("field_11");
|
||||
builder.Property(e => e.Field12).IsRequired().HasColumnName("field_12");
|
||||
builder.Property(e => e.Field13).IsRequired().HasDefaultValue(0).HasColumnName("field_13");
|
||||
builder.Property(e => e.Field14).IsRequired().HasDefaultValue(0).HasColumnName("field_14");
|
||||
builder.Property(e => e.Field15).IsRequired().HasDefaultValue(0).HasColumnName("field_15");
|
||||
builder.Property(e => e.Field16).IsRequired().HasDefaultValue(0).HasColumnName("field_16");
|
||||
|
||||
builder.Property(e => e.IsDeleted)
|
||||
.IsRequired()
|
||||
@@ -195,7 +197,7 @@ public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||
|
||||
builder.Property(e => e.CreatedAt)
|
||||
.IsRequired()
|
||||
.HasDefaultValueSql("NOW()")
|
||||
.HasDefaultValueSql("datetime('now')")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
// 派生属性不落库
|
||||
@@ -203,16 +205,21 @@ public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||
|
||||
// 索引
|
||||
builder.HasIndex(e => e.ScenarioId).HasDatabaseName("idx_ploss_scenario");
|
||||
builder.HasIndex(e => e.RxPower).HasDatabaseName("idx_ploss_rx_power");
|
||||
builder.HasIndex(e => e.Ploss).HasDatabaseName("idx_ploss_ploss");
|
||||
builder.HasIndex(e => e.Threshold).HasDatabaseName("idx_ploss_threshold");
|
||||
builder.HasIndex(e => e.FodResult).HasDatabaseName("idx_ploss_fod_result");
|
||||
builder.HasIndex(e => e.Field2).HasDatabaseName("idx_ploss_field_2");
|
||||
builder.HasIndex(e => e.Field7).HasDatabaseName("idx_ploss_field_7");
|
||||
builder.HasIndex(e => e.Field8).HasDatabaseName("idx_ploss_field_8");
|
||||
builder.HasIndex(e => e.Field10).HasDatabaseName("idx_ploss_field_10");
|
||||
builder.HasIndex(e => e.PowLoss).HasDatabaseName("idx_ploss_pow_loss");
|
||||
builder.HasIndex(e => e.DeltaP).HasDatabaseName("idx_ploss_delta_p");
|
||||
|
||||
// 关系配置
|
||||
builder.HasOne(e => e.Scenario)
|
||||
.WithMany(e => e.PlossRecords)
|
||||
.HasForeignKey(e => e.ScenarioId)
|
||||
.IsRequired();
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// 全局查询过滤器
|
||||
builder.HasQueryFilter(e => !e.IsDeleted);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -221,7 +228,7 @@ public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||
|
||||
## 7. 动态阈值表
|
||||
|
||||
> 阈值根据 RxPower 动态查表(不落库)
|
||||
> 阈值根据 RxPower 动态查表(不落库,业务规则)
|
||||
|
||||
| Rx Power 区间 | Threshold | 备注 |
|
||||
|---------------|-----------|------|
|
||||
@@ -230,15 +237,3 @@ public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||
| 10000-15000 mW | 750 mW | |
|
||||
| 15000-30000 mW | 1000 mW | |
|
||||
| 30000-50000 mW | 1250 mW | 高功率 |
|
||||
|
||||
```csharp
|
||||
// Services/ThresholdCalculator.cs
|
||||
public static int GetThresholdByPower(int rxPower)
|
||||
{
|
||||
if (rxPower <= 5000) return 350;
|
||||
if (rxPower <= 10000) return 500;
|
||||
if (rxPower <= 15000) return 750;
|
||||
if (rxPower <= 30000) return 1000;
|
||||
return 1250;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user