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

7.3 KiB
Raw Permalink Blame History

ploss_record 实体

所属模块:数据模型概览


1. 表定义

表名ploss_record

描述:存储 Ploss FOD 格式解析数据,对应日志格式 FOD-> (1)...(13)


2. 字段定义

类型修正说明:需求文档中 rx_power, tx_power, vcoil, vin, isns, pwm_duty 为 uint160-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 模型

实体类

// 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;
}

配置类

// 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 高功率
// 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;
}