更新
This commit is contained in:
@@ -118,6 +118,9 @@ public partial class PumpControlChannel : ObservableObject
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int flowStabilizationRawSetpoint;
|
private int flowStabilizationRawSetpoint;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private double flowStabilizationIntegralError;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string flowStabilizationStatusText = "稳流未启用";
|
private string flowStabilizationStatusText = "稳流未启用";
|
||||||
|
|
||||||
@@ -338,10 +341,26 @@ public partial class PumpControlChannel : ObservableObject
|
|||||||
if (!value)
|
if (!value)
|
||||||
{
|
{
|
||||||
FlowStabilizationStatusText = "稳流未启用";
|
FlowStabilizationStatusText = "稳流未启用";
|
||||||
|
FlowStabilizationRawSetpoint = 0;
|
||||||
|
FlowStabilizationIntegralError = 0;
|
||||||
ConsecutiveFlowStabilizationFailureCount = 0;
|
ConsecutiveFlowStabilizationFailureCount = 0;
|
||||||
ConsecutiveFlowStabilizationLimitCount = 0;
|
ConsecutiveFlowStabilizationLimitCount = 0;
|
||||||
ConsecutiveFlowStabilizationUnavailableCount = 0;
|
ConsecutiveFlowStabilizationUnavailableCount = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FlowStabilizationIntegralError = 0;
|
||||||
|
ConsecutiveFlowStabilizationFailureCount = 0;
|
||||||
|
ConsecutiveFlowStabilizationLimitCount = 0;
|
||||||
|
ConsecutiveFlowStabilizationUnavailableCount = 0;
|
||||||
|
FlowStabilizationStatusText = !IsRunning || PendingRs485RunningState == false
|
||||||
|
? "等待泵运行"
|
||||||
|
: !FlowAvailable
|
||||||
|
? "等待流量反馈"
|
||||||
|
: !ConfirmedSetpointAvailable || ConfirmedSetpointFlowValue <= 0
|
||||||
|
? "等待确认目标流量"
|
||||||
|
: "等待稳流调节";
|
||||||
|
}
|
||||||
|
|
||||||
OnPropertyChanged(nameof(FlowStabilizationStateText));
|
OnPropertyChanged(nameof(FlowStabilizationStateText));
|
||||||
}
|
}
|
||||||
@@ -392,6 +411,7 @@ public partial class PumpControlChannel : ObservableObject
|
|||||||
ConfirmedRawSetpointValue = 0;
|
ConfirmedRawSetpointValue = 0;
|
||||||
ConfirmedSetpointFlowValue = 0;
|
ConfirmedSetpointFlowValue = 0;
|
||||||
FlowStabilizationRawSetpoint = 0;
|
FlowStabilizationRawSetpoint = 0;
|
||||||
|
FlowStabilizationIntegralError = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void OnSetpointAvailableChanged(bool value)
|
partial void OnSetpointAvailableChanged(bool value)
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public partial class MainViewModel
|
|||||||
private const double FlowStabilizationDeadbandLpm = 0.05d;
|
private const double FlowStabilizationDeadbandLpm = 0.05d;
|
||||||
private const int FlowStabilizationMaxRawStep = 5;
|
private const int FlowStabilizationMaxRawStep = 5;
|
||||||
private const double FlowStabilizationMaxRelativeTrim = 0.20d;
|
private const double FlowStabilizationMaxRelativeTrim = 0.20d;
|
||||||
|
private const double FlowStabilizationProportionalGainRatio = 0.25d;
|
||||||
|
private const double FlowStabilizationIntegralGainRatioPerSecond = 0.04d;
|
||||||
|
private const double FlowStabilizationMaxIntegralRawTrimRatio = 0.10d;
|
||||||
private const int FlowStabilizationMaxConsecutiveFailures = 3;
|
private const int FlowStabilizationMaxConsecutiveFailures = 3;
|
||||||
private const int FlowStabilizationMaxConsecutiveLimitHits = 3;
|
private const int FlowStabilizationMaxConsecutiveLimitHits = 3;
|
||||||
private const int FlowStabilizationMaxUnavailableCycles = 3;
|
private const int FlowStabilizationMaxUnavailableCycles = 3;
|
||||||
@@ -686,6 +689,7 @@ public partial class MainViewModel
|
|||||||
{
|
{
|
||||||
pump.FlowStabilizationStatusText = "等待泵运行";
|
pump.FlowStabilizationStatusText = "等待泵运行";
|
||||||
ResetFlowStabilizationProtectionCounters(pump);
|
ResetFlowStabilizationProtectionCounters(pump);
|
||||||
|
ResetFlowStabilizationControllerState(pump);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,6 +707,7 @@ public partial class MainViewModel
|
|||||||
{
|
{
|
||||||
pump.FlowStabilizationStatusText = "等待确认目标流量";
|
pump.FlowStabilizationStatusText = "等待确认目标流量";
|
||||||
ResetFlowStabilizationProtectionCounters(pump);
|
ResetFlowStabilizationProtectionCounters(pump);
|
||||||
|
ResetFlowStabilizationControllerState(pump);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,13 +721,15 @@ public partial class MainViewModel
|
|||||||
|
|
||||||
private async Task TryAdjustRs485FlowStabilizationAsync(PumpControlChannel pump)
|
private async Task TryAdjustRs485FlowStabilizationAsync(PumpControlChannel pump)
|
||||||
{
|
{
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
var targetFlow = pump.ConfirmedSetpointFlowValue;
|
var targetFlow = pump.ConfirmedSetpointFlowValue;
|
||||||
var flowError = targetFlow - pump.FlowValue;
|
var flowError = targetFlow - pump.FlowValue;
|
||||||
if (Math.Abs(flowError) <= FlowStabilizationDeadbandLpm)
|
if (Math.Abs(flowError) <= FlowStabilizationDeadbandLpm)
|
||||||
{
|
{
|
||||||
ResetFlowStabilizationProtectionCounters(pump);
|
ResetFlowStabilizationProtectionCounters(pump);
|
||||||
|
pump.FlowStabilizationIntegralError = 0;
|
||||||
pump.FlowStabilizationStatusText = $"稳流保持:目标 {targetFlow:F2} / 当前 {pump.FlowValue:F2} L/min";
|
pump.FlowStabilizationStatusText = $"稳流保持:目标 {targetFlow:F2} / 当前 {pump.FlowValue:F2} L/min";
|
||||||
pump.LastFlowStabilizationAdjustmentUtc = DateTime.UtcNow;
|
pump.LastFlowStabilizationAdjustmentUtc = now;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,7 +739,7 @@ public partial class MainViewModel
|
|||||||
if (targetRaw <= 0)
|
if (targetRaw <= 0)
|
||||||
{
|
{
|
||||||
DisableFlowStabilizationForProtection(pump, "稳流保护:目标流量换算值无效");
|
DisableFlowStabilizationForProtection(pump, "稳流保护:目标流量换算值无效");
|
||||||
pump.LastFlowStabilizationAdjustmentUtc = DateTime.UtcNow;
|
pump.LastFlowStabilizationAdjustmentUtc = now;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,17 +751,42 @@ public partial class MainViewModel
|
|||||||
var maxTrim = Math.Max(FlowStabilizationMaxRawStep, (int)Math.Round(targetRaw * FlowStabilizationMaxRelativeTrim, MidpointRounding.AwayFromZero));
|
var maxTrim = Math.Max(FlowStabilizationMaxRawStep, (int)Math.Round(targetRaw * FlowStabilizationMaxRelativeTrim, MidpointRounding.AwayFromZero));
|
||||||
var minRaw = Math.Max(1, targetRaw - maxTrim);
|
var minRaw = Math.Max(1, targetRaw - maxTrim);
|
||||||
var maxRaw = Math.Min(MaxRs485MotorCommand, targetRaw + maxTrim);
|
var maxRaw = Math.Min(MaxRs485MotorCommand, targetRaw + maxTrim);
|
||||||
var rawStep = Math.Sign(flowError) * FlowStabilizationMaxRawStep;
|
var elapsedSeconds = CalculateFlowStabilizationElapsedSeconds(pump, now);
|
||||||
|
var proportionalRaw = flowError * pump.Rs485RawPerLitrePerMinute * FlowStabilizationProportionalGainRatio;
|
||||||
|
var integralGain = Math.Max(0.0001d, pump.Rs485RawPerLitrePerMinute * FlowStabilizationIntegralGainRatioPerSecond);
|
||||||
|
var maxIntegralRaw = Math.Max(FlowStabilizationMaxRawStep, targetRaw * FlowStabilizationMaxIntegralRawTrimRatio);
|
||||||
|
var integralLimit = maxIntegralRaw / integralGain;
|
||||||
|
var nextIntegralError = Math.Clamp(
|
||||||
|
pump.FlowStabilizationIntegralError + flowError * elapsedSeconds,
|
||||||
|
-integralLimit,
|
||||||
|
integralLimit);
|
||||||
|
var integralRaw = nextIntegralError * integralGain;
|
||||||
|
var controllerOutputRaw = proportionalRaw + integralRaw;
|
||||||
|
var rawStep = (int)Math.Round(controllerOutputRaw, MidpointRounding.AwayFromZero);
|
||||||
|
if (rawStep == 0)
|
||||||
|
{
|
||||||
|
rawStep = Math.Sign(flowError);
|
||||||
|
}
|
||||||
|
|
||||||
|
rawStep = Math.Clamp(rawStep, -FlowStabilizationMaxRawStep, FlowStabilizationMaxRawStep);
|
||||||
var nextRaw = Math.Clamp(currentRaw + rawStep, minRaw, maxRaw);
|
var nextRaw = Math.Clamp(currentRaw + rawStep, minRaw, maxRaw);
|
||||||
|
var appliedRawStep = nextRaw - currentRaw;
|
||||||
Logger.Information(
|
Logger.Information(
|
||||||
"RS485 稳流调节计算,PumpKey={PumpKey},PumpName={PumpName},TargetFlowLpm={TargetFlowLpm},CurrentFlowLpm={CurrentFlowLpm},FlowErrorLpm={FlowErrorLpm},TargetRaw={TargetRaw},CurrentRaw={CurrentRaw},NextRaw={NextRaw},MinRaw={MinRaw},MaxRaw={MaxRaw}",
|
"RS485 PI稳流调节计算,PumpKey={PumpKey},PumpName={PumpName},TargetFlowLpm={TargetFlowLpm},CurrentFlowLpm={CurrentFlowLpm},FlowErrorLpm={FlowErrorLpm},ElapsedSeconds={ElapsedSeconds},P={ProportionalRaw},I={IntegralRaw},IntegralError={IntegralError},ControllerOutputRaw={ControllerOutputRaw},TargetRaw={TargetRaw},CurrentRaw={CurrentRaw},RawStep={RawStep},AppliedRawStep={AppliedRawStep},NextRaw={NextRaw},MinRaw={MinRaw},MaxRaw={MaxRaw}",
|
||||||
pump.Key,
|
pump.Key,
|
||||||
pump.Name,
|
pump.Name,
|
||||||
targetFlow,
|
targetFlow,
|
||||||
pump.FlowValue,
|
pump.FlowValue,
|
||||||
flowError,
|
flowError,
|
||||||
|
elapsedSeconds,
|
||||||
|
proportionalRaw,
|
||||||
|
integralRaw,
|
||||||
|
nextIntegralError,
|
||||||
|
controllerOutputRaw,
|
||||||
targetRaw,
|
targetRaw,
|
||||||
currentRaw,
|
currentRaw,
|
||||||
|
rawStep,
|
||||||
|
appliedRawStep,
|
||||||
nextRaw,
|
nextRaw,
|
||||||
minRaw,
|
minRaw,
|
||||||
maxRaw);
|
maxRaw);
|
||||||
@@ -778,12 +810,12 @@ public partial class MainViewModel
|
|||||||
maxRaw,
|
maxRaw,
|
||||||
pump.ConsecutiveFlowStabilizationLimitCount);
|
pump.ConsecutiveFlowStabilizationLimitCount);
|
||||||
DisableFlowStabilizationForProtection(pump, $"稳流保护:{message},已连续 {pump.ConsecutiveFlowStabilizationLimitCount} 次无法继续调节");
|
DisableFlowStabilizationForProtection(pump, $"稳流保护:{message},已连续 {pump.ConsecutiveFlowStabilizationLimitCount} 次无法继续调节");
|
||||||
pump.LastFlowStabilizationAdjustmentUtc = DateTime.UtcNow;
|
pump.LastFlowStabilizationAdjustmentUtc = now;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pump.FlowStabilizationStatusText = $"{message}({pump.ConsecutiveFlowStabilizationLimitCount}/{FlowStabilizationMaxConsecutiveLimitHits})";
|
pump.FlowStabilizationStatusText = $"{message}({pump.ConsecutiveFlowStabilizationLimitCount}/{FlowStabilizationMaxConsecutiveLimitHits})";
|
||||||
pump.LastFlowStabilizationAdjustmentUtc = DateTime.UtcNow;
|
pump.LastFlowStabilizationAdjustmentUtc = now;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,14 +850,15 @@ public partial class MainViewModel
|
|||||||
pump.ConsecutiveFlowStabilizationFailureCount = 0;
|
pump.ConsecutiveFlowStabilizationFailureCount = 0;
|
||||||
pump.ConsecutiveFlowStabilizationLimitCount = 0;
|
pump.ConsecutiveFlowStabilizationLimitCount = 0;
|
||||||
pump.ConsecutiveFlowStabilizationUnavailableCount = 0;
|
pump.ConsecutiveFlowStabilizationUnavailableCount = 0;
|
||||||
|
pump.FlowStabilizationIntegralError = nextIntegralError;
|
||||||
pump.FlowStabilizationRawSetpoint = nextRaw;
|
pump.FlowStabilizationRawSetpoint = nextRaw;
|
||||||
CacheResolvedRs485Setpoint(pump, nextRaw);
|
CacheResolvedRs485Setpoint(pump, nextRaw);
|
||||||
ApplyPostCommandPumpState(pump, result, expectedRunning: true);
|
ApplyPostCommandPumpState(pump, result, expectedRunning: true);
|
||||||
pump.FlowStabilizationStatusText = $"稳流调节:目标 {targetFlow:F2} / 当前 {pump.FlowValue:F2} L/min / 控制值 {nextRaw}";
|
pump.FlowStabilizationStatusText = $"PI稳流调节:目标 {targetFlow:F2} / 当前 {pump.FlowValue:F2} L/min / 控制值 {nextRaw}";
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
pump.LastFlowStabilizationAdjustmentUtc = DateTime.UtcNow;
|
pump.LastFlowStabilizationAdjustmentUtc = now;
|
||||||
EndRs485PumpOperation(pump);
|
EndRs485PumpOperation(pump);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -855,6 +888,20 @@ public partial class MainViewModel
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static double CalculateFlowStabilizationElapsedSeconds(PumpControlChannel pump, DateTime now)
|
||||||
|
{
|
||||||
|
if (pump.LastFlowStabilizationAdjustmentUtc == DateTime.MinValue)
|
||||||
|
{
|
||||||
|
return FlowStabilizationAdjustmentInterval.TotalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
var elapsedSeconds = (now - pump.LastFlowStabilizationAdjustmentUtc).TotalSeconds;
|
||||||
|
return Math.Clamp(
|
||||||
|
elapsedSeconds,
|
||||||
|
FlowStabilizationAdjustmentInterval.TotalSeconds,
|
||||||
|
FlowStabilizationAdjustmentInterval.TotalSeconds * 3d);
|
||||||
|
}
|
||||||
|
|
||||||
private bool RegisterFlowStabilizationCommandFailure(PumpControlChannel pump, string message)
|
private bool RegisterFlowStabilizationCommandFailure(PumpControlChannel pump, string message)
|
||||||
{
|
{
|
||||||
pump.ConsecutiveFlowStabilizationFailureCount++;
|
pump.ConsecutiveFlowStabilizationFailureCount++;
|
||||||
@@ -901,6 +948,12 @@ public partial class MainViewModel
|
|||||||
pump.ConsecutiveFlowStabilizationUnavailableCount = 0;
|
pump.ConsecutiveFlowStabilizationUnavailableCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ResetFlowStabilizationControllerState(PumpControlChannel pump)
|
||||||
|
{
|
||||||
|
pump.FlowStabilizationIntegralError = 0;
|
||||||
|
pump.FlowStabilizationRawSetpoint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
private void RaiseRs485CalibrationSummaryChanges()
|
private void RaiseRs485CalibrationSummaryChanges()
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(Rs485EnabledPumpCount));
|
OnPropertyChanged(nameof(Rs485EnabledPumpCount));
|
||||||
@@ -1508,7 +1561,7 @@ public partial class MainViewModel
|
|||||||
|
|
||||||
if (ShouldUseRs485DirectPumpControl(pump))
|
if (ShouldUseRs485DirectPumpControl(pump))
|
||||||
{
|
{
|
||||||
if (!TryResolveRs485MotorCommand(pump, out var rawMotorSpeed, out var resolveMessage))
|
if (!TryResolveRs485MotorCommand(pump, out var rawMotorSpeed, out var resolvedTargetFlow, out var resolveMessage))
|
||||||
{
|
{
|
||||||
pump.SetpointStatusText = resolveMessage;
|
pump.SetpointStatusText = resolveMessage;
|
||||||
Rs485StatusText = resolveMessage;
|
Rs485StatusText = resolveMessage;
|
||||||
@@ -1531,6 +1584,7 @@ public partial class MainViewModel
|
|||||||
return Rs485StartExecutionResult.Failed;
|
return Rs485StartExecutionResult.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CacheConfirmedRs485Setpoint(pump, rawMotorSpeed, resolvedTargetFlow);
|
||||||
CacheResolvedRs485Setpoint(pump, rawMotorSpeed);
|
CacheResolvedRs485Setpoint(pump, rawMotorSpeed);
|
||||||
ApplyPostCommandPumpState(pump, directResult, expectedRunning: true);
|
ApplyPostCommandPumpState(pump, directResult, expectedRunning: true);
|
||||||
await RefreshTelemetryAsync();
|
await RefreshTelemetryAsync();
|
||||||
@@ -1736,9 +1790,14 @@ public partial class MainViewModel
|
|||||||
private bool IsRs485ManagedPump(PumpControlChannel pump) =>
|
private bool IsRs485ManagedPump(PumpControlChannel pump) =>
|
||||||
_pumpActuationService.IsManagedPump(pump);
|
_pumpActuationService.IsManagedPump(pump);
|
||||||
|
|
||||||
private bool TryResolveRs485MotorCommand(PumpControlChannel pump, out short rawMotorSpeed, out string message)
|
private bool TryResolveRs485MotorCommand(
|
||||||
|
PumpControlChannel pump,
|
||||||
|
out short rawMotorSpeed,
|
||||||
|
out double targetFlowLpm,
|
||||||
|
out string message)
|
||||||
{
|
{
|
||||||
rawMotorSpeed = 0;
|
rawMotorSpeed = 0;
|
||||||
|
targetFlowLpm = 0;
|
||||||
message = string.Empty;
|
message = string.Empty;
|
||||||
|
|
||||||
if (!pump.HasSetpointCalibration)
|
if (!pump.HasSetpointCalibration)
|
||||||
@@ -1753,7 +1812,13 @@ public partial class MainViewModel
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var candidateRaw = pump.ConfirmedSetpointAvailable ? pump.ConfirmedRawSetpointValue : 0;
|
var candidateRaw = 0;
|
||||||
|
if (pump.ConfirmedSetpointAvailable && pump.ConfirmedRawSetpointValue > 0)
|
||||||
|
{
|
||||||
|
candidateRaw = pump.ConfirmedRawSetpointValue;
|
||||||
|
targetFlowLpm = pump.ConfirmedSetpointFlowValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (candidateRaw <= 0
|
if (candidateRaw <= 0
|
||||||
&& double.TryParse(
|
&& double.TryParse(
|
||||||
pump.PendingSetpointText,
|
pump.PendingSetpointText,
|
||||||
@@ -1764,6 +1829,7 @@ public partial class MainViewModel
|
|||||||
&& pendingFlow <= pump.Rs485MaxFlowLpm)
|
&& pendingFlow <= pump.Rs485MaxFlowLpm)
|
||||||
{
|
{
|
||||||
candidateRaw = ConvertFlowToRawSpeed(pump, pendingFlow);
|
candidateRaw = ConvertFlowToRawSpeed(pump, pendingFlow);
|
||||||
|
targetFlowLpm = pendingFlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidateRaw <= 0)
|
if (candidateRaw <= 0)
|
||||||
@@ -1772,6 +1838,17 @@ public partial class MainViewModel
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetFlowLpm <= 0 && pump.HasSetpointCalibration)
|
||||||
|
{
|
||||||
|
targetFlowLpm = ConvertRawSpeedToFlow(pump, candidateRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetFlowLpm <= 0)
|
||||||
|
{
|
||||||
|
message = $"{pump.Name} 启动前请输入大于 0 的目标流量";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (candidateRaw > MaxRs485MotorCommand)
|
if (candidateRaw > MaxRs485MotorCommand)
|
||||||
{
|
{
|
||||||
message = $"{pump.Name} 的直接启停控制值超过 {MaxRs485MotorCommand}";
|
message = $"{pump.Name} 的直接启停控制值超过 {MaxRs485MotorCommand}";
|
||||||
@@ -1793,6 +1870,7 @@ public partial class MainViewModel
|
|||||||
pump.ConfirmedRawSetpointValue = rawMotorSpeed;
|
pump.ConfirmedRawSetpointValue = rawMotorSpeed;
|
||||||
pump.ConfirmedSetpointFlowValue = flowLpm;
|
pump.ConfirmedSetpointFlowValue = flowLpm;
|
||||||
pump.FlowStabilizationRawSetpoint = rawMotorSpeed;
|
pump.FlowStabilizationRawSetpoint = rawMotorSpeed;
|
||||||
|
pump.FlowStabilizationIntegralError = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryBeginRs485PumpOperation(PumpControlChannel pump, string operationName)
|
private bool TryBeginRs485PumpOperation(PumpControlChannel pump, string operationName)
|
||||||
@@ -1847,6 +1925,11 @@ public partial class MainViewModel
|
|||||||
pump.IsRunning = result.RunStatus.Value == 1;
|
pump.IsRunning = result.RunStatus.Value == 1;
|
||||||
pump.StateAvailable = result.RunStatus.Value is 0 or 1;
|
pump.StateAvailable = result.RunStatus.Value is 0 or 1;
|
||||||
pump.Rs485RunStatusCode = result.RunStatus.Value;
|
pump.Rs485RunStatusCode = result.RunStatus.Value;
|
||||||
|
if (!expectedRunning || result.RunStatus.Value != 1)
|
||||||
|
{
|
||||||
|
ResetFlowStabilizationAfterPumpStopped(pump);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1856,8 +1939,7 @@ public partial class MainViewModel
|
|||||||
pump.IsRunning = false;
|
pump.IsRunning = false;
|
||||||
pump.StateAvailable = true;
|
pump.StateAvailable = true;
|
||||||
pump.Rs485RunStatusCode = 0;
|
pump.Rs485RunStatusCode = 0;
|
||||||
pump.FlowStabilizationRawSetpoint = 0;
|
ResetFlowStabilizationAfterPumpStopped(pump);
|
||||||
ResetFlowStabilizationProtectionCounters(pump);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1867,6 +1949,16 @@ public partial class MainViewModel
|
|||||||
pump.Rs485RunStatusCode = null;
|
pump.Rs485RunStatusCode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ResetFlowStabilizationAfterPumpStopped(PumpControlChannel pump)
|
||||||
|
{
|
||||||
|
ResetFlowStabilizationControllerState(pump);
|
||||||
|
ResetFlowStabilizationProtectionCounters(pump);
|
||||||
|
if (pump.IsFlowStabilizationEnabled)
|
||||||
|
{
|
||||||
|
pump.FlowStabilizationStatusText = "等待泵运行";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<Rs485ToggleExecutionResult> TryTogglePumpControlViaRs485(PumpControlChannel pump, bool nextState)
|
private async Task<Rs485ToggleExecutionResult> TryTogglePumpControlViaRs485(PumpControlChannel pump, bool nextState)
|
||||||
{
|
{
|
||||||
if (!ShouldUseRs485DirectPumpControl(pump))
|
if (!ShouldUseRs485DirectPumpControl(pump))
|
||||||
@@ -1894,7 +1986,7 @@ public partial class MainViewModel
|
|||||||
{
|
{
|
||||||
if (nextState)
|
if (nextState)
|
||||||
{
|
{
|
||||||
if (!TryResolveRs485MotorCommand(pump, out var rawMotorSpeed, out var resolveMessage))
|
if (!TryResolveRs485MotorCommand(pump, out var rawMotorSpeed, out var resolvedTargetFlow, out var resolveMessage))
|
||||||
{
|
{
|
||||||
pump.SetpointStatusText = resolveMessage;
|
pump.SetpointStatusText = resolveMessage;
|
||||||
Rs485StatusText = resolveMessage;
|
Rs485StatusText = resolveMessage;
|
||||||
@@ -1911,6 +2003,7 @@ public partial class MainViewModel
|
|||||||
return Rs485ToggleExecutionResult.Failed;
|
return Rs485ToggleExecutionResult.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CacheConfirmedRs485Setpoint(pump, rawMotorSpeed, resolvedTargetFlow);
|
||||||
CacheResolvedRs485Setpoint(pump, rawMotorSpeed);
|
CacheResolvedRs485Setpoint(pump, rawMotorSpeed);
|
||||||
ApplyPostCommandPumpState(pump, startResult, expectedRunning: true);
|
ApplyPostCommandPumpState(pump, startResult, expectedRunning: true);
|
||||||
await RefreshTelemetryAsync();
|
await RefreshTelemetryAsync();
|
||||||
|
|||||||
Reference in New Issue
Block a user