更新
This commit is contained in:
@@ -11,8 +11,10 @@ public sealed class ExperimentDataService : IExperimentDataService
|
||||
private readonly IRealtimeDataService _realtimeDataService;
|
||||
private readonly DispatcherTimer _timer;
|
||||
private readonly DateTime _startedAt = DateTime.Now;
|
||||
private double? _initialMass;
|
||||
private double _accumulatedTotalHeatRelease;
|
||||
private double _accumulatedTotalSmoke;
|
||||
private bool _isTestRunning;
|
||||
|
||||
public ExperimentDataService(IRealtimeDataService realtimeDataService)
|
||||
{
|
||||
@@ -37,16 +39,34 @@ public sealed class ExperimentDataService : IExperimentDataService
|
||||
|
||||
public event EventHandler<RealtimeSnapshot>? SnapshotUpdated;
|
||||
|
||||
public void StartTest()
|
||||
{
|
||||
Records.Clear();
|
||||
ResetComputedState();
|
||||
_isTestRunning = true;
|
||||
|
||||
if (double.IsFinite(CurrentSnapshot.CurrentMass))
|
||||
{
|
||||
_initialMass = CurrentSnapshot.CurrentMass;
|
||||
}
|
||||
}
|
||||
|
||||
public void StopTest()
|
||||
{
|
||||
_isTestRunning = false;
|
||||
_initialMass = null;
|
||||
}
|
||||
|
||||
public void ClearRecords()
|
||||
{
|
||||
Records.Clear();
|
||||
_accumulatedTotalHeatRelease = 0;
|
||||
_accumulatedTotalSmoke = 0;
|
||||
ResetComputedState();
|
||||
}
|
||||
|
||||
private void RecordSnapshot(RealtimeSnapshot snapshot)
|
||||
{
|
||||
var accumulatedSnapshot = ApplyAccumulatedTotals(snapshot);
|
||||
var massSnapshot = ApplyMassLoss(snapshot);
|
||||
var accumulatedSnapshot = ApplyAccumulatedTotals(massSnapshot);
|
||||
|
||||
CurrentSnapshot = accumulatedSnapshot;
|
||||
Records.Add(RealtimeDataRecord.FromSnapshot(accumulatedSnapshot));
|
||||
@@ -61,6 +81,15 @@ public sealed class ExperimentDataService : IExperimentDataService
|
||||
|
||||
private RealtimeSnapshot ApplyAccumulatedTotals(RealtimeSnapshot snapshot)
|
||||
{
|
||||
if (!_isTestRunning)
|
||||
{
|
||||
return snapshot with
|
||||
{
|
||||
TotalHeatRelease = double.NaN,
|
||||
TotalSmoke = double.NaN
|
||||
};
|
||||
}
|
||||
|
||||
if (double.IsFinite(snapshot.HeatReleaseRate))
|
||||
{
|
||||
_accumulatedTotalHeatRelease += snapshot.HeatReleaseRate;
|
||||
@@ -77,4 +106,36 @@ public sealed class ExperimentDataService : IExperimentDataService
|
||||
TotalSmoke = _accumulatedTotalSmoke
|
||||
};
|
||||
}
|
||||
|
||||
private RealtimeSnapshot ApplyMassLoss(RealtimeSnapshot snapshot)
|
||||
{
|
||||
if (!_isTestRunning)
|
||||
{
|
||||
return snapshot with
|
||||
{
|
||||
MassLoss = double.NaN
|
||||
};
|
||||
}
|
||||
|
||||
if (!_initialMass.HasValue && double.IsFinite(snapshot.CurrentMass))
|
||||
{
|
||||
_initialMass = snapshot.CurrentMass;
|
||||
}
|
||||
|
||||
var massLoss = _initialMass.HasValue && double.IsFinite(snapshot.CurrentMass)
|
||||
? _initialMass.Value - snapshot.CurrentMass
|
||||
: double.NaN;
|
||||
|
||||
return snapshot with
|
||||
{
|
||||
MassLoss = massLoss
|
||||
};
|
||||
}
|
||||
|
||||
private void ResetComputedState()
|
||||
{
|
||||
_initialMass = null;
|
||||
_accumulatedTotalHeatRelease = 0;
|
||||
_accumulatedTotalSmoke = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,9 @@ public interface IExperimentDataService
|
||||
|
||||
event EventHandler<RealtimeSnapshot>? SnapshotUpdated;
|
||||
|
||||
void StartTest();
|
||||
|
||||
void StopTest();
|
||||
|
||||
void ClearRecords();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace ConeCalorimeter.Services;
|
||||
|
||||
public sealed class ModbusRealtimeDataService : IRealtimeDataService
|
||||
{
|
||||
private const ushort CurrentMassRegister = 1;
|
||||
private const ushort OxygenRegister = 10;
|
||||
private const ushort OrificeFlowRegister = 14;
|
||||
private const ushort OrificePressureRegister = 16;
|
||||
@@ -45,7 +46,7 @@ public sealed class ModbusRealtimeDataService : IRealtimeDataService
|
||||
Qa300: ReadFloatOrEmpty(Qa300Register),
|
||||
TotalHeatRelease: double.NaN,
|
||||
SmokeProduction: ReadFloatOrEmpty(SmokeProductionRegister),
|
||||
CurrentMass: double.NaN,
|
||||
CurrentMass: ReadFloatOrEmpty(CurrentMassRegister),
|
||||
MassLoss: double.NaN,
|
||||
IgnitionSeconds: ReadInt16OrEmpty(IgnitionSecondsRegister),
|
||||
TestSeconds: ReadInt16OrEmpty(TestSecondsRegister),
|
||||
|
||||
@@ -254,6 +254,16 @@ public sealed class TestPageViewModel : PageViewModel
|
||||
|
||||
LastAction = action;
|
||||
|
||||
if (action == "测试开始")
|
||||
{
|
||||
_experimentDataService.StartTest();
|
||||
ClearPlotSeries();
|
||||
}
|
||||
else if (action == "测试结束")
|
||||
{
|
||||
_experimentDataService.StopTest();
|
||||
}
|
||||
|
||||
if (!TryGetDeviceActionCoil(action, out var coilAddress, out var value))
|
||||
{
|
||||
return;
|
||||
@@ -265,6 +275,17 @@ public sealed class TestPageViewModel : PageViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearPlotSeries()
|
||||
{
|
||||
_heatReleaseSeries.Points.Clear();
|
||||
_totalHeatSeries.Points.Clear();
|
||||
_totalSmokeSeries.Points.Clear();
|
||||
|
||||
var bottomAxis = HeatReleasePlot.Axes.First(axis => axis.Position == AxisPosition.Bottom);
|
||||
bottomAxis.Maximum = 300;
|
||||
HeatReleasePlot.InvalidatePlot(true);
|
||||
}
|
||||
|
||||
private static bool TryGetDeviceActionCoil(string action, out ushort coilAddress, out bool value)
|
||||
{
|
||||
value = true;
|
||||
|
||||
Reference in New Issue
Block a user