| | |
| | | |
| | | using Flurl.Util; |
| | | using Furion.DatabaseAccessor; |
| | | using Furion.Logging; |
| | | using IoTClient; |
| | | using StackExchange.Redis; |
| | | using System.Data; |
| | | |
| | | namespace WCS.Application; |
| | | public static class PLCService |
| | | { |
| | | private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); |
| | | |
| | | public static void OnChangeEvent(object sender, EventArgs e) |
| | | { |
| | | try |
| | | { |
| | | var mod = sender as WcsDeviceDto; |
| | | Console.WriteLine("PLC值为" + mod.Value); |
| | | switch (mod.Type) |
| | | { |
| | | case PLCTypeEnum.StackingMachine: |
| | | StackingMachine(mod); |
| | | break; |
| | | case PLCTypeEnum.ConveyorLine: |
| | | ConveyorLine(mod); |
| | | break; |
| | | case PLCTypeEnum.AGV: |
| | | AGV(mod); |
| | | break; |
| | | case PLCTypeEnum.PalletMachine: |
| | | PalletMachine(mod); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Log.Error(ex.Message, ex); |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 跺机业务处理 |
| | | /// </summary> |
| | | /// <param name="modDevice"></param> |
| | | private static void StackingMachine(WcsDeviceDto modDevice) |
| | | { |
| | | var plcConn = modDevice.PLCUtil; |
| | | switch (modDevice.ToString()) |
| | | { |
| | | case "820": |
| | | var modTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Wait && s.TaskType == TaskTypeEnum.Out && s.StartRoadway == modDevice.StationNum); |
| | | if (modTask == null) |
| | | { |
| | | break; |
| | | } |
| | | var modTaskMonitor = new WcsTaskMonitor() |
| | | { |
| | | TaskNo = modTask.TaskNo, |
| | | StartLocat = modTask.StartLocate, |
| | | EndLocat = modTask.EndLocate, |
| | | PalletNo = modTask.PalletNo, |
| | | }; |
| | | // 根据跺机号确认放货工位 |
| | | string outStationNum = "0"; |
| | | string endRow = "", endColumn = "", endStorey = ""; |
| | | switch (modDevice.StationNum) |
| | | { |
| | | case "R01": |
| | | outStationNum = "11"; |
| | | endRow = "1"; |
| | | endColumn = "100"; |
| | | endStorey = "1"; |
| | | break; |
| | | case "R02": |
| | | outStationNum = "7"; |
| | | endRow = "1"; |
| | | endColumn = "100"; |
| | | endStorey = "1"; |
| | | break; |
| | | default: break; |
| | | } |
| | | var modD = modDevice.listDevice.FirstOrDefault(); |
| | | if (modD == null) |
| | | { |
| | | Log.Error($"IP{modDevice.PlcId}.设备id:{modDevice.Id}缺少工位级别设备信息"); |
| | | break; |
| | | } |
| | | var (result, value) = plcConn.GetPlcDBValue(modD.PosType.Value, modD.DbNumber, modD.PlcPos); |
| | | if (result.IsSucceed) |
| | | { |
| | | if (value == 120)// 放货工位空闲 可放货 |
| | | { |
| | | if (int.Parse(outStationNum) > 0) |
| | | { |
| | | var row = int.Parse(modTaskMonitor.StartLocat.Substring(0, 2)).ToString(); |
| | | var column = int.Parse(modTaskMonitor.StartLocat.Substring(2, 2)).ToString(); |
| | | var layer = int.Parse(modTaskMonitor.StartLocat.Substring(4, 2)).ToString(); |
| | | var deep = int.Parse(modTaskMonitor.StartLocat.Substring(6, 2)).ToString(); |
| | | if (int.Parse(row) > 2) //大于4 |
| | | { |
| | | row = (int.Parse(row) - 2).ToString(); |
| | | } |
| | | else |
| | | { |
| | | // 起始储位地址为空,跳过 写入任务明细表 |
| | | modTaskMonitor.StartLocat = ""; |
| | | modTaskMonitor.InteractiveMsg = "起始储位为空!"; |
| | | |
| | | _db.Insertable(modTaskMonitor).ExecuteCommand(); |
| | | |
| | | // 通知任务界面任务已存在更新 请更新界面 |
| | | //if (TaskAction.refresh) |
| | | //{ |
| | | // wSChat.AlarmInformation("1"); |
| | | //} |
| | | break; |
| | | } |
| | | //给PLC写入任务数据 |
| | | var listResult = new List<Result>(); |
| | | //任务号 |
| | | var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType.Value, modDevice.DbNumber, modPosTask.PlcPos, modTaskMonitor.TaskNo)); |
| | | //托盘号 |
| | | var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "PalletNo"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType.Value, modDevice.DbNumber, modPosPalletNo.PlcPos, modTaskMonitor.PalletNo)); |
| | | //起始排 |
| | | var modPosRow = modDevice.listStation.FirstOrDefault(s => s.Text == "StartRow"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType.Value, modDevice.DbNumber, modPosRow.PlcPos, row)); |
| | | // 起始列 |
| | | var modPosColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "StartColumn"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType.Value, modDevice.DbNumber, modPosColumn.PlcPos, column)); |
| | | // 起始层 |
| | | var modPosStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "StartLayer"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType.Value, modDevice.DbNumber, modPosStorey.PlcPos, layer)); |
| | | |
| | | // 目标放货工位 |
| | | var modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "EndRow"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType.Value, modDevice.DbNumber, modPosEndRow.PlcPos, endRow)); |
| | | var modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "EndColumn"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType.Value, modDevice.DbNumber, modPosEndColumn.PlcPos, endColumn)); |
| | | var modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "EndLayer"); |
| | | listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType.Value, modDevice.DbNumber, modPosEndStorey.PlcPos, endColumn)); |
| | | //全部写入成功 |
| | | if (listResult.All(s => s.IsSucceed)) |
| | | { |
| | | // 写入跺机任务下发完成 |
| | | plcConn.SetPlcDBValue(modDevice.PosType.Value, modDevice.DbNumber, modDevice.WcsPos, "10"); |
| | | |
| | | // 将出库任务待执行改为正在执行 |
| | | _db.Updateable<WcsTask>() |
| | | .SetColumns(s => s.FinishDate == DateTime.Now) |
| | | .SetColumns(s => s.Status == TaskStatusEnum.Doing) |
| | | .SetColumns(s => s.Levels == 2) |
| | | .Where(s => s.Id == modTask.Id) |
| | | .ExecuteCommand(); |
| | | var modInsertTaskMonitor = new WcsTaskMonitor() |
| | | { |
| | | TaskNo = modTask.TaskNo, |
| | | PlcId = modDevice.Id, |
| | | PlcName = modDevice.Text, |
| | | InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{outStationNum}工位", |
| | | PalletNo = modTask.PalletNo, |
| | | Status = TaskStatusEnum.Complete, |
| | | StartLocat = modTask.StartLocate, |
| | | EndLocat = outStationNum, |
| | | }; |
| | | _db.Insertable(modInsertTaskMonitor).ExecuteCommand(); |
| | | // 通知任务界面任务已存在更新 请更新界面 |
| | | //if (TaskAction.refresh) |
| | | //{ |
| | | // wSChat.AlarmInformation("1"); |
| | | //} |
| | | //修改led屏信息 |
| | | //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Log.Error(string.Join(',', result.ErrList)); |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 输送线业务处理 |
| | | /// </summary> |
| | | /// <param name="modDevice"></param> |
| | | private static void ConveyorLine(WcsDeviceDto modDevice) |
| | | { |
| | | |
| | | } |
| | | /// <summary> |
| | | /// AGV业务处理 |
| | | /// </summary> |
| | | /// <param name="modDevice"></param> |
| | | private static void AGV(WcsDeviceDto modDevice) |
| | | { |
| | | |
| | | } |
| | | /// <summary> |
| | | /// 叠托机业务处理 |
| | | /// </summary> |
| | | /// <param name="modDevice"></param> |
| | | private static void PalletMachine(WcsDeviceDto modDevice) |
| | | { |
| | | |
| | | } |
| | | |
| | | private static void Test(WcsDeviceDto modDevice) |
| | | { |
| | | //写死测试读string |
| | | var (res, val) = mod.PLCUtil.GetPlcDBValue(PLCDataTypeEnum.String, "DB100", "64"); |
| | | var (res, val) = modDevice.PLCUtil.GetPlcDBValue(PLCDataTypeEnum.String, "DB100", "64"); |
| | | Console.WriteLine("DB100.64----" + val); |
| | | //测试批量读取 |
| | | Dictionary<string, PLCDataTypeEnum> listaddress = new Dictionary<string, PLCDataTypeEnum>(); |
| | | foreach (var modStation in mod.listStation) |
| | | foreach (var modStation in modDevice.listStation) |
| | | { |
| | | listaddress.Add(modStation.PlcPos, modStation.PosType.Value); |
| | | } |
| | | var result = mod.PLCUtil.GetPlcBatchDBValue(listaddress); |
| | | var result = modDevice.PLCUtil.GetPlcBatchDBValue(listaddress); |
| | | if (result.Value.Count > 0) |
| | | { |
| | | foreach (var value in result.Value) |
| | |
| | | |
| | | } |
| | | } |
| | | if (mod.Value == 820) |
| | | if (modDevice.Value == 820) |
| | | { |
| | | //测试写入830 |
| | | //var result = mod.PLCUtil.SetPlcDBValue(mod.PosType.Value, mod.DbNumber, mod.PlcPos, "830"); |
| | |
| | | |
| | | //} |
| | | } |
| | | else if (mod.Value == 840) |
| | | else if (modDevice.Value == 840) |
| | | { |
| | | |
| | | } |
| | | else if (mod.Value == 860) |
| | | else if (modDevice.Value == 860) |
| | | { |
| | | |
| | | } |
| | | break; |
| | | case PLCTypeEnum.ConveyorLine: |
| | | |
| | | break; |
| | | case PLCTypeEnum.AGV: |
| | | break; |
| | | case PLCTypeEnum.PalletMachine: |
| | | |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |