forked from amkovkov/GranuSightSoftware2
refactor: hardware services
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
namespace GSS2.Core.Abstractions;
|
||||||
|
|
||||||
|
public abstract record ServiceConfigurationBase
|
||||||
|
{
|
||||||
|
public virtual string ToString(string separator, int indent)
|
||||||
|
{
|
||||||
|
List<string?> strs = new List<string?>();
|
||||||
|
foreach (var prop in GetType().GetProperties())
|
||||||
|
strs.Add($"{prop.Name}: {prop.GetValue(this)}");
|
||||||
|
return string.Join(separator, strs.Select(s => $"{new string(' ', indent)}{s}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
using System.Runtime.InteropServices;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using LibCameraSharp;
|
|
||||||
using Stream = LibCameraSharp.Stream;
|
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
using LibCameraSharp;
|
||||||
|
|
||||||
using GSS2.Core.Extentions;
|
using GSS2.Core.Extentions;
|
||||||
|
using GSS2.Core.Abstractions;
|
||||||
|
|
||||||
|
using Stream = LibCameraSharp.Stream;
|
||||||
|
|
||||||
namespace GSS2.Core.Hardware;
|
namespace GSS2.Core.Hardware;
|
||||||
|
|
||||||
@@ -26,31 +32,6 @@ public class CameraService : IDisposable
|
|||||||
public ulong Length { get; init; }
|
public ulong Length { get; init; }
|
||||||
public ulong AlignedOffset { get; init; }
|
public ulong AlignedOffset { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CameraServiceConfiguration
|
|
||||||
{
|
|
||||||
public static CameraServiceConfiguration Default => new CameraServiceConfiguration
|
|
||||||
{
|
|
||||||
CameraId = "",
|
|
||||||
ViewFinderFrameBufferCount = 5,
|
|
||||||
ViewFinderWidth = 1920,
|
|
||||||
ViewFinderHeight = 1080,
|
|
||||||
ViewFinderFps = 30,
|
|
||||||
ImageCaptureFrameBufferCount = 2,
|
|
||||||
ImageCaptureWidth = 4056,
|
|
||||||
ImageCaptureHeight = 3080,
|
|
||||||
};
|
|
||||||
|
|
||||||
public string CameraId { get; set; } = "";
|
|
||||||
public int ViewFinderFrameBufferCount { get; set; }
|
|
||||||
public int ViewFinderWidth { get; set; }
|
|
||||||
public int ViewFinderHeight { get; set; }
|
|
||||||
public int ViewFinderFps { get; set; }
|
|
||||||
public int ImageCaptureFrameBufferCount { get; set; }
|
|
||||||
public int ImageCaptureWidth { get; set; }
|
|
||||||
public int ImageCaptureHeight { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum State
|
private enum State
|
||||||
{
|
{
|
||||||
@@ -63,6 +44,30 @@ public class CameraService : IDisposable
|
|||||||
ImageCaptureFrameBuffersMapped = 1 << 6
|
ImageCaptureFrameBuffersMapped = 1 << 6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record CameraServiceConfiguration : ServiceConfigurationBase
|
||||||
|
{
|
||||||
|
public static CameraServiceConfiguration Default => new CameraServiceConfiguration
|
||||||
|
{
|
||||||
|
CameraId = "",
|
||||||
|
ViewFinderFrameBufferCount = 5,
|
||||||
|
ViewFinderWidth = 4056,
|
||||||
|
ViewFinderHeight = 3080,
|
||||||
|
ViewFinderFps = 30,
|
||||||
|
ImageCaptureFrameBufferCount = 2,
|
||||||
|
ImageCaptureWidth = 4056,
|
||||||
|
ImageCaptureHeight = 3080
|
||||||
|
};
|
||||||
|
|
||||||
|
public string CameraId { get; set; } = "";
|
||||||
|
public int ViewFinderFrameBufferCount { get; set; }
|
||||||
|
public int ViewFinderWidth { get; set; }
|
||||||
|
public int ViewFinderHeight { get; set; }
|
||||||
|
public int ViewFinderFps { get; set; }
|
||||||
|
public int ImageCaptureFrameBufferCount { get; set; }
|
||||||
|
public int ImageCaptureWidth { get; set; }
|
||||||
|
public int ImageCaptureHeight { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private bool _disposedValue;
|
private bool _disposedValue;
|
||||||
private readonly ILogger<CameraService> _logger;
|
private readonly ILogger<CameraService> _logger;
|
||||||
private readonly CameraServiceConfiguration _configuration;
|
private readonly CameraServiceConfiguration _configuration;
|
||||||
@@ -77,40 +82,41 @@ public class CameraService : IDisposable
|
|||||||
private Stream? _viewFinderStream;
|
private Stream? _viewFinderStream;
|
||||||
private Stream? _imageCaptureStream;
|
private Stream? _imageCaptureStream;
|
||||||
private List<MappedBuffer>? _imageCaptureMappedBuffers;
|
private List<MappedBuffer>? _imageCaptureMappedBuffers;
|
||||||
|
private System.Timers.Timer? _viewFinderTimer = null;
|
||||||
|
private System.Timers.ElapsedEventHandler? _viewFinderTimerElapsed = null;
|
||||||
|
private EventHandler<Camera.RequestCompletedEventArgs>? _viewFinderRequestComplitedHandler = null;
|
||||||
private readonly CancellationTokenSource _disposeCts = new CancellationTokenSource();
|
private readonly CancellationTokenSource _disposeCts = new CancellationTokenSource();
|
||||||
|
|
||||||
public bool IsImageCapturing { get; private set; } = false;
|
public bool IsImageCapturing { get; private set; } = false;
|
||||||
|
public List<FrameBuffer> ViewFinderBufferQueue { get; private set; } = new List<FrameBuffer>();
|
||||||
|
|
||||||
public CameraService(ILogger<CameraService> logger, CameraServiceConfiguration? configuration = null, bool autoInitialize = false)
|
public CameraService(ILogger<CameraService> logger, CameraServiceConfiguration? configuration = null, bool autoInitialize = false)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_logger.LogInformation("CameraService initialization");
|
_logger.LogInformation("Initialization");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (configuration is null)
|
if (configuration is null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("CameraService configuration not set. Using default configuration.");
|
configuration = CameraServiceConfiguration.Default;
|
||||||
_configuration = CameraServiceConfiguration.Default;
|
_logger.LogWarning("Configuration not set. Using default configuration.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
_logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4));
|
||||||
|
|
||||||
_logger.LogDebug(@$"CameraService use following configuration:
|
|
||||||
CameraId: {_configuration.CameraId}
|
|
||||||
ViewFinderFrameBufferCount: {_configuration.ViewFinderFrameBufferCount}
|
|
||||||
ViewFinderWidth: {_configuration.ViewFinderWidth}
|
|
||||||
ViewFinderHeight: {_configuration.ViewFinderHeight}
|
|
||||||
ViewFinderFps: {_configuration.ViewFinderFps}
|
|
||||||
ImageCaptureFrameBufferCount: {_configuration.ImageCaptureFrameBufferCount}
|
|
||||||
ImageCaptureWidth: {_configuration.ImageCaptureWidth}
|
|
||||||
ImageCaptureHeight: {_configuration.ImageCaptureHeight}
|
|
||||||
");
|
|
||||||
|
|
||||||
if (autoInitialize)
|
if (autoInitialize)
|
||||||
Initialize(CancellationToken.None);
|
Initialize(CancellationToken.None);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogCritical(e, "An exception occurred while initialization");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Initialized");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task InitializeAsync(CancellationToken cancellationToken)
|
public async Task InitializeAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@@ -664,11 +670,6 @@ public class CameraService : IDisposable
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FrameBuffer> ViewFinderBufferQueue { get; private set; } = new List<FrameBuffer>();
|
|
||||||
private System.Timers.Timer? _viewFinderTimer = null;
|
|
||||||
private System.Timers.ElapsedEventHandler? _viewFinderTimerElapsed = null;
|
|
||||||
private EventHandler<Camera.RequestCompletedEventArgs>? _viewFinderRequestComplitedHandler = null;
|
|
||||||
|
|
||||||
public void StartViewFinder()
|
public void StartViewFinder()
|
||||||
{
|
{
|
||||||
if (_camera is null)
|
if (_camera is null)
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public class ComputeResourcesService
|
|||||||
public ComputeResourcesService(ILogger<ComputeResourcesService> logger)
|
public ComputeResourcesService(ILogger<ComputeResourcesService> logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_logger.LogInformation("Initialization");
|
||||||
|
_logger.LogInformation("Initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputeResourcesSnapshot GetSnapshot()
|
public ComputeResourcesSnapshot GetSnapshot()
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
using System.Device.Gpio;
|
using System.Device.Gpio;
|
||||||
using System.Device.Pwm;
|
using System.Device.Pwm;
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
using GSS2.Core.Abstractions;
|
||||||
|
|
||||||
namespace GSS2.Core.Hardware;
|
namespace GSS2.Core.Hardware;
|
||||||
|
|
||||||
public class IlluminatorService : IDisposable
|
public class IlluminatorService : IDisposable
|
||||||
{
|
{
|
||||||
public class IlluminatorServiceConfiguration
|
public record IlluminatorServiceConfiguration : ServiceConfigurationBase
|
||||||
{
|
{
|
||||||
public static IlluminatorServiceConfiguration Default => new IlluminatorServiceConfiguration
|
public static IlluminatorServiceConfiguration Default => new IlluminatorServiceConfiguration
|
||||||
{
|
{
|
||||||
@@ -76,38 +79,22 @@ public class IlluminatorService : IDisposable
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_logger.LogInformation("Illuminator initialization");
|
_logger.LogInformation("Initialization");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (configuration is null)
|
if (configuration is null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Illuminator configuration not set. Using default configuration.");
|
configuration = IlluminatorServiceConfiguration.Default;
|
||||||
_configuration = IlluminatorServiceConfiguration.Default;
|
_logger.LogWarning("Configuration not set. Using default configuration.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
_logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4));
|
||||||
|
|
||||||
_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.WhitePwmPin);
|
||||||
CheckPwmPin(_configuration.Uv254PwmPin);
|
CheckPwmPin(_configuration.Uv254PwmPin);
|
||||||
CheckPwmPin(_configuration.Uv365PwmPin);
|
CheckPwmPin(_configuration.Uv365PwmPin);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_gpio = new GpioController();
|
_gpio = new GpioController();
|
||||||
_whitePwm = PwmChannel.Create(PinPwmChips[_configuration.WhitePwmPin], PinPwmChannels[_configuration.WhitePwmPin], _configuration.PwmFrequency, CalculateDuty(0, _configuration.MaxWhitePwmDuty));
|
_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));
|
_uv254Pwm = PwmChannel.Create(PinPwmChips[_configuration.Uv254PwmPin], PinPwmChannels[_configuration.Uv254PwmPin], _configuration.PwmFrequency, CalculateDuty(0, _configuration.MaxUv254PwmDuty));
|
||||||
@@ -120,9 +107,11 @@ public class IlluminatorService : IDisposable
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.LogCritical(e, "An exception occurred while illuminator initialization");
|
_logger.LogCritical(e, "An exception occurred while initialization");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetIntensity(double? white = null, double? uv365 = null, double? uv254 = null)
|
public void SetIntensity(double? white = null, double? uv365 = null, double? uv254 = null)
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
|
|
||||||
using GSS2.LightsControl.CSharpClient;
|
using GSS2.LightsControl.CSharpClient;
|
||||||
|
using GSS2.Core.Abstractions;
|
||||||
|
|
||||||
namespace GSS2.Core.Hardware;
|
namespace GSS2.Core.Hardware;
|
||||||
|
|
||||||
public class LightsService
|
public class LightsService
|
||||||
{
|
{
|
||||||
public class LightsServiceConfiguration()
|
public record LightsServiceConfiguration : ServiceConfigurationBase
|
||||||
{
|
{
|
||||||
public static LightsServiceConfiguration Default => new LightsServiceConfiguration
|
public static LightsServiceConfiguration Default => new LightsServiceConfiguration
|
||||||
{
|
{
|
||||||
@@ -27,24 +31,28 @@ public class LightsService
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_logger.LogInformation("Lights initialization");
|
_logger.LogInformation("Initialization");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (configuration is null)
|
if (configuration is null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Lights configuration not set. Using default configuration.");
|
configuration = LightsServiceConfiguration.Default;
|
||||||
_configuration = LightsServiceConfiguration.Default;
|
_logger.LogWarning("Configuration not set. Using default configuration.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
_logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4));
|
||||||
|
|
||||||
_logger.LogDebug(@$"Lights use following configuration:
|
|
||||||
ServerAddress: {_configuration.ServerAddress}
|
|
||||||
");
|
|
||||||
|
|
||||||
_client = new Lights.LightsClient(GrpcChannel.ForAddress(_configuration.ServerAddress));
|
_client = new Lights.LightsClient(GrpcChannel.ForAddress(_configuration.ServerAddress));
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogCritical(e, "An exception occurred while initialization");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Initialized");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Run(CancellationToken cancellationToken)
|
public async Task Run(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
using System.Device.I2c;
|
using System.Device.I2c;
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
using GSS2.Core.Abstractions;
|
||||||
|
|
||||||
namespace GSS2.Core.Hardware;
|
namespace GSS2.Core.Hardware;
|
||||||
|
|
||||||
public class TemperatureHumidityService : IDisposable
|
public class TemperatureHumidityService : IDisposable
|
||||||
{
|
{
|
||||||
public class TemperatureHumidityServiceConfiguration
|
public record TemperatureHumidityServiceConfiguration : ServiceConfigurationBase
|
||||||
{
|
{
|
||||||
public static TemperatureHumidityServiceConfiguration Default => new TemperatureHumidityServiceConfiguration
|
public static TemperatureHumidityServiceConfiguration Default => new TemperatureHumidityServiceConfiguration
|
||||||
{
|
{
|
||||||
@@ -26,32 +29,27 @@ public class TemperatureHumidityService : IDisposable
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_logger.LogInformation("Temperature and humidity sensor initialization");
|
_logger.LogInformation("Initialization");
|
||||||
|
|
||||||
if (configuration is null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Temperature and humidity sensor configuration not set. Using default configuration.");
|
|
||||||
_configuration = TemperatureHumidityServiceConfiguration.Default;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogDebug(@$"Temperature and humidity sensor use following configuration:
|
|
||||||
Bus: {_configuration.Bus}
|
|
||||||
Address: {_configuration.Address}
|
|
||||||
");
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (configuration is null)
|
||||||
|
{
|
||||||
|
configuration = TemperatureHumidityServiceConfiguration.Default;
|
||||||
|
_logger.LogWarning("Configuration not set. Using default configuration.");
|
||||||
|
}
|
||||||
|
_configuration = configuration;
|
||||||
|
_logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4));
|
||||||
|
|
||||||
_sensor = I2cDevice.Create(new I2cConnectionSettings(_configuration.Bus, _configuration.Address));
|
_sensor = I2cDevice.Create(new I2cConnectionSettings(_configuration.Bus, _configuration.Address));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.LogCritical(e, "An exception occurred while temperature and humidity sensor initialization");
|
_logger.LogCritical(e, "An exception occurred while initialization");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("Initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
public (double temperature, double relativeHumidity) Measure(int measurementsCount = 1, bool checkCrc = true, CancellationToken cancellationToken = default)
|
public (double temperature, double relativeHumidity) Measure(int measurementsCount = 1, bool checkCrc = true, CancellationToken cancellationToken = default)
|
||||||
|
|||||||
Reference in New Issue
Block a user