Ready to test in Fab

This commit is contained in:
2023-06-03 19:05:08 -07:00
parent 1f5deedc73
commit 2c38ecb399
46 changed files with 1159 additions and 347 deletions

View File

@ -0,0 +1,20 @@
using Barcode.Host.Shared.Models.Stateless;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace Barcode.Host.Server.ApiControllers;
[Route("api/[controller]")]
public class LastScanController : Controller, ILastScanController<IActionResult>
{
private readonly ILastScanService _LastScanService;
public LastScanController(ILastScanService lastScanService) =>
_LastScanService = lastScanService;
[HttpGet()]
public IActionResult GetScan() =>
Json(_LastScanService.GetScan(), new JsonSerializerOptions { PropertyNamingPolicy = null, WriteIndented = true });
}

View File

@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
<TargetFramework>net7.0</TargetFramework>
<UserSecretsId>02dce973-df1d-4325-962a-ed549af8d4c5</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
@ -22,6 +22,7 @@
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
@ -31,9 +32,18 @@
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Barcode.Host.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,186 @@
using Barcode.Host.Server.Models;
using Barcode.Host.Shared.DataModels;
using Barcode.Host.Shared.KeyboardMouse;
using Barcode.Host.Shared.Models.Stateless;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog.Context;
namespace Barcode.Host.Server.HostedService;
public class TimedHostedService : IHostedService, IAggregateInputReader, IDisposable
{
public event InputReader.RaiseKeyPress? OnKeyPress;
private readonly int _ExecutionCount;
private readonly AppSettings _AppSettings;
private readonly ISerialService _SerialService;
private readonly ILastScanService _LastScanService;
private readonly ILogger<TimedHostedService> _Logger;
private readonly ILinuxGroupManager _LinuxGroupManager;
private readonly Dictionary<string, InputReader> _Readers;
private readonly Dictionary<EventCode, char> _CharToEventCodes;
private readonly List<(string MethodName, Timer Timer)> _Timers;
public TimedHostedService(ILogger<TimedHostedService> logger, AppSettings appSettings, ILinuxGroupManager linuxGroupManager, ILastScanService lastScanService, ISerialService serialService)
{
_Readers = new();
_Logger = logger;
_ExecutionCount = 0;
_CharToEventCodes = new();
_AppSettings = appSettings;
_SerialService = serialService;
_LastScanService = lastScanService;
_LinuxGroupManager = linuxGroupManager;
Timer writeTimer = new(Write, null, Timeout.Infinite, Timeout.Infinite);
Timer scanForNewInputsTimer = new(ScanForNewInputs, null, Timeout.Infinite, Timeout.Infinite);
_Timers = new List<(string, Timer)>() { (nameof(Write), writeTimer), (nameof(ScanForNewInputs), scanForNewInputsTimer) };
}
public Task StartAsync(CancellationToken stoppingToken)
{
string? methodName = IMethodName.GetActualAsyncMethodName();
using (LogContext.PushProperty("MethodName", methodName))
{
_Logger.LogInformation($"Timed Hosted Service: {_AppSettings.GitCommitSeven}:{Environment.ProcessId} running.");
_SerialService.Open();
if (!_LinuxGroupManager.IsInInputGroup().WaitAsync(stoppingToken).Result)
{
if (string.IsNullOrEmpty(_AppSettings.RootPassword))
throw new Exception($"Please check appsettings file(s) for <{nameof(_AppSettings.RootPassword)}>!");
_ = _LinuxGroupManager.AddUserToInputGroup(_AppSettings.RootPassword);
_ = _LinuxGroupManager.RebootSystem(_AppSettings.RootPassword);
}
List<(EventCode, char)> collection = _LastScanService.IncludeEventCodes();
foreach ((EventCode eventCode, char @char) in collection)
_CharToEventCodes.Add(eventCode, @char);
int dueTime = 0;
foreach ((string _, Timer timer) in _Timers)
{
dueTime += 300;
_ = timer.Change(dueTime, Timeout.Infinite);
}
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken stoppingToken)
{
string? methodName = IMethodName.GetActualAsyncMethodName();
using (LogContext.PushProperty("MethodName", methodName))
{
_Logger.LogInformation($"Timed Hosted Service: {_AppSettings.GitCommitSeven}:{Environment.ProcessId} is stopping.");
for (short i = 0; i < short.MaxValue; i++)
{
Thread.Sleep(500);
if (_ExecutionCount == 0)
break;
}
}
return Task.CompletedTask;
}
public void Dispose()
{
foreach ((string _, Timer timer) in _Timers)
timer.Dispose();
foreach (InputReader inputReader in _Readers.Values)
{
inputReader.OnKeyPress -= ReaderOnOnKeyPress;
inputReader.Dispose();
}
_Readers.Clear();
_SerialService.Close();
GC.SuppressFinalize(this);
}
private void ReaderOnOnKeyPress(KeyPressEvent e)
{
OnKeyPress?.Invoke(e);
if (e.TimeSpan.TotalMilliseconds > _AppSettings.ClearLastScanServiceAfter)
_LastScanService.Clear();
if (e.KeyState == KeyState.KeyUp && _CharToEventCodes.TryGetValue(e.EventCode, out char @char))
_LastScanService.Add(e.EventCode, @char);
}
private Timer? GetTimer(string methodName)
{
(string MethodName, Timer Timer)[] results = _Timers.Where(l => l.MethodName == methodName).ToArray();
return !results.Any() ? null : results.First().Timer;
}
private void ScanForNewInputs()
{
string fileName;
IEnumerable<LinuxDevice>? devices = null;
string[] files = Directory.GetFiles("/dev/input/", "event*");
foreach (string file in files)
{
if (_Readers is null || _Readers.ContainsKey(file))
continue;
devices ??= DeviceReader.Get(_AppSettings.LinuxDevicePath);
fileName = Path.GetFileName(file);
InputReader reader = new(file, _Logger);
if (devices.Any(l => !string.IsNullOrEmpty(l.Name) && l.Name.EndsWith(_AppSettings.DeviceNameEndsWith) && l.Handlers.Any(m => m == fileName)))
reader.OnKeyPress += ReaderOnOnKeyPress;
_Readers?.Add(file, reader);
}
IEnumerable<InputReader>? deadReaders = _Readers?.Values.Where(r => r.Faulted);
if (deadReaders is not null)
{
foreach (InputReader? inputReader in deadReaders)
{
_ = _Readers?.Remove(inputReader.Path);
inputReader.OnKeyPress -= ReaderOnOnKeyPress;
inputReader.Dispose();
}
}
}
private void ScanForNewInputs(object? sender)
{
try
{ ScanForNewInputs(); }
catch (Exception ex) { _Logger.LogError(ex, nameof(ScanForNewInputs)); }
try
{
Timer? timer = GetTimer(nameof(ScanForNewInputs));
if (timer is not null)
{
TimeSpan timeSpan = new(DateTime.Now.AddSeconds(30).Ticks - DateTime.Now.Ticks);
_ = timer.Change((int)timeSpan.TotalMilliseconds, Timeout.Infinite);
}
}
catch (Exception ex) { _Logger.LogError(ex, $"{nameof(ScanForNewInputs)}-{nameof(Timer)}.{nameof(Timer.Change)}"); }
}
private void Write()
{
int count = _LastScanService.GetCount();
if (count > 0)
{
Result<string> result = _LastScanService.GetScan();
if (!string.IsNullOrEmpty(result.Results))
_SerialService.SerialPortWrite(count, result.Results);
}
}
private void Write(object? sender)
{
try
{ Write(); }
catch (Exception ex) { _Logger.LogError(ex, nameof(Write)); }
try
{
Timer? timer = GetTimer(nameof(Write));
if (timer is not null)
{
TimeSpan timeSpan = new(DateTime.Now.AddMilliseconds(_AppSettings.WriteToSerialEvery).Ticks - DateTime.Now.Ticks);
_ = timer.Change((int)timeSpan.TotalMilliseconds, Timeout.Infinite);
}
}
catch (Exception ex) { _Logger.LogError(ex, $"{nameof(Write)}-{nameof(Timer)}.{nameof(Timer.Change)}"); }
}
}

View File

@ -2,26 +2,23 @@ using System.Text.Json;
namespace Barcode.Host.Server.Models;
public record AppSettings(string ApiExportPath,
string ApiLoggingContentTypes,
string ApiLoggingPathPrefixes,
string ApiLogPath,
string ApiUrl,
string AttachmentPath,
string BuildNumber,
public record AppSettings(string BuildNumber,
string Company,
string ConnectionString,
int ClearLastScanServiceAfter,
string DeviceNameEndsWith,
int ExpectedScanLengthA,
int ExpectedScanLengthB,
string GitCommitSeven,
string InboundApiAllowedIPList,
string LinuxDevicePath,
bool IsDevelopment,
bool IsStaging,
string MockRoot,
string MonAResource,
string MonASite,
string OI2SqlConnectionString,
string OIExportPath,
string RootPassword,
string URLs,
string WorkingDirectoryName)
string WorkingDirectoryName,
int WriteToSerialEvery)
{
public override string ToString()

View File

@ -9,26 +9,23 @@ public class AppSettings
#nullable disable
[Display(Name = "Api Export Path"), Required] public string ApiExportPath { get; set; }
[Display(Name = "Api Logging Content Types"), Required] public string ApiLoggingContentTypes { get; set; }
[Display(Name = "Api Logging Path Prefixes"), Required] public string ApiLoggingPathPrefixes { get; set; }
[Display(Name = "Api Log Path"), Required] public string ApiLogPath { get; set; }
[Display(Name = "Api URL"), Required] public string ApiUrl { get; set; }
[Display(Name = "Attachment Path"), Required] public string AttachmentPath { get; set; }
[Display(Name = "Build Number"), Required] public string BuildNumber { get; set; }
[Display(Name = "Company"), Required] public string Company { get; set; }
[Display(Name = "Connection String"), Required] public string ConnectionString { get; set; }
[Display(Name = "Last Scan Service Clear After"), Required] public int? ClearLastScanServiceAfter { get; set; }
[Display(Name = "Device Name Ends With"), Required] public string DeviceNameEndsWith { get; set; }
[Display(Name = "ExpectedScanLengthA"), Required] public int? ExpectedScanLengthA { get; set; }
[Display(Name = "ExpectedScanLengthB"), Required] public int? ExpectedScanLengthB { get; set; }
[Display(Name = "Git Commit Seven"), Required] public string GitCommitSeven { get; set; }
[Display(Name = "Inbound Api Allowed IP List"), Required] public string InboundApiAllowedIPList { get; set; }
[Display(Name = "Linux Device Path"), Required] public string LinuxDevicePath { get; set; }
[Display(Name = "Is Development"), Required] public bool? IsDevelopment { get; set; }
[Display(Name = "Is Staging"), Required] public bool? IsStaging { get; set; }
[Display(Name = "Mock Root"), Required] public string MockRoot { get; set; }
[Display(Name = "MonA Resource"), Required] public string MonAResource { get; set; }
[Display(Name = "MonA Site"), Required] public string MonASite { get; set; }
[Display(Name = "Oi 2 Sql Connection String"), Required] public string Oi2SqlConnectionString { get; set; }
[Display(Name = "OI Export Path"), Required] public string OIExportPath { get; set; }
[Display(Name = "RootPassword"), Required] public string RootPassword { get; set; }
[Display(Name = "URLs"), Required] public string URLs { get; set; }
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; }
[Display(Name = "WriteToSerialEvery"), Required] public int? WriteToSerialEvery { get; set; }
#nullable restore
@ -43,28 +40,22 @@ public class AppSettings
Models.AppSettings result;
if (appSettings is null)
throw new NullReferenceException(nameof(appSettings));
if (appSettings.ApiExportPath is null)
throw new NullReferenceException(nameof(ApiExportPath));
if (appSettings.ApiLoggingContentTypes is null)
throw new NullReferenceException(nameof(ApiLoggingContentTypes));
if (appSettings.ApiLoggingPathPrefixes is null)
throw new NullReferenceException(nameof(ApiLoggingPathPrefixes));
if (appSettings.ApiLogPath is null)
throw new NullReferenceException(nameof(ApiLogPath));
if (appSettings.ApiUrl is null)
throw new NullReferenceException(nameof(ApiUrl));
if (appSettings.AttachmentPath is null)
throw new NullReferenceException(nameof(AttachmentPath));
if (appSettings.BuildNumber is null)
throw new NullReferenceException(nameof(BuildNumber));
if (appSettings.Company is null)
throw new NullReferenceException(nameof(Company));
if (appSettings.ConnectionString is null)
throw new NullReferenceException(nameof(ConnectionString));
if (appSettings.ClearLastScanServiceAfter is null)
throw new NullReferenceException(nameof(ClearLastScanServiceAfter));
if (appSettings.DeviceNameEndsWith is null)
throw new NullReferenceException(nameof(DeviceNameEndsWith));
if (appSettings.ExpectedScanLengthA is null)
throw new NullReferenceException(nameof(ExpectedScanLengthA));
if (appSettings.ExpectedScanLengthB is null)
throw new NullReferenceException(nameof(ExpectedScanLengthB));
if (appSettings.GitCommitSeven is null)
throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.InboundApiAllowedIPList is null)
throw new NullReferenceException(nameof(InboundApiAllowedIPList));
if (appSettings.LinuxDevicePath is null)
throw new NullReferenceException(nameof(LinuxDevicePath));
if (appSettings.IsDevelopment is null)
throw new NullReferenceException(nameof(IsDevelopment));
if (appSettings.IsStaging is null)
@ -75,35 +66,32 @@ public class AppSettings
throw new NullReferenceException(nameof(MonAResource));
if (appSettings.MonASite is null)
throw new NullReferenceException(nameof(MonASite));
if (appSettings.Oi2SqlConnectionString is null)
throw new NullReferenceException(nameof(Oi2SqlConnectionString));
if (appSettings.OIExportPath is null)
throw new NullReferenceException(nameof(OIExportPath));
if (appSettings.RootPassword is null)
throw new NullReferenceException(nameof(RootPassword));
if (appSettings.URLs is null)
throw new NullReferenceException(nameof(URLs));
if (appSettings.WorkingDirectoryName is null)
throw new NullReferenceException(nameof(WorkingDirectoryName));
if (appSettings.WriteToSerialEvery is null)
throw new NullReferenceException(nameof(WriteToSerialEvery));
result = new(
appSettings.ApiExportPath,
appSettings.ApiLoggingContentTypes,
appSettings.ApiLoggingPathPrefixes,
appSettings.ApiLogPath,
appSettings.ApiUrl,
appSettings.AttachmentPath,
appSettings.BuildNumber,
appSettings.Company,
appSettings.ConnectionString,
appSettings.ClearLastScanServiceAfter.Value,
appSettings.DeviceNameEndsWith,
appSettings.ExpectedScanLengthA.Value,
appSettings.ExpectedScanLengthB.Value,
appSettings.GitCommitSeven,
appSettings.InboundApiAllowedIPList,
appSettings.LinuxDevicePath,
appSettings.IsDevelopment.Value,
appSettings.IsStaging.Value,
appSettings.MockRoot,
appSettings.MonAResource,
appSettings.MonASite,
appSettings.Oi2SqlConnectionString,
appSettings.OIExportPath,
appSettings.RootPassword,
appSettings.URLs,
appSettings.WorkingDirectoryName);
appSettings.WorkingDirectoryName,
appSettings.WriteToSerialEvery.Value);
return result;
}

View File

@ -1,7 +1,9 @@
using Barcode.Host.Server.Models;
using Barcode.Host.Server.HostedService;
using Barcode.Host.Server.Models;
using Barcode.Host.Server.Services;
using Barcode.Host.Shared.Models;
using Barcode.Host.Shared.Models.Stateless;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -35,7 +37,7 @@ public class Program
public static int Main(string[] args)
{
LoggerConfiguration loggerConfiguration = new();
(string assemblyName, WebApplicationOptions _) = Get(args);
(string assemblyName, _) = Get(args);
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration);
@ -49,44 +51,35 @@ public class Program
ILogger log = Log.ForContext<Program>();
try
{
_ = webApplicationBuilder.Services.AddMemoryCache();
_ = webApplicationBuilder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);
if (appSettings.IsStaging && appSettings.IsDevelopment)
throw new NotSupportedException("Please check appsettings file(s)!");
if (appSettings.IsStaging != webApplicationBuilder.Environment.IsStaging())
throw new NotSupportedException("Please check appsettings file(s)!");
if (appSettings.IsDevelopment != webApplicationBuilder.Environment.IsDevelopment())
throw new NotSupportedException("Please check appsettings file(s)!");
_ = webApplicationBuilder.Services.AddControllersWithViews();
_ = webApplicationBuilder.Services.AddDistributedMemoryCache();
_ = webApplicationBuilder.Services.AddSingleton(_ => appSettings);
_ = webApplicationBuilder.Services.AddSingleton<ISerialService, SerialService>();
_ = webApplicationBuilder.Services.AddSingleton<ILastScanService, LastScanService>();
_ = webApplicationBuilder.Services.AddSingleton<ILinuxGroupManager, LinuxGroupManager>();
_ = webApplicationBuilder.Services.AddHostedService<TimedHostedService>();
_ = webApplicationBuilder.Services.AddSwaggerGen();
_ = webApplicationBuilder.Services.AddSession(sessionOptions =>
{
sessionOptions.IdleTimeout = TimeSpan.FromSeconds(2000);
sessionOptions.Cookie.HttpOnly = true;
sessionOptions.Cookie.IsEssential = true;
}
);
WebApplication webApplication = webApplicationBuilder.Build();
_ = webApplication.UseCors(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
if (!webApplicationBuilder.Environment.IsDevelopment())
if (appSettings.IsDevelopment)
{
_ = webApplication.UseExceptionHandler("/Error");
_ = webApplication.UseHttpsRedirection();
_ = webApplication.UseHsts();
}
else
{
if (string.IsNullOrEmpty(appSettings.URLs))
{
Environment.ExitCode = -1;
webApplication.Lifetime.StopApplication();
}
_ = webApplication.UseSwagger();
_ = webApplication.UseDeveloperExceptionPage();
_ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Server V1"));
}
if (!appSettings.IsDevelopment)
{
_ = webApplication.UseExceptionHandler("/Error");
_ = webApplication.UseHsts();
}
_ = webApplication.UseCors(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
_ = webApplication.Lifetime.ApplicationStopped.Register(Log.CloseAndFlush);
_ = SerilogApplicationBuilderExtensions.UseSerilogRequestLogging(webApplication);
_ = webApplication.UseFileServer(enableDirectoryBrowsing: true);
_ = webApplication.UseStaticFiles();
_ = webApplication.UseSession();
_ = webApplication.MapControllers();
log.Information("Starting Web Application");
webApplication.Run();

View File

@ -0,0 +1,93 @@
using Barcode.Host.Shared.DataModels;
using Barcode.Host.Shared.KeyboardMouse;
using Barcode.Host.Shared.Models.Stateless;
namespace Barcode.Host.Server.Services;
public class LastScanService : ILastScanService
{
private readonly List<(EventCode EventCode, char Char)> _EventCodes;
public LastScanService() =>
_EventCodes = new();
void ILastScanService.Clear()
{
lock (_EventCodes)
_EventCodes.Clear();
}
void ILastScanService.Add(EventCode eventCode, char @char)
{
lock (_EventCodes)
_EventCodes.Add((eventCode, @char));
}
Result<string> ILastScanService.GetScan()
{
Result<string> result;
char[] chars;
lock (_EventCodes)
chars = _EventCodes.Select(l => l.Char).ToArray();
result = new() { Results = new string(chars), TotalRows = chars.Length };
return result;
}
int ILastScanService.GetCount()
{
int result;
lock (_EventCodes)
result = _EventCodes.Count;
return result;
}
List<(EventCode, char)> ILastScanService.IncludeEventCodes()
{
List<(EventCode, char)> results = new()
{
(EventCode.A, 'A'),
(EventCode.B, 'B'),
(EventCode.C, 'C'),
(EventCode.D, 'D'),
(EventCode.E, 'E'),
(EventCode.F, 'F'),
(EventCode.G, 'G'),
(EventCode.H, 'H'),
(EventCode.I, 'I'),
(EventCode.J, 'J'),
(EventCode.K, 'K'),
(EventCode.L, 'L'),
(EventCode.M, 'M'),
(EventCode.N, 'N'),
(EventCode.O, 'O'),
(EventCode.P, 'P'),
(EventCode.Q, 'Q'),
(EventCode.R, 'R'),
(EventCode.S, 'S'),
(EventCode.T, 'T'),
(EventCode.U, 'U'),
(EventCode.V, 'V'),
(EventCode.W, 'W'),
(EventCode.X, 'X'),
(EventCode.Y, 'Y'),
(EventCode.Z, 'Z'),
(EventCode.Num0, '0'),
(EventCode.Num1, '1'),
(EventCode.Num2, '2'),
(EventCode.Num3, '3'),
(EventCode.Num4, '4'),
(EventCode.Num5, '5'),
(EventCode.Num6, '6'),
(EventCode.Num7, '7'),
(EventCode.Num8, '8'),
(EventCode.Num9, '9'),
(EventCode.Minus, '-'),
(EventCode.Dot, '.'),
(EventCode.Slash, '/'),
(EventCode.Space, ' '),
};
return results;
}
}

View File

@ -0,0 +1,42 @@
using Barcode.Host.Shared.Models.Stateless;
using CliWrap;
using CliWrap.Buffered;
namespace Barcode.Host.Server.Services;
public class LinuxGroupManager : ILinuxGroupManager
{
public async Task<bool> IsInInputGroup()
{
BufferedCommandResult result = await Cli.Wrap("id")
.ExecuteBufferedAsync();
string output = result.StandardOutput;
const StringSplitOptions options = StringSplitOptions.RemoveEmptyEntries;
bool inInputGroup = output.Split(new[] { ' ' }, options)
.First(p => p.StartsWith("groups"))
.Remove(0, "groups".Length)
.Split(',', options)
.Any(p => p.Contains("input"));
return inInputGroup;
}
public async Task AddUserToInputGroup(string password)
{
using CancellationTokenSource cts = new();
cts.CancelAfter(TimeSpan.FromSeconds(10));
_ = await Cli.Wrap("bash")
.WithArguments($"-c \"echo '{password}' | sudo -S gpasswd -a $USER input")
.ExecuteBufferedAsync(cts.Token);
}
public async Task RebootSystem(string password)
{
using CancellationTokenSource cts = new();
cts.CancelAfter(TimeSpan.FromSeconds(10));
_ = await Cli.Wrap("bash")
.WithArguments($"-c \"echo '{password}' | sudo -S reboot\"")
.ExecuteBufferedAsync(cts.Token);
}
}

View File

@ -0,0 +1,44 @@
using Barcode.Host.Server.Models;
using Barcode.Host.Shared.Models.Stateless;
using System.Text;
namespace Barcode.Host.Server.Services;
public class SerialService : ISerialService
{
private string _LastRaw;
private readonly AppSettings _AppSettings;
private readonly System.IO.Ports.SerialPort _SerialPort;
public SerialService(AppSettings appSettings)
{
_LastRaw = string.Empty;
_AppSettings = appSettings;
_SerialPort = new("/dev/ttyUSB0", 9600) { ReadTimeout = 2 };
}
void ISerialService.Open() =>
_SerialPort.Open();
void ISerialService.Close() =>
_SerialPort.Close();
void ISerialService.SerialPortWrite(int count, string raw)
{
if (raw != _LastRaw)
{
string message;
if (count == _AppSettings.ExpectedScanLengthA)
message = $" {raw[2..]} {DateTime.Now:h:m tt}";
else if (count == _AppSettings.ExpectedScanLengthB)
message = $" {raw[2..]}";
else
message = $" {raw}";
byte[] bytes = Encoding.ASCII.GetBytes(message);
_SerialPort.Write(bytes, 0, bytes.Length);
_LastRaw = raw;
}
}
}

View File

@ -1,47 +1,13 @@
{
"ApiExportPath": "\\\\messdv002.na.infineon.com\\Candela",
"ApiUrl": "~/api",
"ConnectionString": "Data Source=MESSAD1001\\TEST1,59583;Integrated Security=True;Initial Catalog=Metrology;",
"IsDevelopment": true,
"MockRoot": "",
"MonAResource": "OI_Metrology_Viewer_IFX",
"Oi2SqlConnectionString": "Data Source=MESSAD1001\\TEST1,59583;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;",
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
"ExpectedScanLengthA": 6,
"ExpectedScanLengthB": 9,
"Logging": {
"LogLevel": {
"Log4netProvider": "Debug"
}
},
"URLs": "https://localhost:7130;http://localhost:5126"
"IsDevelopment": true,
"Serilog": {
"MinimumLevel": "Debug"
}
}

View File

@ -1,31 +1,26 @@
{
"AllowedHosts": "*",
"ApiExportPath": "\\\\messv02ecc1.ec.local\\EC_Metrology_Si",
"ApiLoggingContentTypes": "application/json",
"ApiLoggingPathPrefixes": "/api/inbound",
"ApiUrl": "~/api",
"ApiLogPath": "D:\\Metrology\\MetrologyAPILogs",
"AttachmentPath": "\\\\messv02ecc1.ec.local\\EC_Metrology_Si\\MetrologyAttachments",
"BuildNumber": "1",
"Company": "Infineon Technologies Americas Corp.",
"ConnectionString": "Data Source=messv01ec.ec.local\\PROD1,53959;Integrated Security=True;Initial Catalog=Metrology;",
"DeviceNameEndsWith": "Symbol Bar Code Scanner",
"ExpectedScanLengthA": 8,
"ExpectedScanLengthB": 14,
"ExpectedScanLengthBExample": "1TO172125.1.11",
"ClearLastScanServiceAfter": 250,
"GitCommitSeven": "1234567",
"LinuxDevicePath": "/proc/bus/input/devices",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Log4netProvider": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"InboundApiAllowedIPList": "",
"IsDevelopment": false,
"IsStaging": false,
"MockRoot": "",
"MonAResource": "OI_Metrology_Viewer_EC",
"MonASite": "auc",
"Oi2SqlConnectionString": "Data Source=messv01ec.ec.local\\PROD1,53959;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;",
"OIExportPath": "\\\\openinsight-db-srv.na.infineon.com\\apps\\Metrology\\Data",
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
@ -63,6 +58,8 @@
"Application": "Sample"
}
},
"URLs": "http://localhost:5002;",
"WorkingDirectoryName": "IFXApps"
"RootPassword": "",
"URLs": "http://localhost:5003;",
"WorkingDirectoryName": "IFXApps",
"WriteToSerialEvery": 750
}