bklLiudl
2024-09-11 5af0a043ffbbe444f7e43b6bf52a9e94c74283f2
跺机交互流程
3个文件已修改
2个文件已添加
1182 ■■■■■ 已修改文件
Admin.NET/WCS.Application/Entity/WcsTaskMonitor.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Model/PlcTaskInfo.cs 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCCommon.cs 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCService.cs 789 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Entity/WcsTaskMonitor.cs
@@ -35,7 +35,13 @@
    /// </summary>
    [SugarColumn(ColumnName = "EndLocat", ColumnDescription = "目标位置", Length = 32)]
    public string? EndLocat { get; set; }
    /// <summary>
    /// 目标位置
    /// </summary>
    [SugarColumn(ColumnName = "EndRoadway", ColumnDescription = "目标巷道", Length = 20)]
    public string? EndRoadway { get; set; }
    /// <summary>
    /// 交互信息
    /// </summary>
Admin.NET/WCS.Application/Model/PlcTaskInfo.cs
New file
@@ -0,0 +1,51 @@
namespace WCS.Application;
/// <summary>
/// PLC任务信息
/// </summary>
public class PlcTaskInfo
{
    /// <summary>
    /// IP地址
    /// </summary>
    public string Ip { get; set; }
    /// <summary>
    /// 起始工位
    /// </summary>
    public string StartStation { get; set; }
    /// <summary>
    /// 目标工位
    /// </summary>
    public string EndStation { get; set; }
    /// <summary>
    /// 起始排
    /// </summary>
    public string StartPai { get; set; }
    /// <summary>
    /// 起始列
    /// </summary>
    public string StartLie { get; set; }
    /// <summary>
    /// 起始层
    /// </summary>
    public string StartCeng { get; set; }
    /// <summary>
    /// 目标排
    /// </summary>
    public string EndPai { get; set; }
    /// <summary>
    /// 目标列
    /// </summary>
    public string EndLie { get; set; }
    /// <summary>
    /// 目标层
    /// </summary>
    public string EndCeng { get; set; }
    /// <summary>
    /// 起始巷道
    /// </summary>
    public string StartRoadway { get; set; }
    /// <summary>
    /// 目标巷道
    /// </summary>
    public string EndRoadway { get; set; }
}
Admin.NET/WCS.Application/PLC/PLCCommon.cs
New file
@@ -0,0 +1,326 @@
using Microsoft.AspNetCore.SignalR;
using RazorEngine.Compilation.ImpromptuInterface.Dynamic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WCS.Application;
public static class PLCCommon
{
    private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
    /// <summary>
    /// 获取任务相关信息
    /// </summary>
    /// <param name="endLocat">目标位置</param>
    /// <param name="taskType">1:出库任务 2:移库任务</param>
    /// <param name="roadWay">起始巷道</param>
    /// <param name="endRoadWay">目标巷道</param>
    /// <returns></returns>
    public static PlcTaskInfo GetCTaskInfo(string endLocat,string taskType,string roadWay,string endRoadWay)
    {
        // 各层输送线跺机放货工位集合
        var conveyList1 = new List<string>() { "033", "039", "044", "051", "059" };
        var conveyList2 = new List<string>() { "205", "234" };
        var conveyList3 = new List<string>() { "440", "443" };
        PlcTaskInfo taskInfo = new PlcTaskInfo();
        taskInfo.EndCeng = "3";
        taskInfo.EndLie = "65";
        taskInfo.EndPai = int.Parse(roadWay.Substring(1,2)).ToString();
        // 移库任务
        if (taskType == "2")
        {
            if (roadWay == endRoadWay)                                              // 同巷道移库,获取目标地址
            {
                taskInfo = GetEndPai(endLocat.Substring(1, 2), endLocat.Substring(0, 2), endLocat.Substring(4, 2), endLocat.Substring(6, 2));
            }
            else                                                                    // 跨巷道移库,获取三楼出库口
            {
                taskInfo.Ip = "10.18.51.130";
                switch (roadWay)
                {
                    case "R01":
                        taskInfo.EndStation = "402";
                        break;
                    case "R02":
                        taskInfo.EndStation = "406";
                        break;
                    case "R03":
                        taskInfo.EndStation = "410";
                        break;
                    case "R04":
                        taskInfo.EndStation = "414";
                        break;
                    case "R05":
                        taskInfo.EndStation = "418";
                        break;
                    case "R06":
                        taskInfo.EndStation = "422";
                        break;
                    case "R07":
                        taskInfo.EndStation = "426";
                        break;
                    case "R08":
                        taskInfo.EndStation = "430";
                        break;
                    case "R09":
                        taskInfo.EndStation = "434";
                        break;
                    case "R10":
                        taskInfo.EndStation = "438";
                        break;
                }
            }
        }
        // 出库任务
        if (taskType == "1")
        {
            if (conveyList1.Contains(endLocat))
            {
                taskInfo.Ip = "10.18.51.110";
                taskInfo.EndCeng = "1";
                #region 一层输送线
                switch (roadWay)
                {
                    case "R01":
                        taskInfo.EndStation = "147";
                        break;
                    case "R02":
                        taskInfo.EndStation = "139";
                        break;
                    case "R03":
                        taskInfo.EndStation = "129";
                        break;
                    case "R04":
                        taskInfo.EndStation = "121";
                        break;
                    case "R05":
                        taskInfo.EndStation = "111";
                        break;
                    case "R06":
                        taskInfo.EndStation = "103";
                        break;
                    case "R07":
                        taskInfo.EndStation = "093";
                        break;
                    case "R08":
                        taskInfo.EndStation = "85";
                        break;
                    case "R09":
                        taskInfo.EndStation = "75";
                        break;
                    case "R10":
                        taskInfo.EndStation = "67";
                        break;
                }
                #endregion
            }
            else if (conveyList2.Contains(endLocat))
            {
                #region 二层输送线
                taskInfo.Ip = "10.18.51.120";
                taskInfo.EndCeng = "2";
                switch (roadWay)
                {
                    case "R01":
                        taskInfo.EndStation = "254";
                        break;
                    case "R02":
                        taskInfo.EndStation = "262";
                        break;
                    case "R03":
                        taskInfo.EndStation = "272";
                        break;
                    case "R04":
                        taskInfo.EndStation = "280";
                        break;
                    case "R05":
                        taskInfo.EndStation = "290";
                        break;
                    case "R06":
                        taskInfo.EndStation = "294";
                        break;
                    case "R07":
                        taskInfo.EndStation = "309";
                        break;
                    case "R08":
                        taskInfo.EndStation = "317";
                        break;
                    case "R09":
                        taskInfo.EndStation = "327";
                        break;
                    case "R10":
                        taskInfo.EndStation = "331";
                        break;
                }
                #endregion
            }
            else if (conveyList3.Contains(endLocat))
            {
                #region 三层输送线
                taskInfo.Ip = "10.18.51.130";
                taskInfo.EndCeng = "3";
                switch (roadWay)
                {
                    case "R01":
                        taskInfo.EndStation = "402";
                        break;
                    case "R02":
                        taskInfo.EndStation = "406";
                        break;
                    case "R03":
                        taskInfo.EndStation = "410";
                        break;
                    case "R04":
                        taskInfo.EndStation = "414";
                        break;
                    case "R05":
                        taskInfo.EndStation = "418";
                        break;
                    case "R06":
                        taskInfo.EndStation = "422";
                        break;
                    case "R07":
                        taskInfo.EndStation = "426";
                        break;
                    case "R08":
                        taskInfo.EndStation = "430";
                        break;
                    case "R09":
                        taskInfo.EndStation = "434";
                        break;
                    case "R10":
                        taskInfo.EndStation = "438";
                        break;
                }
                #endregion
            }
            else
            {
                throw new Exception("出库口工位未查询到");
            }
        }
        return taskInfo;
    }
    /// <summary>
    /// 根据工位号获取对应的输送线Ip
    /// </summary>
    /// <param name="startStation"></param>
    /// <returns></returns>
    public static PlcTaskInfo GetPlcIp(string startStation)
    {
        PlcTaskInfo taskInfo = new PlcTaskInfo();
        var conveyList1 = new List<string>() { "147", "145", "139", "137", "129", "127", "121", "119", "111", "109", "103", "101", "093", "091", "085", "083", "075", "073", "067", "065" };
        var conveyList2 = new List<string>() { "252", "254", "260", "262", "272", "272", "278", "280", "288", "290", "294", "301", "307", "309", "315", "317", "325", "327", "331", "337" };
        var conveyList3 = new List<string>() { "401", "402", "405", "406", "409", "410", "413", "414", "417", "418", "421", "422", "425", "426", "429", "430", "433", "434", "437", "438" };
        if (conveyList1.Contains(startStation))
        {
            taskInfo.Ip = "10.18.51.110";
        }
        else if (conveyList2.Contains(startStation))
        {
            taskInfo.Ip = "10.18.51.120";
        }
        else if (conveyList3.Contains(startStation))
        {
            taskInfo.Ip = "10.18.51.130";
        }
        else
        {
            throw new Exception("工位未查询到");
        }
        return taskInfo;
    }
    /// <summary>
    /// 根据wms目标地址转换为Plc目标地址
    /// </summary>
    /// <param name="lie">列</param>
    /// <param name="pai">排</param>
    /// <param name="ceng">层</param>
    /// <param name="dept">深度</param>
    /// <returns></returns>
    public static PlcTaskInfo GetEndPai(string lie, string pai,string ceng, string dept)
    {
        var roadNum = int.Parse(lie);
        var paiNum = int.Parse(pai);
        var deptNum = int.Parse(dept);
        var paiVal = 0;
        // 判断巷道奇偶数
        if (roadNum % 2 == 0)// 偶数
        {
            // 判断排奇偶数
            if (paiNum % 2 == 0)
            {
                if (deptNum == 1)
                {
                    paiVal = 3;
                }
                else
                {
                    paiVal = 4;
                }
            }
            else
            {
                if (deptNum == 1)
                {
                    paiVal = 1;
                }
                else
                {
                    paiVal = 2;
                }
            }
        }
        else   // 奇数
        {
            // 判断排奇偶数
            if (paiNum % 2 == 0)
            {
                if (deptNum == 1)
                {
                    paiVal = 3;
                }
                else
                {
                    paiVal = 4;
                }
            }
            else
            {
                if (deptNum == 1)
                {
                    paiVal = 2;
                }
                else
                {
                    paiVal = 1;
                }
            }
        }
        PlcTaskInfo taskInfo = new PlcTaskInfo();
        taskInfo.EndPai = pai;
        taskInfo.EndCeng = ceng;
        taskInfo.EndLie = paiVal.ToString();
        return taskInfo;
    }
}
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -1,7 +1,11 @@

using DocumentFormat.OpenXml.Bibliography;
using Elastic.Clients.Elasticsearch.Tasks;
using Furion.Logging;
using IoTClient;
using Microsoft.AspNetCore.SignalR;
using RazorEngine.Compilation.ImpromptuInterface.Dynamic;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global.Models;
using System.Data;
namespace WCS.Application;
@@ -48,532 +52,337 @@
    /// 跺机业务处理
    /// </summary>
    /// <param name="modDevice"></param>
    private static void StackingMachine(WcsDeviceDto modDevice)
    private static async void StackingMachine(WcsDeviceDto modDevice)
    {
        var plcConn = modDevice.PLCUtil;
        switch (modDevice.ToString())
        switch (modDevice.Value.ToString())
        {
            case "820":
                // 跺机空闲,获取出库任务、移库任务
                {
                    var modTask = _db.Queryable<WcsTask>().First(s => s.Status == TaskStatusEnum.Wait && s.TaskType == TaskTypeEnum.Out && s.StartRoadway == modDevice.StationNum);
                    // 获取任务信息
                    var modTask = _db.Queryable<WcsTask>().OrderBy(m=>m.CreateTime).OrderBy(m=>m.Levels,OrderByType.Desc)
                        .First(s => s.Status == TaskStatusEnum.Wait && (s.TaskType == TaskTypeEnum.Out || s.TaskType == TaskTypeEnum.Move)
                        && 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, 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();
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                    // 根据目标地址和巷道获取放货工位对应的排列层
                    PlcTaskInfo taskInfo = PLCCommon.GetCTaskInfo(modTask.EndLocate, modTask.TaskType.ToString(),
                        modTask.StartRoadway, modTask.EndRoadway);
                    // 目标工位不为null,需先判断放货工位是否空闲
                    if (!string.IsNullOrEmpty(taskInfo.EndStation))
                    {
                        // 打开对应的输送线连接
                        var plcConveyorConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == taskInfo.Ip);
                        if (plcConveyorConn.Connected)
                        {
                            // 获取放货工位配置信息
                            var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == taskInfo.EndStation
                            && m.DeviceType == DeviceTypeEnum.Business);
                            var (result, value) = plcConveyorConn.GetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.PlcPos);
                            if (result.IsSucceed)
                            {
                                if (value.ToString() != "720")              // 720:放货空位空闲,可放货
                                {
                                    Log.Error(string.Format("任务号:{0}:放货工位占用,稍后执行。", modTask.TaskNo));
                                    break;
                                }
                                //给PLC写入任务数据
                                var listResult = new List<Result>();
                                //任务号
                                var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                                listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTaskMonitor.TaskNo));
                                //托盘号
                                var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "PalletNo");
                                listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTaskMonitor.PalletNo));
                                //起始排
                                var modPosRow = modDevice.listStation.FirstOrDefault(s => s.Text == "StartRow");
                                listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, row));
                                // 起始列
                                var modPosColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "StartColumn");
                                listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, column));
                                // 起始层
                                var modPosStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "StartLayer");
                                listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, layer));
                                // 目标放货工位
                                var modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "EndRow");
                                listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, endRow));
                                var modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "EndColumn");
                                listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, endColumn));
                                var modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "EndLayer");
                                listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, endColumn));
                                //全部写入成功
                                if (listResult.All(s => s.IsSucceed))
                                {
                                    // 写入跺机任务下发完成
                                    plcConn.SetPlcDBValue(modDevice.PosType, 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();
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    //修改led屏信息
                                    //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    // 获取转换后的起始排列层
                    PlcTaskInfo startTaskInfo = PLCCommon.GetEndPai(modTask.StartLocate.Substring(1, 2),
                    modTask.StartLocate.Substring(0, 2), modTask.StartLocate.Substring(4, 2),
                    modTask.StartLocate.Substring(6, 2));
                    // 给PLC写入任务数据
                    var listResult = new List<Result>();
                    // 任务号托盘号
                    var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号");
                    listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo));
                    var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "托盘码");
                    listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo));
                    // 起始排列层
                    var modPosRow = modDevice.listStation.FirstOrDefault(s => s.Text == "取货排");
                    listResult.Add(plcConn.SetPlcDBValue(modPosRow.PosType, modDevice.DbNumber, modPosRow.PlcPos, startTaskInfo.EndPai));
                    var modPosColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "取货列");
                    listResult.Add(plcConn.SetPlcDBValue(modPosColumn.PosType, modDevice.DbNumber, modPosColumn.PlcPos, startTaskInfo.EndLie));
                    var modPosStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "取货层");
                    listResult.Add(plcConn.SetPlcDBValue(modPosStorey.PosType, modDevice.DbNumber, modPosStorey.PlcPos, startTaskInfo.EndCeng));
                    // 目标放货工位(固定排列层)
                    var modPosEndRow = modDevice.listStation.FirstOrDefault(s => s.Text == "放货排");
                    listResult.Add(plcConn.SetPlcDBValue(modPosEndRow.PosType, modDevice.DbNumber, modPosEndRow.PlcPos, taskInfo.EndPai));
                    var modPosEndColumn = modDevice.listStation.FirstOrDefault(s => s.Text == "放货列");
                    listResult.Add(plcConn.SetPlcDBValue(modPosEndColumn.PosType, modDevice.DbNumber, modPosEndColumn.PlcPos, taskInfo.EndLie));
                    var modPosEndStorey = modDevice.listStation.FirstOrDefault(s => s.Text == "放货层");
                    listResult.Add(plcConn.SetPlcDBValue(modPosEndStorey.PosType, modDevice.DbNumber, modPosEndStorey.PlcPos, taskInfo.EndCeng));
                    // 是否写入成功
                    if (listResult.All(s => s.IsSucceed))
                    {
                        Log.Error(string.Join(',', result.ErrList));
                        // 写入跺机任务下发完成
                        plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "830");
                        // 将移库任务待执行改为正在执行
                        _db.Updateable<WcsTask>()
                            .SetColumns(s => s.Status == TaskStatusEnum.Doing)
                            .Where(s => s.Id == modTask.Id)
                            .ExecuteCommand();
                        WcsTaskMonitor modInsertTaskMonitor;
                        if (string.IsNullOrEmpty(taskInfo.EndStation))
                        {
                            // 同巷道移库
                            modInsertTaskMonitor = new WcsTaskMonitor()
                            {
                                TaskNo = modTask.TaskNo,
                                PlcId = modDevice.Id,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{modTask.EndLocate}储位。",
                                PalletNo = modTask.PalletNo,
                                Status = TaskStatusEnum.Complete,
                                StartLocat = modTask.StartLocate,
                                EndLocat = modTask.EndLocate,
                            };
                        }
                        else
                        {
                            // 出库任务 跨巷道移库
                            modInsertTaskMonitor = new WcsTaskMonitor()
                            {
                                TaskNo = modTask.TaskNo,
                                PlcId = modDevice.Id,
                                PlcName = modDevice.Text,
                                InteractiveMsg = $"写入指令:{modTask.StartLocate}储位====》{taskInfo.EndStation}工位。",
                                PalletNo = modTask.PalletNo,
                                Status = TaskStatusEnum.Complete,
                                StartLocat = modTask.StartLocate,
                                EndLocat = modTask.EndLocate,
                            };
                        }
                        // 插入交互日志
                        _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                        //修改led屏信息
                        //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo);
                    }
                }
                break;
            case "20":
            case "840":
                // 取货完成
                {
                    var modPosPlcTask = modDevice.listStation.FirstOrDefault(s => s.Text == "PlcTaskNo");
                    var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                    var (result, TaskNo) = plcConn.GetPlcDBValue(modPosPlcTask.PosType, modDevice.DbNumber, modPosPlcTask.PlcPos);
                    if (!result.IsSucceed)
                        break;
                    string taskNo = Convert.ToString(TaskNo);
                    var modTask = _db.Queryable<WcsTask>().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing);
                    if (modTask == null)
                    // 获取跺机点位配置
                    var modPosTask = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号");
                    var (res, val) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosTask.PlcPos);
                    var modPosEndStation = modDevice.listStation.FirstOrDefault(m => m.Text == "目的工位");
                    var (endStationRes, endStation) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosTask.PlcPos);
                    if (res.IsSucceed)
                    {
                        Log.Error("【跺机】当前托盘号不存在对应的任务");
                        break;
                    }
                    if (modTask.TaskType.Value == TaskTypeEnum.In)
                    {
                        //入库任务
                        var res = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, taskNo);
                        if (!res.IsSucceed)
                            break;
                        // 根据跺机号确认取货工位
                        string outStationNum = "0";
                        switch (modDevice.StationNum)
                        // 获取任务信息
                        string tasknoVal = val.ToString();
                        var modTask = _db.Queryable<WcsTask>().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == true);
                        if (modTask == null)
                        {
                            case "R01":
                                outStationNum = "10";
                            Log.Error(string.Format("PLC控制字840:未找到对应的任务。"));
                            break;
                        }
                        // 记录任务明细
                        var modInsertTaskMonitor = new WcsTaskMonitor()
                        {
                            TaskNo = modTask.TaskNo,
                            PlcId = modDevice.Id,
                            PlcName = modDevice.Text,
                            PalletNo = modTask.PalletNo,
                            Status = TaskStatusEnum.Complete,
                            StartLocat = modTask.StartLocate,
                        };
                        if (modTask.TaskType == TaskTypeEnum.In)
                        {
                            // 获取跺机起始工位点位配置,读取起始工位
                            var modPosStartStation = modDevice.listStation.FirstOrDefault(m => m.Text == "起始工位");
                            var (startStationRes, startStationVal) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPosStartStation.PlcPos);
                            if (startStationRes.IsSucceed)
                            {
                                // 根据工位号获取对应的输送线IP
                                PlcTaskInfo taskInfo = PLCCommon.GetPlcIp(startStationVal);
                                var plcConveyorConn = PLCTaskAction.listPlcConn.First(m => m.PlcIP == taskInfo.Ip);
                                if (plcConveyorConn.Connected)
                                {
                                    // 向取货工位写入流程字640  取货已完成
                                    var ConveyorMod = PLCTaskAction.plcDevices.First(m => m.StationNum == startStationVal
                                                            && m.DeviceType == DeviceTypeEnum.Business && m.IsDelete == true);
                                    var retc = plcConveyorConn.SetPlcDBValue(ConveyorMod.PosType, ConveyorMod.DbNumber, ConveyorMod.WcsPos, "640");
                                    var modcTaskMonitor = new WcsTaskMonitor()
                                    {
                                        TaskNo = modTask.TaskNo,
                                        PlcId = ConveyorMod.Id,
                                        PlcName = ConveyorMod.Text,
                                        PalletNo = modTask.PalletNo,
                                        Status = TaskStatusEnum.Complete,
                                        StartLocat = startStationVal,
                                        EndLocat = modTask.EndLocate                  // 目标储位地址
                                    };
                                    if (!retc.IsSucceed)
                                    {
                                        modcTaskMonitor.InteractiveMsg = string.Format("输送线取货工位:{0},写入取货完成640失败等待在次写入", startStationVal);
                                        // 插入交互日志
                                        _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                                        //下发任务日志
                                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                        break;
                                    }
                                    modcTaskMonitor.InteractiveMsg = string.Format("输送线取货工位:{0},写入取货完成640成功", startStationVal);
                                    // 插入交互日志
                                    _db.Insertable(modcTaskMonitor).ExecuteCommand();
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modcTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                }
                                // 写入流程控制字
                                var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850");
                                if (!ret.IsSucceed)
                                {
                                    break;              // 写入失败跳出等待再次写入
                                }
                                modInsertTaskMonitor.InteractiveMsg = string.Format("输送线取货工位:{0}跺机取货完成850成功", startStationVal);
                                modInsertTaskMonitor.EndLocat = modTask.EndLocate;                  // 目标储位地址
                                                                                             // 插入交互日志
                                _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                                //下发任务日志
                                _taskLogHubContext.Clients.All.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                            }
                        }
                        else if (modTask.TaskType == TaskTypeEnum.Out)
                        {
                            // 写入流程控制字
                            var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850");
                            if (!ret.IsSucceed)
                            {
                                break;              // 写入失败跳出等待再次写入
                            }
                            // 记录任务明细
                            modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成", modTask.StartLocate);
                            modInsertTaskMonitor.EndLocat = endStation;                  // 放货工位
                        }
                        else
                        {
                            // 写入流程控制字
                            var ret = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "850");
                            if (!ret.IsSucceed)
                            {
                                break;              // 写入失败跳出等待再次写入
                            }
                            modInsertTaskMonitor.InteractiveMsg = string.Format("储位地址:{0}取货完成", modTask.StartLocate);
                            modInsertTaskMonitor.EndLocat = endStation;                  // 目标储位
                        }
                        // 插入交互日志
                        _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                        //修改led屏信息
                        //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo);
                    }
                }
                break;
            case "860":
                {
                    // 获取跺机点位配置
                    var modPos860Task = modDevice.listStation.FirstOrDefault(m => m.Text == "任务号");
                    var (res, val) = plcConn.GetPlcDBValue(PLCDataTypeEnum.String, modDevice.DbNumber, modPos860Task.PlcPos);
                    // 根据任务号获取任务信息
                    if (res.IsSucceed)
                    {
                        string tasknoVal = val.ToString();
                        var modTask = _db.Queryable<WcsTask>().First(m => m.Status == TaskStatusEnum.Doing && m.TaskNo == tasknoVal && m.IsDelete == true);
                        if (modTask == null)
                        {
                            Log.Error(string.Format("跺机控制字860:未找到对应的任务。"));
                            break;
                        }
                        switch (modTask.TaskType)
                        {
                            case TaskTypeEnum.In:
                                {
                                    var res870 = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "870");
                                    if (!res870.IsSucceed)
                                    {
                                        Log.Error(string.Format("跺机控制字860写入870失败!"));
                                        break;
                                    }
                                    // 改变任务状态
                                    modTask.Status = TaskStatusEnum.Complete;
                                    modTask.FinishDate = DateTime.Now;
                                    _db.Updateable(modTask).ExecuteCommand();
                                    if (modTask.Origin == "WMS")
                                    {
                                        // 反馈WMS
                                        var requestMode = new TaskRequest()
                                        {
                                            TaskNo = modTask.TaskNo,
                                            PalletNo = modTask.PalletNo,
                                            TaskType = "1",
                                            TaskStatus = TaskStatusEnum.Complete
                                        };
                                        // 此处添加调用WMS接口 liudl
                                    }
                                    // 此处添加不空跑业务
                                }
                                break;
                            case "R02":
                                outStationNum = "6";
                            case TaskTypeEnum.Out: // 出库任务
                                {
                                }
                                break;
                            case TaskTypeEnum.Move:       // 移库任务
                                {
                                }
                                break;
                            default: break;
                        }
                        var modDevice2 = modDevice.listDevice.Where(s => s.StationNum == outStationNum).FirstOrDefault();
                        var modStation = _db.Queryable<WcsPosition>().First(s => s.DeviceId == modDevice2.Id && s.Text == "TaskNo");
                        // 向取货工位写入任务号
                        res = plcConn.SetPlcDBValue(modStation.PosType, modDevice2.DbNumber, modStation.PlcPos, taskNo);
                        if (!res.IsSucceed)
                            break;
                        // 向取货工位写入流程控制字
                        res = plcConn.SetPlcDBValue(modDevice2.PosType, modDevice2.DbNumber, modDevice2.WcsPos, "100");
                        if (!res.IsSucceed)
                            break;
                        var modTaskMonitor = new WcsTaskMonitor()
                        {
                            TaskNo = modTask.TaskNo,
                            PlcId = modDevice2.PlcId,
                            PlcName = modDevice2.Text,
                            InteractiveMsg = "跺机取货完成",
                            StartLocat = outStationNum,
                            EndLocat = modTask.EndLocate,
                            PalletNo = modTask.PalletNo,
                            Status = TaskStatusEnum.Complete
                        };
                        _db.Insertable(modTaskMonitor).ExecuteCommand();
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                    }
                    else if (modTask.TaskType.Value == TaskTypeEnum.Out)
                    {
                        //入库任务
                        var res = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, taskNo);
                        if (!res.IsSucceed)
                            break;
                        res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "20");
                        if (!res.IsSucceed)
                            break;
                        // 根据跺机号确认取货工位
                        string outStationNum = "0";
                        switch (modDevice.StationNum)
                        {
                            case "R01":
                                outStationNum = "11";
                                break;
                            case "R02":
                                outStationNum = "7";
                                break;
                            default: break;
                        }
                        var modStation = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                        var modTaskMonitor = new WcsTaskMonitor()
                        {
                            TaskNo = modTask.TaskNo,
                            PlcId = modDevice.PlcId,
                            PlcName = modDevice.Text,
                            InteractiveMsg = "跺机取货完成",
                            StartLocat = outStationNum,
                            EndLocat = modTask.EndLocate,
                            PalletNo = modTask.PalletNo,
                            Status = TaskStatusEnum.Complete
                        };
                        _db.Insertable(modTaskMonitor).ExecuteCommand();
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                    }
                }
                break;
            case "30":
            case "841":
                {
                    //操作完成(放货完成)
                    var modPosPlcTask = modDevice.listStation.FirstOrDefault(s => s.Text == "PlcTaskNo");
                    var (result, TaskNo) = plcConn.GetPlcDBValue(modPosPlcTask.PosType, modDevice.DbNumber, modPosPlcTask.PlcPos);
                    if (!result.IsSucceed)
                        break;
                    string taskNo = Convert.ToString(TaskNo);
                    var modTask = _db.Queryable<WcsTask>().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing);
                    if (modTask == null)
                    {
                        Log.Error("【跺机】当前托盘号不存在对应的任务");
                        break;
                    }
                    switch (modTask.TaskType)
                    {
                        case TaskTypeEnum.In:
                        case TaskTypeEnum.PLC:
                            {
                                //入库任务
                                var modStation = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                                // 写入plc任务号
                                var res = plcConn.SetPlcDBValue(modStation.PosType, modDevice.DbNumber, modStation.PlcPos, taskNo);
                                if (!res.IsSucceed)
                                    break;
                                res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "30");
                                if (!res.IsSucceed)
                                    break;
                                //修改任务状态
                                modTask.Status = TaskStatusEnum.Complete;
                                _db.Updateable<WcsTask>()
                                        .SetColumns(s => s.Status == TaskStatusEnum.Complete)
                                        .Where(s => s.Id == modTask.Id)
                                        .ExecuteCommand();
                                //反馈给WMS
                                var modTaskRequest = modTask.Adapt<TaskRequest>();
                                HttpService httpService = new HttpService();
                                var modResponseTask = httpService.RequestTask(modTaskRequest).Result;
                                if (modResponseTask.StatusCode == "0")
                                {
                                    //请求成功
                                    modTask.IsSuccess = TaskSuccessEnum.Success;
                                    _db.Updateable(modTask).UpdateColumns(s => s.IsSuccess).ExecuteCommand();
                                    //todo:修改储位信息 任务类型 执行状态 起始位置 目标位置
                                    //
                                    //记录任务明细
                                    var modTaskMonitor = new WcsTaskMonitor()
                                    {
                                        TaskNo = modTask.TaskNo,
                                        PlcId = modDevice.PlcId,
                                        PlcName = modDevice.Text,
                                        InteractiveMsg = "任务完成,返回给WMS任务完成",
                                        StartLocat = modTask.StartLocate,
                                        EndLocat = modTask.EndLocate,
                                        PalletNo = modTask.PalletNo,
                                        Status = TaskStatusEnum.Complete
                                    };
                                    _db.Insertable(modTaskMonitor).ExecuteCommand();
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                }
                                else
                                {
                                    //请求失败
                                    modTask.IsSuccess = TaskSuccessEnum.Fail;
                                    modTask.Information = modResponseTask.Message;
                                    _db.Updateable(modTask).UpdateColumns(s => new { s.IsSuccess, s.Information }).ExecuteCommand();
                                }
                                //todo:垛机入库不空跑
                                //todo:LED
                            }
                            break;
                        case TaskTypeEnum.Out://出库
                            {
                                // 从出库任务获取巷道号
                                string num = ""; // 放货工位号
                                if (modTask.StartRoadway == "R01")
                                {
                                    num = "11"; //交互工位
                                }
                                else if (modTask.StartRoadway == "R02")
                                {
                                    num = "7"; //交互工位
                                }
                                var modDevice2 = modDevice.listDevice.FirstOrDefault(s => s.StationNum == num);
                                if (modDevice2 == null)
                                {
                                    Log.Error($"【跺机】找不到工位{num}设备信息");
                                    break;
                                }
                                // 根据目标口获取目标工位
                                string outCode = modTask.EndLocate.IsNullOrEmpty() ? "-1" : modTask.EndLocate;
                                var listStation = _db.Queryable<WcsPosition>().Where(s => s.DeviceId == modDevice2.Id).ToList();
                                //给PLC写入任务数据
                                var listResult = new List<Result>();
                                //任务号
                                var modPosTask = listStation.FirstOrDefault(s => s.Text == "TaskNo");
                                listResult.Add(plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, modTask.TaskNo));
                                //托盘号
                                var modPosPalletNo = listStation.FirstOrDefault(s => s.Text == "PalletNo");
                                listResult.Add(plcConn.SetPlcDBValue(modPosPalletNo.PosType, modDevice.DbNumber, modPosPalletNo.PlcPos, modTask.PalletNo));
                                //起始工位
                                var modPosLocatNo = listStation.FirstOrDefault(s => s.Text == "StartLocatNo");
                                listResult.Add(plcConn.SetPlcDBValue(modPosLocatNo.PosType, modDevice.DbNumber, modPosLocatNo.PlcPos, num));
                                // 目标工位
                                var modPosEndLocatNo = listStation.FirstOrDefault(s => s.Text == "EndLocatNo");
                                listResult.Add(plcConn.SetPlcDBValue(modPosEndLocatNo.PosType, modDevice.DbNumber, modPosEndLocatNo.PlcPos, outCode));
                                //全部写入成功
                                if (listResult.All(s => s.IsSucceed))
                                {
                                    // 写入工位wcs控制字
                                    var res = plcConn.SetPlcDBValue(modDevice2.PosType, modDevice2.DbNumber, modDevice2.WcsPos, "120");
                                    if (!res.IsSucceed)
                                        break;
                                    //写入plc任务号
                                    var modStation = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                                    res = plcConn.SetPlcDBValue(modStation.PosType, modDevice.DbNumber, modStation.PlcPos, modTask.TaskNo);
                                    if (!res.IsSucceed)
                                        break;
                                    //写入跺机wcs控制字流程30 返回垛机执行完成
                                    res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "30");
                                    if (!res.IsSucceed)
                                        break;
                                    //记录任务明细
                                    var modTaskMonitor = new WcsTaskMonitor()
                                    {
                                        TaskNo = modTask.TaskNo,
                                        PlcId = modDevice2.PlcId,
                                        PlcName = modDevice2.Text,
                                        InteractiveMsg = $"写入指令:收到跺机放货完成;放货{num}工位===》{outCode}出库口",
                                        PalletNo = modTask.PalletNo,
                                        Status = TaskStatusEnum.Complete,
                                        StartLocat = num, //起始位置
                                        EndLocat = outCode, //目标工位
                                    };
                                    _db.Insertable(modTaskMonitor).ExecuteCommand();
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    //todo:垛机出库不空跑
                                }
                            }
                            break;
                        case TaskTypeEnum.Move:
                            {
                                //移库任务
                                var modStation = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                                // 写入plc任务号
                                var res = plcConn.SetPlcDBValue(modStation.PosType, modDevice.DbNumber, modStation.PlcPos, taskNo);
                                if (!res.IsSucceed)
                                    break;
                                //写入plc控制字
                                res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "30");
                                if (!res.IsSucceed)
                                    break;
                                modTask.Status = TaskStatusEnum.Complete;
                                _db.Updateable(modTask).UpdateColumns(s => s.Status).ExecuteCommand();
                                var modTaskRequest = modTask.Adapt<TaskRequest>();
                                HttpService httpService = new HttpService();
                                var modResponseTask = httpService.RequestTask(modTaskRequest).Result;
                                if (modResponseTask.StatusCode == "0")
                                {
                                    //请求成功
                                    modTask.IsSuccess = TaskSuccessEnum.Success;
                                    _db.Updateable(modTask).UpdateColumns(s => s.IsSuccess).ExecuteCommand();
                                    //todo:修改储位信息 任务类型 执行状态 起始位置 目标位置
                                    //
                                    //记录任务明细
                                    var modTaskMonitor = new WcsTaskMonitor()
                                    {
                                        TaskNo = modTask.TaskNo,
                                        PlcId = modDevice.PlcId,
                                        PlcName = modDevice.Text,
                                        InteractiveMsg = "任务完成,返回给WMS任务完成",
                                        StartLocat = modTask.StartLocate,
                                        EndLocat = modTask.EndLocate,
                                        PalletNo = modTask.PalletNo,
                                        Status = TaskStatusEnum.Complete
                                    };
                                    _db.Insertable(modTaskMonitor).ExecuteCommand();
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                }
                                else
                                {
                                    //请求失败
                                    modTask.IsSuccess = TaskSuccessEnum.Fail;
                                    modTask.Information = modResponseTask.Message;
                                    _db.Updateable(modTask).UpdateColumns(s => new { s.IsSuccess, s.Information }).ExecuteCommand();
                                }
                                //todo:LED屏
                            }
                            break;
                        default:
                            break;
                    }
                }
                break;
            case "100":
            case "843":
                {
                    //空取货异常
                    var modPosPlcTask = modDevice.listStation.FirstOrDefault(s => s.Text == "PlcTaskNo");
                    var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                    var (result, TaskNo) = plcConn.GetPlcDBValue(modPosPlcTask.PosType, modDevice.DbNumber, modPosPlcTask.PlcPos);
                    if (!result.IsSucceed)
                        break;
                    string taskNo = Convert.ToString(TaskNo);
                    var modTask = _db.Queryable<WcsTask>().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing);
                    if (modTask == null)
                    {
                        Log.Error($"【跺机】当前任务号不存在对应的任务,任务号:{modTask.TaskNo}");
                        break;
                    }
                    var res = plcConn.SetPlcDBValue(modPosTask.PosType, modDevice.DbNumber, modPosTask.PlcPos, taskNo);
                    if (!res.IsSucceed)
                        break;
                    res = plcConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "100");
                    if (!res.IsSucceed)
                        break;
                    modTask.Status = TaskStatusEnum.Exception;
                    _db.Updateable(modTask).UpdateColumns(s => s.Status).ExecuteCommand();
                    Log.Information($"【跺机】wcs任务变更空取异常,任务号:{modTask.TaskNo}");
                    var modTaskRequest = modTask.Adapt<TaskRequest>();
                    HttpService httpService = new HttpService();
                    var modResponseTask = httpService.RequestEmptyException(modTaskRequest).Result;
                    if (modResponseTask.StatusCode == "0")
                    {
                        //请求成功
                        modTask.IsSuccess = TaskSuccessEnum.Success;
                        _db.Updateable(modTask).UpdateColumns(s => s.IsSuccess).ExecuteCommand();
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTask(modTask.Adapt<WcsTaskOutput>());
                    }
                    else
                    {
                        //请求失败
                        modTask.IsSuccess = TaskSuccessEnum.Fail;
                        modTask.Information = modResponseTask.Message;
                        _db.Updateable(modTask).UpdateColumns(s => new { s.IsSuccess, s.Information }).ExecuteCommand();
                    }
                    //todo:LED屏
                }
                break;
            case "101":
            case "861":
                {
                    //满放货异常
                    var modPosPlcTask = modDevice.listStation.FirstOrDefault(s => s.Text == "PlcTaskNo");
                    var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "TaskNo");
                    var modPosPalletNo = modDevice.listStation.FirstOrDefault(s => s.Text == "PalletNo");
                    var (result, TaskNo) = plcConn.GetPlcDBValue(modPosPlcTask.PosType, modDevice.DbNumber, modPosPlcTask.PlcPos);
                    if (!result.IsSucceed)
                        break;
                    string taskNo = Convert.ToString(TaskNo);
                    var modTask = _db.Queryable<WcsTask>().First(s => s.TaskNo == taskNo && s.Status == TaskStatusEnum.Doing);
                    if (modTask == null)
                    {
                        Log.Error($"【跺机】当前任务号不存在对应的任务,任务号:{modTask.TaskNo}");
                        break;
                    }
                    modTask.Status = TaskStatusEnum.Exception;
                    _db.Updateable(modTask).UpdateColumns(s => s.Status).ExecuteCommand();
                    Log.Information($"【跺机】wcs任务变更满取异常,任务号:{modTask.TaskNo}");
                    var modTaskRequest = modTask.Adapt<TaskRequest>();
                    HttpService httpService = new HttpService();
                    var modResponseTask = httpService.RequestEmptyException(modTaskRequest).Result;
                    if (modResponseTask.StatusCode == "0")
                    {
                        //请求成功
                        modTask.IsSuccess = TaskSuccessEnum.Success;
                        _db.Updateable(modTask).UpdateColumns(s => s.IsSuccess).ExecuteCommand();
                        var modInsertTask = modResponseTask.TaskList;
                        modInsertTask.TaskType = TaskTypeEnum.In;
                        modInsertTask.Origin = "WMS";
                        modInsertTask.StartLocate = modTask.StartLocate;
                        modInsertTask.Levels = 1;
                        _db.Insertable(modInsertTask);
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTask(modInsertTask.Adapt<WcsTaskOutput>());
                    }
                    else
                    {
                        //请求失败
                        modTask.IsSuccess = TaskSuccessEnum.Fail;
                        modTask.Information = modResponseTask.Message;
                        _db.Updateable(modTask).UpdateColumns(s => new { s.IsSuccess, s.Information }).ExecuteCommand();
                    }
                    //todo:LED屏
                }
                break;
@@ -656,4 +465,6 @@
        }
    }
}
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs
@@ -33,6 +33,12 @@
    {
        get { return listPlcUtil; }
    }
    // 交互点集合
    public static List<WcsDevice> plcDevices
    {
        get { return listPlcDevice; }
    }
    public static event EventHandler DeviceValueChangeEvent;
    static PLCTaskAction()
    {
@@ -145,7 +151,7 @@
                                dto.listStation = listPlcStation.Where(s => s.DeviceId == modDevice.Id).ToList();
                                dto.listDevice = listDevice.Where(s => s.StationNum == modDevice.StationNum && s.Level == DeviceLevelEnum.Station).ToList();
                                //这里触发值变更事件
                                //DeviceValueChangeEvent?.Invoke(dto, EventArgs.Empty);
                                DeviceValueChangeEvent?.Invoke(dto, EventArgs.Empty);
                            }
                            else if (!modPlcUtil.Connected)
                            {