1.扫码枪实现

2.体重秤实现
3.打印机实现
This commit is contained in:
syc_zhaoqianyan 2025-07-01 14:20:07 +08:00
parent 2a5c0a55ad
commit 66fc5b3b19
51 changed files with 4538 additions and 1599 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,8 +33,6 @@
<ProjectReference Include="..\..\services\Syc.Basic.Web.WMS.Application\Syc.Basic.Web.WMS.Application.csproj" />
<ProjectReference Include="..\..\services\Syc.Basic.Web.WMS.EntityFrameworkCore\Syc.Basic.Web.WMS.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\services\Syc.Basic.Web.WMS.HttpApi\Syc.Basic.Web.WMS.HttpApi.csproj" />
<ProjectReference Include="..\..\share\Seyounth.Auto.Hs.Runtime\Seyounth.Auto.Hs.Runtime.csproj" />
<ProjectReference Include="..\..\share\Seyounth.Auto.Plc\Seyounth.Auto.Plc.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,51 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Syc.Basic.Web.WMS.Entitys;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace Syc.Basic.Web.WMS
{
/// <summary>
/// 程序启动时从数据库同步队列数据
/// </summary>
public class SyncDataFromDbBackgroupService : BackgroundService
{
private readonly IRepository<Silk> silkRepository;
private readonly ILogger<SyncDataFromDbBackgroupService> logger;
public SyncDataFromDbBackgroupService(
IRepository<Silk> silkRepository
,ILogger<SyncDataFromDbBackgroupService> logger)
{
this.silkRepository = silkRepository;
this.logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var status = new int[]
{
0,1
};
var data = await silkRepository.GetListAsync(x => status.Contains(x.Status) && x.IsDelete == 0);
logger.LogInformation($"已从 Silk 表检索到{data.Count}条待处理数据");
/* 加载已扫码未称重的 */
var list1 = data.Where(e => e.Status == 0).OrderBy(e => e.Createtime).ToList();
logger.LogInformation($"已扫码未称重 {list1.Count} 条,分别是:{string.Join(",", list1)},已加载进队列");
foreach ( var item in list1)
if(!QueueManage.YarnBalanceQueue.Any(e => e.Code == item.Code))
QueueManage.YarnBalanceQueue.Enqueue(item);
/* 加载已称重未装箱的 */
var list2 = data.Where(e => e.Status == 1).OrderBy(e => e.Createtime).ToList();
logger.LogInformation($"已称重待装箱 {list2.Count} 条,分别是:{string.Join(",",list2)},已加载进队列");
foreach (var item in list2)
if(!QueueManage.BoxQueue.Contains(item.Code))
QueueManage.BoxQueue.Add(item.Code);
}
}
}

View File

@ -25,6 +25,17 @@ using System.Net;
using StackExchange.Redis;
using Syc.Authorize.JwtBearer;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.AspNetCore.Http;
using Seyounth.Auto.Hs.Runtime.Scanner;
using Syc.Basic.Web.WMS.WebSocket;
using Syc.Core.Tools;
using Seyounth.Auto.Hs.Runtime.Balances;
using Serilog;
using System.Threading.Tasks;
using System.Threading;
using Syc.Basic.Web.WMS.Entitys;
using Microsoft.EntityFrameworkCore.Migrations;
using Volo.Abp.Domain.Repositories;
namespace Syc.Basic.Web.WMS;
@ -48,12 +59,12 @@ public class WMSHttpApiHostModule : AbpModule
{
var configuration = context.Services.GetConfiguration();
var hostingEnvironment = context.Services.GetHostingEnvironment();
ConfigureUrls(configuration);
ConfigureLocalization();
ConfigureVirtualFileSystem(context);
ConfigureCors(context, configuration);
ConfigureSwaggerServices(context, configuration);
//context.Services.AddHostedService<SyncDataFromDbBackgroupService>();
}
private void ConfigureRedis()
@ -200,10 +211,10 @@ public class WMSHttpApiHostModule : AbpModule
app.UseCorrelationId();
app.UseStaticFiles();
app.UseWebSockets();
app.UseRouting();
app.UseCors();
app.UseSpecificationException();
app.UseSwagger();
app.UseAppAuthentication();
app.UseUnitOfWork();
@ -212,8 +223,44 @@ public class WMSHttpApiHostModule : AbpModule
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "WMS API");
});
app.Map("/ws", c =>
{
c.Use(async (context, next) => {
if (context.WebSockets.IsWebSocketRequest)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
//X-Correlation-Id
var Correlation = context.Request.Headers["X-Correlation-Id"].FirstOrDefault();
Log.Information($"接收到来自IP{context.Request.Host.Host}的连接");
WebSocketManager.SocketManager?.AddSocket(webSocket, Correlation);
await EchoWebSocket(webSocket);
}
else
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await next();
}
});
});
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
}
async Task EchoWebSocket(System.Net.WebSockets.WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
var receiveResult = await webSocket.ReceiveAsync(
new ArraySegment<byte>(buffer), CancellationToken.None);
while (!receiveResult.CloseStatus.HasValue)
{
receiveResult = await webSocket.ReceiveAsync(
new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(
receiveResult.CloseStatus.Value,
receiveResult.CloseStatusDescription,
CancellationToken.None);
}
}

View File

@ -63,28 +63,47 @@
{
//
"Id": 1,
"IP": "127.0.0.1",
"Port": 3306
"IP": "127.0.0.1",//"192.168.3.202",
"Port": 2002
},
{
//
"Id": 2,
"IP": "127.0.0.1",
"Port": 3307
"IP": "127.0.0.1",//"192.168.3.120",
"Port": 2003
}
],
"Balance": [
{
//
//
"Id": 1,
"IP": "127.0.0.1",
"Port":4306
"Port": 9102
},
{
//
//
"Id": 2,
"IP": "127.0.0.1",
"Port": 4306
"IP": "192.168.3.217",
"Port": 9101
}
]
],
"Printer": [
{
//
"Id": 1,
"IP": "192.168.3.99",
"Port": 9110
},
{
//
"Id": 2,
"IP": "192.168.3.100",
"Port": 9111
}
],
"Plc": {
//PLC
"IP": "192.168.3.30",
"Port":502
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Syc.Basic.Web.WMS.Dto
{
public class BoxDto
{
public int Id { get; set; }
//条码
public string Code { get; set; }
//规格
public string Spec { get; set; }
//名称
public string Type { get; set; }
//数量
public int? Qty { get; set; }
//净重
public double? Net_Weight { get; set; }
//毛重
public double? Gross_Weight { get; set; }
//生产批号
public string Lot_No { get; set; }
//长度
public double? Length { get; set; }
//打包时间
public DateTime? Dom_Time { get; set; }
//生产日期
public string? Exp_Time { get; set; }
/// <summary>
/// 是否在装箱
/// </summary>
public bool IsUse { get; set; } = true;
public int IsDelete { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using Syc.Basic.Web.WMS.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Syc.Basic.Web.WMS.IService
{
public interface IBoxService
{
Task InsertBox(BoxDto input);
}
}

View File

@ -0,0 +1,28 @@
using Syc.Basic.Web.WMS.Entitys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Syc.Basic.Web.WMS
{
public static class QueueManage
{
/// <summary>
/// 丝锭称重队列
/// </summary>
public static Queue<Silk> YarnBalanceQueue = new Queue<Silk>();
/// <summary>
/// 打印标签队列
/// </summary>
public static Queue<Silk> YarnPrinterQueue = new Queue<Silk>();
/// <summary>
/// 当前包装箱队列
/// </summary>
public static List<string> BoxQueue = new List<string>();
}
}

View File

@ -144,6 +144,11 @@
隐藏子菜单
</summary>
</member>
<member name="P:Syc.Basic.Web.WMS.Dto.BoxDto.IsUse">
<summary>
是否在装箱
</summary>
</member>
<member name="M:Syc.Basic.Web.WMS.IServices.IAuthService.LoginAsync(Syc.Basic.Web.WMS.Dtos.LoginInput)">
<summary>
登录
@ -183,6 +188,21 @@
</summary>
<returns></returns>
</member>
<member name="F:Syc.Basic.Web.WMS.QueueManage.YarnBalanceQueue">
<summary>
丝锭称重队列
</summary>
</member>
<member name="F:Syc.Basic.Web.WMS.QueueManage.YarnPrinterQueue">
<summary>
打印标签队列
</summary>
</member>
<member name="F:Syc.Basic.Web.WMS.QueueManage.BoxQueue">
<summary>
当前包装箱队列
</summary>
</member>
<member name="P:Syc.Basic.Web.WMS.WebSocket.DeviceMessage.Id">
<summary>
设备id

View File

@ -0,0 +1,200 @@
using Microsoft.Extensions.Logging;
using NUglify.Helpers;
using Seyounth.Auto.Hs.Runtime.Balances;
using Seyounth.Auto.Hs.Runtime.Plc;
using Seyounth.Auto.Hs.Runtime.Printer;
using Syc.Abp.Application.Contracts;
using Syc.Basic.Web.WMS.Entitys;
using Syc.Basic.Web.WMS.Service;
using Syc.Basic.Web.WMS.WebSocket;
using Syc.Core.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
namespace Syc.Basic.Web.WMS.DeviceEventHandle
{
public class DefaultBalanceEventHandle : IBalanceEventHandle
{
private readonly IRepository<Silk> silkRepository;
private readonly IPlcService plcService;
private readonly IRepository<Produce> produceRepository;
private readonly IRepository<Box> boxRepository;
private readonly IPrinterService printerService;
private readonly IUnitOfWorkManager unitOfWork;
private readonly ILogger<DefaultBalanceEventHandle> logger;
private readonly static object _lock = new object();
public DefaultBalanceEventHandle(IRepository<Silk> silkRepository,IPlcService plcService,IRepository<Produce> produceRepository,IRepository<Box> boxRepository,IPrinterService printerService,IUnitOfWorkManager unitOfWork, ILogger<DefaultBalanceEventHandle> logger)
{
this.silkRepository = silkRepository;
this.plcService = plcService;
this.produceRepository = produceRepository;
this.boxRepository = boxRepository;
this.printerService = printerService;
this.unitOfWork = unitOfWork;
this.logger = logger;
}
public async Task ExecAsync(decimal weight, int id)
{
using (var uow = unitOfWork.Reserve(UnitOfWork.UnitOfWorkReservationName))
{
try
{
if (weight <= 0)
return;
//logger.LogInformation($"重量稳定:{weight}");
if (id == 1)
await Yanr(weight);
else
await Box(weight);
await uow.CompleteAsync();
}
catch (Exception ex) when (ex is FriendlyException friendlyException)
{
logger.LogError(ex.GetBaseException(), "称重报错");
await WebSocketManager.SocketManager.BroadcastAsync(friendlyException.Message);
await uow.RollbackAsync();
}
catch (Exception ex)
{
logger.LogError(ex.GetBaseException(), "称重报错");
await uow.RollbackAsync();
}
}
}
/// <summary>
/// 丝锭称重
/// </summary>
/// <param name="weight"></param>
/// <returns></returns>
public async Task Yanr(decimal weight)
{
if (await silkRepository.AnyAsync(e => e.Status == 0 && e.IsDelete == 0))
{
var silk = await silkRepository.FirstOrDefaultAsync(e => e.Status == 0 && e.IsDelete == 0);//QueueManage.YarnBalanceQueue.Dequeue();
silk.Status = 1;
silk.Status_Details = "已称重待装箱";
silk.Net_Weight = (double)weight;
await silkRepository.UpdateAsync(silk);
string content = "#!A1" +
"\r\n#N13" +
"\r\n#PC1017/0" +
"\r\n#IMR44/46" +
//"\r\n#HV50" +
"\r\n#PR6//" +
"\r\n#PO0" +
"\r\n#ERNC/1//0.00" +
"\r\n#R0/0" +
"\r\n#T3.64 #J43.18 #FD/0/L #SS100/BVUN/21X21/0 #VW/L/\"YuLinHengShenXinCaiLiaoYouXianGongSi\"#G" +
"\r\n#T11.85 #J40.47 #FD/0/L #SS100/BVUN/19X19/0 #VW/L/\"Yulin Hengshen COLtd\"#G" +
"\r\n#T2.28 #J25.31 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Name " + silk.Name +"\"#G" +
"\r\n#T2.28 #J20.91 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Type " +silk.Type+ "\"#G" +
"\r\n#T2.28 #J16.51 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Net Weight "+silk.Net_Weight+ "\"#G" +
"\r\n#T2.28 #J12.61 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Length "+silk.Length+ "\"#G" +
"\r\n#T2.28 #J7.95 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Date "+silk.Date.ToString()+ "\"#G" +
"\r\n#T2.28 #J3.89 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Lot No "+silk.Lot_No+ "\"#G" +
"\r\n#T11.51 #J29.54 #FD/0/L #SB13/ONKP2.0/8.80/2 #VW/L/\"" + silk.Code+"\"#G" +
"\r\n#Q1#G" +
"\r\n#!P1" +
"\r\n";
await printerService.PrintAsync(1, content);
logger.LogInformation($"Silk({silk.Id}|{silk.Code})状态更改为【已称重待装箱】,同时向打印机发送打印标签指令");
}
}
/// <summary>
/// 整箱称重
/// </summary>
/// <param name="weight"></param>
public async Task Box(decimal weight)
{
/* PLC未给顶升到位信号则忽略此次事件处理 */
if (!await plcService.IsTop()) return;
if (await silkRepository.AnyAsync(e => e.Status == 1 && e.IsDelete == 0))
{
var query = await silkRepository.GetQueryableAsync();
query =query.Where(x => x.Status == 1 && x.IsDelete == 0);
var count = query.Count();
var produce = await produceRepository.FirstOrDefaultAsync(e => e.IfUse == 1);
if (produce is null)
throw Oops.Oh("无生产信息,请先设置生产信息再扫码");
if (produce.Qty.Value > count)
{
throw Oops.Oh("数量未满箱,无法打印标签");
}
logger.LogInformation($"当前生产信息:{produce.Name}|{produce.Spec}|{produce.Lot_No}|{produce.BoxSpec}|{produce.Qty}");
//var netWeight = query.FirstOrDefault(e => e.Code == QueueManage.BoxQueue.FirstOrDefault()).Net_Weight * produce.Qty.Value;
var takeQuery = query.Take(produce.Qty.Value);
var netWeight = takeQuery.Sum(e => e.Net_Weight);
var box = new Box()
{
Dom_Time = DateTime.Now,
Type = produce.Type,
Exp_Time = produce.Exp_Time,
Qty = produce.Qty,
Length = produce.Length,
Lot_No = produce.Lot_No,
Code = Guid.NewGuid().ToString().Substring(9, 18),
Net_Weight = netWeight,
Spec = produce.BoxSpec,
Gross_Weight = (double)weight,
IsUse = true,
IsDelete = 0
};
string content = "#!A1" +
"\r\n#N13" +
"\r\n#PC1017/0" +
"\r\n#IMR104/130" +
//"\r\n#HV50" +
"\r\n#PR6//" +
"\r\n#PO0" +
"\r\n#ERNC/1//0.00" +
"\r\n#R0/0" +
"\r\n#T7.28 #J11.17 #FD/1/L #SS100/BVUN/51X68/0 #VW/L/\"YuLinHengShenXinCaiLiaoYouXianGongSi\"#G" +
"\r\n#T13.37 #J40.30 #FD/1/L #SS100/BVUN/46X62/0 #VW/L/\"Yulin Hengshen COLtd\"#G" +
"\r\n#T52.15 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"TYPE " + box.Type + "\"#G" +
"\r\n#T67.39 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"QTY/PCS " + box.Qty + "\"#G" +
"\r\n#T82.63 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"LOT NO. " + box.Lot_No + "\"#G" +
"\r\n#T98.97 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"DOM. " + box.Dom_Time.ToString() + "\"#G" +
"\r\n#T52.15 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"SPEC " + box.Spec + "\"#G" +
"\r\n#T67.39 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"CTY./NO. " + box.Net_Weight + "\"#G" +
"\r\n#T81.19 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"LENGTH " + box.Length + "\"#G" +
"\r\n#T98.21 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"EXP. " + box.Exp_Time.ToString() + "\"#G" +
"\r\n#T41.06 #J6.68 #FD/1/L #SB13/ONKP2.0/20.82/5 #VW/L/\"" + box.Code + "\"#G" +
"\r\n#Q1#G\r\n#!P1\r\n";
var entity = await boxRepository.InsertAsync(box, true);
var silks = takeQuery.ToList();
var codes = silks.Select(e => e.Code);
logger.LogInformation($"从数据库中待装箱编号:{string.Join(";", codes)}");
silks.ForEach(e =>
{
logger.LogInformation($"{e.Code}已装箱");
e.BoxId = entity.Id;
e.Status = 2;
e.Status_Details = "已装箱";
});
await silkRepository.UpdateManyAsync(silks);
await printerService.PrintAsync(2, content);
await plcService.ClearTop();
await plcService.BoxTagPrintDoneAsync((short)1);
logger.LogInformation($"称重完成,已将数据({box.Id}|{box.Code})插入到box表同时向打印机发送出标指令");
}
}
}
}

View File

@ -1,6 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Seyounth.Auto.Hs.Runtime.Printer;
using Seyounth.Auto.Hs.Runtime.Scanner;
using Syc.Abp.Application.Contracts;
using Syc.Basic.Web.WMS.Entitys;
using Syc.Basic.Web.WMS.WebSocket;
using Syc.Core.Tools;
@ -19,13 +21,21 @@ namespace Syc.Basic.Web.WMS
/// </summary>
public class DefaultScannerEventHandle : IScannerEventHandle
{
private readonly IRepository<Produce> produceRepository;
private readonly IPrinterService printerService;
private readonly IRepository<Box> boxRepository;
private readonly IRepository<Silk> silkRepository;
private readonly IUnitOfWorkManager uowm;
private readonly ILogger<DefaultScannerEventHandle> logger;
public DefaultScannerEventHandle(IRepository<Silk> silkRepository, IUnitOfWorkManager unitOfWork)
public DefaultScannerEventHandle(IRepository<Produce> produceRepository,IPrinterService printerService,IRepository<Box> boxRepository,IRepository<Silk> silkRepository,IUnitOfWorkManager unitOfWork,ILogger<DefaultScannerEventHandle> logger)
{
this.produceRepository = produceRepository;
this.printerService = printerService;
this.boxRepository = boxRepository;
this.silkRepository = silkRepository;
this.uowm = unitOfWork;
this.logger = logger;
}
/// <summary>
@ -35,6 +45,88 @@ namespace Syc.Basic.Web.WMS
/// <param name="id"></param>
/// <returns></returns>
public async Task ExecAsync(string code, int id)
{
using (var uow = uowm.Reserve(UnitOfWork.UnitOfWorkReservationName))
{
try
{
if (id == 1)
await Yarn(code);
else
await Box(code);
await uow.CompleteAsync();
}
catch (Exception ex) when (ex is FriendlyException friendlyException)
{
logger.LogError(ex.GetBaseException(),"扫码报错");
await WebSocketManager.SocketManager.BroadcastAsync(friendlyException.Message);
await uow.RollbackAsync();
}
catch (Exception ex)
{
logger.LogError(ex.GetBaseException(), "扫码报错");
await uow.RollbackAsync();
}
}
}
/// <summary>
/// 整箱扫码
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public async Task Box(string code)
{
//if (!QueueManage.BoxQueue.Contains(code))
//{
// logger.LogInformation($"{code} 加入box集合");
// QueueManage.BoxQueue.Add(code);
//}
//else
//{
// logger.LogWarning($"{code}已在box集合中无需重复扫码");
//}
}
/// <summary>
/// 丝锭扫码
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public async Task Yarn(string code)
{
//throw Oops.Oh("异常返回前端测试");
logger.LogInformation($"接收到丝锭条码:{code}");
var produce = await produceRepository.FirstOrDefaultAsync(e => e.IfUse == 1 && e.IsDelete == 0);
var b = await silkRepository.AnyAsync(e => e.Code == code && e.IsDelete == 0);
if (produce is null)
{
throw Oops.Oh("无生产信息,请先设置生产信息再扫码");
}
if (b)
{
throw Oops.Oh("条码已存在");
}
logger.LogInformation($"当前生产信息:{produce.Name}|{produce.Spec}|{produce.Lot_No}|{produce.BoxSpec}|{produce.Qty}");
Silk silk = new Silk()
{
Code = code,
Length = produce.Length,
Lot_No = produce.Lot_No,
Name = produce.Name,
Date = DateTime.Now,
Type = produce.Type,
Status = 0,
Status_Details = "已扫码待称重",
Net_Weight = 0,
Createtime = DateTime.Now,
};
silk = await silkRepository.InsertAsync(silk);
logger.LogInformation($"丝锭:{code} 已添加到数据库");
}
public async Task ExecAsync2(string code, int id)
{
using (var uow = uowm.Reserve(UnitOfWork.UnitOfWorkReservationName))
{
@ -53,32 +145,11 @@ namespace Syc.Basic.Web.WMS
await WebSocketManager.SocketManager.BroadcastAsync(msg.ToJsonString());
await uow.CompleteAsync();
}
catch (Exception ex)
catch (Exception ex) when (ex is FriendlyException friendlyException)
{
await WebSocketManager.SocketManager.BroadcastAsync(friendlyException.Message);
await uow.RollbackAsync();
}
}
}
public async Task ExecAsync2(string code, int id)
{
using (var uow = uowm.Reserve(UnitOfWork.UnitOfWorkReservationName))
{
try
{
/*
* IScannerEventHandle接口
*/
var msg = new DeviceMessage(id, "体重秤", code);
if (!code.IsNullOrWhiteSpace())
{
var result = await silkRepository.AnyAsync(x => x.Code == code);
if (result)
msg.Value = $"存在重复编号({code}";
}
await WebSocketManager.SocketManager.BroadcastAsync(msg.ToJsonString());
await uow.CompleteAsync();
}
catch (Exception ex)
{
await uow.RollbackAsync();

View File

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Syc.Basic.Web.WMS.Dto
{
public class BoxDto
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Code { get; set; }
public string? Spec { get; set; }
public int? Qty { get; set; }
public double? Net_Weight { get; set; }
public string? Lot_No { get; set; }
public double? Length { get; set; }
public DateTime? Dom_Time { get; set; }
public string Exp_Time { get; set; }
public int IsDelete { get; set; }
}
}

View File

@ -16,6 +16,7 @@ namespace Syc.Basic.Web.WMS.Dto
public string Lot_No { get; set; }
public string Name { get; set; }
public int? Qty { get; set; }
public string BoxSpec { get; set; }
public string Exp_Time { get; set; }
public int IfUse { get; set; }
public int IsDelete { get; set; }

View File

@ -9,13 +9,25 @@ namespace Syc.Basic.Web.WMS.Dto
public class SilkDto
{
public int Id { get; set; }
//条码
public string Code { get; set; }
//名称
public string Name { get; set; }
//配方
public string Type { get; set; }
public string Spec { get; set; }
//净重
public double? Net_Weight { get; set; }
//长度
public double? Length { get; set; }
//包装时间
public DateTime? Date { get; set; }
//生产批号
public string Lot_No { get; set; }
public int Status { get; set; }
public string Status_Details { get; set; }
public int? BoxId { get; set; }
public int IsDelete { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Syc.Basic.Web.WMS.Dto
{
public class UpdInput
{
public int Id { get; set; }
public int IfUse { get; set; }
}
}

View File

@ -3,28 +3,41 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NUglify.Helpers;
using Seyounth.Auto.Hs.Runtime.Plc;
using Seyounth.Auto.Hs.Runtime.Printer;
using Syc.Abp.Application.Contracts;
using Syc.Basic.Web.WMS.Dto;
using Syc.Basic.Web.WMS.Entitys;
using Syc.Basic.Web.WMS.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
namespace Syc.Basic.Web.WMS.Service
{
[AllowAnonymous]
public class BoxService : ApiService
public class BoxService : ApiService, IBoxService, ITransientDependency
{
private readonly IRepository<Box> boxRepository;
private readonly IRepository<Produce> produceRepository;
private readonly IRepository<Silk> silkRepository;
private readonly IPlcService plcService;
private readonly ILogger<BoxService> logger;
private readonly IPrinterService printerService;
public BoxService(IRepository<Box> boxRepository, ILogger<BoxService> logger)
public BoxService(IRepository<Box> boxRepository,IRepository<Produce> produceRepository,IRepository<Silk> silkRepository,IPlcService plcService, ILogger<BoxService> logger,IPrinterService printerService)
{
this.boxRepository = boxRepository;
this.produceRepository = produceRepository;
this.silkRepository = silkRepository;
this.plcService = plcService;
this.logger = logger;
this.printerService = printerService;
}
/// <summary>
/// 查询纸箱
@ -37,7 +50,7 @@ namespace Syc.Basic.Web.WMS.Service
var boxlist = await boxRepository.GetQueryableAsync();
boxlist = boxlist.Where(x => x.IsDelete == 0);
if (input.Lot_No != null)
boxlist = boxlist.Where(x => x.Name.Contains(input.Lot_No));
boxlist = boxlist.Where(x => x.Lot_No.Contains(input.Lot_No));
if (input.Spec != null)
boxlist = boxlist.Where(x => x.Spec.Contains(input.Spec));
@ -52,18 +65,41 @@ namespace Syc.Basic.Web.WMS.Service
Dom_Time = e.Dom_Time,
Exp_Time = e.Exp_Time.ToString(),
Lot_No = e.Lot_No,
Name = e.Name,
Spec = e.Spec,
Gross_Weight = e.Gross_Weight,
Type = e.Type
}).ToList();
PageOutput<BoxDto> pageOutput = new PageOutput<BoxDto>();
pageOutput.Total = boxlist.Count();
pageOutput.Data = data;
pageOutput.Data = data.OrderByDescending(x=>x.Id);
pageOutput.PageIndex = input.Page;
pageOutput.PageSize=input.PageSize;
return pageOutput;
}
/// <summary>
/// 查询数量纸箱
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
public async Task<List<BoxDto>> GetBoxByNum()
{
var produce=await produceRepository.FirstOrDefaultAsync(x=>x.IfUse==1);
var silks = await silkRepository.GetListAsync(x=>x.Status==1||x.Status==0);
var boxlist = await boxRepository.GetQueryableAsync();
boxlist = boxlist.Where(x => x.IsDelete == 0);
var data = boxlist.Select(e => new BoxDto()
{
Net_Weight = e.Net_Weight,
Id = e.Id,
Code = e.Code
}).ToList();
return data.OrderByDescending(x => x.Id).ToList().Take(1).ToList();
}
/// <summary>
/// 添加纸箱
/// </summary>
/// <param name="input"></param>
@ -73,10 +109,15 @@ namespace Syc.Basic.Web.WMS.Service
{
if (await boxRepository.AnyAsync(x => x.Code == input.Code))
throw Oops.Oh("条码已存在,不允许添加");
var boxs = await boxRepository.GetListAsync(e => e.IsUse);
if (boxs.Any())
{
boxs.ForEach(e => e.IsUse = false);
await boxRepository.UpdateManyAsync(boxs);
}
var box = new Box()
{
Name = input.Name,
Dom_Time = DateTime.Now,
Exp_Time = string.IsNullOrWhiteSpace(input.Exp_Time) ? null : Convert.ToDateTime(input.Exp_Time),
Qty = input.Qty,
@ -85,9 +126,69 @@ namespace Syc.Basic.Web.WMS.Service
Code = input.Code,
Net_Weight = input.Net_Weight,
Spec = input.Spec,
IsUse = true,
IsDelete = 0
};
await boxRepository.InsertAsync(box);
var entity= await boxRepository.InsertAsync(box,true);
string content = "#!A1" +
"\r\n#N13" +
"\r\n#PC1017/0" +
"\r\n#IMR104/130" +
//"\r\n#HV50" +
"\r\n#PR6//" +
"\r\n#PO0" +
"\r\n#ERNC/1//0.00" +
"\r\n#R0/0" +
"\r\n#T7.28 #J11.17 #FD/1/L #SS100/BVUN/51X68/0 #VW/L/\"YuLinHengShenXinCaiLiaoYouXianGongSi\"#G" +
"\r\n#T13.37 #J40.30 #FD/1/L #SS100/BVUN/46X62/0 #VW/L/\"Yulin Hengshen COLtd\"#G" +
"\r\n#T52.15 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"TYPE " + box.Type + "\"#G" +
"\r\n#T67.39 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"QTY/PCS " + box.Qty + "\"#G" +
"\r\n#T82.63 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"LOT NO. " + box.Lot_No + "\"#G" +
"\r\n#T98.97 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"DOM. " + box.Dom_Time.ToString() + "\"#G" +
"\r\n#T52.15 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"SPEC " + box.Spec + "\"#G" +
"\r\n#T67.39 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"CTY./NO. " + box.Net_Weight + "\"#G" +
"\r\n#T81.19 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"LENGTH " + box.Length + "\"#G" +
"\r\n#T98.21 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"EXP. " + box.Exp_Time.ToString() + "\"#G" +
"\r\n#T41.06 #J6.68 #FD/1/L #SB13/ONKP2.0/20.82/5 #VW/L/\"" + box.Code + "\"#G" +
"\r\n#Q1#G\r\n#!P1\r\n";
await printerService.PrintAsync(2, content);
}
/// <summary>
/// 打印纸箱
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task PrintBox(DelInput input)
{
var box = await boxRepository.FirstOrDefaultAsync(x=>x.Id==input.id);
string content = "#!A1" +
"\r\n#N13" +
"\r\n#PC1017/0" +
"\r\n#IMR104/130" +
//"\r\n#HV50" +
"\r\n#PR6//" +
"\r\n#PO0" +
"\r\n#ERNC/1//0.00" +
"\r\n#R0/0" +
"\r\n#T7.28 #J11.17 #FD/1/L #SS100/BVUN/51X68/0 #VW/L/\"YuLinHengShenXinCaiLiaoYouXianGongSi\"#G" +
"\r\n#T13.37 #J40.30 #FD/1/L #SS100/BVUN/46X62/0 #VW/L/\"Yulin Hengshen COLtd\"#G" +
"\r\n#T52.15 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"TYPE " + box.Type + "\"#G" +
"\r\n#T67.39 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"QTY/PCS " + box.Qty + "\"#G" +
"\r\n#T82.63 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"LOT NO. " + box.Lot_No + "\"#G" +
"\r\n#T98.97 #J9.14 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"DOM. " + box.Dom_Time.ToString() + "\"#G" +
"\r\n#T52.15 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"SPEC " + box.Spec + "\"#G" +
"\r\n#T67.39 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"CTY./NO. " + box.Net_Weight + "\"#G" +
"\r\n#T81.19 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"LENGTH " + box.Length + "\"#G" +
"\r\n#T98.21 #J69.25 #FD/1/L #SS100/BVUN/47X63/0 #VW/L/\"EXP. " + box.Exp_Time.ToString() + "\"#G" +
"\r\n#T41.06 #J6.68 #FD/1/L #SB13/ONKP2.0/20.82/5 #VW/L/\"" + box.Code + "\"#G" +
"\r\n#Q1#G\r\n#!P1\r\n";
await printerService.PrintAsync(2, content);
}
/// <summary>
/// 修改纸箱
@ -106,7 +207,6 @@ namespace Syc.Basic.Web.WMS.Service
box.Net_Weight = input.Net_Weight;
box.Dom_Time = DateTime.Now;
box.Qty = input.Qty;
box.Name = input.Name;
box.Exp_Time = string.IsNullOrWhiteSpace(input.Exp_Time) ? null : Convert.ToDateTime(input.Exp_Time);
await boxRepository.UpdateAsync(box);
}
@ -142,5 +242,23 @@ namespace Syc.Basic.Web.WMS.Service
}
await boxRepository.UpdateManyAsync(boxs);
}
/// <summary>
/// 设置热缩机温度
/// </summary>
/// <returns></returns>
public async Task SetTemperature(ByIdInput<short> input)
{
await plcService.SetTemperatureAsync(input.Id);
}
/// <summary>
/// 设置热缩机温度
/// </summary>
/// <returns></returns>
public async Task<int> GetTemperature()
{
return await plcService.GetTemperatureAsync();
}
}
}

View File

@ -2,6 +2,7 @@
using Microsoft.Extensions.Logging;
using Syc.Basic.Web.WMS.Dto;
using Syc.Basic.Web.WMS.Entitys;
using Syc.Basic.Web.WMS.IService;
using System;
using System.Collections.Generic;
using System.Linq;
@ -12,14 +13,16 @@ using Volo.Abp.Domain.Repositories;
namespace Syc.Basic.Web.WMS.Service
{
public class ProduceService:ApiService
public class ProduceService : ApiService
{
private readonly IRepository<Produce> produceRepository;
private readonly IBoxService boxService;
private readonly ILogger<ProduceService> logger;
public ProduceService(IRepository<Produce> produceRepository, ILogger<ProduceService> logger)
public ProduceService(IRepository<Produce> produceRepository, IBoxService boxService, ILogger<ProduceService> logger)
{
this.produceRepository = produceRepository;
this.boxService = boxService;
this.logger = logger;
}
/// <summary>
@ -44,16 +47,17 @@ namespace Syc.Basic.Web.WMS.Service
Id = x.Id,
Length = x.Length,
Type = x.Type,
Exp_Time = x.Exp_Time.ToString(),
BoxSpec = x.BoxSpec,
Exp_Time = x.Exp_Time.HasValue ? x.Exp_Time.Value.ToString("yyyy-MM-dd HH:m") : "-",
IfUse = x.IfUse,
Name = x.Name,
Qty = x.Qty
});
PageOutput<ProduceDto> pageOutput = new PageOutput<ProduceDto>();
pageOutput.Total = list.Count();
pageOutput.Data = data;
pageOutput.Data = data.OrderByDescending(x=>x.Id);
pageOutput.PageIndex = input.Page;
pageOutput.PageSize = input.PageSize;
return pageOutput;
@ -65,9 +69,9 @@ namespace Syc.Basic.Web.WMS.Service
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<ProduceDto>> GetProduceListById(ProduceInput input)
public async Task<List<ProduceDto>> GetProduceListByUse()
{
var list = await produceRepository.GetListAsync(x => x.IsDelete == 0 && x.Id == input.Id);
var list = await produceRepository.GetListAsync(x => x.IsDelete == 0 && x.IfUse==1);
var data = ObjectMapper.Map(list, new List<ProduceDto>());
return data;
}
@ -87,7 +91,7 @@ namespace Syc.Basic.Web.WMS.Service
item.IfUse = 0;
}
}
var produce = new Produce()
{
@ -95,7 +99,8 @@ namespace Syc.Basic.Web.WMS.Service
Lot_No = input.Lot_No,
Spec = input.Spec,
Type = input.Type,
Qty=input.Qty,
Qty = input.Qty,
BoxSpec = input.BoxSpec,
Exp_Time = string.IsNullOrWhiteSpace(input.Exp_Time) ? null : Convert.ToDateTime(input.Exp_Time),
IfUse = 1,
Name = input.Name,
@ -119,7 +124,33 @@ namespace Syc.Basic.Web.WMS.Service
produce.Length = input.Length;
produce.Lot_No = input.Lot_No;
produce.Qty = input.Qty;
produce.Name = input.Name;
produce.BoxSpec = input.BoxSpec;
produce.Exp_Time = string.IsNullOrWhiteSpace(input.Exp_Time) ? null : Convert.ToDateTime(input.Exp_Time);
await produceRepository.UpdateAsync(produce);
}
/// <summary>
/// 修改生产
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task UpdateProduceUse(UpdInput input)
{
var produces = await produceRepository.GetListAsync();
var produce = await produceRepository.FirstOrDefaultAsync(x => x.Id == input.Id);
if (input.IfUse == 1)
{
produce.IfUse = input.IfUse;
if (produces.Count > 0)
{
foreach (var item in produces)
{
item.IfUse = 0;
}
}
}
produce.IfUse = input.IfUse;
await produceRepository.UpdateAsync(produce);
}
@ -147,7 +178,7 @@ namespace Syc.Basic.Web.WMS.Service
public async Task DeletesProduces(DelInput input)
{
var produces = await produceRepository.GetListAsync(x => input.ids.Contains(x.Id));
if (produces.Count==0)
if (produces.Count == 0)
throw Oops.Oh("删除失败,数据为空");
foreach (var produce in produces)
{

View File

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Seyounth.Auto.Hs.Runtime.Printer;
using Syc.Basic.Web.WMS.Dto;
using Syc.Basic.Web.WMS.Entitys;
using System;
@ -17,15 +18,42 @@ namespace Syc.Basic.Web.WMS.Service
[AllowAnonymous]
public class SilkService:ApiService
{
private readonly IPrinterService printerService;
private readonly IRepository<Produce> produceRepository;
private readonly IRepository<Silk> silkRepository;
private readonly ILogger<SilkService> logger;
public SilkService(IRepository<Silk> silkRepository,ILogger<SilkService> logger)
public SilkService(IPrinterService printerService,IRepository<Produce> produceRepository ,IRepository<Silk> silkRepository,ILogger<SilkService> logger)
{
this.printerService = printerService;
this.produceRepository = produceRepository;
this.silkRepository = silkRepository;
this.logger = logger;
}
/// <summary>
/// 根据数量查询丝锭
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
public async Task<List<SilkDto>> GetSilkByNum()
{
var produce = await produceRepository.FirstOrDefaultAsync(x => x.IfUse == 1);
var list = await silkRepository.GetQueryableAsync();
list = list.Where(x => x.Status==1 && x.IsDelete == 0 || x.Status == 0 && x.IsDelete == 0);
var data = list.Select(e => new SilkDto()
{
Net_Weight = e.Net_Weight,
Id = e.Id,
Code = e.Code,
Status = e.Status,
Status_Details = e.Status_Details
}).ToList();
return data.OrderByDescending(x => x.Id).ToList().ToList();
}
/// <summary>
/// 查询丝锭
/// </summary>
/// <param name="input"></param>
@ -43,19 +71,22 @@ namespace Syc.Basic.Web.WMS.Service
var result = silklist.PageResult(input.Page, input.PageSize);
var data = result.Queryable.Select(x=>new SilkDto()
{
Spec=x.Spec,
Name=x.Name,
Net_Weight=x.Net_Weight,
Lot_No=x.Lot_No,
Code=x.Code,
Date=x.Date,
Id=x.Id,
Length=x.Length,
Type=x.Type
Type=x.Type,
BoxId=x.BoxId,
Status=x.Status,
Status_Details=x.Status_Details
});
PageOutput<SilkDto> pageOutput = new PageOutput<SilkDto>();
pageOutput.Total = silklist.Count();
pageOutput.Data = data;
pageOutput.Data = data.OrderByDescending(x => x.Id);
pageOutput.PageIndex = input.Page;
pageOutput.PageSize = input.PageSize;
return pageOutput;
@ -68,7 +99,7 @@ namespace Syc.Basic.Web.WMS.Service
[HttpPost]
public async Task InsertSilk(SilkDto input)
{
if (await silkRepository.AnyAsync(x => x.Code == input.Code))
if (await silkRepository.AnyAsync(x => x.Code == input.Code&&x.IsDelete==0))
throw Oops.Oh("条码已存在,不允许添加");
var silk = new Silk()
@ -78,11 +109,68 @@ namespace Syc.Basic.Web.WMS.Service
Lot_No = input.Lot_No,
Code = input.Code,
Net_Weight = input.Net_Weight,
Spec = input.Spec,
Name = input.Name,
Type = input.Type,
IsDelete = 0
};
await silkRepository.InsertAsync(silk);
var entity = await silkRepository.InsertAsync(silk,true);
string content = "#!A1" +
"\r\n#N13" +
"\r\n#PC1017/0" +
"\r\n#IMR44/46" +
//"\r\n#HV50" +
"\r\n#PR6//" +
"\r\n#PO0" +
"\r\n#ERNC/1//0.00" +
"\r\n#R0/0" +
"\r\n#T3.64 #J43.18 #FD/0/L #SS100/BVUN/21X21/0 #VW/L/\"YuLinHengShenXinCaiLiaoYouXianGongSi\"#G" +
"\r\n#T11.85 #J40.47 #FD/0/L #SS100/BVUN/19X19/0 #VW/L/\"Yulin Hengshen COLtd\"#G" +
"\r\n#T2.28 #J25.31 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Name " + silk.Name + "\"#G" +
"\r\n#T2.28 #J20.91 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Type " + silk.Type + "\"#G" +
"\r\n#T2.28 #J16.51 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Net Weight " + silk.Net_Weight + "\"#G" +
"\r\n#T2.28 #J12.61 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Length " + silk.Length + "\"#G" +
"\r\n#T2.28 #J7.95 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Date " + silk.Date.ToString() + "\"#G" +
"\r\n#T2.28 #J3.89 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Lot No " + silk.Lot_No + "\"#G" +
"\r\n#T11.51 #J29.54 #FD/0/L #SB13/ONKP2.0/8.80/2 #VW/L/\"" + silk.Code + "\"#G" +
"\r\n#Q1#G" +
"\r\n#!P1" +
"\r\n";
await printerService.PrintAsync(1,content);
}
/// <summary>
/// 打印丝锭
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task PrintSilk(DelInput input)
{
var silk = await silkRepository.FirstOrDefaultAsync(x=>x.Id==input.id);
string content = "#!A1" +
"\r\n#N13" +
"\r\n#PC1017/0" +
"\r\n#IMR44/46" +
//"\r\n#HV50" +
"\r\n#PR6//" +
"\r\n#PO0" +
"\r\n#ERNC/1//0.00" +
"\r\n#R0/0" +
"\r\n#T3.64 #J43.18 #FD/0/L #SS100/BVUN/21X21/0 #VW/L/\"YuLinHengShenXinCaiLiaoYouXianGongSi\"#G" +
"\r\n#T11.85 #J40.47 #FD/0/L #SS100/BVUN/19X19/0 #VW/L/\"Yulin Hengshen COLtd\"#G" +
"\r\n#T2.28 #J25.31 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Name " + silk.Name + "\"#G" +
"\r\n#T2.28 #J20.91 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Type " + silk.Type + "\"#G" +
"\r\n#T2.28 #J16.51 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Net Weight " + silk.Net_Weight + "\"#G" +
"\r\n#T2.28 #J12.61 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Length " + silk.Length + "\"#G" +
"\r\n#T2.28 #J7.95 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Date " + silk.Date.ToString() + "\"#G" +
"\r\n#T2.28 #J3.89 #FD/0/L #SS100/BVUN/20X20/0 #VW/L/\"Lot No " + silk.Lot_No + "\"#G" +
"\r\n#T11.51 #J29.54 #FD/0/L #SB13/ONKP2.0/8.80/2 #VW/L/\"" + silk.Code + "\"#G" +
"\r\n#Q1#G" +
"\r\n#!P1" +
"\r\n";
await printerService.PrintAsync(1, content);
}
/// <summary>
/// 修改丝锭
@ -94,7 +182,7 @@ namespace Syc.Basic.Web.WMS.Service
{
var silks = await silkRepository.FirstOrDefaultAsync(x=>x.Id==input.Id);
silks.Spec = input.Spec;
silks.Name = input.Name;
silks.Type = input.Type;
silks.Length = input.Length;
silks.Code = input.Code;

View File

@ -4,6 +4,19 @@
<name>Syc.Basic.Web.WMS.Application</name>
</assembly>
<members>
<member name="M:Syc.Basic.Web.WMS.DeviceEventHandle.DefaultBalanceEventHandle.Yanr(System.Decimal)">
<summary>
丝锭称重
</summary>
<param name="weight"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.DeviceEventHandle.DefaultBalanceEventHandle.Box(System.Decimal)">
<summary>
整箱称重
</summary>
<param name="weight"></param>
</member>
<member name="T:Syc.Basic.Web.WMS.DefaultScannerEventHandle">
<summary>
默认的扫码枪扫码触发事件处理
@ -17,6 +30,20 @@
<param name="id"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.DefaultScannerEventHandle.Box(System.String)">
<summary>
整箱扫码
</summary>
<param name="code"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.DefaultScannerEventHandle.Yarn(System.String)">
<summary>
丝锭扫码
</summary>
<param name="code"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.AuthService.LoginAsync(Syc.Basic.Web.WMS.Dtos.LoginInput)">
<summary>
账号密码登录
@ -56,6 +83,13 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.BoxService.GetBoxByNum">
<summary>
查询数量纸箱
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.BoxService.InsertBox(Syc.Basic.Web.WMS.Dto.BoxDto)">
<summary>
添加纸箱
@ -63,6 +97,13 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.BoxService.PrintBox(Syc.Basic.Web.WMS.Dto.DelInput)">
<summary>
打印纸箱
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.BoxService.UpdateBox(Syc.Basic.Web.WMS.Dto.BoxDto)">
<summary>
修改纸箱
@ -84,6 +125,18 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.BoxService.SetTemperature(Syc.Abp.Application.Contracts.ByIdInput{System.Int16})">
<summary>
设置热缩机温度
</summary>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.BoxService.GetTemperature">
<summary>
设置热缩机温度
</summary>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.ProduceService.GetProduceList(Syc.Basic.Web.WMS.Dto.ProduceInput)">
<summary>
查询生产
@ -91,7 +144,7 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.ProduceService.GetProduceListById(Syc.Basic.Web.WMS.Dto.ProduceInput)">
<member name="M:Syc.Basic.Web.WMS.Service.ProduceService.GetProduceListByUse">
<summary>
通过id查询生产列表
</summary>
@ -112,6 +165,13 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.ProduceService.UpdateProduceUse(Syc.Basic.Web.WMS.Dto.UpdInput)">
<summary>
修改生产
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.ProduceService.DeleteProduce(Syc.Basic.Web.WMS.Dto.DelInput)">
<summary>
删除生产
@ -126,6 +186,13 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.SilkService.GetSilkByNum">
<summary>
根据数量查询丝锭
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.SilkService.GetSilkList(Syc.Basic.Web.WMS.Dto.SilkInput)">
<summary>
查询丝锭
@ -140,6 +207,13 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.SilkService.PrintSilk(Syc.Basic.Web.WMS.Dto.DelInput)">
<summary>
打印丝锭
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Syc.Basic.Web.WMS.Service.SilkService.UpdateSilk(Syc.Basic.Web.WMS.Dto.SilkDto)">
<summary>
修改丝锭

View File

@ -12,6 +12,7 @@ using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AutoMapper;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Modularity;
using Syc.Basic.Web.WMS.DeviceEventHandle;
namespace Syc.Basic.Web.WMS;
@ -43,6 +44,7 @@ public class WMSApplicationModule : AbpModule
context.Services.AddHs<DefaultOnWarningHandler, DefaultWeighSpindleRequestHandler, DefaultWeighSpindleRequestHandler>();
context.Services.AddScannerEventHandle<DefaultScannerEventHandle>();
context.Services.AddBalanceEventHandle<DefaultBalanceEventHandle>();
}
private void ConfigureMapper()

View File

@ -9,15 +9,30 @@ namespace Syc.Basic.Web.WMS.Entitys
{
public class Box:Entity<int>
{
public string Name { get; set; }
//条码
public string Code { get; set; }
//规格
public string Spec { get; set; }
//名称
public string Type { get; set; }
//数量
public int? Qty { get; set; }
//净重
public double? Net_Weight { get; set; }
//毛重
public double? Gross_Weight { get; set; }
//生产批号
public string Lot_No { get; set; }
//长度
public double? Length { get; set; }
//打包时间
public DateTime? Dom_Time { get; set; }
//生产日期
public DateTime? Exp_Time { get; set; }
/// <summary>
/// 是否在装箱
/// </summary>
public bool IsUse { get; set; } = true;
public int IsDelete { get; set; }
}
}

View File

@ -16,6 +16,7 @@ namespace Syc.Basic.Web.WMS.Entitys
public string Lot_No { get; set; }
public string Name { get; set; }
public int? Qty { get; set; }
public string BoxSpec { get; set; }
public DateTime? Exp_Time { get; set; }
public int IfUse { get; set; }
public int IsDelete { get; set; }

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -9,13 +10,35 @@ namespace Syc.Basic.Web.WMS.Entitys
{
public class Silk:Entity<int>
{
//条码
public string Code { get; set; }
//名称
public string Name { get; set; }
//配方
public string Type { get; set; }
public string Spec { get; set; }
//净重
public double? Net_Weight { get; set; }
//长度
public double? Length { get; set; }
//包装时间
public DateTime? Date { get; set; }
//生产批号
public string Lot_No { get; set; }
/// <summary>
/// 0:已扫码待称重 1:已称重待装箱 2:已装箱
/// </summary>
[ConcurrencyCheck]
public int Status { get; set; }
public string Status_Details { get; set; }
public int? BoxId { get; set; }
public int IsDelete { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime Createtime { get; set; } = DateTime.Now;
}
}

View File

@ -73,7 +73,7 @@ namespace Syc.Basic.Web.EFCoreRepositoryImpl
.WhereIf(!mobile.IsNullOrWhiteSpace(), e => e.Telephone.Contains(mobile));
var count = await query.CountAsync();
var items = await query.Page(page,pageSize).ToListAsync();
var items = await query.OrderBy(e => e.Id).Page(page,pageSize).ToListAsync();
return (items, count);
}

View File

@ -11,21 +11,16 @@ public class BalanceService : IBalanceService
private readonly ILogger<BalanceService> _logger;
public BalanceService(ILogger<BalanceService> logger)
public BalanceService(IEnumerable<IBalance> balances,ILogger<BalanceService> logger)
{
_logger = logger;
_balances.AddRange(balances);
//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());
await Task.WhenAll(_balances.Select(e => e.ConnectAsync()));
}
public async Task StopAsync()

View File

@ -0,0 +1,193 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Seyounth.Auto.Hs.Runtime.Printer;
using Seyounth.Auto.Hs.Runtime.Scanner;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Seyounth.Auto.Hs.Runtime.Balances
{
public class BoxBalance : IBalance
{
public int Id => 2;
//扫到码后的业务逻辑
private readonly static object _lock = new object();
private List<decimal> _weights = new List<decimal>();
public event Action<string> OnScanned;
private DeviceConnectConfig DeviceConnectConfig;
private TcpClient _tcp;
private NetworkStream _stream;
private readonly IServiceProvider serviceProvider;
private readonly IEnumerable<IBalanceEventHandle> balanceEventHandles;
private readonly ILogger<BoxBalance> logger;
private CancellationTokenSource _receiveDataCancellationToken;
private bool tag;
public BoxBalance(IConfiguration configuration,IServiceProvider serviceProvider,IEnumerable<IBalanceEventHandle> balanceEventHandles, ILogger<BoxBalance> logger)
{
/*
* IP/
*/
var configs = configuration.GetSection("Balance").Get<DeviceConnectConfig[]>();
if (configs is not null && configs.Length > 0)
{
DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id);
}
this.serviceProvider = serviceProvider;
this.balanceEventHandles = balanceEventHandles;
this.logger = logger;
}
public event Func<decimal, Task> OnWeightChanged;
/// <summary>
/// 连接体重秤
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task ConnectAsync()
{
while (true)
{
if (_tcp is not null)
{
try
{
_tcp.Dispose();
}
catch (Exception ex)
{
/*
*
*/
}
}
_tcp = new TcpClient();
try
{
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port));
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
logger.LogInformation("体重秤连接成功");
_receiveDataCancellationToken?.Cancel();
_receiveDataCancellationToken = new CancellationTokenSource();
ReceiveData(_receiveDataCancellationToken.Token);
break;
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await Task.Delay(1000 * 5);
logger.LogError(ex.GetBaseException(), "体重秤连接失败,尝试重连中");
continue;
}
catch (Exception ex)
{
logger.LogError(ex, "体重秤连接失败");
}
}
}
/// <summary>
/// 接收扫码枪数据
/// </summary>
/// <returns></returns>
private async Task ReceiveData(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
//一次最大读取1M
byte[] buffer = new byte[1024];
/* readCount :实际读取字节数*/
var readCount = _stream.Read(buffer, 0, buffer.Length);
if (readCount <= 0)
throw new SocketException();
/* UTF-8 编码获取字符串*/
var result = Encoding.UTF8.GetString(buffer, 0, readCount);
/* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */
var matchs = Regex.Match(result, "-?\\d+(.?\\d+)?");
var weight = 0m;
if (!string.IsNullOrWhiteSpace(matchs.Value))
weight = Convert.ToDecimal(matchs.Value);
if (weight <= 0)
continue;
//logger.LogInformation("XXXXXXXXXXXXXXXXXXXXXXXXXXX");
if (MonitorWeightStability(_weights, weight))
{
using (var scope = serviceProvider.CreateScope())
{
var handles = scope.ServiceProvider.GetService<IEnumerable<IBalanceEventHandle>>();
foreach (var item in handles)
{
await item.ExecAsync(weight, Id);
}
}
//logger.LogInformation($"箱扫码枪接收数据:{result},字节数:{readCount}");
}
}
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
logger.LogError(ex.GetBaseException(), "体重秤连接失败,尝试重连中");
await ConnectAsync();
}
catch (Exception ex)
{
logger.LogError(ex, "体重秤连接失败");
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task DisconnectAsync()
{
_receiveDataCancellationToken?.Cancel();
_tcp?.Dispose();
return Task.CompletedTask;
}
/// <summary>
/// 由于物体刚上称时重量浮动的原因体重称上传10次的重量一样视为稳定
/// </summary>
/// <param name="weightList"></param>
/// <param name="weight"></param>
/// <returns></returns>
public bool MonitorWeightStability(List<decimal> weightList, decimal weight)
{
//由于电子秤上传重量频率较高故加锁保证
lock (_lock)
{
weightList.Add(weight);
if (weightList.Count > 10)
{
for (int i = weightList.Count - 1; i > 9; i--)
weightList.RemoveAt(i);
}
if (weightList.Count == 10)
{
var result = weightList.Distinct().Count() == 1;
weightList.Clear();
return result;
}
return false;
}
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Seyounth.Auto.Hs.Runtime.Balances
{
/// <summary>
/// 电子秤称重事件
/// </summary>
public interface IBalanceEventHandle
{
/// <summary>
/// 称重触发
/// </summary>
/// <param name="weight"></param>
/// <param name="id"></param>
/// <returns></returns>
Task ExecAsync(decimal weight,int id);
}
}

View File

@ -0,0 +1,203 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Seyounth.Auto.Hs.Runtime.Balances
{
public class SilkBalance : IBalance
{
public int Id => 1;
//扫到码后的业务逻辑
//扫到码后的业务逻辑
private readonly static object _lock = new object();
private List<decimal> _weights = new List<decimal>();
public event Action<string> OnScanned;
private DeviceConnectConfig DeviceConnectConfig;
private TcpClient _tcp;
private NetworkStream _stream;
private readonly IServiceProvider serviceProvider;
private readonly IEnumerable<IBalanceEventHandle> balanceEventHandles;
private readonly ILogger<SilkBalance> logger;
private CancellationTokenSource _receiveDataCancellationToken;
private bool tag;
public SilkBalance(IConfiguration configuration, IServiceProvider serviceProvider, IEnumerable<IBalanceEventHandle> balanceEventHandles, ILogger<SilkBalance> logger)
{
/*
* IP/
*/
var configs = configuration.GetSection("Balance").Get<DeviceConnectConfig[]>();
if (configs is not null && configs.Length > 0)
{
DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id);
}
this.serviceProvider = serviceProvider;
this.balanceEventHandles = balanceEventHandles;
this.logger = logger;
}
public event Func<decimal, Task> OnWeightChanged;
/// <summary>
/// 连接体重秤
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task ConnectAsync()
{
while (true)
{
if (_tcp is not null)
{
try
{
_tcp.Dispose();
}
catch (Exception ex)
{
/*
*
*/
}
}
_tcp = new TcpClient();
try
{
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port));
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
logger.LogInformation("体重秤连接成功");
_receiveDataCancellationToken?.Cancel();
_receiveDataCancellationToken = new CancellationTokenSource();
ReceiveData(_receiveDataCancellationToken.Token);
break;
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await Task.Delay(1000 * 5);
logger.LogError(ex.GetBaseException(), "体重秤连接失败,尝试重连中");
continue;
}
catch (Exception ex)
{
logger.LogError(ex, "体重秤连接失败");
}
}
}
/// <summary>
/// 接收扫码枪数据
/// </summary>
/// <returns></returns>
private async Task ReceiveData(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
//一次最大读取1M
byte[] buffer = new byte[1024];
/* readCount :实际读取字节数*/
var readCount = _stream.Read(buffer, 0, buffer.Length);
if (readCount <= 0)
throw new SocketException();
/* UTF-8 编码获取字符串*/
var result = Encoding.UTF8.GetString(buffer, 0, readCount);
/* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */
var matchs = Regex.Match(result, "-?\\d+(.?\\d+)?");
var weight = 0m;
if (!string.IsNullOrWhiteSpace(matchs.Value))
weight = Convert.ToDecimal(matchs.Value);
;
//logger.LogInformation("YYYYYYYYYYYYYYYYYYYY");
//1.刚开机,重量为 0
if (weight <= 0)
{
tag = true;
continue;
}
;
if (MonitorWeightStability(_weights, weight))
{
if (tag)
{
//logger.LogInformation($"丝锭称接收数据:{result},字节数:{readCount}");
using (var scope = serviceProvider.CreateAsyncScope())
{
var handles = scope.ServiceProvider.GetService<IEnumerable<IBalanceEventHandle>>();
foreach (var item in handles)
{
await item.ExecAsync(weight, Id);
}
}
tag = false;
}
}
}
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
logger.LogError(ex.GetBaseException(), "体重秤连接失败,尝试重连中");
await ConnectAsync();
}
catch (Exception ex)
{
logger.LogError(ex, "体重秤连接失败");
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task DisconnectAsync()
{
_receiveDataCancellationToken?.Cancel();
_tcp?.Dispose();
return Task.CompletedTask;
}
/// <summary>
/// 由于物体刚上称时重量浮动的原因体重称上传10次的重量一样视为稳定
/// </summary>
/// <param name="weightList"></param>
/// <param name="weight"></param>
/// <returns></returns>
public bool MonitorWeightStability(List<decimal> weightList, decimal weight)
{
//由于电子秤上传重量频率较高故加锁保证
lock (_lock)
{
weightList.Add(weight);
if (weightList.Count > 10)
{
for (int i = weightList.Count - 1; i > 9; i--)
weightList.RemoveAt(i);
}
if (weightList.Count == 10)
{
var result = weightList.Distinct().Count() == 1;
weightList.Clear();
return result;
}
return false;
}
}
}
}

View File

@ -38,7 +38,8 @@ public class HsAutoRuntime : IHsAutoRuntime
/// <exception cref="NotImplementedException"></exception>
private Task PlcServiceOnOnWarning(Tuple<short, short> warning)
{
throw new NotImplementedException();
//throw new NotImplementedException();
return Task.CompletedTask;
}
private void ScannersOnOnScanned(IScanner scanner, string barcode)
@ -120,13 +121,13 @@ public class HsAutoRuntime : IHsAutoRuntime
? "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}");
}),
//_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

View File

@ -1,9 +1,12 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
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;
using Seyounth.Auto.Plc.Business;
using Seyounth.Extensions.Plc;
namespace Seyounth.Auto.Hs.Runtime;
@ -28,11 +31,23 @@ public static class HsExtensions
services.AddSingleton<IPrinterService, PrinterService>();
services.AddSingleton<IScannerService, ScannerService>();
services.AddSingleton<IHsAutoRuntime, HsAutoRuntime>();
services.AddSingleton<IScanner,YarnScanner>();
services.AddSingleton<IScanner,BoxScanner>();
services.AddSingleton<IScanner, YarnScanner>();
services.AddSingleton<IScanner, BoxScanner>();
services.AddSingleton<IBalance, BoxBalance>();
services.AddSingleton<IBalance, SilkBalance>();
services.AddSingleton<IPrinter, BoxPrinter>();
services.AddSingleton<IPrinter, SilkPrinter>();
services.AddSingleton<IPlc,SycModbusTcpNet>((serviceProvider) =>
{
var configuration = serviceProvider.GetService<IConfiguration>();
var deviceConnectConfig = configuration.GetSection("Plc").Get<DeviceConnectConfig>();
return new SycModbusTcpNet(deviceConnectConfig.IP, deviceConnectConfig.Port);
});
#region
//services.AddHostedService<PlcBackgroundService>();
// services.AddHostedService<HsBackgroundService>();
//services.AddHostedService<HsBackgroundService>();
#endregion
services.AddMediatR(cfg =>
{
@ -40,4 +55,21 @@ public static class HsExtensions
});
return services;
}
public static IServiceCollection AddScannerEventHandle<TOnWarningHandler>(
this IServiceCollection services)
where TOnWarningHandler :class,IScannerEventHandle
{
services.AddTransient<IScannerEventHandle,TOnWarningHandler>();
return services;
}
public static IServiceCollection AddBalanceEventHandle<TOnWarningHandler>(
this IServiceCollection services)
where TOnWarningHandler : class, IBalanceEventHandle
{
services.AddTransient<IBalanceEventHandle, TOnWarningHandler>();
return services;
}
}

View File

@ -43,4 +43,28 @@ public interface IPlcService
/// <param name="rs"></param>
/// <returns></returns>
Task WriteFilmLabelPrintResult(short rs);
/// <summary>
/// 整箱称重是否顶升到位
/// </summary>
/// <returns></returns>
Task<bool> IsTop();
/// <summary>
/// 请求打印清零
/// </summary>
/// <returns></returns>
Task ClearTop();
/// <summary>
/// 外箱标签打印完成
/// </summary>
/// <returns></returns>
Task BoxTagPrintDoneAsync(short value);
/// <summary>
/// 设置热缩机温度
/// </summary>
/// <returns></returns>
Task SetTemperatureAsync(short val);
}

View File

@ -4,6 +4,11 @@ namespace Seyounth.Auto.Hs.Runtime.Plc;
public class PlcBackgroundService(IPlcService plc) : BackgroundService
{
public override async Task StartAsync(CancellationToken cancellationToken)
{
await plc.StartAsync();
await base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
@ -12,4 +17,10 @@ public class PlcBackgroundService(IPlcService plc) : BackgroundService
await Task.Delay(50, stoppingToken);
}
}
public override Task StopAsync(CancellationToken cancellationToken)
{
plc.StopAsync();
return base.StopAsync(cancellationToken);
}
}

View File

@ -8,10 +8,10 @@ public class PlcService : IPlcService
private readonly ILogger<PlcService> _logger;
private readonly IPlc _plc;
public PlcService(ILogger<PlcService> logger)
public PlcService(IPlc plc,ILogger<PlcService> logger)
{
_logger = logger;
_plc = plc;
//todo:此处创建PLC对象
}
@ -27,12 +27,12 @@ public class PlcService : IPlcService
public async Task<short> GetTemperatureAsync()
{
return (await _plc.ReadAsync<short>("D1000", 1))[0];
return (await _plc.ReadAsync<short>("1000", 1))[0];
}
public async Task QueryWarningInfo()
{
var flags = await _plc.ReadAsync<short>("D1003", 2);
var flags = await _plc.ReadAsync<short>("1003", 2);
if (flags.Any(f => f != 0))
OnWarning?.Invoke(Tuple.Create(flags[0], flags[1]));
}
@ -53,4 +53,27 @@ public class PlcService : IPlcService
{
throw new NotImplementedException();
}
public async Task<bool> IsTop()
{
var arr = await _plc.ReadAsync<short>("1002", 1);
//_logger.LogInformation($"是否顶升寄存器值:{arr?.FirstOrDefault()}");
return arr?.FirstOrDefault() == 1;
}
public async Task BoxTagPrintDoneAsync(short value)
{
await _plc.WriteAsync<short>("1102",value);
_logger.LogInformation("已回复打印完成信号");
}
public async Task SetTemperatureAsync(short val)
{
await _plc.WriteAsync<short>("1100", val);
}
public async Task ClearTop()
{
await _plc.WriteAsync("1002",0);
}
}

View File

@ -0,0 +1,154 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Seyounth.Auto.Hs.Runtime.Scanner;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Unicode;
using System.Threading.Tasks;
namespace Seyounth.Auto.Hs.Runtime.Printer
{
public class BoxPrinter : IPrinter
{
public int Id => 2;
//扫到码后的业务逻辑
public event Action<string> OnScanned;
private DeviceConnectConfig DeviceConnectConfig;
private TcpClient _tcp;
private NetworkStream _stream;
private readonly ILogger<BoxPrinter> logger;
private Queue<string> _sendQueue = new Queue<string>();
private CancellationTokenSource _cts = new CancellationTokenSource();
public BoxPrinter(IConfiguration configuration, ILogger<BoxPrinter> logger)
{
/*
* IP/
*/
var configs = configuration.GetSection("Printer").Get<DeviceConnectConfig[]>();
if (configs is not null && configs.Length > 0)
{
DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id);
}
this.logger = logger;
}
/// <summary>
/// 连接打印机
/// </summary>
/// <returns></returns>
public async Task ConnectAsync()
{
while (true)
{
if (_tcp is not null)
{
try
{
_tcp.Dispose();
}
catch (Exception ex)
{
/*
*
*/
}
}
_tcp = new TcpClient();
try
{
logger.LogInformation("打印机开始连接........");
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port));
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
if (_cts is not null && !_cts.IsCancellationRequested)
_cts.Cancel();
logger.LogInformation("打印机连接成功");
_cts = new CancellationTokenSource();
SendAsync(_cts.Token);
break;
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await Task.Delay(1000 * 5);
logger.LogError(ex.GetBaseException(), "打印机连接失败,尝试重连中");
continue;
}
catch (Exception ex)
{
logger.LogError(ex, "打印机连接失败");
}
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <returns></returns>
private async Task SendAsync(CancellationToken token)
{
try
{
while (!token.IsCancellationRequested)
{
if (_sendQueue.Count > 0)
{
string content = _sendQueue.Peek();
var buffer = Encoding.UTF8.GetBytes(content);
await _stream.WriteAsync(buffer, 0, buffer.Length);
_ = _sendQueue.Dequeue();
}
await Task.Delay(1000);
}
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await ConnectAsync();
logger.LogError(ex.GetBaseException(), "打印失败");
}
catch (Exception ex)
{
logger.LogError(ex, "打印失败");
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task DisconnectAsync()
{
_cts.Cancel();
_tcp?.Dispose();
return Task.CompletedTask;
}
/// <summary>
/// 打印数据
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public async Task PrintAsync(string content) => _sendQueue.Enqueue(content);
//{
// var buffer = Encoding.UTF8.GetBytes(content);
// try
// {
// await _stream.WriteAsync(buffer,0, buffer.Length);
// }
// catch (Exception ex)
// {
// logger.LogError(ex,$"发送打印机数据失败,内容:{content}");
// }
//}
}
}

View File

@ -10,22 +10,16 @@ public class PrinterService : IPrinterService
private readonly List<IPrinter> _printers = new List<IPrinter>();
public PrinterService(ILogger<PrinterService> logger)
public PrinterService(IEnumerable<IPrinter> printers,ILogger<PrinterService> logger)
{
_logger = logger;
_printers.AddRange(printers);
//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}");
})));
await Task.WhenAll(Printers.Select(e => e.ConnectAsync()));
}
public async Task StopAsync()

View File

@ -0,0 +1,147 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Seyounth.Auto.Hs.Runtime.Printer
{
public class SilkPrinter : IPrinter
{
public int Id => 1;
//扫到码后的业务逻辑
public event Action<string> OnScanned;
private DeviceConnectConfig DeviceConnectConfig;
private TcpClient _tcp;
private NetworkStream _stream;
private readonly ILogger<SilkPrinter> logger;
private CancellationTokenSource _cts;
private Queue<string> _sendQueue = new Queue<string>();
public SilkPrinter(IConfiguration configuration, ILogger<SilkPrinter> logger)
{
/*
* IP/
*/
var configs = configuration.GetSection("Printer").Get<DeviceConnectConfig[]>();
if (configs is not null && configs.Length > 0)
{
DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id);
}
this.logger = logger;
}
/// <summary>
/// 连接打印机
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task ConnectAsync()
{
while (true)
{
if (_tcp is not null)
{
try
{
_tcp.Dispose();
}
catch (Exception ex)
{
/*
*
*/
}
}
_tcp = new TcpClient();
try
{
logger.LogInformation("打印机开始连接........");
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port));
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
if (_cts is not null && !_cts.IsCancellationRequested)
_cts.Cancel();
logger.LogInformation("打印机连接成功");
_cts = new CancellationTokenSource();
SendAsync(_cts.Token);
break;
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await Task.Delay(1000 * 5);
logger.LogError(ex.GetBaseException(), "打印机连接失败,尝试重连中");
continue;
}
catch (Exception ex)
{
logger.LogError(ex, "打印机连接失败");
}
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <returns></returns>
private async Task SendAsync(CancellationToken token)
{
try
{
while (!token.IsCancellationRequested)
{
if (_sendQueue.Count > 0)
{
string content = _sendQueue.Peek();
var buffer = Encoding.UTF8.GetBytes(content);
await _stream.WriteAsync(buffer, 0, buffer.Length);
_ = _sendQueue.Dequeue();
}
await Task.Delay(1000);
}
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await ConnectAsync();
logger.LogError(ex.GetBaseException(), "打印失败");
}
catch (Exception ex)
{
logger.LogError(ex, "打印失败");
}
}
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task DisconnectAsync()
{
_cts.Cancel();
_tcp?.Dispose();
return Task.CompletedTask;
}
public async Task PrintAsync(string content) => _sendQueue.Enqueue(content);
//{
// var buffer = Encoding.UTF8.GetBytes(content);
// try
// {
// await _stream.WriteAsync(buffer, 0, buffer.Length);
// }
// catch (Exception ex)
// {
// logger.LogError(ex, $"发送打印机数据失败,内容:{content}");
// }
//}
}
}

View File

@ -7,6 +7,7 @@ using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
namespace Seyounth.Auto.Hs.Runtime.Scanner
{
@ -25,10 +26,13 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
private TcpClient _tcp;
//字节流、可以理解为后端与扫码枪之间的一条管道,扫码枪的数据就是通过这条管道发送给我们的
private NetworkStream _stream;
private readonly IServiceProvider serviceProvider;
private readonly IEnumerable<IScannerEventHandle> scannerEventHandles;
private readonly ILogger<BoxScanner> logger;
private CancellationTokenSource _receiveDataCancellationToken;
private CancellationTokenSource _cts = new CancellationTokenSource();
public BoxScanner(IConfiguration configuration, ILogger<BoxScanner> logger)
public BoxScanner(IConfiguration configuration, IServiceProvider serviceProvider,IEnumerable<IScannerEventHandle> scannerEventHandles,ILogger<BoxScanner> logger)
{
/*
* IP/
@ -39,6 +43,8 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id);
}
this.serviceProvider = serviceProvider;
this.scannerEventHandles = scannerEventHandles;
this.logger = logger;
}
@ -48,40 +54,45 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
/// <returns></returns>
public async Task ConnectAsync()
{
if (_tcp is not null)
while (true)
{
if (_tcp is not null)
{
try
{
_tcp.Dispose();
}
catch (Exception ex)
{
/*
*
*/
}
}
_tcp = new TcpClient();
try
{
_tcp.Dispose();
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port));
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
logger.LogInformation("箱扫码枪连接成功,开始接收数据");
_receiveDataCancellationToken?.Cancel();
_receiveDataCancellationToken = new CancellationTokenSource();
ReceiveData(_receiveDataCancellationToken.Token);
break;
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await Task.Delay(1000 * 5);
logger.LogError(ex.GetBaseException(), "箱扫码枪连接失败,尝试重连中");
continue;
}
catch (Exception ex)
{
/*
*
*/
logger.LogError(ex, "箱扫码枪连接失败");
}
}
_tcp = new TcpClient();
try
{
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port))
.ContinueWith((task, obj) =>
{
if (task.IsCompletedSuccessfully)
{
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
logger.LogInformation("箱扫码枪连接成功,开始接收数据");
_receiveDataCancellationToken = new CancellationTokenSource();
Task.Factory.StartNew(() => ReceiveData(_receiveDataCancellationToken.Token), _receiveDataCancellationToken.Token);
}
}, null);
}
catch (Exception ex)
{
logger.LogError(ex, "箱扫码枪连接失败");
}
}
@ -89,19 +100,38 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
/// 接收扫码枪数据
/// </summary>
/// <returns></returns>
private void ReceiveData(CancellationToken cancellationToken)
private async Task ReceiveData(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
try
{
//一次最大读取1M
byte[] buffer = new byte[1024];
/* readCount :实际读取字节数*/
var readCount = _stream.Read(buffer, 0, buffer.Length);
/* UTF-8 编码获取字符串*/
var result = Encoding.UTF8.GetString(buffer, 0, readCount);
logger.LogInformation($"箱扫码枪接收数据:{result},字节数:{readCount}");
/* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */
Task.Run(() => OnScanned?.Invoke(result));
while (!cancellationToken.IsCancellationRequested)
{
//一次最大读取1M
byte[] buffer = new byte[1024];
/* readCount :实际读取字节数*/
var readCount = _stream.Read(buffer, 0, buffer.Length);
if (readCount <= 0)
throw new SocketException();
/* UTF-8 编码获取字符串*/
var result = Encoding.UTF8.GetString(buffer, 0, readCount);
if (string.IsNullOrWhiteSpace(result)) continue;
logger.LogInformation($"箱扫码枪接收数据:{result},字节数:{readCount}");
/* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */
var handles = serviceProvider.GetService<IEnumerable<IScannerEventHandle>>();
foreach (var item in handles)
{
await item.ExecAsync(result, Id);
}
}
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
logger.LogError(ex.GetBaseException(), "箱扫码枪连接失败,尝试重连中");
await ConnectAsync();
}
catch (Exception ex)
{
logger.LogError(ex, "箱扫码枪连接失败");
}
}
@ -111,7 +141,7 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
/// <returns></returns>
public Task DisconnectAsync()
{
_receiveDataCancellationToken.Cancel();
_receiveDataCancellationToken?.Cancel();
_tcp?.Dispose();
return Task.CompletedTask;
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Seyounth.Auto.Hs.Runtime.Scanner
{
public interface IScannerEventHandle
{
/// <summary>
/// 扫码触发
/// </summary>
/// <param name="code"></param>
/// <param name="id"></param>
/// <returns></returns>
Task ExecAsync(string code, int id);
}
}

View File

@ -14,19 +14,11 @@ public class ScannerService : IScannerService
public IReadOnlyList<IScanner> Scanners => _scanners;
private readonly ILogger<ScannerService> _logger;
private readonly List<IScanner> _scanners = new List<IScanner>();
public async Task StartAsync()
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}");
})));
await Task.WhenAll(_scanners.Select(e => e.ConnectAsync()));
}
public async Task StopAsync()

View File

@ -23,10 +23,11 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
private DeviceConnectConfig DeviceConnectConfig;
private TcpClient _tcp;
private NetworkStream _stream;
private readonly IEnumerable<IScannerEventHandle> scannerEventHandles;
private readonly ILogger<YarnScanner> logger;
private CancellationTokenSource _receiveDataCancellationToken;
public YarnScanner(IConfiguration configuration,ILogger<YarnScanner> logger)
public YarnScanner(IConfiguration configuration, IEnumerable<IScannerEventHandle> scannerEventHandles, ILogger<YarnScanner> logger)
{
/*
* IP/
@ -37,7 +38,7 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id);
}
OnScanned += ;
this.scannerEventHandles = scannerEventHandles;
this.logger = logger;
}
@ -47,40 +48,45 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
/// <returns></returns>
public async Task ConnectAsync()
{
if (_tcp is not null)
while (true)
{
if (_tcp is not null)
{
try
{
_tcp.Dispose();
}
catch (Exception ex)
{
/*
*
*/
}
}
_tcp = new TcpClient();
try
{
_tcp.Dispose();
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port));
if (_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
logger.LogInformation("人工扫码枪连接成功,开始接收数据");
_receiveDataCancellationToken?.Cancel();
_receiveDataCancellationToken = new CancellationTokenSource();
ReceiveData(_receiveDataCancellationToken.Token);
break;
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
await Task.Delay(1000 * 5);
logger.LogError(ex.GetBaseException(), "人工扫码枪连接失败,尝试重连中");
continue;
}
catch (Exception ex)
{
/*
*
*/
logger.LogError(ex, "人工扫码枪连接失败");
}
}
_tcp = new TcpClient();
try
{
await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP),DeviceConnectConfig.Port))
.ContinueWith((task,obj) =>
{
if (task.IsCompletedSuccessfully)
{
if(_stream is not null)
_stream.Dispose();
_stream = _tcp.GetStream();
logger.LogInformation("人工扫码枪连接成功,开始接收数据");
_receiveDataCancellationToken = new CancellationTokenSource();
Task.Factory.StartNew(() => ReceiveData(_receiveDataCancellationToken.Token), _receiveDataCancellationToken.Token);
}
},null);
}
catch (Exception ex)
{
logger.LogError(ex, "人工扫纱扫码枪连接失败");
}
}
@ -88,30 +94,38 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
/// 接收扫码枪数据
/// </summary>
/// <returns></returns>
private void ReceiveData(CancellationToken cancellationToken)
private async Task ReceiveData(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
try
{
//一次最大读取1M
byte[] buffer = new byte[1024];
/* readCount :实际读取字节数*/
var readCount = _stream.Read(buffer,0,buffer.Length);
/* UTF-8 编码获取字符串*/
var result = Encoding.UTF8.GetString(buffer,0,readCount);
logger.LogInformation($"人工扫纱扫码枪接收数据:{result},字节数:{readCount}");
/* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */
Task.Run(() => OnScanned?.Invoke(result));
while (!cancellationToken.IsCancellationRequested)
{
//一次最大读取1M
byte[] buffer = new byte[1024];
/* readCount :实际读取字节数*/
var readCount = _stream.Read(buffer, 0, buffer.Length);
if (readCount == 0)
throw new SocketException();
/* UTF-8 编码获取字符串*/
var result = Encoding.UTF8.GetString(buffer, 0, readCount);
if (string.IsNullOrWhiteSpace(result)) continue;
logger.LogInformation($"人工扫纱扫码枪接收数据:{result},字节数:{readCount}");
/* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */
foreach (var item in scannerEventHandles)
{
await item.ExecAsync(result, Id);
}
}
}
catch (Exception ex) when (ex.GetBaseException() is OperationCanceledException oce || ex.GetBaseException() is SocketException socketException)
{
logger.LogError(ex.GetBaseException(), "人工扫码枪连接失败,尝试重连中");
await ConnectAsync();
}
catch (Exception ex)
{
logger.LogError(ex, "人工扫码枪连接失败");
}
}
/// <summary>
/// 把人工扫码的逻辑写这里,在这里将码返回给前端
/// </summary>
/// <param name="code"></param>
private void (string code)
{
}
/// <summary>
@ -120,7 +134,7 @@ namespace Seyounth.Auto.Hs.Runtime.Scanner
/// <returns></returns>
public Task DisconnectAsync()
{
_receiveDataCancellationToken.Cancel();
_receiveDataCancellationToken?.Cancel();
_tcp?.Dispose();
return Task.CompletedTask;
}

View File

@ -6,6 +6,12 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<!--<ItemGroup>
<Compile Remove="Handlers\**" />
<EmbeddedResource Remove="Handlers\**" />
<None Remove="Handlers\**" />
</ItemGroup>-->
<ItemGroup>
<PackageReference Include="MediatR" Version="12.5.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
@ -14,4 +20,14 @@
<PackageReference Include="Seyounth.Extensions.Plc" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Seyounth.Auto.Plc\Seyounth.Auto.Plc.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="HslCommunication">
<HintPath>..\Seyounth.Auto.Plc\DLLFile\HslCommunication.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -4,6 +4,8 @@ using System.Text;
using System.Net;
using Seyounth.Extensions.Plc;
using Seyounth.Auto.Plc.Helper;
using System.Runtime.InteropServices;
using System.Threading.Tasks.Dataflow;
namespace Seyounth.Auto.Plc.Business
{
@ -88,9 +90,16 @@ namespace Seyounth.Auto.Plc.Business
return string.Empty;
}
public Task WriteAsync<T>(string address, params T[] values)
public async Task WriteAsync<T>(string address, params T[] values)
{
throw new NotImplementedException();
var type = typeof(T);
var buffer = new byte[values.Length * Marshal.SizeOf(type)];
if (type.IsPrimitive)
{
Buffer.BlockCopy(values, 0, buffer, 0, buffer.Length);
}
//Encoding.ASCII.GetBytes();
await Melse.WriteAsync(address, buffer);
}
public async Task WriteStringAsync(string address, string value)

View File

@ -98,9 +98,12 @@ namespace Seyounth.Auto.Plc.Business
return string.Empty;
}
public Task WriteAsync<T>(string address, params T[] values)
public async Task WriteAsync<T>(string address, params T[] values)
{
throw new NotImplementedException();
if (values is short[])
await Melse.WriteAsync(address, values as short[]);
else if (values is int[])
await Melse.WriteAsync(address, values as int[]);
}
public async Task WriteStringAsync(string address, string value)

View File

@ -6,10 +6,9 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\share\Seyounth.Auto.Hs.Runtime\Seyounth.Auto.Hs.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Seyounth.Extensions.Plc" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="HslCommunication">
<HintPath>DLLFile\HslCommunication.dll</HintPath>