初始化 代码
This commit is contained in:
commit
210572ce49
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
/packages/
|
||||||
|
riderModule.iml
|
||||||
|
/_ReSharper.Caches/
|
13
.idea/.idea.Seyounth.Auto.Hs/.idea/.gitignore
generated
vendored
Normal file
13
.idea/.idea.Seyounth.Auto.Hs/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Rider 忽略的文件
|
||||||
|
/projectSettingsUpdater.xml
|
||||||
|
/.idea.Seyounth.Auto.Hs.iml
|
||||||
|
/modules.xml
|
||||||
|
/contentModel.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
4
.idea/.idea.Seyounth.Auto.Hs/.idea/encodings.xml
generated
Normal file
4
.idea/.idea.Seyounth.Auto.Hs/.idea/encodings.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||||
|
</project>
|
8
.idea/.idea.Seyounth.Auto.Hs/.idea/indexLayout.xml
generated
Normal file
8
.idea/.idea.Seyounth.Auto.Hs/.idea/indexLayout.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="UserContentModel">
|
||||||
|
<attachedFolders />
|
||||||
|
<explicitIncludes />
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
67
Seyounth.Auto.Hs.Runtime/Balances/BalanceService.cs
Normal file
67
Seyounth.Auto.Hs.Runtime/Balances/BalanceService.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Balances;
|
||||||
|
|
||||||
|
public class BalanceService : IBalanceService
|
||||||
|
{
|
||||||
|
public IReadOnlyList<IBalance> Balances => _balances;
|
||||||
|
|
||||||
|
private readonly List<IBalance> _balances = new List<IBalance>();
|
||||||
|
|
||||||
|
private readonly ILogger<BalanceService> _logger;
|
||||||
|
|
||||||
|
|
||||||
|
public BalanceService(ILogger<BalanceService> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
//todo:向_balances里添加Balance
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(_balances.Select(balance => balance.ConnectAsync().ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
_logger.LogInformation($"Balance {balance.Id} connected successfully.");
|
||||||
|
else
|
||||||
|
_logger.LogError($"Balance {balance.Id} failed to connect, error: {t.Exception?.Message}");
|
||||||
|
})).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(_balances.Select(balance => balance.DisconnectAsync().ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
_logger.LogInformation($"Balance {balance.Id} disconnected successfully.");
|
||||||
|
else
|
||||||
|
_logger.LogError($"Balance {balance.Id} failed to disconnect, error: {t.Exception?.Message}");
|
||||||
|
})).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<decimal?> WeighAsync(int id)
|
||||||
|
{
|
||||||
|
decimal rs = 0;
|
||||||
|
var balance = _balances.FirstOrDefault(b => b.Id == id);
|
||||||
|
if (balance != null)
|
||||||
|
{
|
||||||
|
Func<decimal, Task> weightChangedHandler = (weight) =>
|
||||||
|
{
|
||||||
|
rs = weight;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
|
|
||||||
|
balance.OnWeightChanged += weightChangedHandler;
|
||||||
|
while (rs == 0)
|
||||||
|
{
|
||||||
|
await Task.Delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
balance.OnWeightChanged -= weightChangedHandler;
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogError($"Balance {id} not found.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
12
Seyounth.Auto.Hs.Runtime/Balances/IBalance.cs
Normal file
12
Seyounth.Auto.Hs.Runtime/Balances/IBalance.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Balances;
|
||||||
|
|
||||||
|
public interface IBalance
|
||||||
|
{
|
||||||
|
int Id { get; }
|
||||||
|
|
||||||
|
Task ConnectAsync();
|
||||||
|
|
||||||
|
Task DisconnectAsync();
|
||||||
|
|
||||||
|
event Func<decimal, Task> OnWeightChanged;
|
||||||
|
}
|
17
Seyounth.Auto.Hs.Runtime/Balances/IBalanceService.cs
Normal file
17
Seyounth.Auto.Hs.Runtime/Balances/IBalanceService.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Balances;
|
||||||
|
|
||||||
|
public interface IBalanceService
|
||||||
|
{
|
||||||
|
IReadOnlyList<IBalance> Balances { get; }
|
||||||
|
|
||||||
|
Task StartAsync();
|
||||||
|
|
||||||
|
Task StopAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用指定的电子称称重
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<decimal?> WeighAsync(int id);
|
||||||
|
}
|
15
Seyounth.Auto.Hs.Runtime/Handlers/OnWarningHandler.cs
Normal file
15
Seyounth.Auto.Hs.Runtime/Handlers/OnWarningHandler.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Handlers;
|
||||||
|
|
||||||
|
public class OnWarning(int first, int second) : IRequest
|
||||||
|
{
|
||||||
|
public int First { get; } = first;
|
||||||
|
|
||||||
|
public int Second { get; } = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class OnWarningHandler : IRequestHandler<OnWarning>
|
||||||
|
{
|
||||||
|
public abstract Task Handle(OnWarning request, CancellationToken cancellationToken);
|
||||||
|
}
|
21
Seyounth.Auto.Hs.Runtime/Handlers/WeighBoxRequestHandler.cs
Normal file
21
Seyounth.Auto.Hs.Runtime/Handlers/WeighBoxRequestHandler.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Handlers;
|
||||||
|
|
||||||
|
public class WeighBoxRequest : IRequest<string>
|
||||||
|
{
|
||||||
|
public string Barcode { get; }
|
||||||
|
|
||||||
|
public decimal? Weight { get; }
|
||||||
|
|
||||||
|
public WeighBoxRequest(string barcode, decimal? weight)
|
||||||
|
{
|
||||||
|
Barcode = barcode;
|
||||||
|
Weight = weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class WeighBoxRequestHandler : IRequestHandler<WeighBoxRequest, string>
|
||||||
|
{
|
||||||
|
public abstract Task<string> Handle(WeighBoxRequest request, CancellationToken cancellationToken);
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Handlers;
|
||||||
|
|
||||||
|
public class WeighSpindleRequest : IRequest<string>
|
||||||
|
{
|
||||||
|
public decimal? Weight { get; }
|
||||||
|
public string Barcode { get; }
|
||||||
|
|
||||||
|
public WeighSpindleRequest(string barcode, decimal? weight)
|
||||||
|
{
|
||||||
|
Weight = weight;
|
||||||
|
Barcode = barcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class WeighSpindleRequestHandler : IRequestHandler<WeighSpindleRequest, string>
|
||||||
|
{
|
||||||
|
public abstract Task<string> Handle(WeighSpindleRequest request, CancellationToken cancellationToken);
|
||||||
|
}
|
174
Seyounth.Auto.Hs.Runtime/HsAutoRuntime.cs
Normal file
174
Seyounth.Auto.Hs.Runtime/HsAutoRuntime.cs
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Balances;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Handlers;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Plc;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Printer;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Scanner;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime;
|
||||||
|
|
||||||
|
public class HsAutoRuntime : IHsAutoRuntime
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
private readonly IBalanceService _balance;
|
||||||
|
private readonly IScannerService _scanners;
|
||||||
|
private readonly ILogger<HsAutoRuntime> _logger;
|
||||||
|
private readonly IPlcService _plcService;
|
||||||
|
private readonly IPrinterService _printers;
|
||||||
|
|
||||||
|
public HsAutoRuntime(IPlcService plcService, IMediator mediator, IBalanceService balances, IScannerService scanners,
|
||||||
|
ILogger<HsAutoRuntime> logger, IPrinterService printers)
|
||||||
|
{
|
||||||
|
_printers = printers;
|
||||||
|
_mediator = mediator;
|
||||||
|
_balance = balances;
|
||||||
|
_scanners = scanners;
|
||||||
|
_logger = logger;
|
||||||
|
_plcService = plcService;
|
||||||
|
_scanners.OnScanned += ScannersOnOnScanned;
|
||||||
|
plcService.OnWarning += PlcServiceOnOnWarning;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取到报警信息处理逻辑
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="warning"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
private Task PlcServiceOnOnWarning(Tuple<short, short> warning)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ScannersOnOnScanned(IScanner scanner, string barcode)
|
||||||
|
{
|
||||||
|
if (scanner.Id == 1)
|
||||||
|
{
|
||||||
|
#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
|
HandleFilmOnScanned(barcode);
|
||||||
|
#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
|
}
|
||||||
|
else if (scanner.Id == 2)
|
||||||
|
{
|
||||||
|
#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
|
HandleBoxOnScanned(barcode);
|
||||||
|
#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleFilmOnScanned(string barcode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Film Scanner: {barcode}", barcode);
|
||||||
|
var weight = await _balance.WeighAsync(1);
|
||||||
|
_logger.LogInformation($"Film Barcode:{barcode}| Weight: {weight}");
|
||||||
|
var content = await _mediator.Send(new WeighSpindleRequest(barcode, weight));
|
||||||
|
_logger.LogInformation($"Film Barcode:{barcode}| print content: {content}");
|
||||||
|
await _printers.PrintAsync(1, content);
|
||||||
|
await _plcService.WriteFilmLabelPrintResult(1);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"Film Scanner: {barcode}| Exception: {ex.Message}");
|
||||||
|
await _plcService.WriteFilmLabelPrintResult(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleBoxOnScanned(string barcode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Box Scanner: {barcode}", barcode);
|
||||||
|
int jackingFlag;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
jackingFlag = await _plcService.GetJackingFlagAsync();
|
||||||
|
} while (jackingFlag == 0);
|
||||||
|
|
||||||
|
_logger.LogInformation($"Box Barcode:{barcode}| Jacking flag: {jackingFlag}");
|
||||||
|
var weight = await _balance.WeighAsync(2);
|
||||||
|
_logger.LogInformation($"Box Barcode:{barcode}| Weight: {weight}");
|
||||||
|
var content = await _mediator.Send(new WeighBoxRequest(barcode, weight));
|
||||||
|
_logger.LogInformation($"Box Barcode:{barcode}| WeighBoxResult: {content}");
|
||||||
|
await _printers.PrintAsync(2, content);
|
||||||
|
await _plcService.WriteBoxLabelPrintResult(1);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Box Scanner: {barcode}", barcode);
|
||||||
|
await _plcService.WriteBoxLabelPrintResult(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task RunAsync()
|
||||||
|
{
|
||||||
|
var tasks = new List<Task>
|
||||||
|
{
|
||||||
|
_balance.StartAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Balance connected successfully."
|
||||||
|
: $"Balance connection failed. error: {t.Exception?.Message}");
|
||||||
|
}),
|
||||||
|
_scanners.StartAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Scanner connected successfully."
|
||||||
|
: $"Scanner connection failed. error: {t.Exception?.Message}");
|
||||||
|
}),
|
||||||
|
_plcService.StartAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Plc connected successfully."
|
||||||
|
: $"Plc connection failed. error: {t.Exception?.Message}");
|
||||||
|
}),
|
||||||
|
_printers.StartAsync().ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Printer connected successfully."
|
||||||
|
: $"Printer connection failed. error: {t.Exception?.Message}");
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task StopAsync()
|
||||||
|
{
|
||||||
|
var tasks = new List<Task>
|
||||||
|
{
|
||||||
|
_balance.StopAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Balance stop successfully."
|
||||||
|
: $"Balance stop failed. error: {t.Exception?.Message}");
|
||||||
|
}),
|
||||||
|
_scanners.StopAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Scanner stop successfully."
|
||||||
|
: $"Scanner stop failed. error: {t.Exception?.Message}");
|
||||||
|
}),
|
||||||
|
_plcService.StopAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Plc stop successfully."
|
||||||
|
: $"Plc stop failed. error: {t.Exception?.Message}");
|
||||||
|
}),
|
||||||
|
_printers.StopAsync().ContinueWith(t =>
|
||||||
|
{
|
||||||
|
_logger.LogInformation(t.IsCompletedSuccessfully
|
||||||
|
? "Printer stop successfully."
|
||||||
|
: $"Printer stop failed. error: {t.Exception?.Message}");
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
}
|
26
Seyounth.Auto.Hs.Runtime/HsBackgroundService.cs
Normal file
26
Seyounth.Auto.Hs.Runtime/HsBackgroundService.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime;
|
||||||
|
|
||||||
|
public class HsBackgroundService(IHsAutoRuntime hs) : BackgroundService
|
||||||
|
{
|
||||||
|
public override async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await hs.RunAsync();
|
||||||
|
await base.StartAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await Task.Delay(1000, stoppingToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await hs.StopAsync();
|
||||||
|
await base.StopAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
35
Seyounth.Auto.Hs.Runtime/HsExtensions.cs
Normal file
35
Seyounth.Auto.Hs.Runtime/HsExtensions.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Balances;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Handlers;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Plc;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Printer;
|
||||||
|
using Seyounth.Auto.Hs.Runtime.Scanner;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime;
|
||||||
|
|
||||||
|
public static class HsExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 添加HS手动包装服务
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services"></param>
|
||||||
|
/// <typeparam name="TOnWarningHandler">报警信息处理器</typeparam>
|
||||||
|
/// <typeparam name="TWeighBoxRequestHandler">纸箱称重处理器</typeparam>
|
||||||
|
/// <typeparam name="TWeighSpindleRequestHandler">丝锭称重处理器</typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceCollection AddHs<TOnWarningHandler, TWeighBoxRequestHandler, TWeighSpindleRequestHandler>(
|
||||||
|
this IServiceCollection services)
|
||||||
|
where TOnWarningHandler : OnWarningHandler
|
||||||
|
where TWeighBoxRequestHandler : WeighSpindleRequestHandler
|
||||||
|
where TWeighSpindleRequestHandler : WeighSpindleRequestHandler
|
||||||
|
{
|
||||||
|
services.AddSingleton<IBalanceService, BalanceService>();
|
||||||
|
services.AddSingleton<IPlcService, PlcService>();
|
||||||
|
services.AddSingleton<IPrinterService, PrinterService>();
|
||||||
|
services.AddSingleton<IScannerService, ScannerService>();
|
||||||
|
services.AddSingleton<IHsAutoRuntime, HsAutoRuntime>();
|
||||||
|
services.AddHostedService<PlcBackgroundService>();
|
||||||
|
services.AddHostedService<HsBackgroundService>();
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
8
Seyounth.Auto.Hs.Runtime/IHsAutoRuntime.cs
Normal file
8
Seyounth.Auto.Hs.Runtime/IHsAutoRuntime.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime;
|
||||||
|
|
||||||
|
public interface IHsAutoRuntime
|
||||||
|
{
|
||||||
|
Task RunAsync();
|
||||||
|
|
||||||
|
Task StopAsync();
|
||||||
|
}
|
8
Seyounth.Auto.Hs.Runtime/Plc/HsPlcAddressAbstract.cs
Normal file
8
Seyounth.Auto.Hs.Runtime/Plc/HsPlcAddressAbstract.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Plc;
|
||||||
|
|
||||||
|
public abstract class HsPlcAddressAbstract
|
||||||
|
{
|
||||||
|
public abstract string 热缩机当前温度 { get; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
46
Seyounth.Auto.Hs.Runtime/Plc/IPlcService.cs
Normal file
46
Seyounth.Auto.Hs.Runtime/Plc/IPlcService.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Plc;
|
||||||
|
|
||||||
|
public interface IPlcService
|
||||||
|
{
|
||||||
|
Task StartAsync();
|
||||||
|
Task StopAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询热缩机当前温度
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<short> GetTemperatureAsync();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询报警信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task QueryWarningInfo();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 触发报警信息
|
||||||
|
/// </summary>
|
||||||
|
event Func<Tuple<short, short>, Task> OnWarning;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取顶升机构状态
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<short> GetJackingFlagAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入外箱标签打印结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rs"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task WriteBoxLabelPrintResult(short rs);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入外膜标签打印结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rs"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task WriteFilmLabelPrintResult(short rs);
|
||||||
|
}
|
15
Seyounth.Auto.Hs.Runtime/Plc/PlcBackgroundService.cs
Normal file
15
Seyounth.Auto.Hs.Runtime/Plc/PlcBackgroundService.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Plc;
|
||||||
|
|
||||||
|
public class PlcBackgroundService(IPlcService plc) : BackgroundService
|
||||||
|
{
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await plc.QueryWarningInfo();
|
||||||
|
await Task.Delay(50, stoppingToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
Seyounth.Auto.Hs.Runtime/Plc/PlcService.cs
Normal file
56
Seyounth.Auto.Hs.Runtime/Plc/PlcService.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Seyounth.Extensions.Plc;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Plc;
|
||||||
|
|
||||||
|
public class PlcService : IPlcService
|
||||||
|
{
|
||||||
|
private readonly ILogger<PlcService> _logger;
|
||||||
|
|
||||||
|
private readonly IPlc _plc;
|
||||||
|
|
||||||
|
public PlcService(ILogger<PlcService> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
//todo:此处创建PLC对象
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
await _plc.ConnectAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync()
|
||||||
|
{
|
||||||
|
await _plc.DisconnectAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<short> GetTemperatureAsync()
|
||||||
|
{
|
||||||
|
return (await _plc.ReadAsync<short>("D1000", 1))[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task QueryWarningInfo()
|
||||||
|
{
|
||||||
|
var flags = await _plc.ReadAsync<short>("D1003", 2);
|
||||||
|
if (flags.Any(f => f != 0))
|
||||||
|
OnWarning?.Invoke(Tuple.Create(flags[0], flags[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Func<Tuple<short, short>, Task> OnWarning;
|
||||||
|
|
||||||
|
public Task<short> GetJackingFlagAsync()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task WriteBoxLabelPrintResult(short rs)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task WriteFilmLabelPrintResult(short rs)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
10
Seyounth.Auto.Hs.Runtime/Printer/IPrinter.cs
Normal file
10
Seyounth.Auto.Hs.Runtime/Printer/IPrinter.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Printer;
|
||||||
|
|
||||||
|
public interface IPrinter
|
||||||
|
{
|
||||||
|
int Id { get; }
|
||||||
|
Task ConnectAsync();
|
||||||
|
Task DisconnectAsync();
|
||||||
|
|
||||||
|
Task PrintAsync(string content);
|
||||||
|
}
|
12
Seyounth.Auto.Hs.Runtime/Printer/IPrinterService.cs
Normal file
12
Seyounth.Auto.Hs.Runtime/Printer/IPrinterService.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Printer;
|
||||||
|
|
||||||
|
public interface IPrinterService
|
||||||
|
{
|
||||||
|
IReadOnlyList<IPrinter> Printers { get; }
|
||||||
|
|
||||||
|
Task StartAsync();
|
||||||
|
|
||||||
|
Task StopAsync();
|
||||||
|
|
||||||
|
Task PrintAsync(int id, string content);
|
||||||
|
}
|
50
Seyounth.Auto.Hs.Runtime/Printer/PrinterService.cs
Normal file
50
Seyounth.Auto.Hs.Runtime/Printer/PrinterService.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Printer;
|
||||||
|
|
||||||
|
public class PrinterService : IPrinterService
|
||||||
|
{
|
||||||
|
public IReadOnlyList<IPrinter> Printers => _printers;
|
||||||
|
|
||||||
|
private readonly ILogger<PrinterService> _logger;
|
||||||
|
|
||||||
|
private readonly List<IPrinter> _printers = new List<IPrinter>();
|
||||||
|
|
||||||
|
public PrinterService(ILogger<PrinterService> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
//todo: load printers from configuration or new
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(Printers.Select(x => x.ConnectAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
_logger.LogInformation($"Printer {x.Id} connected");
|
||||||
|
else
|
||||||
|
_logger.LogError(t.Exception, $"Printer {x.Id} failed to connect,error: {t.Exception.Message}");
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(Printers.Select(x => x.DisconnectAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
_logger.LogInformation($"Printer {x.Id} disconnected");
|
||||||
|
else
|
||||||
|
_logger.LogError(t.Exception, $"Printer {x.Id} failed to disconnect,error: {t.Exception.Message}");
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task PrintAsync(int id, string content)
|
||||||
|
{
|
||||||
|
var printer = Printers.FirstOrDefault(x => x.Id == id);
|
||||||
|
if (printer == null)
|
||||||
|
throw new ArgumentException("Printer not found", nameof(id));
|
||||||
|
return printer.PrintAsync(content);
|
||||||
|
}
|
||||||
|
}
|
12
Seyounth.Auto.Hs.Runtime/Scanner/IScanner.cs
Normal file
12
Seyounth.Auto.Hs.Runtime/Scanner/IScanner.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Scanner;
|
||||||
|
|
||||||
|
public interface IScanner
|
||||||
|
{
|
||||||
|
int Id { get; }
|
||||||
|
|
||||||
|
Task ConnectAsync();
|
||||||
|
|
||||||
|
Task DisconnectAsync();
|
||||||
|
|
||||||
|
event Action<string> OnScanned;
|
||||||
|
}
|
11
Seyounth.Auto.Hs.Runtime/Scanner/IScannerService.cs
Normal file
11
Seyounth.Auto.Hs.Runtime/Scanner/IScannerService.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace Seyounth.Auto.Hs.Runtime.Scanner;
|
||||||
|
|
||||||
|
public interface IScannerService
|
||||||
|
{
|
||||||
|
IReadOnlyList<IScanner> Scanners { get; }
|
||||||
|
Task StartAsync();
|
||||||
|
|
||||||
|
Task StopAsync();
|
||||||
|
|
||||||
|
event Action<IScanner, string> OnScanned;
|
||||||
|
}
|
46
Seyounth.Auto.Hs.Runtime/Scanner/ScannerService.cs
Normal file
46
Seyounth.Auto.Hs.Runtime/Scanner/ScannerService.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Seyounth.Auto.Hs.Runtime.Scanner;
|
||||||
|
|
||||||
|
public class ScannerService : IScannerService
|
||||||
|
{
|
||||||
|
public ScannerService(ILogger<ScannerService> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
//todo:向_scanners里添加HikScanner
|
||||||
|
|
||||||
|
_scanners.ForEach(x => x.OnScanned += (barcode) => OnScanned?.Invoke(x, barcode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<IScanner> Scanners => _scanners;
|
||||||
|
|
||||||
|
private readonly ILogger<ScannerService> _logger;
|
||||||
|
|
||||||
|
private readonly List<IScanner> _scanners = new List<IScanner>();
|
||||||
|
|
||||||
|
public async Task StartAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(_scanners.Select(x => x.ConnectAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
_logger.LogInformation($"Scanner {x.Id} connected successfully.");
|
||||||
|
else
|
||||||
|
_logger.LogError($"Scanner {x.Id} failed to connect, error: {t.Exception?.Message}");
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync()
|
||||||
|
{
|
||||||
|
await Task.WhenAll(_scanners.Select(x => x.DisconnectAsync()
|
||||||
|
.ContinueWith(t =>
|
||||||
|
{
|
||||||
|
if (t.IsCompletedSuccessfully)
|
||||||
|
_logger.LogInformation($"Scanner {x.Id} disconnected.");
|
||||||
|
else
|
||||||
|
_logger.LogError($"Scanner {x.Id} failed to disconnect, error: {t.Exception?.Message}");
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<IScanner, string>? OnScanned;
|
||||||
|
}
|
15
Seyounth.Auto.Hs.Runtime/Seyounth.Auto.Hs.Runtime.csproj
Normal file
15
Seyounth.Auto.Hs.Runtime/Seyounth.Auto.Hs.Runtime.csproj
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MediatR" Version="12.5.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.5" />
|
||||||
|
<PackageReference Include="Seyounth.Extensions.Plc" Version="1.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
16
Seyounth.Auto.Hs.sln
Normal file
16
Seyounth.Auto.Hs.sln
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seyounth.Auto.Hs.Runtime", "Seyounth.Auto.Hs.Runtime\Seyounth.Auto.Hs.Runtime.csproj", "{6966BCFD-A22C-4C83-8171-96BB005F38D4}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6966BCFD-A22C-4C83-8171-96BB005F38D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6966BCFD-A22C-4C83-8171-96BB005F38D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6966BCFD-A22C-4C83-8171-96BB005F38D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6966BCFD-A22C-4C83-8171-96BB005F38D4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
7
nuget.config
Normal file
7
nuget.config
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="Seyounth" value="http://8.134.253.216:8002/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
Loading…
x
Reference in New Issue
Block a user