first commit

This commit is contained in:
2026-09-02 16:31:50 +08:00
commit a461727193
911 changed files with 692450 additions and 0 deletions
@@ -0,0 +1,36 @@
using JSMachine.WMS.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JSMachine.WMS.PLC.ModbusImpl.Elevator
{
/// <summary>
/// 电梯 PLC 通信实现,初始化时将连接实例注册到 PLC 管理器供后台任务使用。
/// </summary>
public class ElevatorPlc : ModbusEngineBase, IModbusEngine
{
/// <summary>
/// 初始化并连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <param name="plc_key"></param>
/// <returns></returns>
public override IModbusEngine Init(string ip, int port)
{
int elevatorNo = Global.AppSettings.ElevatorConfig.First(p => p.IP == ip).ElevatorNo;
IModbusEngine modbus = base.Init(ip, port);
//必须先将PLC实例添加到字典,否则job先执行后无法拿到实例会导致无法重连
PLCManager.AddPLC(elevatorNo, modbus);
modbus.Connet();
return modbus;
}
}
}
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JSMachine.WMS.PLC.ModbusImpl.Elevator.Enums
{
public enum ElevatorType
{
/// <summary>
/// 一号提升机
/// </summary>
ElevatorOne=1,
/// <summary>
/// 二号提升机
/// </summary>
ElevatorTwo=2
}
}
@@ -0,0 +1,32 @@
using JSMachine.WMS.Common;
using JSMachine.WMS.Infrastructure.AppConfiguration;
using Microsoft.AspNetCore.Builder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JSMachine.WMS.PLC.ModbusImpl.Elevator.Exstension
{
/// <summary>
/// 电梯 PLC 的 ASP.NET Core 应用构建扩展。
/// </summary>
public static class ElevatorPlcExstension
{
/// <summary>
/// 按配置异步初始化每台电梯的 PLC 连接。
/// </summary>
/// <param name="app">当前应用构建器。</param>
public static void UseElevatorPlc(this IApplicationBuilder app)
{
foreach (ElevatorConfig elevatorConfig in Global.AppSettings.ElevatorConfig)
{
Task.Run(() =>
{
new ElevatorPlc().Init(elevatorConfig.IP, elevatorConfig.Port);
});
}
}
}
}
@@ -0,0 +1,65 @@
using JSMachine.WMS.Infrastructure.Helper;
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Enums;
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JSMachine.WMS.PLC.ModbusImpl.Elevator.ModbusIO.Read
{
public static class ElevatorStatusRead
{
/// <summary>
/// 读取所有提升机状态
/// </summary>
/// <returns></returns>
public static async Task<List<ElevatorPlcStatus>> ReadAllElevatorStatus()
{
ElevatorPlcStatus elevatorStatusOne = await ReadElevatorStatus(1);
ElevatorPlcStatus elevatorStatusTwo = await ReadElevatorStatus(2);
elevatorStatusOne ??= new() { ElevatorNo = 1 };
elevatorStatusTwo ??= new() { ElevatorNo = 2 };
return [elevatorStatusOne, elevatorStatusTwo];
}
/// <summary>
/// 读取指定提升机状态
/// </summary>
/// <param name="elevatorNo"></param>
/// <returns></returns>
public static async Task<ElevatorPlcStatus> ReadElevatorStatus(int elevatorNo)
{
IModbusEngine modbusEngine = PLCManager.GetPLC(elevatorNo);
if (modbusEngine == null)
return null;
ushort[] data = await modbusEngine.ReadUshortsAsync(1, 0, 20);
if (data == null)
{
return null;
}
ElevatorPlcStatus elevatorStatus = new()
{
ElevatorNo = elevatorNo,
StockInPutdownChanelOne = data[2] == 1,
StockInPutdownChanelTwo = data[0] == 1,
StockInPickupChannelOne = data[7] == 1,
StockInPickupChannelTwo = data[5] == 1,
StockOutPutdownChanelOne = data[6] == 1,
StockOutPutdownChanelTwo = data[4] == 1,
StockOutPickupChanelOne = data[3] == 1,
StockOutPickupChanelTwo = data[1] == 1,
};
return elevatorStatus;
}
}
}
@@ -0,0 +1,40 @@
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Model;
namespace JSMachine.WMS.PLC.ModbusImpl.PaperFeedGroundRack.ModbusIO.Write
{
public static class ElevatorWrite
{
public async static Task<bool> WriteElevator(ElevatorPlcStatus elevatorStatus)
{
IModbusEngine modbusEngine = PLCManager.GetPLC(elevatorStatus.ElevatorNo);
if (modbusEngine == null)
return false;
if (elevatorStatus.StockInPutdownChanelOne)
await modbusEngine.WriteUshortOneAsync(1, 10, elevatorStatus.StockInPutdownChanelOne ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockInPutdownChanelTwo)
await modbusEngine.WriteUshortOneAsync(1, 8, elevatorStatus.StockInPutdownChanelTwo ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockInPickupChannelOne)
await modbusEngine.WriteUshortOneAsync(1, 15, elevatorStatus.StockInPickupChannelOne ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockInPickupChannelTwo)
await modbusEngine.WriteUshortOneAsync(1, 13, elevatorStatus.StockInPickupChannelTwo ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockOutPutdownChanelOne)
await modbusEngine.WriteUshortOneAsync(1, 14, elevatorStatus.StockOutPutdownChanelOne ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockOutPutdownChanelTwo)
await modbusEngine.WriteUshortOneAsync(1, 12, elevatorStatus.StockOutPutdownChanelTwo ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockOutPickupChanelOne)
await modbusEngine.WriteUshortOneAsync(1, 11, elevatorStatus.StockOutPickupChanelOne ? (ushort)1 : (ushort)0);
if (elevatorStatus.StockOutPickupChanelTwo)
await modbusEngine.WriteUshortOneAsync(1, 9, elevatorStatus.StockOutPickupChanelTwo ? (ushort)1 : (ushort)0);
return true;
}
}
}
@@ -0,0 +1,53 @@
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JSMachine.WMS.PLC.ModbusImpl.Elevator.Model
{
/// <summary>
/// 提升机状态,用于读取PLC的时候表明提升机允许干什么,用于写PLC的时候表示动作已经完成给PLC反馈
/// </summary>
public class ElevatorPlcStatus
{
/// <summary>
/// 提升机编号 1,2
/// </summary>
public int ElevatorNo { get; set; }
/// <summary>
/// 入库放货通道2 网带号1001 读取数据位0 写入数据位8
/// </summary>
public bool StockInPutdownChanelTwo { get; set; }
/// <summary>
/// 入库放货通道1 网带号1011 读取数据位2 写入数据位10
/// </summary>
public bool StockInPutdownChanelOne { get; set; }
/// <summary>
/// 入库取货通道2 网带号2004 读取数据位5 写入数据位13
/// </summary>
public bool StockInPickupChannelTwo { get; set; }
/// <summary>
/// 入库取货通道1 网带号2014 读取数据位7 写入数据位15
/// </summary>
public bool StockInPickupChannelOne { get; set; }
/// <summary>
/// 出库放货通道2 网带号2001 读取数据位4 写入数据位12
/// </summary>
public bool StockOutPutdownChanelTwo { get; set; }
/// <summary>
/// 出库放货通道1 网带号2011 读取数据位6 写入数据位14
/// </summary>
public bool StockOutPutdownChanelOne { get; set; }
/// <summary>
/// 出库取货通道2 网带号1006 读取数据位1 写入数据位9
/// </summary>
public bool StockOutPickupChanelTwo { get; set; }
/// <summary>
/// 出库取货通道1 网带号1016 读取数据位3 写入数据位11
/// </summary>
public bool StockOutPickupChanelOne { get; set; }
}
}
@@ -0,0 +1,79 @@
using JSMachine.WMS.App.Dto.Enum;
using JSMachine.WMS.App.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JSMachine.WMS.PLC.ModbusImpl.Elevator.ModbusIO.Read;
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Model;
using JSMachine.WMS.App.IService;
using JSMachine.WMS.Infrastructure;
using JSMachine.WMS.Infrastructure.Helper;
namespace JSMachine.WMS.PLC.ModbusImpl.Elevator.Util
{
public static class ElevatorUtil
{
private static IStorageRackService IStorageRackService = GlobalServericeProvidor.GetService<IStorageRackService>();
private static IERPTaskService IERPTaskService = GlobalServericeProvidor.GetService<IERPTaskService>();
/// <summary>
/// 获取可用的提升机库位
/// </summary>
/// <param name="floor"></param>
/// <returns></returns>
public static async Task<StorageRackDto> GetUsableElevatorChannel(Guid erpTaskId,FloorEnum floor)
{
List<StorageRackDto> usableElevatorWareHouse = await IStorageRackService.GetUsableElevatorWareHouse(floor);
if (usableElevatorWareHouse.IsNullOrEmpty())
{
string msg = $"{(floor == FloorEnum.FirstFloor ? 1 : 2)}楼所有提升机库位均被WMS锁定";
LogHelper.Warn(msg);
_ = IERPTaskService.UpdateTaskMsg(erpTaskId, msg);
return null;
}
List<ElevatorPlcStatus> elevatorPlcStatuses = await ElevatorStatusRead.ReadAllElevatorStatus();
StorageRackDto elevator = null;
foreach (StorageRackDto elvatorWarehouse in usableElevatorWareHouse)
{
int elevatorNo = elvatorWarehouse.StorageRackName.Contains("1号") ? 1 : 2;
ElevatorPlcStatus elevatorPlcStatus = elevatorPlcStatuses.First(p => p.ElevatorNo == elevatorNo);
if (floor == FloorEnum.FirstFloor)
{
if (elvatorWarehouse.ElevatorChannel == 1011 && elevatorPlcStatus.StockInPutdownChanelOne ||
elvatorWarehouse.ElevatorChannel == 1001 && elevatorPlcStatus.StockInPutdownChanelTwo)
{
elevator = elvatorWarehouse;
break;
}
}
else
{
if (elvatorWarehouse.ElevatorChannel == 2011 && elevatorPlcStatus.StockOutPutdownChanelOne ||
elvatorWarehouse.ElevatorChannel == 2001 && elevatorPlcStatus.StockOutPutdownChanelTwo)
{
elevator = elvatorWarehouse;
break;
}
}
}
if(elevator == null)
{
string msg = $"{(floor == FloorEnum.FirstFloor ? 1 : 2)}楼 提升机库位不允许放货或者被WMS锁定";
LogHelper.Warn(msg);
_ = IERPTaskService.UpdateTaskMsg(erpTaskId, msg);
}
return elevator;
}
}
}
@@ -0,0 +1,55 @@
using JSMachine.WMS.Common;
using JSMachine.WMS.Infrastructure.AppConfiguration;
using JSMachine.WMS.Infrastructure.Helper;
using JSMachine.WMS.PLC.ModbusImpl.Elevator;
using System.Collections.Concurrent;
namespace JSMachine.WMS.PLC.ModbusImpl
{
/// <summary>
/// 进程内 PLC 引擎注册表,按提升机编号管理通信实例。
/// </summary>
public static class PLCManager
{
private static readonly ConcurrentDictionary<int, IModbusEngine> PLC_Dic = new();
/// <summary>
/// 添加或替换指定提升机的 PLC 引擎。
/// </summary>
/// <param name="elevatorNo">提升机编号。</param>
/// <param name="modbusEngine">对应的 Modbus 引擎。</param>
public static void AddPLC(int elevatorNo, IModbusEngine modbusEngine)
{
if (PLC_Dic.ContainsKey(elevatorNo))
{
PLC_Dic[elevatorNo] = modbusEngine;
}
else
{
PLC_Dic.TryAdd(elevatorNo, modbusEngine);
}
}
/// <summary>
/// 获取指定提升机的 PLC 引擎;未注册时记录警告并返回空值。
/// </summary>
/// <param name="elevatorNo">提升机编号。</param>
/// <returns>已注册的通信引擎,未连接时返回空值。</returns>
public static IModbusEngine GetPLC(int elevatorNo)
{
if (!PLC_Dic.ContainsKey(elevatorNo))
{
LogHelper.Warn($"{elevatorNo} 号提升机PLC尚未连接");
//ElevatorConfig elevatorConfig = Global.AppSettings.ElevatorConfig.First(p => p.ElevatorNo == elevatorNo);
//new ElevatorPlc().Init(elevatorConfig.IP, elevatorConfig.Port);
return null;
}
return PLC_Dic[elevatorNo];
}
}
}