更新121
This commit is contained in:
@@ -1833,6 +1833,10 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveParameterConfigFromInputsAsync()
|
private async Task SaveParameterConfigFromInputsAsync()
|
||||||
|
{
|
||||||
|
ParameterStatusText = "正在检查并保存修改项...";
|
||||||
|
await _testPageInputWriteLock.WaitAsync();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (!TryReadParameterConfig(out TestParameterConfig config, out string error))
|
if (!TryReadParameterConfig(out TestParameterConfig config, out string error))
|
||||||
{
|
{
|
||||||
@@ -1841,9 +1845,8 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
IReadOnlyList<string> changedPlcItems = await WriteChangedParameterConfigToPlcAsync(_parameterConfig, config);
|
||||||
{
|
bool communicationConfigChanged = HasCommunicationConfigChanged(_parameterConfig, config);
|
||||||
await WriteParameterConfigToPlcAsync(config);
|
|
||||||
_parameterConfig = config;
|
_parameterConfig = config;
|
||||||
SaveParameterConfig();
|
SaveParameterConfig();
|
||||||
UpdateParameterSummaries();
|
UpdateParameterSummaries();
|
||||||
@@ -1853,45 +1856,103 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
await AutoStopIfSpeedTorqueProtectionReachedAsync();
|
await AutoStopIfSpeedTorqueProtectionReachedAsync();
|
||||||
_hasLoadedParameterConfigFromPlc = true;
|
_hasLoadedParameterConfigFromPlc = true;
|
||||||
_parameterRetryTimer.Stop();
|
_parameterRetryTimer.Stop();
|
||||||
ParameterStatusText = "PLC配置写入成功";
|
|
||||||
|
if (changedPlcItems.Count > 0)
|
||||||
|
{
|
||||||
|
ParameterStatusText = $"保存成功,仅写入 {changedPlcItems.Count} 项:{string.Join("、", changedPlcItems)}";
|
||||||
|
}
|
||||||
|
else if (communicationConfigChanged)
|
||||||
|
{
|
||||||
|
ParameterStatusText = "保存成功,通信配置已更新,无需写入 PLC 参数。";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ParameterStatusText = "参数未修改,无需写入 PLC。";
|
||||||
|
}
|
||||||
|
|
||||||
Log.Information(
|
Log.Information(
|
||||||
"PLC参数配置写入成功,地址 {IpAddress}:{Port},站号 {UnitId},轴向力模式 {AxialForceMode}",
|
"参数配置差异保存成功,PLC写入 {WriteCount} 项:{ChangedItems},通信配置修改 {CommunicationConfigChanged},地址 {IpAddress}:{Port},站号 {UnitId}",
|
||||||
|
changedPlcItems.Count,
|
||||||
|
changedPlcItems.Count > 0 ? string.Join("、", changedPlcItems) : "无",
|
||||||
|
communicationConfigChanged,
|
||||||
config.PlcIpAddress,
|
config.PlcIpAddress,
|
||||||
config.PlcPort,
|
config.PlcPort,
|
||||||
config.PlcUnitId,
|
config.PlcUnitId);
|
||||||
config.UseAxialPullForceSetpoint ? "轴向拉力" : "轴向跳动力");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ParameterStatusText = $"PLC配置写入失败:{ex.Message}";
|
ParameterStatusText = $"PLC配置写入失败:{ex.Message}";
|
||||||
Log.Error(ex, "PLC参数配置写入失败");
|
Log.Error(ex, "PLC参数配置写入失败");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_testPageInputWriteLock.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task WriteParameterConfigToPlcAsync(TestParameterConfig config)
|
private async Task<IReadOnlyList<string>> WriteChangedParameterConfigToPlcAsync(TestParameterConfig current, TestParameterConfig updated)
|
||||||
{
|
{
|
||||||
PlcConnectionConfig plcConfig = config.ToPlcConnectionConfig();
|
PlcConnectionConfig plcConfig = updated.ToPlcConnectionConfig();
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialDisplacementLimitRegister, (float)config.AxialDisplacementLimit);
|
var changedItems = new List<string>();
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialSpeedRegister, (float)config.AxialSpeed);
|
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialManualDisplacementRegister, (float)config.AxialManualDisplacement);
|
await WriteChangedFloatAsync(AxialDisplacementLimitRegister, "轴向位移极限", current.AxialDisplacementLimit, updated.AxialDisplacementLimit);
|
||||||
await _plcCoilService.WriteCoilAsync(plcConfig, AxialForceModeCoil, config.UseAxialPullForceSetpoint);
|
await WriteChangedFloatAsync(AxialSpeedRegister, "轴向手/自动速度", current.AxialSpeed, updated.AxialSpeed);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialPullForceSetpointRegister, (float)config.AxialForceSetpoint);
|
await WriteChangedFloatAsync(AxialManualDisplacementRegister, "轴向手动位移", current.AxialManualDisplacement, updated.AxialManualDisplacement);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialJumpForceSetpointRegister, (float)config.AxialJumpForceSetpoint);
|
await WriteChangedCoilAsync(AxialForceModeCoil, "轴向力模式", current.UseAxialPullForceSetpoint, updated.UseAxialPullForceSetpoint);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialForceLowerLimitRegister, (float)config.AxialForceLowerLimit);
|
await WriteChangedFloatAsync(AxialPullForceSetpointRegister, "轴向拉力设置", current.AxialForceSetpoint, updated.AxialForceSetpoint);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialForceUpperLimitRegister, (float)config.AxialForceUpperLimit);
|
await WriteChangedFloatAsync(AxialJumpForceSetpointRegister, "轴向跳动力设置", current.AxialJumpForceSetpoint, updated.AxialJumpForceSetpoint);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialForceCoefficientRegister, (float)config.AxialForceCoefficient);
|
await WriteChangedFloatAsync(AxialForceLowerLimitRegister, "轴向力下限", current.AxialForceLowerLimit, updated.AxialForceLowerLimit);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, AxialForceProtectionRegister, (float)config.AxialForceProtection);
|
await WriteChangedFloatAsync(AxialForceUpperLimitRegister, "轴向力上限", current.AxialForceUpperLimit, updated.AxialForceUpperLimit);
|
||||||
await _plcRegisterService.WriteUInt16Async(plcConfig, AxialForceHoldTimeRegister, ScaleTenthsToPlc(config.AxialForceHoldTime, "轴向力保持时间设置"));
|
await WriteChangedFloatAsync(AxialForceCoefficientRegister, "轴向力系数", current.AxialForceCoefficient, updated.AxialForceCoefficient);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, SpeedTorqueDisplacementLimitRegister, (float)config.SpeedTorqueDisplacementLimit);
|
await WriteChangedFloatAsync(AxialForceProtectionRegister, "轴向力保护", current.AxialForceProtection, updated.AxialForceProtection);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, SpeedTorqueSpeedRegister, (float)config.SpeedTorqueSpeed);
|
await WriteChangedTenthsAsync(AxialForceHoldTimeRegister, "轴向力保持时间", current.AxialForceHoldTime, updated.AxialForceHoldTime);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, SpeedTorqueManualDisplacementRegister, (float)config.SpeedTorqueManualDisplacement);
|
await WriteChangedFloatAsync(SpeedTorqueDisplacementLimitRegister, "转速/扭矩位移极限", current.SpeedTorqueDisplacementLimit, updated.SpeedTorqueDisplacementLimit);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, TorqueCoefficientRegister, (float)config.TorqueCoefficient);
|
await WriteChangedFloatAsync(SpeedTorqueSpeedRegister, "转速/扭矩手/自动速度", current.SpeedTorqueSpeed, updated.SpeedTorqueSpeed);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, TorqueProtectionRegister, (float)config.TorqueProtection);
|
await WriteChangedFloatAsync(SpeedTorqueManualDisplacementRegister, "转速/扭矩手动位移", current.SpeedTorqueManualDisplacement, updated.SpeedTorqueManualDisplacement);
|
||||||
await _plcRegisterService.WriteUInt16Async(plcConfig, HoldTorqueRegister, ScaleTenthsToPlc(config.HoldTorque, "保持扭矩设置"));
|
await WriteChangedFloatAsync(TorqueCoefficientRegister, "扭矩系数", current.TorqueCoefficient, updated.TorqueCoefficient);
|
||||||
await _plcRegisterService.WriteUInt16Async(plcConfig, TorqueHoldTimeRegister, ScaleTenthsToPlc(config.TorqueHoldTime, "扭矩保持时间设置"));
|
await WriteChangedFloatAsync(TorqueProtectionRegister, "扭矩保护", current.TorqueProtection, updated.TorqueProtection);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, SpeedCoefficientRegister, (float)config.SpeedCoefficient);
|
await WriteChangedTenthsAsync(HoldTorqueRegister, "保持扭矩", current.HoldTorque, updated.HoldTorque);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, SpeedStopThresholdRegister, (float)config.SpeedStopThreshold);
|
await WriteChangedTenthsAsync(TorqueHoldTimeRegister, "扭矩保持时间", current.TorqueHoldTime, updated.TorqueHoldTime);
|
||||||
await _plcRegisterService.WriteFloatAsync(plcConfig, PressureCoefficientRegister, (float)config.PressureCoefficient);
|
await WriteChangedFloatAsync(SpeedCoefficientRegister, "转速系数", current.SpeedCoefficient, updated.SpeedCoefficient);
|
||||||
|
await WriteChangedFloatAsync(SpeedStopThresholdRegister, "低速停止", current.SpeedStopThreshold, updated.SpeedStopThreshold);
|
||||||
|
await WriteChangedFloatAsync(PressureCoefficientRegister, "压力系数", current.PressureCoefficient, updated.PressureCoefficient);
|
||||||
|
|
||||||
|
return changedItems;
|
||||||
|
|
||||||
|
async Task WriteChangedFloatAsync(ushort registerAddress, string fieldName, double oldValue, double newValue)
|
||||||
|
{
|
||||||
|
if (AreEquivalentFloatRegisterValues(oldValue, newValue))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _plcRegisterService.WriteFloatAsync(plcConfig, registerAddress, (float)newValue);
|
||||||
|
changedItems.Add($"{fieldName}(D{registerAddress})");
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task WriteChangedTenthsAsync(ushort registerAddress, string fieldName, double oldValue, double newValue)
|
||||||
|
{
|
||||||
|
ushort oldRawValue = ScaleTenthsToPlc(oldValue, fieldName);
|
||||||
|
ushort newRawValue = ScaleTenthsToPlc(newValue, fieldName);
|
||||||
|
if (oldRawValue == newRawValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _plcRegisterService.WriteUInt16Async(plcConfig, registerAddress, newRawValue);
|
||||||
|
changedItems.Add($"{fieldName}(D{registerAddress})");
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task WriteChangedCoilAsync(ushort coilAddress, string fieldName, bool oldValue, bool newValue)
|
||||||
|
{
|
||||||
|
if (oldValue == newValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _plcCoilService.WriteCoilAsync(plcConfig, coilAddress, newValue);
|
||||||
|
changedItems.Add($"{fieldName}(M{coilAddress})");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryReadParameterConfig(out TestParameterConfig config, out string error)
|
private bool TryReadParameterConfig(out TestParameterConfig config, out string error)
|
||||||
@@ -3541,6 +3602,21 @@ public sealed class MainWindowViewModel : ObservableObject
|
|||||||
return value.ToString("0.###", CultureInfo.InvariantCulture);
|
return value.ToString("0.###", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool AreEquivalentFloatRegisterValues(double left, double right)
|
||||||
|
{
|
||||||
|
return BitConverter.SingleToInt32Bits((float)left) == BitConverter.SingleToInt32Bits((float)right);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool HasCommunicationConfigChanged(TestParameterConfig current, TestParameterConfig updated)
|
||||||
|
{
|
||||||
|
return !string.Equals(current.PlcIpAddress, updated.PlcIpAddress, StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| current.PlcPort != updated.PlcPort
|
||||||
|
|| current.PlcUnitId != updated.PlcUnitId
|
||||||
|
|| current.PlcPulseMilliseconds != updated.PlcPulseMilliseconds
|
||||||
|
|| current.PlcTimeoutMilliseconds != updated.PlcTimeoutMilliseconds
|
||||||
|
|| current.FloatWordOrder != updated.FloatWordOrder;
|
||||||
|
}
|
||||||
|
|
||||||
private static double ScaleTenthsFromPlc(ushort registerValue)
|
private static double ScaleTenthsFromPlc(ushort registerValue)
|
||||||
{
|
{
|
||||||
return registerValue / TenthsRegisterScale;
|
return registerValue / TenthsRegisterScale;
|
||||||
|
|||||||
Reference in New Issue
Block a user