更新
This commit is contained in:
@@ -22,10 +22,13 @@ public sealed record RealtimeDataRecord(
|
|||||||
double CurrentMass,
|
double CurrentMass,
|
||||||
double InitialMass,
|
double InitialMass,
|
||||||
double MassLoss,
|
double MassLoss,
|
||||||
|
double MassLossRate,
|
||||||
int IgnitionSeconds,
|
int IgnitionSeconds,
|
||||||
int TestSeconds,
|
int TestSeconds,
|
||||||
double TotalSmoke)
|
double TotalSmoke)
|
||||||
{
|
{
|
||||||
|
private const double DefaultIrradiatedAreaSquareMeters = 0.01;
|
||||||
|
|
||||||
public static RealtimeDataRecord FromSnapshot(RealtimeSnapshot snapshot)
|
public static RealtimeDataRecord FromSnapshot(RealtimeSnapshot snapshot)
|
||||||
{
|
{
|
||||||
return new RealtimeDataRecord(
|
return new RealtimeDataRecord(
|
||||||
@@ -50,19 +53,17 @@ public sealed record RealtimeDataRecord(
|
|||||||
snapshot.CurrentMass,
|
snapshot.CurrentMass,
|
||||||
snapshot.InitialMass,
|
snapshot.InitialMass,
|
||||||
snapshot.MassLoss,
|
snapshot.MassLoss,
|
||||||
|
snapshot.MassLossRate,
|
||||||
snapshot.IgnitionSeconds,
|
snapshot.IgnitionSeconds,
|
||||||
snapshot.TestSeconds,
|
snapshot.TestSeconds,
|
||||||
snapshot.TotalSmoke);
|
snapshot.TotalSmoke);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double MassLossRate =>
|
|
||||||
double.IsFinite(MassLoss) && TestSeconds > 0 ? MassLoss / TestSeconds : double.NaN;
|
|
||||||
|
|
||||||
public double HeatReleaseRateKw =>
|
public double HeatReleaseRateKw =>
|
||||||
double.IsFinite(HeatReleaseRate) ? HeatReleaseRate * 1000 : double.NaN;
|
double.IsFinite(HeatReleaseRate) ? HeatReleaseRate : double.NaN;
|
||||||
|
|
||||||
public double EffectiveHeatOfCombustion =>
|
public double EffectiveHeatOfCombustion =>
|
||||||
double.IsFinite(HeatReleaseRate) && double.IsFinite(MassLossRate) && MassLossRate > 0
|
double.IsFinite(HeatReleaseRate) && double.IsFinite(MassLossRate) && MassLossRate > 0
|
||||||
? HeatReleaseRate / MassLossRate * 10
|
? HeatReleaseRate * DefaultIrradiatedAreaSquareMeters / MassLossRate
|
||||||
: double.NaN;
|
: double.NaN;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public sealed record RealtimeSnapshot(
|
|||||||
double CurrentMass,
|
double CurrentMass,
|
||||||
double InitialMass,
|
double InitialMass,
|
||||||
double MassLoss,
|
double MassLoss,
|
||||||
|
double MassLossRate,
|
||||||
int IgnitionSeconds,
|
int IgnitionSeconds,
|
||||||
int TestSeconds,
|
int TestSeconds,
|
||||||
double TotalSmoke);
|
double TotalSmoke);
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ public sealed class ExperimentDataService : IExperimentDataService
|
|||||||
private readonly DispatcherTimer _timer;
|
private readonly DispatcherTimer _timer;
|
||||||
private readonly DateTime _startedAt = DateTime.Now;
|
private readonly DateTime _startedAt = DateTime.Now;
|
||||||
private double? _initialMass;
|
private double? _initialMass;
|
||||||
|
private double? _previousMass;
|
||||||
|
private int? _previousMassSeconds;
|
||||||
private double _accumulatedTotalHeatRelease;
|
private double _accumulatedTotalHeatRelease;
|
||||||
private double _accumulatedTotalSmoke;
|
private double _accumulatedTotalSmoke;
|
||||||
private int? _lastAccumulationSeconds;
|
private int? _lastAccumulationSeconds;
|
||||||
@@ -139,7 +141,8 @@ public sealed class ExperimentDataService : IExperimentDataService
|
|||||||
return snapshot with
|
return snapshot with
|
||||||
{
|
{
|
||||||
InitialMass = _initialMass ?? double.NaN,
|
InitialMass = _initialMass ?? double.NaN,
|
||||||
MassLoss = double.NaN
|
MassLoss = double.NaN,
|
||||||
|
MassLossRate = double.NaN
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,17 +154,46 @@ public sealed class ExperimentDataService : IExperimentDataService
|
|||||||
var massLoss = _initialMass.HasValue && double.IsFinite(snapshot.CurrentMass)
|
var massLoss = _initialMass.HasValue && double.IsFinite(snapshot.CurrentMass)
|
||||||
? _initialMass.Value - snapshot.CurrentMass
|
? _initialMass.Value - snapshot.CurrentMass
|
||||||
: double.NaN;
|
: double.NaN;
|
||||||
|
var massLossRate = CalculateMassLossRate(snapshot);
|
||||||
|
|
||||||
return snapshot with
|
return snapshot with
|
||||||
{
|
{
|
||||||
InitialMass = _initialMass ?? double.NaN,
|
InitialMass = _initialMass ?? double.NaN,
|
||||||
MassLoss = massLoss
|
MassLoss = massLoss,
|
||||||
|
MassLossRate = massLossRate
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double CalculateMassLossRate(RealtimeSnapshot snapshot)
|
||||||
|
{
|
||||||
|
if (snapshot.TestSeconds < 0 || !double.IsFinite(snapshot.CurrentMass))
|
||||||
|
{
|
||||||
|
return double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_previousMass.HasValue || !_previousMassSeconds.HasValue)
|
||||||
|
{
|
||||||
|
_previousMass = snapshot.CurrentMass;
|
||||||
|
_previousMassSeconds = snapshot.TestSeconds;
|
||||||
|
return double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
var deltaSeconds = snapshot.TestSeconds - _previousMassSeconds.Value;
|
||||||
|
var deltaMass = _previousMass.Value - snapshot.CurrentMass;
|
||||||
|
|
||||||
|
_previousMass = snapshot.CurrentMass;
|
||||||
|
_previousMassSeconds = snapshot.TestSeconds;
|
||||||
|
|
||||||
|
return deltaSeconds > 0 && deltaMass >= 0
|
||||||
|
? deltaMass / deltaSeconds
|
||||||
|
: double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
private void ResetComputedState()
|
private void ResetComputedState()
|
||||||
{
|
{
|
||||||
_initialMass = null;
|
_initialMass = null;
|
||||||
|
_previousMass = null;
|
||||||
|
_previousMassSeconds = null;
|
||||||
_accumulatedTotalHeatRelease = 0;
|
_accumulatedTotalHeatRelease = 0;
|
||||||
_accumulatedTotalSmoke = 0;
|
_accumulatedTotalSmoke = 0;
|
||||||
_lastAccumulationSeconds = null;
|
_lastAccumulationSeconds = null;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public sealed class ModbusRealtimeDataService : IRealtimeDataService
|
|||||||
CurrentMass: ReadFloatOrEmpty(CurrentMassRegister),
|
CurrentMass: ReadFloatOrEmpty(CurrentMassRegister),
|
||||||
InitialMass: double.NaN,
|
InitialMass: double.NaN,
|
||||||
MassLoss: double.NaN,
|
MassLoss: double.NaN,
|
||||||
|
MassLossRate: double.NaN,
|
||||||
IgnitionSeconds: ReadInt16OrEmpty(IgnitionSecondsRegister),
|
IgnitionSeconds: ReadInt16OrEmpty(IgnitionSecondsRegister),
|
||||||
TestSeconds: ReadInt16OrEmpty(TestSecondsRegister),
|
TestSeconds: ReadInt16OrEmpty(TestSecondsRegister),
|
||||||
TotalSmoke: double.NaN);
|
TotalSmoke: double.NaN);
|
||||||
|
|||||||
Reference in New Issue
Block a user