diff --git a/src/Exo/Service/Exo.Service.Grpc/GrpcCoolingService.cs b/src/Exo/Service/Exo.Service.Grpc/GrpcCoolingService.cs index 5fff81d3..bcdf0a14 100644 --- a/src/Exo/Service/Exo.Service.Grpc/GrpcCoolingService.cs +++ b/src/Exo/Service/Exo.Service.Grpc/GrpcCoolingService.cs @@ -120,4 +120,69 @@ public ValueTask SetSoftwareControlCurveCoolingAsync(SoftwareCurveCoolingParamet _ => throw new InvalidOperationException("Unsupported control curve data."), }; } + + public ValueTask SetHardwareControlCurveCoolingAsync(HardwareCurveCoolingParameters parameters, CancellationToken cancellationToken) + { + return parameters.ControlCurve.RawValue switch + { + UnsignedIntegerCoolingControlCurve unsignedIntegerCurve => + _coolingService.SetHardwareControlCurveAsync + ( + parameters.CoolingDeviceId, + parameters.CoolerId, + parameters.SensorId, + new InterpolatedSegmentControlCurve + ( + ImmutableArray.CreateRange(unsignedIntegerCurve.SegmentPoints, dp => new DataPoint(dp.X, checked((byte)dp.Y))), + unsignedIntegerCurve.InitialValue, + MonotonicityValidators.IncreasingUpTo100 + ), + cancellationToken + ), + SignedIntegerCoolingControlCurve signedIntegerCurve => + _coolingService.SetHardwareControlCurveAsync + ( + parameters.CoolingDeviceId, + parameters.CoolerId, + parameters.SensorId, + new InterpolatedSegmentControlCurve + ( + ImmutableArray.CreateRange(signedIntegerCurve.SegmentPoints, dp => new DataPoint(dp.X, checked((byte)dp.Y))), + signedIntegerCurve.InitialValue, + MonotonicityValidators.IncreasingUpTo100 + ), + cancellationToken + ), + SinglePrecisionFloatingPointCoolingControlCurve singleFloatCurve => + _coolingService.SetHardwareControlCurveAsync + ( + parameters.CoolingDeviceId, + parameters.CoolerId, + parameters.SensorId, + new InterpolatedSegmentControlCurve + ( + ImmutableArray.CreateRange(singleFloatCurve.SegmentPoints, dp => new DataPoint(dp.X, checked((byte)dp.Y))), + singleFloatCurve.InitialValue, + MonotonicityValidators.IncreasingUpTo100 + ), + cancellationToken + ), + DoublePrecisionFloatingPointCoolingControlCurve doubleFloatCurve => + _coolingService.SetHardwareControlCurveAsync + ( + parameters.CoolingDeviceId, + parameters.CoolerId, + parameters.SensorId, + new InterpolatedSegmentControlCurve + ( + ImmutableArray.CreateRange(doubleFloatCurve.SegmentPoints, dp => new DataPoint(dp.X, checked((byte)dp.Y))), + doubleFloatCurve.InitialValue, + MonotonicityValidators.IncreasingUpTo100 + ), + cancellationToken + ), + null => throw new ArgumentException("Missing control curve."), + _ => throw new InvalidOperationException("Unsupported control curve data."), + }; + } } diff --git a/src/Exo/Ui/Exo.Contracts.Ui.Settings/Cooling/HardwareCurveCoolingParameters.cs b/src/Exo/Ui/Exo.Contracts.Ui.Settings/Cooling/HardwareCurveCoolingParameters.cs new file mode 100644 index 00000000..d1ceb2c7 --- /dev/null +++ b/src/Exo/Ui/Exo.Contracts.Ui.Settings/Cooling/HardwareCurveCoolingParameters.cs @@ -0,0 +1,17 @@ +using System.Runtime.Serialization; + +namespace Exo.Contracts.Ui.Settings.Cooling; + +[DataContract] +public sealed class HardwareCurveCoolingParameters +{ + [DataMember(Order = 1)] + public required Guid CoolingDeviceId { get; init; } + [DataMember(Order = 2)] + public required Guid CoolerId { get; init; } + [DataMember(Order = 3)] + public required Guid SensorId { get; init; } + + [DataMember(Order = 4)] + public required CoolingControlCurve ControlCurve { get; init; } +} diff --git a/src/Exo/Ui/Exo.Contracts.Ui.Settings/ICoolingService.cs b/src/Exo/Ui/Exo.Contracts.Ui.Settings/ICoolingService.cs index 1d293b1e..5f5c4108 100644 --- a/src/Exo/Ui/Exo.Contracts.Ui.Settings/ICoolingService.cs +++ b/src/Exo/Ui/Exo.Contracts.Ui.Settings/ICoolingService.cs @@ -40,4 +40,11 @@ public interface ICoolingService /// [OperationContract(Name = "SetSoftwareControlCurveCooling")] ValueTask SetSoftwareControlCurveCoolingAsync(SoftwareCurveCoolingParameters parameters, CancellationToken cancellationToken); + + /// Sets a hardware-managed control curve for the specified device and cooler. + /// + /// + /// + [OperationContract(Name = "SetHardwareControlCurveCooling")] + ValueTask SetHardwareControlCurveCoolingAsync(HardwareCurveCoolingParameters parameters, CancellationToken cancellationToken); }