From 691129eff4e1c3b6b5e133b5782d4a8a981390a9 Mon Sep 17 00:00:00 2001 From: Alek-ban Date: Thu, 12 Feb 2026 08:34:19 +0300 Subject: [PATCH] refactor: hardware services --- .../Abstractions/ServiceConfigurationBase.cs | 12 ++ GSS2.Core/Hardware/CameraService.cs | 109 +++++++++--------- GSS2.Core/Hardware/ComputeResourcesService.cs | 2 + GSS2.Core/Hardware/IlluminatorService.cs | 51 ++++---- GSS2.Core/Hardware/LightsService.cs | 34 +++--- .../Hardware/TemperatureHumidityService.cs | 34 +++--- 6 files changed, 126 insertions(+), 116 deletions(-) create mode 100644 GSS2.Core/Abstractions/ServiceConfigurationBase.cs diff --git a/GSS2.Core/Abstractions/ServiceConfigurationBase.cs b/GSS2.Core/Abstractions/ServiceConfigurationBase.cs new file mode 100644 index 0000000..4037ba3 --- /dev/null +++ b/GSS2.Core/Abstractions/ServiceConfigurationBase.cs @@ -0,0 +1,12 @@ +namespace GSS2.Core.Abstractions; + +public abstract record ServiceConfigurationBase +{ + public virtual string ToString(string separator, int indent) + { + List strs = new List(); + foreach (var prop in GetType().GetProperties()) + strs.Add($"{prop.Name}: {prop.GetValue(this)}"); + return string.Join(separator, strs.Select(s => $"{new string(' ', indent)}{s}")); + } +} \ No newline at end of file diff --git a/GSS2.Core/Hardware/CameraService.cs b/GSS2.Core/Hardware/CameraService.cs index 7fb7989..3cc9817 100644 --- a/GSS2.Core/Hardware/CameraService.cs +++ b/GSS2.Core/Hardware/CameraService.cs @@ -1,9 +1,15 @@ -using System.Runtime.InteropServices; -using Microsoft.Extensions.Logging; -using LibCameraSharp; -using Stream = LibCameraSharp.Stream; using System.Buffers; +using System.Text; +using System.Runtime.InteropServices; + +using Microsoft.Extensions.Logging; + +using LibCameraSharp; + using GSS2.Core.Extentions; +using GSS2.Core.Abstractions; + +using Stream = LibCameraSharp.Stream; namespace GSS2.Core.Hardware; @@ -26,31 +32,6 @@ public class CameraService : IDisposable public ulong Length { 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] private enum State { @@ -63,6 +44,30 @@ public class CameraService : IDisposable 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 readonly ILogger _logger; private readonly CameraServiceConfiguration _configuration; @@ -77,39 +82,40 @@ public class CameraService : IDisposable private Stream? _viewFinderStream; private Stream? _imageCaptureStream; private List? _imageCaptureMappedBuffers; + private System.Timers.Timer? _viewFinderTimer = null; + private System.Timers.ElapsedEventHandler? _viewFinderTimerElapsed = null; + private EventHandler? _viewFinderRequestComplitedHandler = null; private readonly CancellationTokenSource _disposeCts = new CancellationTokenSource(); public bool IsImageCapturing { get; private set; } = false; + public List ViewFinderBufferQueue { get; private set; } = new List(); public CameraService(ILogger logger, CameraServiceConfiguration? configuration = null, bool autoInitialize = false) { _logger = logger; - _logger.LogInformation("CameraService initialization"); + _logger.LogInformation("Initialization"); - if (configuration is null) - { - _logger.LogWarning("CameraService configuration not set. Using default configuration."); - _configuration = CameraServiceConfiguration.Default; - } - else + try { + if (configuration is null) + { + configuration = CameraServiceConfiguration.Default; + _logger.LogWarning("Configuration not set. Using default configuration."); + } _configuration = configuration; + _logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4)); + + if (autoInitialize) + Initialize(CancellationToken.None); + } + catch (Exception e) + { + _logger.LogCritical(e, "An exception occurred while initialization"); + throw; } - _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) - Initialize(CancellationToken.None); + _logger.LogInformation("Initialized"); } public async Task InitializeAsync(CancellationToken cancellationToken) @@ -664,11 +670,6 @@ public class CameraService : IDisposable return image; } - public List ViewFinderBufferQueue { get; private set; } = new List(); - private System.Timers.Timer? _viewFinderTimer = null; - private System.Timers.ElapsedEventHandler? _viewFinderTimerElapsed = null; - private EventHandler? _viewFinderRequestComplitedHandler = null; - public void StartViewFinder() { if (_camera is null) diff --git a/GSS2.Core/Hardware/ComputeResourcesService.cs b/GSS2.Core/Hardware/ComputeResourcesService.cs index 3414bbb..9f0b5d8 100644 --- a/GSS2.Core/Hardware/ComputeResourcesService.cs +++ b/GSS2.Core/Hardware/ComputeResourcesService.cs @@ -34,6 +34,8 @@ public class ComputeResourcesService public ComputeResourcesService(ILogger logger) { _logger = logger; + _logger.LogInformation("Initialization"); + _logger.LogInformation("Initialized"); } public ComputeResourcesSnapshot GetSnapshot() diff --git a/GSS2.Core/Hardware/IlluminatorService.cs b/GSS2.Core/Hardware/IlluminatorService.cs index 64ba463..c623c83 100644 --- a/GSS2.Core/Hardware/IlluminatorService.cs +++ b/GSS2.Core/Hardware/IlluminatorService.cs @@ -1,12 +1,15 @@ using System.Device.Gpio; using System.Device.Pwm; + using Microsoft.Extensions.Logging; +using GSS2.Core.Abstractions; + namespace GSS2.Core.Hardware; public class IlluminatorService : IDisposable { - public class IlluminatorServiceConfiguration + public record IlluminatorServiceConfiguration : ServiceConfigurationBase { public static IlluminatorServiceConfiguration Default => new IlluminatorServiceConfiguration { @@ -76,38 +79,22 @@ public class IlluminatorService : IDisposable { _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); + _logger.LogInformation("Initialization"); try { + if (configuration is null) + { + configuration = IlluminatorServiceConfiguration.Default; + _logger.LogWarning("Configuration not set. Using default configuration."); + } + _configuration = configuration; + _logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4)); + + CheckPwmPin(_configuration.WhitePwmPin); + CheckPwmPin(_configuration.Uv254PwmPin); + CheckPwmPin(_configuration.Uv365PwmPin); + _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)); @@ -120,9 +107,11 @@ public class IlluminatorService : IDisposable } catch (Exception e) { - _logger.LogCritical(e, "An exception occurred while illuminator initialization"); + _logger.LogCritical(e, "An exception occurred while initialization"); throw; } + + _logger.LogInformation("Initialized"); } public void SetIntensity(double? white = null, double? uv365 = null, double? uv254 = null) diff --git a/GSS2.Core/Hardware/LightsService.cs b/GSS2.Core/Hardware/LightsService.cs index a7b2d2f..6536684 100644 --- a/GSS2.Core/Hardware/LightsService.cs +++ b/GSS2.Core/Hardware/LightsService.cs @@ -1,15 +1,19 @@ using System.Drawing; using System.Runtime.CompilerServices; + using Microsoft.Extensions.Logging; + using Grpc.Core; using Grpc.Net.Client; + using GSS2.LightsControl.CSharpClient; +using GSS2.Core.Abstractions; namespace GSS2.Core.Hardware; public class LightsService { - public class LightsServiceConfiguration() + public record LightsServiceConfiguration : ServiceConfigurationBase { public static LightsServiceConfiguration Default => new LightsServiceConfiguration { @@ -27,23 +31,27 @@ public class LightsService { _logger = logger; - _logger.LogInformation("Lights initialization"); + _logger.LogInformation("Initialization"); - if (configuration is null) - { - _logger.LogWarning("Lights configuration not set. Using default configuration."); - _configuration = LightsServiceConfiguration.Default; - } - else + try { + if (configuration is null) + { + configuration = LightsServiceConfiguration.Default; + _logger.LogWarning("Configuration not set. Using default configuration."); + } _configuration = configuration; + _logger.LogInformation("Using following configuration: \n{}", _configuration.ToString("\n", 4)); + + _client = new Lights.LightsClient(GrpcChannel.ForAddress(_configuration.ServerAddress)); + } + catch (Exception e) + { + _logger.LogCritical(e, "An exception occurred while initialization"); + throw; } - _logger.LogDebug(@$"Lights use following configuration: - ServerAddress: {_configuration.ServerAddress} - "); - - _client = new Lights.LightsClient(GrpcChannel.ForAddress(_configuration.ServerAddress)); + _logger.LogInformation("Initialized"); } public async Task Run(CancellationToken cancellationToken) diff --git a/GSS2.Core/Hardware/TemperatureHumidityService.cs b/GSS2.Core/Hardware/TemperatureHumidityService.cs index 11b7783..e2a92a2 100644 --- a/GSS2.Core/Hardware/TemperatureHumidityService.cs +++ b/GSS2.Core/Hardware/TemperatureHumidityService.cs @@ -1,11 +1,14 @@ using System.Device.I2c; + using Microsoft.Extensions.Logging; +using GSS2.Core.Abstractions; + namespace GSS2.Core.Hardware; public class TemperatureHumidityService : IDisposable { - public class TemperatureHumidityServiceConfiguration + public record TemperatureHumidityServiceConfiguration : ServiceConfigurationBase { public static TemperatureHumidityServiceConfiguration Default => new TemperatureHumidityServiceConfiguration { @@ -26,32 +29,27 @@ public class TemperatureHumidityService : IDisposable { _logger = logger; - _logger.LogInformation("Temperature and humidity sensor 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} - "); + _logger.LogInformation("Initialization"); 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)); } catch (Exception e) { - _logger.LogCritical(e, "An exception occurred while temperature and humidity sensor initialization"); + _logger.LogCritical(e, "An exception occurred while initialization"); throw; } + + _logger.LogInformation("Initialized"); } public (double temperature, double relativeHumidity) Measure(int measurementsCount = 1, bool checkCrc = true, CancellationToken cancellationToken = default)