林豪 左 2 years ago
parent
commit
14ac90883a

+ 122 - 0
WCS.Entity.Protocol/SRM/ISRM520.cs

@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+namespace WCS.Entity.Protocol.SRM
+{
+    /// <summary>
+    ///  堆垛机DB520
+    /// </summary>
+    public interface ISRM520 : IProtocol
+    {
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        short Res1 { get; set; }
+
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        short Res2 { get; set; }
+
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        short Res3 { get; set; }
+
+        /// <summary>
+        ///  货物类型
+        /// </summary>
+        [Description("货物类型")]
+        short GoodsType { get; set; }
+
+        /// <summary>
+        ///  运行速度
+        /// </summary>
+        [Description("运行速度")]
+        SrmRunSpeedEnum RunSpeed { get; set; }
+
+        /// <summary>
+        ///  任务起始行
+        /// </summary>
+        [Description("任务起始行")]
+        short RowPos1 { get; set; }
+
+        /// <summary>
+        ///  任务起始列
+        /// </summary>
+        [Description("任务起始列")]
+        short TravelPos1 { get; set; }
+
+        /// <summary>
+        ///  任务起始层
+        /// </summary>
+        [Description("任务起始层")]
+        short LiftPos1 { get; set; }
+
+        /// <summary>
+        ///  任务起始深度
+        /// </summary>
+        [Description("任务起始深度")]
+        ForkPosition ForkStartPos1 { get; set; }
+
+        /// <summary>
+        ///  任务目标行
+        /// </summary>
+        [Description("任务目标行")]
+        short RowPos2 { get; set; }
+
+        /// <summary>
+        ///  任务目标列
+        /// </summary>
+        [Description("任务目标列")]
+        short TravelPos2 { get; set; }
+
+        /// <summary>
+        ///  任务目标层
+        /// </summary>
+        [Description("任务目标层")]
+        short LiftPos2 { get; set; }
+
+        /// <summary>
+        ///  任务目标深度
+        /// </summary>
+        [Description("任务目标深度")]
+        ForkPosition ForkStartPos2 { get; set; }
+
+        /// <summary>
+        ///  任务号
+        /// </summary>
+        [Description("任务号")]
+        int TaskNumber { get; set; }
+
+        /// <summary>
+        ///  凭证号
+        /// </summary>
+        [Description("凭证号")]
+        short VoucherNo { get; set; }
+
+        /// <summary>
+        ///  完成任务确认清除信号
+        /// </summary>
+        [Description("完成任务确认清除信号")]
+        short OkAck { get; set; }
+
+        /// <summary>
+        ///  任务类型
+        /// </summary>
+        [Description("任务类型")]
+        SrmTaskTypeEnum TaskType { get; set; }
+
+        /// <summary>
+        ///  指令类型
+        /// </summary>
+        [Description("指令类型")]
+        short Cmd { get; set; }
+
+    }
+}

+ 188 - 0
WCS.Entity.Protocol/SRM/ISRM521.cs

@@ -0,0 +1,188 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+namespace WCS.Entity.Protocol.SRM
+{
+    /// <summary>
+    ///  堆垛机DB521
+    /// </summary>
+    public interface ISRM521 : IProtocol
+    {
+        /// <summary>
+        ///  状态
+        /// </summary>
+        [Description("状态")]
+        SrmStatus Status { get; set; }
+
+        /// <summary>
+        ///  自动状态
+        /// </summary>
+        [Description("自动状态")]
+        SrmAutoStatus AutoStatus { get; set; }
+
+        /// <summary>
+        ///  运行状态
+        /// </summary>
+        [Description("运行状态")]
+        SrmRunStatus RunStatus { get; set; }
+
+        /// <summary>
+        ///  任务起始行
+        /// </summary>
+        [Description("任务起始行")]
+        short RowPos1 { get; set; }
+
+        /// <summary>
+        ///  任务起始列
+        /// </summary>
+        [Description("任务起始列")]
+        short TravelPos1 { get; set; }
+
+        /// <summary>
+        ///  任务起始层
+        /// </summary>
+        [Description("任务起始层")]
+        short LiftPos1 { get; set; }
+
+        /// <summary>
+        ///  任务起始深度
+        /// </summary>
+        [Description("任务起始深度")]
+        ForkPosition ForkDestPos1 { get; set; }
+
+        /// <summary>
+        ///  任务目标行
+        /// </summary>
+        [Description("任务目标行")]
+        short RowPos2 { get; set; }
+
+        /// <summary>
+        ///  任务目标列
+        /// </summary>
+        [Description("任务目标列")]
+        short TravelPos2 { get; set; }
+
+        /// <summary>
+        ///  任务目标层
+        /// </summary>
+        [Description("任务目标层")]
+        short LiftPos2 { get; set; }
+
+        /// <summary>
+        ///  任务目标深度
+        /// </summary>
+        [Description("任务目标深度")]
+        ForkPosition ForkDestPos2 { get; set; }
+
+        /// <summary>
+        ///  任务号
+        /// </summary>
+        [Description("任务号")]
+        int TaskNumber { get; set; }
+
+        /// <summary>
+        ///  凭证号
+        /// </summary>
+        [Description("凭证号")]
+        short VoucherNo { get; set; }
+
+        /// <summary>
+        ///  当前行
+        /// </summary>
+        [Description("当前行")]
+        short SrmRow { get; set; }
+
+        /// <summary>
+        ///  当前列
+        /// </summary>
+        [Description("当前列")]
+        short SrmTravel { get; set; }
+
+        /// <summary>
+        ///  当前层
+        /// </summary>
+        [Description("当前层")]
+        short SrmLayer { get; set; }
+
+        /// <summary>
+        ///  完成任务号
+        /// </summary>
+        [Description("完成任务号")]
+        int TaskFinishiId { get; set; }
+
+        /// <summary>
+        ///  行走当前位置 MM
+        /// </summary>
+        [Description("行走当前位置 MM")]
+        int TravelPos { get; set; }
+
+        /// <summary>
+        ///  提升当前位置 MM
+        /// </summary>
+        [Description("提升当前位置 MM")]
+        int LiftPos { get; set; }
+
+        /// <summary>
+        ///  货叉当前位置 MM
+        /// </summary>
+        [Description("货叉当前位置 MM")]
+        int ForkPos1 { get; set; }
+
+        /// <summary>
+        ///  运行速度
+        /// </summary>
+        [Description("运行速度")]
+        SrmRunSpeedEnum RunSpeed { get; set; }
+
+        /// <summary>
+        ///  任务类型
+        /// </summary>
+        [Description("任务类型")]
+        SrmTaskTypeEnum TaskType { get; set; }
+
+        /// <summary>
+        ///  运行总里程
+        /// </summary>
+        [Description("运行总里程")]
+        float TotalKm { get; set; }
+
+        /// <summary>
+        ///  货物类型
+        /// </summary>
+        [Description("货物类型")]
+        short GoodsType { get; set; }
+
+        /// <summary>
+        ///  运行总时长
+        /// </summary>
+        [Description("运行总时长")]
+        float RunTime { get; set; }
+
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        int Res3 { get; set; }
+
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        int Res4 { get; set; }
+
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        int Res5 { get; set; }
+
+        /// <summary>
+        ///  备用
+        /// </summary>
+        [Description("备用")]
+        int Res6 { get; set; }
+
+    }
+}

+ 16 - 0
WCS.Entity.Protocol/SRM/ISRM523.cs

@@ -0,0 +1,16 @@
+using System.ComponentModel;
+
+namespace WCS.Entity.Protocol.SRM
+{
+    /// <summary>
+    ///  堆垛机DB523
+    /// </summary>
+    public interface ISRM523 : IProtocol
+    {
+        /// <summary>
+        ///  报警内容
+        /// </summary>
+        [Description("报警内容")]
+        long Alarm { get; set; }
+    }
+}

+ 237 - 0
WCS.Entity.Protocol/SRM/SrmEnum.cs

@@ -0,0 +1,237 @@
+using System;
+
+namespace WCS.Entity.Protocol.SRM
+{
+    /// <summary>
+    /// 运行模式
+    /// </summary>
+    public enum SrmRunSpeedEnum : short
+    {
+        /// <summary>
+        ///  默认
+        /// </summary>
+        Default = 0,
+
+        /// <summary>
+        ///  低速
+        /// </summary>
+        LowSpeed = 1,
+    }
+
+    /// <summary>
+    /// 任务类型
+    /// </summary>
+    public enum SrmTaskTypeEnum : short
+    {
+        /// <summary>
+        ///  默认 出入库移库使用该任务类型
+        /// </summary>
+        Default = 0,
+
+        /// <summary>
+        ///  完成任务
+        /// </summary>
+        FinishTask = 1,
+
+        /// <summary>
+        ///  删除任务
+        /// </summary>
+        DeleteTask = 2,
+
+        /// <summary>
+        ///  移动任务
+        /// </summary>
+        MoveTask = 3,
+    }
+
+    /// <summary>
+    /// 货叉位置
+    /// </summary>
+    public enum ForkPosition : short
+    {
+        /// <summary>
+        ///  中位
+        /// </summary>
+        Centr = 0,
+
+        /// <summary>
+        ///  一深度
+        /// </summary>
+        OneDepth = 1,
+
+        /// <summary>
+        /// 二深度
+        /// </summary>
+        TwoDepth = 2
+    }
+
+    /// <summary>
+    /// 运行模式
+    /// </summary>
+    public enum SrmAutoStatus : short
+    {
+        /// <summary>
+        ///  自动
+        /// </summary>
+        Automatic = 0,
+
+        /// <summary>
+        ///  半自动
+        /// </summary>
+        SemiAutomatic = 1,
+
+        /// <summary>
+        ///  手动
+        /// </summary>
+        Manual = 2,
+
+        /// <summary>
+        ///  保持维修
+        /// </summary>
+        KeepInRepair
+    }
+
+    /// <summary>
+    /// 运行状态
+    /// </summary>
+    public enum SrmRunStatus : short
+    {
+        /// <summary>
+        ///  空闲
+        /// </summary>
+        Idle = 1,
+
+        /// <summary>
+        ///  取货行走
+        /// </summary>
+        GetGoodsWalk = 2,
+
+        /// <summary>
+        ///  取货伸叉
+        /// </summary>
+        GetGoodsOutstretchFork = 3,
+
+        /// <summary>
+        ///  取货抬叉
+        /// </summary>
+        GetGoodsLiftFork = 4,
+
+        /// <summary>
+        ///  取货收叉
+        /// </summary>
+        GetGoodsRetractFork = 5,
+
+        /// <summary>
+        ///  放货行走
+        /// </summary>
+        PutGoodsWalk = 6,
+
+        /// <summary>
+        ///  放货伸叉
+        /// </summary>
+        PutGoodsOutstretchFork = 7,
+
+        /// <summary>
+        ///  放货降叉
+        /// </summary>
+        PutGoodsDropFork = 6,
+
+        /// <summary>
+        ///  放货收叉
+        /// </summary>
+        PutGoodsRetractFork = 7,
+    }
+
+    /// <summary>
+    /// 堆垛机状态
+    /// </summary>
+    public enum SrmStatus : ushort
+    {
+        /// <summary>
+        ///  PLC的握手信号
+        /// </summary>
+        HandshakeTowcs = 1 << 0,
+
+        /// <summary>
+        ///  完成取货信号
+        /// </summary>
+        GetFinishi = 1 << 1,
+
+        /// <summary>
+        ///  完成放货信号
+        /// </summary>
+        PutFinishi = 1 << 2,
+
+        /// <summary>
+        ///  报警信号
+        /// </summary>
+        Alarm = 1 << 3,
+
+        /// <summary>
+        ///  任务完成信号
+        /// </summary>
+        TaskFinish = 1 << 4,
+
+        /// <summary>
+        ///  设备有货
+        /// </summary>
+        Loaded = 1 << 5,
+
+        /// <summary>
+        ///  货叉在原位
+        /// </summary>
+        ForkCenter = 1 << 6,
+
+        /// <summary>
+        ///  可以下发任务
+        /// </summary>
+        CanTaskIssued = 1 << 7,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES1 = 1 << 8,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES2 = 1 << 9,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES3 = 1 << 10,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES4 = 1 << 11,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES5 = 1 << 12,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES6 = 1 << 13,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES7 = 1 << 14,
+
+        /// <summary>
+        ///  保留
+        /// </summary>
+        RES8 = 1 << 15,
+    }
+
+    /// <summary>
+    /// 堆垛机报警项
+    /// </summary>
+    [Flags]
+    public enum SrmAlarm : ulong { 
+    }
+}

+ 2 - 0
WCS.Entity.Protocol/Station/IStation91.cs

@@ -27,5 +27,7 @@
         /// </summary>
         [IgnoreChanging]
         float Width { get; set; }
+
+
     }
 }

+ 381 - 0
WCS.Entity.Protocol/Station/StationEnum.cs

@@ -0,0 +1,381 @@
+using System;
+
+namespace WCS.Entity.Protocol.Station
+{
+    /// <summary>
+    /// 指令类型
+    /// </summary>
+    [Flags]
+    public enum CmdTypeEnum : ushort
+    {
+        /// <summary>
+        /// AGV放货请求
+        /// </summary>
+        AGV_PUT_ASK = 1 << 0,
+
+        /// <summary>
+        /// AGV放货运行
+        /// </summary>
+        AGV_PUT_RUN = 1 << 1,
+
+        /// <summary>
+        /// AGV放货完成
+        /// </summary>
+        AGV_PUT_OK = 1 << 2,
+
+        /// <summary>
+        /// AGV取货请求
+        /// </summary>
+        AGV_GET_ASK = 1 << 3,
+
+        /// <summary>
+        /// AGV取货运行
+        /// </summary>
+        AGV_GET_RUN = 1 << 4,
+
+        /// <summary>
+        /// AGV取货完成
+        /// </summary>
+        AGV_GET_OK = 1 << 5,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES1 = 1 << 6,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES2 = 1 << 7,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES3 = 1 << 8,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES4 = 1 << 9,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES5 = 1 << 10,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES6 = 1 << 11,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES7 = 1 << 12,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES8 = 1 << 13,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES9 = 1 << 14,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES10 = 1 << 15,
+    }
+
+    /// <summary>
+    /// 指令回复
+    /// </summary>
+    [Flags]
+    public enum CmdReplyEnum : ushort
+    {
+        /// <summary>
+        /// CONV允许接货
+        /// </summary>
+        CONV_PUT_ALLOW = 1 << 0,
+
+        /// <summary>
+        /// CONV接货完成
+        /// </summary>
+        CONV_PUT_ACK = 1 << 1,
+
+        /// <summary>
+        /// CONV运行取货
+        /// </summary>
+        CONV_GET_ALLOW = 1 << 2,
+
+        /// <summary>
+        /// CONV取货完成确认
+        /// </summary>
+        CONV_GET_ACK = 1 << 3,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES11 = 1 << 4,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES12 = 1 << 5,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES1 = 1 << 6,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES2 = 1 << 7,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES3 = 1 << 8,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES4 = 1 << 9,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES5 = 1 << 10,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES6 = 1 << 11,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES7 = 1 << 12,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES8 = 1 << 13,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES9 = 1 << 14,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES10 = 1 << 15,
+    }
+
+    /// <summary>
+    /// 输送机模式
+    /// </summary>
+    public enum ModeEunm : short
+    {
+        /// <summary>
+        /// 自动
+        /// </summary>
+        Automatic = 1,
+
+        /// <summary>
+        /// 手动
+        /// </summary>
+        Manual = 2,
+
+        /// <summary>
+        /// 维修
+        /// </summary>
+        Repair = 3,
+    }
+
+    /// <summary>
+    /// 输送机警报
+    /// </summary>
+    [Flags]
+    public enum AlarmEunm
+    {
+    }
+
+    /// <summary>
+    /// 输送机状态
+    /// </summary>
+    [Flags]
+    public enum StatusEunm : ulong
+    {
+        /// <summary>
+        /// 自动
+        /// </summary>
+        Auto = 1 << 0,
+
+        /// <summary>
+        /// 选中状态位
+        /// </summary>
+        Choice_Bit = 1 << 1,
+
+        /// <summary>
+        /// 任务有货
+        /// </summary>
+        OT_Status = 1 << 2,
+
+        /// <summary>
+        /// 光电有货
+        /// </summary>
+        PH_Status = 1 << 3,
+
+        /// <summary>
+        /// 运行状态位
+        /// </summary>
+        Run = 1 << 4,
+
+        /// <summary>
+        /// 正转
+        /// </summary>
+        Fwd_1 = 1 << 5,
+
+        /// <summary>
+        /// 反转
+        /// </summary>
+        Rev_1 = 1 << 6,
+
+        /// <summary>
+        /// 上升/右转/伸出(顶升移栽升降、拆码盘机升降、提升机升降、拆码盘机拨叉伸出)
+        /// </summary>
+        Up_Right_Front_2 = 1 << 7,
+
+        /// <summary>
+        /// 下降/左转/缩回(顶升移栽升降、拆码盘机升降、提升机升降、拆码盘机拨叉缩回)
+        /// </summary>
+        Down_Left_Back_2 = 1 << 8,
+
+        /// <summary>
+        /// 高位(顶升移栽升降、拆码盘机升降、提升机升降)
+        /// </summary>
+        High_Station_2 = 1 << 9,
+
+        /// <summary>
+        /// 中位(拆码盘机升降)
+        /// </summary>
+        Mid_Station_2 = 1 << 10,
+
+        /// <summary>
+        /// 低位(顶升移栽升降、拆码盘机升降、提升机升降)
+        /// </summary>
+        Low_Station_2 = 1 << 11,
+
+        /// <summary>
+        /// 前位(拆码盘机拨叉伸出)
+        /// </summary>
+        Front_Station_2 = 1 << 12,
+
+        /// <summary>
+        /// 后位(拆码盘机拨叉缩回)
+        /// </summary>
+        Back_Station_2 = 1 << 13,
+
+        /// <summary>
+        /// 手动入库
+        /// </summary>
+        ManualStorage = 1 << 14,
+
+        /// <summary>
+        /// 上位机未分配任务
+        /// </summary>
+        UnassignedTask = 1 << 15,
+    }
+
+    /// <summary>
+    /// 外形故障
+    /// </summary>
+    [Flags]
+    public enum ShapeAlarmEunm : ushort
+    {
+        /// <summary>
+        /// 外形/条码等货物故障
+        /// </summary>
+        Goods_Err = 1 >> 0,
+
+        /// <summary>
+        /// 前超长故障
+        /// </summary>
+        F_Outside = 1 >> 1,
+
+        /// <summary>
+        /// 后超长故障
+        /// </summary>
+        B_Outside = 1 >> 2,
+
+        /// <summary>
+        /// 左超宽故障
+        /// </summary>
+        L_Outside = 1 >> 3,
+
+        /// <summary>
+        /// 右超宽故障
+        /// </summary>
+        R_Outside = 1 >> 4,
+
+        /// <summary>
+        /// 超高故障
+        /// </summary>
+        H_Outside = 1 >> 5,
+
+        /// <summary>
+        /// 条码读取失败
+        /// </summary>
+        BCR_Noread = 1 >> 6,
+
+        /// <summary>
+        /// 超重
+        /// </summary>
+        Overload = 1 >> 7,
+
+        /// <summary>
+        /// 货物严重外检故障
+        /// </summary>
+        Goods_Err_1 = 1 >> 8,
+
+        /// <summary>
+        /// 二维条码未读出
+        /// </summary>
+        BCR_Noread_1 = 1 >> 9,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES1 = 1 >> 10,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES2 = 1 >> 11,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES3 = 1 >> 12,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES4 = 1 >> 13,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES5 = 1 >> 14,
+
+        /// <summary>
+        /// 备用
+        /// </summary>
+        RES6 = 1 >> 15,
+    }
+}

+ 173 - 1
WCS.WorkEngineering/Extensions/DeviceExtension.cs

@@ -1,4 +1,6 @@
-using WCS.Core;
+using System.Collections.Concurrent;
+using WCS.Core;
+using WCS.Entity;
 using WCS.Entity.Protocol.Station;
 
 namespace WCS.WorkEngineering.Extensions
@@ -12,5 +14,175 @@ namespace WCS.WorkEngineering.Extensions
         {
             return source.HasProtocol(typeof(IStation521)) || source.HasProtocol(typeof(IStation520)) || source.HasProtocol(typeof(IStation522));
         }
+
+        #region WCS_DEVICE扩展数据
+
+        private static ConcurrentDictionary<string, object> DeviceValues = new ConcurrentDictionary<string, object>();
+
+        public static void AddFlag(this Device source, DF flag)
+        {
+            var df = source.Get<DF>("DeviceFlag");
+            df = df | flag;
+            source.Set("DeviceFlag", df);
+        }
+
+        public static bool Is(this Device source, DF flag)
+        {
+            var df = source.Get<DF>("DeviceFlag");
+            return (df & flag) == flag;
+        }
+
+        public static void Set<T>(this Device source, string key, T value)
+        {
+            DeviceValues[source.Code + key] = value;
+        }
+
+        public static T Get<T>(this Device source, string key)
+        {
+            if (!DeviceValues.ContainsKey(source.Code + key))
+                return default(T);
+            return (T)DeviceValues[source.Code + key];
+        }
+
+        public static short Code(this Device source)
+        {
+            return short.Parse(source.Code);
+        }
+
+        public static string Tunnel(this Device source)
+        {
+            return source.Get<string>("Tunnel");
+        }
+
+        public static int TunnelNum(this Device source)
+        {
+            return int.Parse(source.Tunnel().Last().ToString());
+        }
+
+        public static int Floor(this Device source)
+        {
+            return source.Get<int>("Floor");
+        }
+
+        public static Device SC(this Device source)
+        {
+            return source.Get<Device>("SC");
+        }
+
+        public static Device RGV(this Device source)
+        {
+            return source.Get<Device>("RGV");
+        }
+
+        //public static LocInfo LocInfo(this WCS_DEVICEHdr source)
+        //{
+        //    return source.Get<LocInfo>("LocInfo");
+        //}
+
+        //public static bool WakeupOn(this WCS_DEVICEHdr source, int sec, string key)
+        //{
+        //    var str = "WakeupOn" + key;
+        //    var last = source.Get<DateTime>(str);
+        //    if ((DateTime.Now - last).TotalMilliseconds > sec)
+        //    {
+        //        source.Set(str, DateTime.Now);
+        //        return true;
+        //    }
+        //    else
+        //    {
+        //        Ltc.Log("OnSleep");
+        //        return false;
+        //    }
+        //}
+
+        //public static bool WakeupOn(this WCS_DEVICEHdr source, int sec)
+        //{
+        //    return source.WakeupOn(sec, "");
+        //}
+
+        #endregion WCS_DEVICE扩展数据
+
+        //#region 静态方法
+
+        //public static WCS_DEVICEHdr[] Where(Func<WCS_DEVICEHdr, bool> func)
+        //{
+        //    var arr = LogicHandler.AllObjects.OfType<WCS_DEVICEHdr>().Where(func).ToArray();
+        //    return arr;
+        //}
+
+        //public static WCS_DEVICEHdr Find(string code)
+        //{
+        //    return Where(v => v.CODE == code).Single();
+        //}
+
+        //public static WCS_DEVICEHdr[] Find(params string[] codes)
+        //{
+        //    return Where(v => codes.Contains(v.CODE)).ToArray();
+        //}
+
+        //public static void Set<T>(string key, T value, params string[] devices)
+        //{
+        //    var arr = LogicHandler.AllObjects.OfType<WCS_DEVICEHdr>().Where(v => devices.Contains(v.CODE)).ToArray();
+        //    Parallel.ForEach(arr, v =>
+        //    {
+        //        v.Set(key, value);
+        //    });
+        //}
+
+        //public static void Set<T>(string key, T value, Func<WCS_DEVICEHdr, bool> func)
+        //{
+        //    var arr = LogicHandler.AllObjects.OfType<WCS_DEVICEHdr>().Where(func).ToArray();
+        //    Parallel.ForEach(arr, v =>
+        //    {
+        //        v.Set(key, value);
+        //    });
+        //}
+
+        //public static void AddFlag(DF flag, params string[] devices)
+        //{
+        //    var arr = LogicHandler.AllObjects.OfType<WCS_DEVICEHdr>().Where(v => devices.Contains(v.CODE)).ToArray();
+        //    Parallel.ForEach(arr, v =>
+        //    {
+        //        v.AddFlag(flag);
+        //    });
+        //}
+
+        //public static void AddFlag(DF flag, Action<WCS_DEVICEHdr> callbck, params string[] devices)
+        //{
+        //    var arr = LogicHandler.AllObjects.OfType<WCS_DEVICEHdr>().Where(v => devices.Contains(v.CODE)).ToArray();
+        //    Parallel.ForEach(arr, v =>
+        //    {
+        //        v.AddFlag(flag);
+        //        callbck?.Invoke(v);
+        //    });
+        //}
+
+        //#endregion 静态方法
+    }
+
+    /// <summary>
+    /// 设备配置
+    /// </summary>
+    [Flags]
+    public enum DF
+    {
+        无 = 0,
+        SRM = 1 << 0,
+        SRM二级品取货 = 1 << 1,
+        SRM涂布取货 = 1 << 2,
+        SRM月台放货 = 1 << 3,
+        一楼RGV放货 = 1 << 4,
+        月台 = 1 << 5,
+        涂布RGV = 1 << 6,
+        BOPPRGV = 1 << 7,
+        涂布RGV取货设备组 = 1 << 8,
+        涂布RGV放货设备组 = 1 << 9,
+        涂布出库RGV取货站台 = 1 << 10,
+        涂布入库RGV取货站台 = 1 << 11,
+        SRM涂布放货 = 1 << 12,
+        涂布RGV取货站台 = 1 << 13,
+        BOPPRGV取货设备组 = 1 << 14,
+        BOPPRGV放货设备组 = 1 << 15,
+        SRMBOPP取货 = 1 << 16,
     }
 }

+ 54 - 0
WCS.WorkEngineering/Extensions/TaskExtension.cs

@@ -0,0 +1,54 @@
+using DBHelper;
+using WCS.Entity;
+
+namespace WCS.WorkEngineering.Extensions
+{
+    /// <summary>
+    /// 任务扩展
+    /// </summary>
+    public static class TaskExtension
+    {
+        /// <summary>
+        /// 更新任务执行记录
+        /// </summary>
+        /// <param name="task">任务信息</param>
+        /// <param name="db">数据库上下文</param>
+        /// <param name="curPoint">当前地址</param>
+        /// <param name="desc">描述</param>
+        public static void AddWCS_TASK_DTL(this WCS_TASK task, Db db, string curPoint, string desc)
+        {
+            db.Default.Insertable(new WCS_TASK_DTL
+            {
+                ParentTaskCode = task.ID,
+                CurPoint = "",
+                NextPoint = "",
+                Desc = "",
+                UPDATETIME = DateTime.Now,
+                ExecTime = DateTime.Now,
+                UPDATEUSER = "WCS"
+            }).AddQueue();
+        }
+
+        /// <summary>
+        /// 更新任务执行记录
+        /// </summary>
+        /// <param name="task">任务信息</param>
+        /// <param name="db">数据库上下文</param>
+        /// <param name="curPoint">当前地址</param>
+        /// <param name="NextPoint">下一个地址</param>
+        /// <param name="desc">描述</param>
+        public static void AddWCS_TASK_DTL(this WCS_TASK task, Db db, string curPoint, string NextPoint, string desc)
+        {
+            db.Default.Insertable(new WCS_TASK_DTL
+            {
+                ParentTaskCode = task.ID,
+                CurPoint = "",
+                NextPoint = "",
+                Desc = "",
+                UPDATETIME = DateTime.Now,
+                ExecTime = DateTime.Now,
+                UPDATEUSER = "WCS"
+            }).AddQueue();
+        }
+    }
+}

+ 28 - 0
WCS.WorkEngineering/Systems/MainLineScanCode.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WCS.Core;
+using WCS.Entity.Protocol.Station;
+
+namespace WCS.WorkEngineering.Systems
+{
+
+    public class MainLineScanCode : DeviceSystem<Device<IStation520, IStation521, IStation522>>
+    {
+        protected override bool ParallelDo => throw new NotImplementedException();
+
+        protected override bool SaveLogsToFile => throw new NotImplementedException();
+
+        public override void Do(Device<IStation520, IStation521, IStation522> obj)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override bool Select(Device dev)
+        {
+            return new int[] { 1701, 2101,1717, 2117}.Contains(int.Parse(dev.Code));
+        }
+    }
+}

+ 201 - 0
WCS.WorkEngineering/Systems/SrmSystems.cs

@@ -0,0 +1,201 @@
+using DBHelper;
+using ServiceCenter.Extensions;
+using System.ComponentModel;
+using WCS.Core;
+using WCS.Entity;
+using WCS.Entity.Protocol.SRM;
+using WCS.Entity.Protocol.Station;
+using WCS.WorkEngineering.Extensions;
+using WCS.WorkEngineering.Worlds;
+
+namespace WCS.WorkEngineering.Systems
+{
+    /// <summary>
+    /// 堆垛机系统
+    /// </summary>
+    [BelongTo(typeof(MainWorld))]
+    [Description("堆垛机系统")]
+    public class SrmSystems : DeviceSystem<Device<ISRM520, ISRM521, ISRM523>>
+    {
+        /// <summary>
+        /// 取货点设备集合
+        /// </summary>
+        private List<Device<IStation520, IStation521, IStation522>> PickUpDevices;
+
+        /// <summary>
+        /// 放货设备
+        /// </summary>
+        private List<Device<IStation520, IStation521, IStation522>> PutDevices;
+
+        public SrmSystems()
+        {
+            //分拣库1
+            PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
+                                         .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
+            PutDevices = World.Devices.Where(v => v.Code is "" or "")
+                                         .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
+            //分拣库2
+            PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
+                                         .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
+            PutDevices = World.Devices.Where(v => v.Code is "" or "")
+                                         .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
+            //分拣库3
+            PickUpDevices = World.Devices.Where(v => v.Code is "" or "")
+                                         .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
+            PutDevices = World.Devices.Where(v => v.Code is "" or "")
+                                         .Select(v => new Device<IStation520, IStation521, IStation522>(v)).ToList();
+        }
+
+        protected override bool ParallelDo => true;
+
+        protected override bool SaveLogsToFile => true;
+
+        public override void Do(Device<ISRM520, ISRM521, ISRM523> obj)
+        {
+            //判断堆垛机是否报警
+            if (obj.Data2.Status.HasFlag(SrmStatus.Alarm)) throw new KnownException(obj.Data3.Alarm.ToString(), LogLevel.High);
+
+            //判断DB520 完成任务确认清除信号 是否为1
+            if (obj.Data.OkAck == 1) throw new KnownException("任务完成确认信号未清除", LogLevel.Mid);
+
+            //判断完成任务号是否大于0
+            if (obj.Data2.TaskFinishiId > 0)
+            {
+                Db.Do(db =>
+                {
+                    //根据DB521任务号获取对应任务
+                    var task = db.Default.Queryable<WCS_TASK>().First(v => v.ID == obj.Data2.TaskFinishiId) ?? throw new KnownException($"未找到任务{obj.Data2.TaskFinishiId}", LogLevel.High);
+                    if (task.STATUS != Entity.TaskStatus.StackerExecution)
+                        throw new KnownException($"任务{task.ID}状态是{task.STATUS.Description()}.堆垛机完成任务需要对应任务状态处于堆垛机执行中", LogLevel.High);
+                    //根据任务类型做不同的处理
+                    switch (task.TYPE)
+                    {
+                        case TaskType.EnterDepot:
+                            //完成任务
+                            task.STATUS = Entity.TaskStatus.Finish;
+                            task.UPDATETIME = DateTime.Now;
+                            task.ENDTIME = DateTime.Now;
+                            task.AddWCS_TASK_DTL(db, task.ADDRTO, "入库任务结束");
+                            break;
+
+                        case TaskType.OutDepot:
+                            task.STATUS = Entity.TaskStatus.ConveyorInProgress;
+                            task.UPDATETIME = DateTime.Now;
+                            task.AddWCS_TASK_DTL(db, task.SRMSTATION, "出库任务到达放货站台");
+                            break;
+
+                        case TaskType.TransferDepot:
+                            task.STATUS = Entity.TaskStatus.Finish;
+                            task.UPDATETIME = DateTime.Now;
+                            task.ENDTIME = DateTime.Now;
+                            task.AddWCS_TASK_DTL(db, task.ADDRTO, "移库任务结束");
+                            break;
+                    }
+
+                    db.Default.Updateable(task).AddQueue();
+                    db.Default.SaveQueues();
+                    obj.Data.OkAck = 1;
+                });
+            }
+
+            //堆垛机是否可以下发任务
+            if (obj.Data2.VoucherNo != obj.Data.VoucherNo) throw new KnownException($"凭证号不一致,DB520:{obj.Data.VoucherNo},DB521:{obj.Data2.VoucherNo}", LogLevel.Mid);
+            if (obj.Data2.AutoStatus != SrmAutoStatus.Automatic) throw new KnownException($"堆垛机处于{obj.Data2.AutoStatus}模式", LogLevel.Low);
+            if (obj.Data2.RunStatus != SrmRunStatus.Idle) throw new KnownException($"堆垛机处于{obj.Data2.RunStatus}状态", LogLevel.High);
+
+            //默认没有移库任务
+            bool isTransfer = false;
+
+            //出入库优先级任务 1:无优先 2:入库 3:出库
+            int enterOrOut = 1;
+
+            //再检查是否有等待执行的货物
+            Db.Do(db =>
+            {
+                //获取当前堆垛机的所有未完成任务
+                var tasks = db.Default.Queryable<WCS_TASK>().Where(v => v.STATUS < Entity.TaskStatus.Finish && (v.DEVICE == obj.Entity.Code));
+                //任务集合是否有处于堆垛机执行状态的任务
+                if (tasks.Any(v => v.STATUS == Entity.TaskStatus.StackerExecution)) throw new KnownException($"有任务处于堆垛机执行状态", LogLevel.High);
+
+                //判断是否存在调整优先级任务
+                if (!tasks.Any(v => v.TYPE != TaskType.TransferDepot && v.STATUS < Entity.TaskStatus.StackerExecution && v.Priority > 0))
+                {
+                    //不存在调整优先级任务,判断是否存在移库任务
+                    isTransfer = tasks.Any(v => v.TYPE == TaskType.TransferDepot && v.STATUS == Entity.TaskStatus.NewBuild);
+                }
+                else //存在调整优先级任务
+                {
+                    //获取出库任务中新建状态最大优先级
+                    var outPriorityNewBuild = tasks.Where(v => v.TYPE == TaskType.OutDepot && v.STATUS == Entity.TaskStatus.NewBuild).Max(v => v.Priority);
+                    //获取入库任务中最后一个交互点是取货点任务的最大优先级
+                    var enterPriority = tasks.Where(v => v.TYPE == TaskType.EnterDepot && v.STATUS < Entity.TaskStatus.StackerExecution && PickUpDevices.Any(p => p.Entity.Code == v.LastInteractionPoint))
+                                             .Max(v => v.Priority);
+                    //出入库最大优先级相加大于零
+                    if (outPriorityNewBuild + enterPriority > 0)
+                    {
+                        //出入库优先级任务 1:无优先 2:入库 3:出库
+                        enterOrOut = enterPriority > outPriorityNewBuild ? 2 : 3;
+                    }
+                }
+            });
+
+            #region 移库
+
+            if (isTransfer)
+            {
+                Db.Do(db =>
+                {
+                    //获取一条当前堆垛机优先级最高的新建移库任务
+                    var task = db.Default.Queryable<WCS_TASK>().Where(v => v.DEVICE == obj.Entity.Code && v.TYPE == TaskType.TransferDepot && v.STATUS == Entity.TaskStatus.NewBuild)
+                                                               .OrderByDescending(v => v.Priority)
+                                                               .First() ?? throw new KnownException("未找到移库任务", LogLevel.High);
+                    //任务状态改为堆垛机执行中
+                    task.STATUS = Entity.TaskStatus.StackerExecution;
+                    task.STARTTIME = DateTime.Now;
+                    task.UPDATETIME = DateTime.Now;
+                    task.AddWCS_TASK_DTL(db, task.ADDRFROM, task.DEVICE, $"堆垛机{obj.Entity.Code}开始执行任务");
+                    db.Default.Updateable(task).AddQueue();
+                    db.Default.SaveQueues();
+                    var addrFrom = task.ADDRFROM.Split("-");
+                    var addrTo = task.ADDRTO.Split("-");
+                    //下发任务
+                    obj.Data.TaskNumber = task.ID;
+                    obj.Data.RowPos1 = addrFrom[0].ToShort();
+                    obj.Data.TravelPos1 = addrFrom[1].ToShort();
+                    obj.Data.LiftPos1 = addrFrom[2].ToShort();
+                    obj.Data.RowPos2 = addrTo[0].ToShort();
+                    obj.Data.TravelPos2 = addrTo[1].ToShort();
+                    obj.Data.LiftPos2 = addrTo[2].ToShort();
+                    obj.Data.VoucherNo++;
+                });
+            }
+
+            #endregion 移库
+
+            #region 出入库
+
+            //上一个周期是不是出库任务 第一次获取返回结果会是false
+            var lastIsOut = obj.Entity.Get<bool>("LastIsOut");
+            obj.Entity.Set("LastIsOut", !lastIsOut);
+
+            //入库任务优先 或 上一个周期是出库任务并且出库任务无优先
+            if (enterOrOut == 2 || (lastIsOut && enterOrOut == 1)) //入库任务
+            {
+                //判断本次优先执行楼层,并设置下次执行时优先楼层
+                var floor = obj.Entity.Get<int>("Floor");
+                floor = floor % 2 + 1;
+                obj.Entity.Set("Floor", floor);
+            }
+            else if (enterOrOut == 3 || !lastIsOut)
+            {
+            }
+
+            #endregion 出入库
+        }
+
+        public override bool Select(Device dev)
+        {
+            return dev.Code.Contains("SRM");
+        }
+    }
+}

+ 1 - 0
WCS.WorkEngineering/WCS.WorkEngineering.csproj

@@ -7,6 +7,7 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
     <PackageReference Include="ServiceCenter" Version="1.0.0.16" />
   </ItemGroup>
 

+ 43 - 0
WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -0,0 +1,43 @@
+using Microsoft.AspNetCore.Mvc;
+using WCS.WorkEngineering.WebApi.Models;
+
+namespace WCS.WorkEngineering.WebApi.Controllers
+{
+    /// <summary>
+    /// AGV相关接口控制器
+    /// </summary>
+    [ApiController]
+    [Route("[controller]/[action]")]
+    public class AgvController : ControllerBase
+    {
+        /// <summary>
+        /// AGV执行回调
+        /// </summary>
+        /// <param name="reqDto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public AgvCallbackResponse AgvCallback(AgvCallbackRequest reqDto)
+        {
+            switch (reqDto.method)
+            {
+                case "申请":
+                    break;
+                case "申请放货":
+                    break;
+
+                case "申请取货":
+                    break;
+
+                case "取放完成":
+                    break;
+
+                default:
+                    break;
+            }
+
+            var res = new AgvCallbackResponse() { code = "0", message = "成功" };
+
+            return res;
+        }
+    }
+}

+ 110 - 0
WCS.WorkEngineering/WebApi/Models/AgvCallbackRequest.cs

@@ -0,0 +1,110 @@
+namespace WCS.WorkEngineering.WebApi.Models
+{
+    public class AgvCallbackRequest
+    {
+        /// <summary>
+        /// 请求编号,每个请求都要一个唯一编号, 同一个请求重复提交, 使用同一编号
+        /// </summary>
+        public string reqCode { get; set; }
+
+        /// <summary>
+        /// 请求时间戳,格式: “yyyy-MM-dd HH:mm:ss”
+        /// </summary>
+        public string reqTime { get; set; }
+
+        /// <summary>
+        /// 地码 X 坐标(mm):任务完成时有值
+        /// </summary>
+        public decimal cooX { get; set; }
+
+        /// <summary>
+        /// 地码 Y 坐标(mm):任务完成时有值
+        /// </summary>
+        public decimal cooY { get; set; }
+
+        /// <summary>
+        /// 当前位置编号
+        /// </summary>
+        public string currentPositionCode { get; set; }
+
+        /// <summary>
+        /// 自定义字段
+        /// </summary>
+        public string data { get; set; }
+
+        /// <summary>
+        /// 地图编号
+        /// </summary>
+        public string mapCode { get; set; }
+
+        /// <summary>
+        /// 地码编号:任务完成时有值
+        /// </summary>
+        public string mapDataCode { get; set; }
+
+        /// <summary>
+        /// 仓位编号:叉车与CTU任务时有值
+        /// </summary>
+        public string stgBinCode { get; set; }
+
+        /// <summary>
+        /// 方法名,申请放货、请求取货、
+        /// </summary>
+        public string method { get; set; }
+
+        /// <summary>
+        /// 货架编号:背货架时有值
+        /// </summary>
+        public string podCode { get; set; }
+
+        /// <summary>
+        /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下”:任务完成时有值
+        /// </summary>
+        public string podDir { get; set; }
+
+        /// <summary>
+        /// 物料编号
+        /// </summary>
+        public string materialLot { get; set; }
+
+        /// <summary>
+        /// AGV编号(同 agvCode )
+        /// </summary>
+        public string robotCode { get; set; }
+
+        /// <summary>
+        /// 当前任务单号
+        /// </summary>
+        public string taskCode { get; set; }
+
+        /// <summary>
+        /// 工作位
+        /// </summary>
+        public string wbCode { get; set; }
+
+        /// <summary>
+        /// 容器编号
+        /// </summary>
+        public string ctnrCode { get; set; }
+
+        /// <summary>
+        /// 容器类型
+        /// </summary>
+        public string ctnrType { get; set; }
+
+        /// <summary>
+        /// 巷道编号
+        /// </summary>
+        public string roadWayCode { get; set; }
+
+        /// <summary>
+        /// 巷道内顺序号巷道尾是0,到巷道头依次递增1
+        /// </summary>
+        public string seq { get; set; }
+
+        /// <summary>
+        /// 设备编号
+        /// </summary>
+        public string eqpCode { get; set; }
+    }
+}

+ 62 - 0
WCS.WorkEngineering/WebApi/Models/CopperLineAgvTaskStockInToIWmsRequest.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WCS.WorkEngineering.WebApi.Models
+{
+    public class CopperLineAgvTaskStockInToIWmsRequest
+    {
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        public string matCode { get; set; }
+        /// <summary>
+        /// 工作站编号
+        /// </summary>
+        public string workAreaCode { get; set; }
+        /// <summary>
+        /// 空/满工字轮标记(满工字轮:1空工字轮:0)
+        /// </summary>
+        public string outSpoolFull { get; set; }
+        /// <summary>
+        /// 取空补满标记
+        /// </summary>
+        public bool intoEmpty { get; set; }
+        /// <summary>
+        /// 湿拉出库标记
+        /// </summary>
+        public string wetOut { get; set; }
+        /// <summary>
+        /// 湿拉退料出库标记
+        /// </summary>
+        public string wetOutReturn { get; set; }
+        /// <summary>
+        /// 改手盘标记
+        /// </summary>
+        public string isSurplus { get; set; }
+        /// <summary>
+        /// 返工标记
+        /// </summary>
+        public string isRework { get; set; }
+        /// <summary>
+        /// 材料号
+        /// </summary>
+        public string matNo { get; set; }
+        /// <summary>
+        /// RFID号
+        /// </summary>
+        public string spoolNo { get; set; }
+        /// <summary>
+        /// 质量状态标记
+        /// </summary>
+        public string gradeCode { get; set; }
+        /// <summary>
+        /// 快投标记
+        /// </summary>
+        public string matFast { get; set; }
+        /// <summary>
+        /// 任务号
+        /// </summary>
+        public string taskNo { get; set; }
+    }
+}

+ 82 - 0
WCS.WorkEngineering/WebApi/Models/CopperLineAgvTaskStockOutToIWmsRequest.cs

@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WCS.WorkEngineering.WebApi.Models
+{
+    public class CopperLineAgvTaskStockOutToIWmsRequest
+    {
+        /// <summary>
+        /// 物料编码
+        /// </summary>
+        public string matCode { get; set; }
+        /// <summary>
+        /// 工作站编号(机台号、立库点位编号)
+        /// </summary>
+        public string wbCode { get; set; }
+        /// <summary>
+        /// 空/满工字轮入库标记(空工字轮:0,满工字轮:1,半工字轮:2)
+        /// </summary>
+        public string inSpoolFull { get; set; }
+        /// <summary>
+        /// 取满补空标记
+        /// </summary>
+        public bool getOutEmpty { get; set; }
+        /// <summary>
+        /// 湿拉上线标记
+        /// </summary>
+        public bool wetInto { get; set; }
+        /// <summary>
+        /// 湿拉特殊上线标记
+        /// </summary>
+        public bool wetIntoSpec { get; set; }
+        /// <summary>
+        /// 湿拉退料入库标记
+        /// </summary>
+        public bool wetIntoReturn { get; set; }
+        /// <summary>
+        /// 湿拉特殊上线点位号
+        /// </summary>
+        public string wetSpecWbCode { get; set; }
+        /// <summary>
+        /// 改手盘标记
+        /// </summary>
+        public string isSurplus { get; set; }
+        /// <summary>
+        /// 返工标记
+        /// </summary>
+        public string isRework { get; set; }
+        /// <summary>
+        /// 材料号
+        /// </summary>
+        public string matNo { get; set; }
+        /// <summary>
+        /// RFID号
+        /// </summary>
+        public string spoolNo { get; set; }
+        /// <summary>
+        /// 质量状态标记
+        /// </summary>
+        public string gradeCode { get; set; }
+        /// <summary>
+        /// 快投标记
+        /// </summary>
+        public string matFast { get; set; }
+        /// <summary>
+        /// 长度
+        /// </summary>
+        public string orderProcessLenOut { get; set; }
+        /// <summary>
+        /// 任务号
+        /// </summary>
+        public string taskNo { get; set; }
+        /// <summary>
+        /// 退料原因
+        /// </summary>
+        public string returnDesc { get; set; }
+        /// <summary>
+        /// 是否锁定
+        /// </summary>
+        public string lockFlag { get; set; }
+    }
+}

+ 87 - 0
WCS.WorkEngineering/WebApi/Models/GenAgvSchedulingTaskRequest.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WCS.WorkEngineering.WebApi.Models
+{
+    public class GenAgvSchedulingTaskRequest
+    {
+        /// <summary>
+        /// 请求编号,每个请求都要一个唯一编号, 同一个请求重复提交, 使用同一编号。
+        /// </summary>
+        public string reqCode { get; set; }
+        /// <summary>
+        /// 请求时间截 格式: “yyyy-MM-dd HH:mm:ss”
+        /// </summary>
+        public string reqTime { get; set; }
+        /// <summary>
+        /// 客户端编号,如PDA,HCWMS等
+        /// </summary>
+        public string clientCode { get; set; }
+        /// <summary>
+        /// 令牌号, 由调度系统颁发
+        /// </summary>
+        public string tokenCode { get; set; }
+        /// <summary>
+        /// 任务类型
+        /// </summary>
+        public string taskTyp { get; set; }
+        /// <summary>
+        /// 容器类型(叉车/CTU专用)叉车项目必传
+        /// </summary>
+        public string ctnrTyp { get; set; }
+        /// <summary>
+        /// 任务模式
+        /// </summary>
+        public string taskMode { get; set; }
+        /// <summary>
+        /// 工作位
+        /// </summary>
+        public string wbCode { get; set; }
+        /// <summary>
+        /// 位置路径
+        /// </summary>
+        public List<positionCodeClass> positionCodePath { get; set; }
+        /// <summary>
+        /// 货架编号
+        /// </summary>
+        public string podCode { get; set; }
+        /// <summary>
+        /// “180”,”0”,”90”,”-90”
+        /// </summary>
+        public string podDir { get; set; }
+        /// <summary>
+        /// 货架类型, 传空时表示随机找个货架
+        /// </summary>
+        public string podTyp { get; set; }
+        /// <summary>
+        /// 物料批次或货架上的物料唯一编码
+        /// </summary>
+        public string materialLot { get; set; }
+        /// <summary>
+        /// 优先级,从(1~127)级,最大优先级最高
+        /// </summary>
+        public string priority { get; set; }
+        /// <summary>
+        /// 任务单号,选填, 不填系统自动生成,UUID小于等于64位
+        /// </summary>
+        public string taskCode { get; set; }
+        /// <summary>
+        /// AGV编号,填写表示指定某一编号的AGV执行该任务
+        /// </summary>
+        public string agvCode { get; set; }
+        /// <summary>
+        /// 组编号
+        /// </summary>
+        public string groupId { get; set; }
+        /// <summary>
+        /// 自定义字段.JSON格式 
+        /// </summary>
+        public string data { get; set; }
+    }
+    public class positionCodeClass
+    {
+        public string positionCode { get; set; }
+        public string type { get; set; }
+    }
+}

+ 26 - 0
WCS.WorkEngineering/WebApi/Models/GenAgvSchedulingTaskResponse.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WCS.WorkEngineering.WebApi.Models
+{
+    public class GenAgvSchedulingTaskResponse
+    {
+        /// <summary>
+        /// 返回码
+        /// </summary>
+        public string code { get; set; }
+        /// <summary>
+        /// 返回消息
+        /// </summary>
+        public string message { get; set; }
+        /// <summary>
+        /// 请求编号
+        /// </summary>
+        public string reqCode { get; set; }
+        /// <summary>
+        /// 自定义返回(返回任务单号)
+        /// </summary>
+        public string data { get; set; }
+    }
+}

+ 22 - 0
WCS.WorkEngineering/WebApi/Models/agvCallbackResponse.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WCS.WorkEngineering.WebApi.Models
+{
+    public class AgvCallbackResponse
+    {
+        /// <summary>
+        /// 返回码 1:允许执行 0:不允许执行
+        /// </summary>
+        public string code { get; set; } = "0";
+        /// <summary>
+        /// 返回消息
+        /// </summary>
+        public string message { get; set; } = "成功";
+        /// <summary>
+        /// 请求编号
+        /// </summary>
+        public string reqCode { get; set; }
+    }
+}

+ 110 - 0
WCS.WorkEngineering/WebApi/任务.cs

@@ -0,0 +1,110 @@
+///// <summary>
+//     /// 镀铜一楼res下任务
+//     /// </summary>
+//     /// <param name="reqDto"></param>
+//     /// <returns></returns>
+//     [HttpPost]
+//     public GenAgvSchedulingTaskResponse CopperLineAgvTaskToRcs(GenAgvSchedulingTaskRequest reqDto)
+//     {
+//         var result = new GenAgvSchedulingTaskResponse();
+//         GenAgvSchedulingTaskRequest resReq = new GenAgvSchedulingTaskRequest();
+//         var apiurl = wms.util.AppSettings.GetConfig("RcsCreateTaskPushUrl");
+//         var strRes = HttpUtil.PostRequest(apiurl, JsonConvert.SerializeObject(resReq), 30000);
+//         if (string.IsNullOrEmpty(strRes))
+//         {
+//             result.message = "返回空";
+//             return result;
+//         }
+//         return JsonConvert.DeserializeObject<GenAgvSchedulingTaskResponse>(strRes);
+//     }
+//     /// <summary>
+//     /// 镀铜一楼res继续任务
+//     /// </summary>
+//     /// <param name="reqDto"></param>
+//     /// <returns></returns>
+//     [HttpPost]
+//     public GenAgvSchedulingTaskResponse CopperLineContinueTaskToRcs(GenAgvSchedulingTaskRequest reqDto)
+//     {
+//         var result = new GenAgvSchedulingTaskResponse();
+//         GenAgvSchedulingTaskRequest resReq = new GenAgvSchedulingTaskRequest()
+//         { };
+//         var apiurl = wms.util.AppSettings.GetConfig("RcsContinuePushUrl");
+//         var strRes = HttpUtil.PostRequest(apiurl, JsonConvert.SerializeObject(resReq), 30000);
+//         if (string.IsNullOrEmpty(strRes))
+//         {
+//             result.message = "返回空";
+//             return result;
+//         }
+//         return JsonConvert.DeserializeObject<GenAgvSchedulingTaskResponse>(strRes);
+//     }
+//     /// <summary>
+//     /// 镀铜二楼IWMS下发满轮出库
+//     /// </summary>
+//     /// <param name="reqDto"></param>
+//     /// <returns></returns>
+//     [HttpPost]
+//     public SRes CopperLineAgvTaskStockOutToIWms(CopperLineAgvTaskStockOutToIWmsRequest reqDto)
+//     {
+//         var result = new SRes();
+//         CopperLineAgvTaskStockOutToIWmsRequest resReq = new CopperLineAgvTaskStockOutToIWmsRequest()
+//         {
+//             matCode = "",
+//             wbCode = "满轮接驳口",
+//             inSpoolFull = "1",
+//             wetInto = true,
+//             wetIntoSpec = false,
+//             isSurplus = "",
+//             isRework = "",
+//             matNo = "",
+//             spoolNo = "",
+//             gradeCode = "",
+//             taskNo = Guid.NewGuid().ToString(),
+
+//         };
+//         var apiurl = wms.util.AppSettings.GetConfig("IWmsStockOutPushUrl");
+//         var strRes = HttpUtil.PostRequest(apiurl, JsonConvert.SerializeObject(reqDto), 30000);
+//         if (string.IsNullOrEmpty(strRes))
+//         {
+//             //result.message = "返回空";
+//             return result;
+//         }
+//         return JsonConvert.DeserializeObject<SRes>(strRes);
+//     }
+//     /// <summary>
+//     /// 镀铜二楼IWMS下发空轮/退料/余料入库
+//     /// </summary>
+//     /// <param name="reqDto"></param>
+//     /// <returns></returns>
+//     [HttpPost]
+//     public SRes CopperLineAgvTaskStockInToIWms(CopperLineAgvTaskStockInToIWmsRequest reqDto)
+//     {
+//         var result = new SRes();
+//         CopperLineAgvTaskStockInToIWmsRequest resReq = new CopperLineAgvTaskStockInToIWmsRequest()
+//         {
+//             matCode = "",
+//             workAreaCode = "11",
+//             outSpoolFull = "1",
+//             taskNo = Guid.NewGuid().ToString()
+//         };
+//         var apiurl = wms.util.AppSettings.GetConfig("IWmsStockInPushUrl");
+//         var strRes = HttpUtil.PostRequest(apiurl, JsonConvert.SerializeObject(reqDto), 30000);
+//         if (string.IsNullOrEmpty(strRes))
+//         {
+//             //result.message = "返回空";
+//             return result;
+//         }
+//         return JsonConvert.DeserializeObject<SRes>(strRes);
+//     }
+
+//     /// <summary>
+//     /// AGV执行回调
+//     /// </summary>
+//     /// <param name="reqDto"></param>
+//     /// <returns></returns>
+//     [HttpPost]
+//     public agvCallbackResponse agvCallback(agvCallbackRequest reqDto)
+//     {
+//         var res = new agvCallbackResponse() { code = "0",message = "成功" };
+
+//         return res;
+//     }

+ 15 - 0
WCS.WorkEngineering/Worlds/SortingMainLineWorld.cs

@@ -0,0 +1,15 @@
+using WCS.Core;
+
+namespace WCS.WorkEngineering.Worlds
+{
+    /// <summary>
+    /// 分拣主线
+    /// </summary>
+    public class SortingMainLineWorld : World
+    {
+        public SortingMainLineWorld()
+        {
+            Interval = 100;
+        }
+    }
+}