forked from amkovkov/GranuSightSoftware2
Первый коммит
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Device.Gpio;
|
||||
using System.Device.Pwm;
|
||||
using System.Device.Pwm.Drivers;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace GSS2.Core.Hardware;
|
||||
|
||||
public class IlluminatorService : IDisposable
|
||||
{
|
||||
public class IlluminatorServiceConfiguration
|
||||
{
|
||||
public static IlluminatorServiceConfiguration Default => new IlluminatorServiceConfiguration
|
||||
{
|
||||
WhitePwmPin = 13,
|
||||
Uv254PwmPin = 18,
|
||||
Uv365PwmPin = 12,
|
||||
WhiteRelayPin = 16,
|
||||
Uv254RelayPin = 15,
|
||||
Uv365RelayPin = 20,
|
||||
FanPin = 21,
|
||||
|
||||
PwmFrequency = 200,
|
||||
|
||||
MaxWhitePwmDuty = 1.0,
|
||||
MaxUv254PwmDuty = 1.0,
|
||||
MaxUv365PwmDuty = 1.0
|
||||
};
|
||||
|
||||
public int WhitePwmPin { get; set; }
|
||||
public int Uv254PwmPin { get; set; }
|
||||
public int Uv365PwmPin { get; set; }
|
||||
public int WhiteRelayPin { get; set; }
|
||||
public int Uv254RelayPin { get; set; }
|
||||
public int Uv365RelayPin { get; set; }
|
||||
public int FanPin { get; set; }
|
||||
|
||||
public int PwmFrequency { get; set; }
|
||||
|
||||
public double MaxWhitePwmDuty { get; set; }
|
||||
public double MaxUv254PwmDuty { get; set; }
|
||||
public double MaxUv365PwmDuty { get; set; }
|
||||
}
|
||||
|
||||
private static readonly Dictionary<int, int> PinPwmChips = new()
|
||||
{
|
||||
{ 12, 0 },
|
||||
{ 13, 0 },
|
||||
{ 14, 0 },
|
||||
{ 15, 0 },
|
||||
{ 18, 0 },
|
||||
{ 19, 0 },
|
||||
};
|
||||
private static readonly Dictionary<int, int> PinPwmChannels = new()
|
||||
{
|
||||
{ 12, 0 },
|
||||
{ 13, 1 },
|
||||
{ 14, 2 },
|
||||
{ 15, 3 },
|
||||
{ 18, 2 },
|
||||
{ 19, 3 }
|
||||
};
|
||||
|
||||
private bool _disposedValue;
|
||||
private readonly ILogger<IlluminatorService> _logger;
|
||||
private readonly IlluminatorServiceConfiguration _configuration;
|
||||
|
||||
private readonly GpioController _gpio;
|
||||
private readonly PwmChannel _whitePwm;
|
||||
private readonly PwmChannel _uv254Pwm;
|
||||
private readonly PwmChannel _uv365Pwm;
|
||||
private readonly GpioPin _whiteRelay;
|
||||
private readonly GpioPin _uv254Relay;
|
||||
private readonly GpioPin _uv365Relay;
|
||||
private readonly GpioPin _fanRelay;
|
||||
|
||||
public IlluminatorService(ILogger<IlluminatorService> logger, IlluminatorServiceConfiguration? configuration = null)
|
||||
{
|
||||
_logger = logger;
|
||||
|
||||
_logger.LogInformation("Illuminator initialization");
|
||||
|
||||
if (configuration is null)
|
||||
{
|
||||
_logger.LogWarning("Illuminator configuration not set. Using default configuration.");
|
||||
_configuration = IlluminatorServiceConfiguration.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
_logger.LogDebug(@$"Illuminator use following configuration:
|
||||
WhitePwmPin: {_configuration.WhitePwmPin}
|
||||
Uv254PwmPin: {_configuration.Uv254PwmPin}
|
||||
Uv365PwmPin: {_configuration.Uv365PwmPin}
|
||||
WhiteRelayPin: {_configuration.WhiteRelayPin}
|
||||
Uv254RelayPin: {_configuration.Uv254RelayPin}
|
||||
Uv365RelayPin: {_configuration.Uv365RelayPin}
|
||||
FanPin: {_configuration.FanPin}
|
||||
PwmFrequency: {_configuration.PwmFrequency}
|
||||
MaxWhitePwmDuty: {_configuration.MaxWhitePwmDuty}
|
||||
MaxUv254PwmDuty: {_configuration.MaxUv254PwmDuty}
|
||||
MaxUv365PwmDuty: {_configuration.MaxUv365PwmDuty}
|
||||
");
|
||||
|
||||
CheckPwmPin(_configuration.WhitePwmPin);
|
||||
CheckPwmPin(_configuration.Uv254PwmPin);
|
||||
CheckPwmPin(_configuration.Uv365PwmPin);
|
||||
|
||||
try
|
||||
{
|
||||
_gpio = new GpioController();
|
||||
_whitePwm = PwmChannel.Create(PinPwmChips[_configuration.WhitePwmPin], PinPwmChannels[_configuration.WhitePwmPin], _configuration.PwmFrequency, CalculateDuty(0, _configuration.MaxWhitePwmDuty));
|
||||
_uv254Pwm = PwmChannel.Create(PinPwmChips[_configuration.Uv254PwmPin], PinPwmChannels[_configuration.Uv254PwmPin], _configuration.PwmFrequency, CalculateDuty(0, _configuration.MaxUv254PwmDuty));
|
||||
_uv365Pwm = PwmChannel.Create(PinPwmChips[_configuration.Uv365PwmPin], PinPwmChannels[_configuration.Uv365PwmPin], _configuration.PwmFrequency, CalculateDuty(0, _configuration.MaxUv365PwmDuty));
|
||||
|
||||
_whiteRelay = _gpio.OpenPin(_configuration.WhiteRelayPin, PinMode.Output, PinValue.Low);
|
||||
_uv254Relay = _gpio.OpenPin(_configuration.Uv254RelayPin, PinMode.Output, PinValue.Low);
|
||||
_uv365Relay = _gpio.OpenPin(_configuration.Uv365RelayPin, PinMode.Output, PinValue.Low);
|
||||
_fanRelay = _gpio.OpenPin(_configuration.FanPin, PinMode.Output, PinValue.Low);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogCritical(e, "An exception occurred while illuminator initialization");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetIntensity(double? white = null, double? uv365 = null, double? uv254 = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (white is not null) _whitePwm.DutyCycle = CalculateDuty(white.Value, _configuration.MaxWhitePwmDuty);
|
||||
if (uv365 is not null) _uv365Pwm.DutyCycle = CalculateDuty(uv365.Value, _configuration.MaxUv365PwmDuty);
|
||||
if (uv254 is not null) _uv254Pwm.DutyCycle = CalculateDuty(uv254.Value, _configuration.MaxUv254PwmDuty);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "An exception occurred while setting illuminator intensity");
|
||||
}
|
||||
}
|
||||
public void TurnOn()
|
||||
{
|
||||
try
|
||||
{
|
||||
_fanRelay.Write(PinValue.High);
|
||||
|
||||
_whitePwm.Start();
|
||||
_uv254Pwm.Start();
|
||||
_uv365Pwm.Start();
|
||||
|
||||
_whiteRelay.Write(PinValue.High);
|
||||
_uv254Relay.Write(PinValue.High);
|
||||
_uv365Relay.Write(PinValue.High);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "An exception occurred while turning on illuminator");
|
||||
}
|
||||
}
|
||||
public void TurnOff()
|
||||
{
|
||||
try
|
||||
{
|
||||
_whitePwm.Stop();
|
||||
_uv254Pwm.Stop();
|
||||
_uv365Pwm.Stop();
|
||||
|
||||
_whiteRelay.Write(PinValue.Low);
|
||||
_uv254Relay.Write(PinValue.Low);
|
||||
_uv365Relay.Write(PinValue.Low);
|
||||
|
||||
_fanRelay.Write(PinValue.Low);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "An exception occurred while turning off illuminator");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
TurnOff();
|
||||
}
|
||||
catch { }
|
||||
|
||||
_whiteRelay?.Dispose();
|
||||
_uv254Relay?.Dispose();
|
||||
_uv365Relay?.Dispose();
|
||||
_fanRelay?.Dispose();
|
||||
_whitePwm?.Dispose();
|
||||
_uv254Pwm?.Dispose();
|
||||
_uv365Pwm?.Dispose();
|
||||
_gpio?.Dispose();
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private static void CheckPwmPin(int pin)
|
||||
{
|
||||
if (!PinPwmChips.TryGetValue(pin, out var _) || !PinPwmChannels.TryGetValue(pin, out var _))
|
||||
throw new ArgumentException($"Unsupported PWM pin {pin}");
|
||||
}
|
||||
private static double CalculateDuty(double intensity, double maxDuty) => Math.Clamp(intensity, 0.0, 1.0) * Math.Clamp(maxDuty, 0.0, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user