Skip to content

Commit

Permalink
✨ Cooling: Implement hardware curves in the backend service.
Browse files Browse the repository at this point in the history
There is a small caveat at the moment, in that the data type of a sensor is considered to be identical for both sensor readings and cooling curve input.
In practice, it is possible for a sensor to have more precision than what the hardware cooling curve allows.
Since we hard-cast out cooling curves upon use in the backend, that shouldn't be too much of a problem, but it would be better if the information was (properly) transferred to the UI.
This is to be done later, as it is not critical for minimum operation.
  • Loading branch information
hexawyz committed Jan 3, 2025
1 parent 4a86ec0 commit 2642a2b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/Exo/Service/Exo.Service.Grpc/GrpcCoolingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ulong, byte>
(
ImmutableArray.CreateRange(unsignedIntegerCurve.SegmentPoints, dp => new DataPoint<ulong, byte>(dp.X, checked((byte)dp.Y))),
unsignedIntegerCurve.InitialValue,
MonotonicityValidators<byte>.IncreasingUpTo100
),
cancellationToken
),
SignedIntegerCoolingControlCurve signedIntegerCurve =>
_coolingService.SetHardwareControlCurveAsync
(
parameters.CoolingDeviceId,
parameters.CoolerId,
parameters.SensorId,
new InterpolatedSegmentControlCurve<long, byte>
(
ImmutableArray.CreateRange(signedIntegerCurve.SegmentPoints, dp => new DataPoint<long, byte>(dp.X, checked((byte)dp.Y))),
signedIntegerCurve.InitialValue,
MonotonicityValidators<byte>.IncreasingUpTo100
),
cancellationToken
),
SinglePrecisionFloatingPointCoolingControlCurve singleFloatCurve =>
_coolingService.SetHardwareControlCurveAsync
(
parameters.CoolingDeviceId,
parameters.CoolerId,
parameters.SensorId,
new InterpolatedSegmentControlCurve<float, byte>
(
ImmutableArray.CreateRange(singleFloatCurve.SegmentPoints, dp => new DataPoint<float, byte>(dp.X, checked((byte)dp.Y))),
singleFloatCurve.InitialValue,
MonotonicityValidators<byte>.IncreasingUpTo100
),
cancellationToken
),
DoublePrecisionFloatingPointCoolingControlCurve doubleFloatCurve =>
_coolingService.SetHardwareControlCurveAsync
(
parameters.CoolingDeviceId,
parameters.CoolerId,
parameters.SensorId,
new InterpolatedSegmentControlCurve<double, byte>
(
ImmutableArray.CreateRange(doubleFloatCurve.SegmentPoints, dp => new DataPoint<double, byte>(dp.X, checked((byte)dp.Y))),
doubleFloatCurve.InitialValue,
MonotonicityValidators<byte>.IncreasingUpTo100
),
cancellationToken
),
null => throw new ArgumentException("Missing control curve."),
_ => throw new InvalidOperationException("Unsupported control curve data."),
};
}
}
Original file line number Diff line number Diff line change
@@ -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; }
}
7 changes: 7 additions & 0 deletions src/Exo/Ui/Exo.Contracts.Ui.Settings/ICoolingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ public interface ICoolingService
/// <returns></returns>
[OperationContract(Name = "SetSoftwareControlCurveCooling")]
ValueTask SetSoftwareControlCurveCoolingAsync(SoftwareCurveCoolingParameters parameters, CancellationToken cancellationToken);

/// <summary>Sets a hardware-managed control curve for the specified device and cooler.</summary>
/// <param name="parameters"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[OperationContract(Name = "SetHardwareControlCurveCooling")]
ValueTask SetHardwareControlCurveCoolingAsync(HardwareCurveCoolingParameters parameters, CancellationToken cancellationToken);
}

0 comments on commit 2642a2b

Please sign in to comment.