Files
WCTDataMiner/docs/data-model/entities/Ploss记录.md

244 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ploss_record 实体
> 所属模块:[数据模型概览](../概览.md)
---
## 1. 表定义
**表名**`ploss_record`
**描述**:存储 Ploss FOD 格式解析数据,对应日志格式 `FOD-> (1)...(13)`
---
## 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 | 充电线圈索引 |
| is_deleted | BOOLEAN | NOT NULL, DEFAULT FALSE | 软删除标记 |
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW() | 创建时间 |
---
## 3. 外键
| 外键 | 引用表 | 说明 |
|------|--------|------|
| scenario_id | test_scenario.id | 关联测试场景(必需) |
---
## 4. 派生字段
> **注意**:以下字段不落库,查询时动态计算
| 字段 | 计算公式 | 说明 |
|------|----------|------|
| margin | threshold - ploss | 安全余量(>0 安全,<0 危险) |
> **使用限制**`Margin` 属性通过 EF Core `Ignore()` 排除映射,仅用于内存计算。不可在数据库查询中直接使用(如 `WHERE Margin > 0`),需改用 `WHERE (threshold - ploss) > 0` 或先加载到内存再计算。
---
## 5. 索引
| 索引名 | 字段 | 用途 |
|--------|------|------|
| 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结果筛选 |
---
## 6. EF Core 模型
### 实体类
```csharp
// Models/PlossRecord.cs
namespace WCTDataMiner.Models;
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; }
/// <summary>安全红线:当前功率段阈值</summary>
public int Threshold { 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;
}
```
### 配置类
```csharp
// Data/Configurations/PlossRecordConfiguration.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using WCTDataMiner.Models;
namespace WCTDataMiner.Data.Configurations;
public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
{
public void Configure(EntityTypeBuilder<PlossRecord> builder)
{
builder.ToTable("ploss_record");
builder.HasKey(e => e.Id);
builder.Property(e => e.Id).HasColumnName("id");
builder.Property(e => e.ScenarioId)
.IsRequired()
.HasColumnName("scenario_id");
builder.Property(e => e.RxType)
.IsRequired()
.HasColumnName("rx_type");
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.IsDeleted)
.IsRequired()
.HasDefaultValue(false)
.HasColumnName("is_deleted");
builder.Property(e => e.CreatedAt)
.IsRequired()
.HasDefaultValueSql("NOW()")
.HasColumnName("created_at");
// 派生属性不落库
builder.Ignore(e => e.Margin);
// 索引
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.HasOne(e => e.Scenario)
.WithMany(e => e.PlossRecords)
.HasForeignKey(e => e.ScenarioId)
.IsRequired();
}
}
```
---
## 7. 动态阈值表
> 阈值根据 RxPower 动态查表(不落库)
| Rx Power 区间 | Threshold | 备注 |
|---------------|-----------|------|
| 0-5000 mW | 350 mW | 低功率最敏感 |
| 5000-10000 mW | 500 mW | |
| 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;
}
```