已添加11个文件
已重命名1个文件
已删除71个文件
已修改19个文件
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "ExpandedNodes": [ |
| | | "" |
| | | ], |
| | | "SelectedNode": "\\WIDESEA_WMSServer.sln", |
| | | "PreviewInSolutionExplorer": false |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace WIDESEAWCS_Common.TaskEnum |
| | | { |
| | | /// <summary> |
| | | /// ä¸å åäº¤äºæ¥æ |
| | | /// </summary> |
| | | public enum StackerCommandEnum |
| | | { |
| | | /// <summary> |
| | | /// åéç»å åæºä»»å¡ |
| | | /// </summary> |
| | | ARQ, |
| | | /// <summary> |
| | | /// åå¤éè¦ç¡®è®¤çæ¥æ<br/> |
| | | /// æ¶å°å¯¹æ¹æ¥æä»¥åæ¯å¦éè¦åå¤ACK<br/> |
| | | /// åå³äºå
ç´ æ¥æç»æä¸çå
ç´ 2<br/> |
| | | /// å¦æä¸º1,éåå¤ACK<br/> |
| | | /// å¦æä¸º0,ä¸åå¤ACK<br/> |
| | | /// </summary> |
| | | ACK, |
| | | /// <summary> |
| | | /// å åæºç»å°WCSçæ¥æ<br/> |
| | | /// 任塿§è¡å®æ<br/> |
| | | /// 任塿 æ³æ§è¡<br/> |
| | | /// ä»»å¡å é¤ãçåå <br/> |
| | | /// </summary> |
| | | ACP, |
| | | /// <summary> |
| | | /// è¿åç»åéè
ï¼æ¥æ¶è
æ¥æ¶å°çæ¥æä¸æ£ç¡®æè
æ¥æ¶è
æ æ³æ£ç¡®å¤çè¯¥æ¥æ |
| | | /// </summary> |
| | | NCK, |
| | | /// <summary> |
| | | /// åéç»å åæºï¼è¯·æ±åå§ååºåå· |
| | | /// </summary> |
| | | SYN, |
| | | /// <summary> |
| | | /// å¿è·³æ£æµ,询é®å¯¹æ¹æ¯å¦ä»å¨çº¿ |
| | | /// </summary> |
| | | DUM, |
| | | /// <summary> |
| | | /// å¿è·³åå¤ |
| | | /// </summary> |
| | | DUA, |
| | | /// <summary> |
| | | /// WCSåéç»å åæºï¼è¯·æ±å é¤ä»»å¡ |
| | | /// </summary> |
| | | DER, |
| | | /// <summary> |
| | | /// å åæºåå¤WCSçDERæ¥æï¼ä»»å¡å é¤/æ æ³å é¤ |
| | | /// </summary> |
| | | DEC, |
| | | /// <summary> |
| | | /// WCSåç»å åæºï¼è¯·æ±å½åå åæºçç¶æ |
| | | /// </summary> |
| | | CRQ, |
| | | /// <summary> |
| | | /// å åæºåç»WCSï¼æ¥åå åæºå½åçç¶æ<br/> |
| | | /// å½å åæºç¶æåçæ¹åå°ä¼åéä¸ä¸ªCSR<br/> |
| | | /// å åæºæ²¡ä»»å¡ï¼åå¤çä»»å¡å·æ¯00000000 |
| | | /// </summary> |
| | | CSR |
| | | } |
| | | } |
| | |
| | | { |
| | | return TaskTypeGroup.RelocationGroup; |
| | | } |
| | | // å°è¯å°ä»»å¡ç±»å转æ¢ä¸ºTaskOtherTypeEnumæä¸¾ç±»åï¼å¦ææåï¼è¿åOtherGroup |
| | | else if (!int.TryParse(Enum.Parse<TaskOtherTypeEnum>(taskTypeStr).ToString(), out result)) |
| | | { |
| | | return TaskTypeGroup.OtherGroup; |
| | | } |
| | | // 妿以ä¸è½¬æ¢é½ä¸æåï¼æåºNotImplementedExceptionå¼å¸¸ |
| | | else |
| | | { |
| | |
| | | // 妿type䏿¯æä¸¾ç±»åï¼è¿å0 |
| | | if (!type.IsEnum) return 0; |
| | | // 妿typeæ¯TaskInStatusEnumæä¸¾ç±»å |
| | | if (type == typeof(TaskInStatusEnum)) |
| | | if (type == typeof(TaskStatusEnum)) |
| | | { |
| | | // è·åTaskInStatusEnumæä¸¾ç±»åçç´¢å¼å表 |
| | | List<int> taskInboundTypes = type.GetEnumIndexList(); |
| | | // è¿å大äºå½åç¶æä¸å°äºInFinishç¶æçç´¢å¼ |
| | | return taskInboundTypes.Where(x => x > currentStatus && x < (int)TaskInStatusEnum.InFinish).OrderBy(x => x).FirstOrDefault(); |
| | | } |
| | | // 妿typeæ¯TaskOutStatusEnumæä¸¾ç±»å |
| | | else if (type == typeof(TaskOutStatusEnum)) |
| | | { |
| | | // è·åTaskOutStatusEnumæä¸¾ç±»åçç´¢å¼å表 |
| | | return type.GetEnumIndexList().Where(x => x > currentStatus && x < (int)TaskOutStatusEnum.OutFinish).OrderBy(x => x).FirstOrDefault(); |
| | | } |
| | | // 妿typeæ¯TaskRobotStatusEnumæä¸¾ç±»å |
| | | else if (type == typeof(TaskRobotStatusEnum)) |
| | | { |
| | | // è·åTaskOutStatusEnumæä¸¾ç±»åçç´¢å¼å表 |
| | | return type.GetEnumIndexList().Where(x => x > currentStatus && x < (int)TaskRobotStatusEnum.RobotFinish).OrderBy(x => x).FirstOrDefault(); |
| | | return taskInboundTypes.Where(x => x > currentStatus).OrderBy(x => x).FirstOrDefault(); |
| | | } |
| | | // 妿以䏿¡ä»¶é½ä¸æ»¡è¶³ï¼æåºNotImplementedExceptionå¼å¸¸ |
| | | else |
| | |
| | | |
| | | namespace WIDESEAWCS_Common.TaskEnum |
| | | { |
| | | public enum TaskInStatusEnum |
| | | public enum TaskStatusEnum |
| | | { |
| | | /// <summary> |
| | | /// æ°å»ºå
¥åºä»»å¡ |
| | | /// æ°å»ºä»»å¡ |
| | | /// </summary> |
| | | [Description("æ°å»ºå
¥åºä»»å¡")] |
| | | InNew = 200, |
| | | |
| | | ///// <summary> |
| | | ///// AGVå
¥åºæ§è¡ä¸ |
| | | ///// </summary> |
| | | //[Description("AGVå
¥åºæ§è¡ä¸")] |
| | | //AGV_InExecuting = 210, |
| | | |
| | | ///// <summary> |
| | | ///// AGVå
¥åºå®æ |
| | | ///// </summary> |
| | | //[Description("AGVæ¬è¿å®æ")] |
| | | //AGV_InFinish = 215, |
| | | [Description("æ°å»º")] |
| | | New = 100, |
| | | |
| | | /// <summary> |
| | | /// è¾é线å
¥åºæ§è¡ä¸ |
| | | /// å åæºå¾
æ§è¡ |
| | | /// </summary> |
| | | [Description("è¾é线å
¥åºæ§è¡ä¸")] |
| | | Line_InExecuting = 220, |
| | | [Description("å åæºå¾
æ§è¡")] |
| | | SC_Execute = 200, |
| | | |
| | | /// <summary> |
| | | /// è¾é线å
¥åºå®æ |
| | | /// å åæºçå¾
ç¡®è®¤ä¸ |
| | | /// </summary> |
| | | [Description("è¾é线è¾é宿")] |
| | | Line_InFinish = 225, |
| | | [Description("å åæºçå¾
确认ä¸")] |
| | | SC_Waiting = 205, |
| | | |
| | | /// <summary> |
| | | /// å åæºå
¥åºæ§è¡ä¸ |
| | | /// å åæºæ§è¡ä¸ |
| | | /// </summary> |
| | | [Description("å åæºå
¥åºæ§è¡ä¸")] |
| | | SC_InExecuting = 230, |
| | | [Description("å åæºæ§è¡ä¸")] |
| | | SC_Executing = 210, |
| | | |
| | | /// <summary> |
| | | /// å åæºå
¥åºå®æ |
| | | /// å åæºå®æ |
| | | /// </summary> |
| | | [Description("å åæºå
¥åºå®æ")] |
| | | SC_InFinish = 235, |
| | | [Description("å åæºå®æ")] |
| | | SC_Finish = 220, |
| | | |
| | | /// <summary> |
| | | /// å
¥åºä»»å¡å®æ |
| | | /// è¾é线å¾
æ§è¡ |
| | | /// </summary> |
| | | [Description("å
¥åºä»»å¡å®æ")] |
| | | InFinish = 290, |
| | | [Description("è¾é线å¾
æ§è¡")] |
| | | Line_Execute = 400, |
| | | |
| | | /// <summary> |
| | | /// å
¥åºä»»å¡æèµ· |
| | | /// è¾é线çå¾
ç¡®è®¤ä¸ |
| | | /// </summary> |
| | | [Description("å
¥åºä»»å¡æèµ·")] |
| | | InPending = 297, |
| | | [Description("è¾é线çå¾
确认ä¸")] |
| | | Line_Waiting = 405, |
| | | |
| | | /// <summary> |
| | | /// å
¥åºä»»å¡åæ¶ |
| | | /// è¾é线æ§è¡ä¸ |
| | | /// </summary> |
| | | [Description("å
¥åºä»»å¡åæ¶")] |
| | | InCancel = 298, |
| | | [Description("è¾é线æ§è¡ä¸")] |
| | | Line_Executing = 410, |
| | | |
| | | /// <summary> |
| | | /// å
¥åºä»»å¡å¼å¸¸ |
| | | /// è¾éçº¿å®æ |
| | | /// </summary> |
| | | [Description("å
¥åºä»»å¡å¼å¸¸")] |
| | | InException = 299, |
| | | } |
| | | |
| | | public enum TaskOutStatusEnum |
| | | { |
| | | /// <summary> |
| | | /// æ°å»ºåºåºä»»å¡ |
| | | /// </summary> |
| | | [Description("æ°å»ºåºåºä»»å¡")] |
| | | OutNew = 100, |
| | | [Description("è¾éçº¿å®æ")] |
| | | Line_Finish = 420, |
| | | |
| | | /// <summary> |
| | | /// å åæºåºåºæ§è¡ä¸ |
| | | /// ä»»å¡å®æ |
| | | /// </summary> |
| | | [Description("å åæºåºåºæ§è¡ä¸")] |
| | | SC_OutExecuting = 110, |
| | | [Description("ä»»å¡å®æ")] |
| | | Finish = 900, |
| | | |
| | | /// <summary> |
| | | /// å åæºåºåºå®æ |
| | | /// ä»»å¡æèµ· |
| | | /// </summary> |
| | | [Description("å åæºåºåºå®æ")] |
| | | SC_OutFinish = 115, |
| | | [Description("ä»»å¡æèµ·")] |
| | | Pending = 970, |
| | | |
| | | /// <summary> |
| | | /// è¾é线åºåºæ§è¡ä¸ |
| | | /// ä»»å¡åæ¶ |
| | | /// </summary> |
| | | [Description("è¾é线åºåºæ§è¡ä¸")] |
| | | Line_OutExecuting = 120, |
| | | [Description("ä»»å¡åæ¶")] |
| | | Cancel = 980, |
| | | |
| | | /// <summary> |
| | | /// è¾é线åºåºå®æ |
| | | /// ä»»å¡å¼å¸¸ |
| | | /// </summary> |
| | | [Description("è¾é线è¾é宿")] |
| | | Line_OutFinish = 125, |
| | | |
| | | ///// <summary> |
| | | ///// AGVåºåºæ§è¡ä¸ |
| | | ///// </summary> |
| | | //[Description("AGVåºåºæ§è¡ä¸")] |
| | | //AGV_OutExecuting = 130, |
| | | |
| | | ///// <summary> |
| | | ///// AGVåºåºå®æ |
| | | ///// </summary> |
| | | //[Description("AGVæ¬è¿å®æ")] |
| | | //AGV_OutFinish = 135, |
| | | |
| | | /// <summary> |
| | | /// åºåºä»»å¡å®æ |
| | | /// </summary> |
| | | [Description("åºåºä»»å¡å®æ")] |
| | | OutFinish = 190, |
| | | |
| | | /// <summary> |
| | | /// åºåºä»»å¡æèµ· |
| | | /// </summary> |
| | | [Description("åºåºä»»å¡æèµ·")] |
| | | OutPending = 197, |
| | | |
| | | /// <summary> |
| | | /// åºåºä»»å¡åæ¶ |
| | | /// </summary> |
| | | [Description("åºåºä»»å¡åæ¶")] |
| | | OutCancel = 198, |
| | | |
| | | /// <summary> |
| | | /// åºåºä»»å¡å¼å¸¸ |
| | | /// </summary> |
| | | [Description("åºåºä»»å¡å¼å¸¸")] |
| | | OutException = 199, |
| | | } |
| | | |
| | | public enum TaskRobotStatusEnum |
| | | { |
| | | /// <summary> |
| | | /// æºæ¢°ææ°å»ºä»»å¡ |
| | | /// </summary> |
| | | [Description("æºæ¢°ææ°å»ºä»»å¡")] |
| | | RobotNew = 300, |
| | | |
| | | /// <summary> |
| | | /// æºæ¢°ææ§è¡ä¸ |
| | | /// </summary> |
| | | [Description("æºæ¢°ææ§è¡ä¸")] |
| | | RobotExecuting = 310, |
| | | |
| | | /// <summary> |
| | | /// æºæ¢°æå®æ |
| | | /// </summary> |
| | | [Description("æºæ¢°æå®æ")] |
| | | RobotFinish = 390, |
| | | |
| | | /// <summary> |
| | | /// æºæ¢°æä»»å¡æèµ· |
| | | /// </summary> |
| | | [Description("æºæ¢°æä»»å¡æèµ·")] |
| | | RobotPending = 397, |
| | | |
| | | /// <summary> |
| | | /// æºæ¢°æä»»å¡åæ¶ |
| | | /// </summary> |
| | | [Description("æºæ¢°æä»»å¡åæ¶")] |
| | | RobotCancel = 398, |
| | | |
| | | /// <summary> |
| | | /// æºæ¢°æä»»å¡å¼å¸¸ |
| | | /// </summary> |
| | | [Description("æºæ¢°æä»»å¡å¼å¸¸")] |
| | | RobotException = 399, |
| | | [Description("ä»»å¡å¼å¸¸")] |
| | | Exception = 990 |
| | | } |
| | | } |
| | |
| | | public List<int> TaskOutboundTypes { get; } |
| | | |
| | | /// <summary> |
| | | /// ææåºåºä»»å¡ç±»å |
| | | /// </summary> |
| | | public List<int> TaskRobotTypes { get; } |
| | | |
| | | /// <summary> |
| | | /// æ¥æ¶WMSä»»å¡ä¿¡æ¯ |
| | | /// </summary> |
| | | /// <param name="taskDTOs">WMSä»»å¡å¯¹è±¡éå</param> |
| | |
| | | /// <param name="nextAddress">ä¸ä¸å°å</param> |
| | | /// <returns></returns> |
| | | Dt_Task QueryExecutingConveyorLineTask(int taskNum, string nextAddress); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®ä»»å¡å·ãå½åå°åæ¥è¯¢è¾éçº¿å®æçä»»å¡ |
| | | /// </summary> |
| | | /// <param name="taskNum">ä»»å¡å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns></returns> |
| | | Dt_Task QueryCompletedConveyorLineTask(int taskNum, string currentAddress); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãä»»å¡ç±»ååç»(å¯é)æç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± æ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="taskTypeGroup">ä»»å¡ç±»ååç»(å¯é)</param> |
| | | /// <returns></returns> |
| | | Dt_Task? QuertStackerCraneTask(string deviceNo, TaskTypeGroup? taskTypeGroup = null); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± æ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | Dt_Task QueryStackerCraneTask(string deviceNo, string currentAddress = ""); |
| | | |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± æ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | Dt_Task QueryRobotCraneTask(string deviceNo,string currentAddress = ""); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± å
¥åºç±»åçæ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | Dt_Task QueryStackerCraneInTask(string deviceNo, string currentAddress = ""); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± åºåºç±»åçæ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | Dt_Task QueryStackerCraneOutTask(string deviceNo, string currentAddress = ""); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± åºåºç±»åçæ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="outStationCodes">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡éåï¼å¯è½ä¸ºnull</returns> |
| | | List<Dt_Task> QueryStackerCraneOutTasks(string deviceNo, List<string> outStationCodes); |
| | | |
| | | /// <summary> |
| | | /// æ´æ°ä»»å¡å¼å¸¸ä¿¡æ¯æ¾ç¤º |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEAWCS_Core.DB.Models; |
| | | |
| | | namespace WIDESEAWCS_Model.Models |
| | | { |
| | | [SugarTable(nameof(Dt_ApiInfo), "æ¥å£ä¿¡æ¯")] |
| | | public class Dt_ApiInfo : BaseEntity |
| | | { |
| | | /// <summary> |
| | | /// ä¸»é® |
| | | /// </summary> |
| | | [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主é®")] |
| | | public int Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æ¥å£ç¼å· |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "æ¥å£ç¼å·")] |
| | | public string ApiCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æ¥å£åç§° |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "æ¥å£åç§°")] |
| | | public string ApiName { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æ¥å£å°å |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, Length = 200, ColumnDescription = "æ¥å£å°å")] |
| | | public string ApiAddress { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 夿³¨ |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "夿³¨")] |
| | | public string Remark { get; set; } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using WIDESEAWCS_Core.DB.Models; |
| | | |
| | | namespace WIDESEAWCS_Model.Models |
| | | { |
| | | [SugarTable(nameof(Dt_StationManger), "ç«å°è¡¨")] |
| | | public class Dt_StationManger : BaseEntity |
| | | { |
| | | /// <summary> |
| | | /// ä¸»é® |
| | | /// </summary> |
| | | [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主é®")] |
| | | public int Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// ç«å°ç¼å· |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "ç«å°ç¼å·")] |
| | | public string StationCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// ç«å°åç§° |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "ç«å°åç§°")] |
| | | public string StationName { get; set; } |
| | | |
| | | /// <summary> |
| | | /// ç«å°ç±»å <br/> |
| | | /// 1ï¼åªå
¥ <br/> |
| | | /// 2ï¼åªåº <br/> |
| | | /// 3ï¼å¯å
¥å¯åº |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, ColumnDescription = "ç«å°ç±»å")] |
| | | public int StationType { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 对åºå åæºæ-å-å± |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "对åºå åæºæ-å-å±")] |
| | | public string StackerCraneStationCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// ç«å°è®¾å¤ç¼å· |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "ç«å°è®¾å¤ç¼å·")] |
| | | public string StationDeviceCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// å åæºç¼å· |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "å åæºç¼å·")] |
| | | public string StackerCraneCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// AGVç«å°ç¼å· |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "AGVç«å°ç¼å·")] |
| | | public string? AGVStationCode { get; set; } |
| | | /// <summary> |
| | | /// AGVç«å°åæ¾é«åº¦ |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, ColumnDescription = "AGVç«å°åæ¾é«åº¦")] |
| | | public decimal AGVStationHeight { get; set; } |
| | | /// <summary> |
| | | /// AGVåç½®ç¹ |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "AGVåç½®ç¹")] |
| | | public string? AGVFrontCode { get; set; } |
| | | /// <summary> |
| | | /// ç«å°æ¯å¦å¯ç¨ <br/> |
| | | /// 0ï¼å¯ç¨ <br/> |
| | | /// 1ï¼å ç¨ <br/> |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = false, ColumnDescription = "ç«å°æ¯å¦å¯ç¨")] |
| | | public int IsOccupied { get; set; } |
| | | |
| | | /// <summary> |
| | | /// ç«å°æ¯å¦å¯ç¨ <br/> |
| | | /// 0ï¼å¯ç¨ <br/> |
| | | /// 1ï¼å ç¨ <br/> |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, ColumnDescription = "ç«å°æ¯å¦å¯ç¨")] |
| | | public int IsManual { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 夿³¨ |
| | | /// </summary> |
| | | [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "夿³¨")] |
| | | public string Remark { get; set; } |
| | | } |
| | | } |
| | |
| | | <ProjectReference Include="..\WIDESEAWCS_Core\WIDESEAWCS_Core.csproj" /> |
| | | </ItemGroup> |
| | | |
| | | <ItemGroup> |
| | | <Folder Include="Models\BasicInfo\" /> |
| | | </ItemGroup> |
| | | |
| | | </Project> |
| | |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_QuartzJob.DTO; |
| | | using WIDESEAWCS_QuartzJob.Models; |
| | | using WIDESEAWCS_QuartzJob.Service; |
| | | |
| | | namespace WIDESEAWCS_QuartzJob.QuartzNet |
| | |
| | | List<DispatchInfoDTO> dispatches = _dispatchInfoService.QueryDispatchInfos(); |
| | | List<DeviceInfoDTO> deviceInfos = await _deviceInfoService.QueryDeviceProInfos(); |
| | | |
| | | deviceInfos.ForEach(x => |
| | | deviceInfos.ForEach(delegate (DeviceInfoDTO x) |
| | | { |
| | | if (!Storage.Devices.Exists(d => d.DeviceCode == x.DeviceCode)) |
| | | DeviceInfoDTO x2 = x; |
| | | if (!Storage.Devices.Exists((IDevice d) => d.DeviceCode == x2.DeviceCode) && !x.DeviceName.Contains("å åæº")) |
| | | { |
| | | try |
| | | { |
| | | if (!x.DeviceName.Contains("å åæº")) |
| | | Type type = Assembly.Load("WIDESEAWCS_Communicator").GetType("WIDESEAWCS_Communicator." + x2.DevicePlcType); |
| | | object obj = Activator.CreateInstance(type, x2.DeviceIp, x2.DevicePort, x2.DeviceName); |
| | | if (new bool?((bool)type.InvokeMember("Connect", BindingFlags.InvokeMethod, null, obj, new object[0])).GetValueOrDefault()) |
| | | { |
| | | #region è¿æ¥PLC |
| | | |
| | | // å è½½ç¨åºé |
| | | Assembly assembly = Assembly.Load($"WIDESEAWCS_Communicator"); |
| | | // è·åç±»å |
| | | Type? type = assembly.GetType($"WIDESEAWCS_Communicator.{x.DevicePlcType}"); |
| | | // å建å®ä¾ |
| | | object? obj = Activator.CreateInstance(type, new object[] { x.DeviceIp, x.DevicePort, x.DeviceName }); |
| | | // è°ç¨è¿æ¥æ¹æ³ |
| | | bool? connectResult = (bool)type.InvokeMember("Connect", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, new object[] { }); |
| | | // å¤æè¿æ¥ç»æ |
| | | if (connectResult ?? false) ConsoleHelper.WriteSuccessLine(type.Name + x.DeviceCode + "è¿æ¥æå"); else ConsoleHelper.WriteErrorLine(type.Name + x.DeviceCode + "è¿æ¥å¤±è´¥"); |
| | | |
| | | #endregion è¿æ¥PLC |
| | | |
| | | #region å®ä¾å设å¤å¯¹è±¡ |
| | | |
| | | List<DeviceProDTO> devicePros = x.ProtocolList.Select(d => new DeviceProDTO |
| | | { |
| | | // 设å¤åç¼ç |
| | | DeviceChildCode = d.DeviceChildCode, |
| | | // è®¾å¤æ°æ®ç±»å |
| | | DeviceDataType = d.DeviceProDataType, |
| | | // 设å¤ID |
| | | DeviceId = d.DeviceId, |
| | | // 设å¤åè®®ID |
| | | DeviceProId = d.Id, |
| | | // 设å¤åè®®æ°æ®å |
| | | DeviceProDataBlock = d.DeviceProDataBlock, |
| | | // 设å¤åè®®æ°æ®é¿åº¦ |
| | | DeviceProDataLength = d.DeviceProDataLength, |
| | | // 设å¤åè®®åç§»é |
| | | DeviceProOffset = d.DeviceProOffset, |
| | | // 设å¤åè®®åæ°æè¿° |
| | | DeviceProParamDes = d.DeviceProParamDes, |
| | | // 设å¤åè®®åæ°åç§° |
| | | DeviceProParamName = d.DeviceProParamName, |
| | | // 设å¤åè®®åæ°ç±»å |
| | | DeviceProParamType = d.DeviceProParamType, |
| | | // 设å¤PLCç±»å |
| | | DevicePlcType = x.DevicePlcType |
| | | }).ToList(); |
| | | |
| | | // æ ¹æ®è®¾å¤ç±»åè·å设å¤å议详æ
|
| | | List<DeviceProtocolDetailDTO> deviceProtocolDetails = _deviceProtocolDetailService.GetDeviceProtocolDetailsByDeviceType(x.DeviceType); |
| | | |
| | | // å 载设å¤ç¨åºé |
| | | Assembly assemblyDevice = Assembly.Load($"WIDESEAWCS_QuartzJob"); |
| | | // è·å设å¤ç±»å对åºçç±»å |
| | | Type typeDevice = assemblyDevice.GetType($"WIDESEAWCS_QuartzJob.{x.DeviceType}"); |
| | | // å建设å¤å®ä¾ |
| | | object deviceInstance = Activator.CreateInstance(typeDevice, new object[] { obj, devicePros, deviceProtocolDetails, x.DeviceCode, x.DeviceName }); |
| | | |
| | | #endregion å®ä¾å设å¤å¯¹è±¡ |
| | | |
| | | x.Device = (IDevice)deviceInstance; |
| | | |
| | | Storage.Devices.Add((IDevice)deviceInstance); |
| | | (type.Name + x2.DeviceCode + "è¿æ¥æå").WriteSuccessLine(); |
| | | } |
| | | else |
| | | { |
| | | (type.Name + x2.DeviceCode + "è¿æ¥å¤±è´¥").WriteErrorLine(); |
| | | } |
| | | |
| | | List<DeviceProDTO> list = x2.ProtocolList.Select((Dt_DeviceProtocol d) => new DeviceProDTO |
| | | { |
| | | DeviceChildCode = d.DeviceChildCode, |
| | | DeviceDataType = d.DeviceProDataType, |
| | | DeviceId = d.DeviceId, |
| | | DeviceProId = d.Id, |
| | | DeviceProDataBlock = d.DeviceProDataBlock, |
| | | DeviceProDataLength = d.DeviceProDataLength, |
| | | DeviceProOffset = d.DeviceProOffset, |
| | | DeviceProParamDes = d.DeviceProParamDes, |
| | | DeviceProParamName = d.DeviceProParamName, |
| | | DeviceProParamType = d.DeviceProParamType, |
| | | DevicePlcType = x2.DevicePlcType |
| | | }).ToList(); |
| | | List<DeviceProtocolDetailDTO> deviceProtocolDetailsByDeviceType = _deviceProtocolDetailService.GetDeviceProtocolDetailsByDeviceType(x2.DeviceType); |
| | | object obj2 = Activator.CreateInstance(Assembly.Load("WIDESEAWCS_QuartzJob").GetType("WIDESEAWCS_QuartzJob." + x2.DeviceType), obj, list, deviceProtocolDetailsByDeviceType, x2.DeviceCode, x2.DeviceName); |
| | | x2.Device = (IDevice)obj2; |
| | | Storage.Devices.Add((IDevice)obj2); |
| | | } |
| | | catch (Exception ex) |
| | | catch (Exception ex2) |
| | | { |
| | | Console.WriteLine("è°åº¦æå¡å¼å¯å¼å¸¸" + ex.ToString()); |
| | | Console.WriteLine("è°åº¦æå¡å¼å¯å¼å¸¸" + ex2.ToString()); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | x.Device = Storage.Devices.FirstOrDefault(d => d.DeviceCode == x.DeviceCode); |
| | | x2.Device = Storage.Devices.FirstOrDefault((IDevice d) => d.DeviceCode == x2.DeviceCode); |
| | | } |
| | | }); |
| | | for (int i = 0; i < dispatches.Count; i++) |
| | | { |
| | | var targetDevice = deviceInfos.FirstOrDefault(x => x.Id == dispatches[i].Id); |
| | | |
| | | if (targetDevice is null) continue; |
| | | |
| | | // ä½¿ç¨æ¨¡å¼å¹é
|
| | | dispatches[i].JobParams = targetDevice switch |
| | | { |
| | | { DeviceName: var name } when name.Contains("å åæº") |
| | | => new RobotCraneDevice { DeviceCode = targetDevice.DeviceCode, DeviceName = targetDevice.DeviceName, IPAddress = targetDevice.DeviceIp + ":" + targetDevice.DevicePort }, |
| | | => new StackerCraneDevice { DeviceCode = targetDevice.DeviceCode, DeviceName = targetDevice.DeviceName, IPAddress = targetDevice.DeviceIp + ":" + targetDevice.DevicePort }, |
| | | _ => targetDevice.Device |
| | | }; |
| | | WebResponseContent responseContent = await _schedulerCenter.AddScheduleJobAsync(dispatches[i]); |
| ÎļþÃû´Ó ´úÂë¹ÜÀí/WCS/WCSServers/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs ÐÞ¸Ä |
| | |
| | | |
| | | namespace WIDESEAWCS_QuartzJob |
| | | { |
| | | public class RobotCraneDevice |
| | | public class StackerCraneDevice |
| | | { |
| | | public string Device { get; set; } |
| | | public string DeviceCode { get; set; } |
| | |
| | | Creater = a.Creater, |
| | | CycleHasRunTimes = 0, |
| | | EndTime = a.EndTime, |
| | | Id = a.Id, |
| | | Id = b.Id, |
| | | IntervalSecond = a.IntervalSecond, |
| | | Modifier = a.Modifier, |
| | | ModifyDate = a.ModifyDate, |
| | |
| | | #region è·å设å¤ç¼å· |
| | | object deviceCodes = _deviceProtocolRepository.QueryData(x => true).GroupBy(x => x.DeviceChildCode).Select(x => new { key = x.Key, value = x.Key }).ToList(); |
| | | |
| | | object areaInfos = Enum.GetNames(typeof(AreaInfo)).Select(x => new { key = x, value = x }).ToList(); |
| | | |
| | | |
| | | #endregion |
| | | |
| | | return WebResponseContent.Instance.OK(data: new { routerTypes, deviceCodes, areaInfos }); |
| | | return WebResponseContent.Instance.OK(data: new { routerTypes, deviceCodes}); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | } |
| | | #endregion |
| | | |
| | | #region TaskOtherTypeEnum |
| | | { |
| | | Type type = typeof(TaskOtherTypeEnum); |
| | | List<int> enums = Enum.GetValues(typeof(TaskOtherTypeEnum)).Cast<int>().ToList(); |
| | | int index = 0; |
| | | foreach (var item in enums) |
| | | { |
| | | FieldInfo? fieldInfo = typeof(TaskOtherTypeEnum).GetField(((TaskOtherTypeEnum)item).ToString()); |
| | | DescriptionAttribute? description = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | if (description != null) |
| | | { |
| | | data.Add(new { key = item.ToString(), value = description.Description }); |
| | | } |
| | | else |
| | | { |
| | | data.Add(new { key = item.ToString(), value = item.ToString() }); |
| | | } |
| | | index++; |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | result = new VueDictionaryDTO { DicNo = key, Config = "", Data = data }; |
| | | } |
| | | break; |
| | |
| | | |
| | | #region TaskInStatusEnum |
| | | { |
| | | Type type = typeof(TaskInStatusEnum); |
| | | List<int> enums = Enum.GetValues(typeof(TaskInStatusEnum)).Cast<int>().ToList(); |
| | | Type type = typeof(TaskStatusEnum); |
| | | List<int> enums = Enum.GetValues(typeof(TaskStatusEnum)).Cast<int>().ToList(); |
| | | int index = 0; |
| | | foreach (var item in enums) |
| | | { |
| | | FieldInfo? fieldInfo = typeof(TaskInStatusEnum).GetField(((TaskInStatusEnum)item).ToString()); |
| | | FieldInfo? fieldInfo = typeof(TaskStatusEnum).GetField(((TaskStatusEnum)item).ToString()); |
| | | DescriptionAttribute? description = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | if (description != null) |
| | | { |
| | |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | #region TaskOutStatusEnum |
| | | { |
| | | Type type = typeof(TaskOutStatusEnum); |
| | | List<int> enums = Enum.GetValues(typeof(TaskOutStatusEnum)).Cast<int>().ToList(); |
| | | int index = 0; |
| | | foreach (var item in enums) |
| | | { |
| | | FieldInfo? fieldInfo = typeof(TaskOutStatusEnum).GetField(((TaskOutStatusEnum)item).ToString()); |
| | | DescriptionAttribute? description = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | if (description != null) |
| | | { |
| | | data.Add(new { key = item.ToString(), value = description.Description }); |
| | | } |
| | | else |
| | | { |
| | | data.Add(new { key = item.ToString(), value = item.ToString() }); |
| | | } |
| | | index++; |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | result = new VueDictionaryDTO { DicNo = key, Config = "", Data = data }; |
| | | } |
| | | break; |
| | |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob.DTO; |
| | | using WIDESEAWCS_QuartzJob.Models; |
| | | using WIDESEAWCS_Tasks.ConveyorLineJob; |
| | | |
| | | namespace WIDESEAWCS_WCSServer.Filter |
| | | { |
| | |
| | | CreateMap<Sys_Menu, MenuDTO>(); |
| | | CreateMap<Dt_DeviceInfo,DeviceInfoDTO>(); |
| | | CreateMap<WMSTaskDTO, Dt_Task>(); |
| | | CreateMap<Dt_Task, ConveyorLineTaskCommand>().ForMember(a => a.TargetAddress, b => b.MapFrom(b => b.NextAddress)).ForMember(a => a.Barcode, b => b.MapFrom(b => b.PalletCode)).ForMember(a => a.TaskNum, b => b.MapFrom(b => b.TaskNum)); |
| | | } |
| | | } |
| | | } |
| | |
| | | //5.PostgreSQL |
| | | "DBType": "SqlServer", |
| | | //è¿æ¥å符串 |
| | | "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", |
| | | |
| | | "ConnectionString": "Data Source=.;Initial Catalog=WCS_FengLv;User ID=sa;Password=123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", |
| | | //è·¨å |
| | | "Cors": { |
| | | "PolicyName": "CorsIpAccess", //çç¥åç§° |
| | |
| | | "ApiName": "WIDESEAWCS", |
| | | "ExpMinutes": 120, |
| | | "QuartzJobAutoStart": true, |
| | | "DBSeedEnable": false, |
| | | "DBSeedEnable": true, |
| | | "QuartzDBSeedEnable": true, |
| | | "LogDeubgEnable": false, //æ¯å¦è®°å½è°è¯æ¥å¿ |
| | | "PrintSql": true, //æå°SQLè¯å¥ |
| | | "PrintSql": false, //æå°SQLè¯å¥ |
| | | "LogAOPEnable": true, //æ¯å¦è®°å½AOPæ¥å¿ |
| | | "WebSocketEnable": true, //æ¯å¦å¼å¯WebSocketæå¡ |
| | | "WebSocketPort": 9296, //WebSocketæå¡ç«¯å£ |
| | | "WebSocketEnable": false, //æ¯å¦å¼å¯WebSocketæå¡ |
| | | "WebSocketPort": 9260, //WebSocketæå¡ç«¯å£ |
| | | "SocketServer": { |
| | | "Enabled": true, |
| | | "Port": 2000, |
| | | "IpAddress": "0.0.0.0", |
| | | "Port": 9298, |
| | | "IpAddress": "192.168.0.237", |
| | | "Backlog": 100, |
| | | "EncodingName": "utf-8", |
| | | "AutoDetectEncoding": true, |
| | |
| | | // è·åä»»å¡ç¶æ |
| | | int taskState = task.TaskState; |
| | | |
| | | // å°è¯å°ä»»å¡ç¶æè½¬æ¢ä¸ºTaskOutStatusEnumæä¸¾ç±»å |
| | | if (!int.TryParse(Enum.Parse<TaskOutStatusEnum>(taskState.ToString()).ToString(), out int result)) |
| | | { |
| | | // å¦æè½¬æ¢å¤±è´¥ï¼åå°ä»»å¡ç¶æè½¬æ¢ä¸ºTaskInStatusEnumæä¸¾ç±»å |
| | | if (!int.TryParse(Enum.Parse<TaskInStatusEnum>(taskState.ToString()).ToString(), out result)) |
| | | { |
| | | // å¦æè½¬æ¢å¤±è´¥ï¼åå°isNormal设置为false |
| | | isNormal = false; |
| | | } |
| | | } |
| | | // å¦æè½¬æ¢æåï¼å夿任å¡ç¶ææ¯å¦å¤§äºOutFinish |
| | | else if ((int)(TaskOutStatusEnum)result > (int)TaskOutStatusEnum.OutFinish) |
| | | { |
| | | // 妿大äºï¼åå°isNormal设置为false |
| | | isNormal = false; |
| | | } |
| | | // åå»ºä»»å¡æ§è¡è¯¦æ
对象 |
| | | Dt_TaskExecuteDetail taskExecuteDetail = new() |
| | | { |
| | |
| | | int taskNum = task.TaskNum; |
| | | int taskState = task.TaskState; |
| | | |
| | | if (!int.TryParse(Enum.Parse<TaskOutStatusEnum>(taskState.ToString()).ToString(), out int result)) |
| | | { |
| | | if ((int)(TaskOutStatusEnum)result > (int)TaskOutStatusEnum.OutFinish) |
| | | isNormal = false; |
| | | } |
| | | else if (!int.TryParse(Enum.Parse<TaskInStatusEnum>(taskState.ToString()).ToString(), out result)) |
| | | { |
| | | if ((int)(TaskInStatusEnum)result > (int)TaskInStatusEnum.InFinish) |
| | | isNormal = false; |
| | | } |
| | | Dt_TaskExecuteDetail taskExecuteDetail = new() |
| | | { |
| | | IsManual = App.User.UserId > 0, |
| | |
| | | if (task != null) |
| | | { |
| | | |
| | | if (!int.TryParse(Enum.Parse<TaskOutboundTypeEnum>(task.TaskType.ToString()).ToString(), out int result)) |
| | | { |
| | | steps = Enum.GetValues(typeof(TaskOutStatusEnum)).Cast<int>().Where(x => x <= (int)TaskOutStatusEnum.OutFinish).ToList(); |
| | | //if (!int.TryParse(Enum.Parse<TaskOutboundTypeEnum>(task.TaskType.ToString()).ToString(), out int result)) |
| | | //{ |
| | | // steps = Enum.GetValues(typeof(TaskOutStatusEnum)).Cast<int>().Where(x => x <= (int)TaskOutStatusEnum.OutFinish).ToList(); |
| | | |
| | | foreach (var item in steps) |
| | | { |
| | | object obj; |
| | | FieldInfo? fieldInfo = typeof(TaskOutStatusEnum).GetField(((TaskOutStatusEnum)item).ToString()); |
| | | DescriptionAttribute? descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | if (descriptionAttribute != null) |
| | | { |
| | | obj = new { title = item, description = descriptionAttribute.Description }; |
| | | } |
| | | else |
| | | { |
| | | obj = new { title = item, description = ((TaskOutStatusEnum)item).ToString() }; |
| | | } |
| | | list.Add(obj); |
| | | } |
| | | } |
| | | else if (!int.TryParse(Enum.Parse<TaskInboundTypeEnum>(task.TaskType.ToString()).ToString(), out result)) |
| | | { |
| | | steps = Enum.GetValues(typeof(TaskInStatusEnum)).Cast<int>().Where(x => x <= (int)TaskInStatusEnum.InFinish).ToList(); |
| | | foreach (var item in steps) |
| | | { |
| | | object obj; |
| | | FieldInfo? fieldInfo = typeof(TaskInStatusEnum).GetField(((TaskInStatusEnum)item).ToString()); |
| | | DescriptionAttribute? descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | if (descriptionAttribute != null) |
| | | { |
| | | obj = new { title = item, description = descriptionAttribute.Description }; |
| | | } |
| | | else |
| | | { |
| | | obj = new { title = item, description = ((TaskInStatusEnum)item).ToString() }; |
| | | } |
| | | list.Add(obj); |
| | | } |
| | | } |
| | | else if (!int.TryParse(Enum.Parse<TaskRelocationTypeEnum>(task.TaskType.ToString()).ToString(), out result)) |
| | | { |
| | | //todo è°ç¨WMSç§»åºå®æ |
| | | } |
| | | else if (!int.TryParse(Enum.Parse<TaskOtherTypeEnum>(task.TaskType.ToString()).ToString(), out result)) |
| | | { |
| | | // foreach (var item in steps) |
| | | // { |
| | | // object obj; |
| | | // FieldInfo? fieldInfo = typeof(TaskOutStatusEnum).GetField(((TaskOutStatusEnum)item).ToString()); |
| | | // DescriptionAttribute? descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | // if (descriptionAttribute != null) |
| | | // { |
| | | // obj = new { title = item, description = descriptionAttribute.Description }; |
| | | // } |
| | | // else |
| | | // { |
| | | // obj = new { title = item, description = ((TaskOutStatusEnum)item).ToString() }; |
| | | // } |
| | | // list.Add(obj); |
| | | // } |
| | | //} |
| | | //else if (!int.TryParse(Enum.Parse<TaskInboundTypeEnum>(task.TaskType.ToString()).ToString(), out result)) |
| | | //{ |
| | | // steps = Enum.GetValues(typeof(TaskInStatusEnum)).Cast<int>().Where(x => x <= (int)TaskInStatusEnum.InFinish).ToList(); |
| | | // foreach (var item in steps) |
| | | // { |
| | | // object obj; |
| | | // FieldInfo? fieldInfo = typeof(TaskInStatusEnum).GetField(((TaskInStatusEnum)item).ToString()); |
| | | // DescriptionAttribute? descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>(); |
| | | // if (descriptionAttribute != null) |
| | | // { |
| | | // obj = new { title = item, description = descriptionAttribute.Description }; |
| | | // } |
| | | // else |
| | | // { |
| | | // obj = new { title = item, description = ((TaskInStatusEnum)item).ToString() }; |
| | | // } |
| | | // list.Add(obj); |
| | | // } |
| | | //} |
| | | //else if (!int.TryParse(Enum.Parse<TaskRelocationTypeEnum>(task.TaskType.ToString()).ToString(), out result)) |
| | | //{ |
| | | // //todo è°ç¨WMSç§»åºå®æ |
| | | //} |
| | | //else if (!int.TryParse(Enum.Parse<TaskOtherTypeEnum>(task.TaskType.ToString()).ToString(), out result)) |
| | | //{ |
| | | |
| | | } |
| | | else |
| | | { |
| | | throw new Exception($"ä»»å¡ç±»åé误,æªæ¾å°è¯¥ä»»å¡ç±»å,ä»»å¡å·:ã{taskNum}ã,ä»»å¡ç±»å:ã{task.TaskType}ã"); |
| | | } |
| | | //} |
| | | //else |
| | | //{ |
| | | // throw new Exception($"ä»»å¡ç±»åé误,æªæ¾å°è¯¥ä»»å¡ç±»å,ä»»å¡å·:ã{taskNum}ã,ä»»å¡ç±»å:ã{task.TaskType}ã"); |
| | | //} |
| | | active = steps.IndexOf(task.TaskState) + 1; |
| | | |
| | | } |
| | |
| | | |
| | | public List<int> TaskOutboundTypes => typeof(TaskOutboundTypeEnum).GetEnumIndexList(); |
| | | |
| | | public List<int> TaskRobotTypes => typeof(TaskOtherTypeEnum).GetEnumIndexList(); |
| | | |
| | | public TaskService(ITaskRepository BaseDal, IRouterService routerService, ITaskExecuteDetailService taskExecuteDetailService, ITaskExecuteDetailRepository taskExecuteDetailRepository, IMapper mapper) : base(BaseDal) |
| | | { |
| | | _routerService = routerService; |
| | |
| | | } |
| | | Dt_Task task = _mapper.Map<Dt_Task>(item); |
| | | task.Creater = "WMS"; |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)//åºåº |
| | | { |
| | | List<Dt_Router> routers = _routerService.QueryNextRoutes(item.RoadWay, item.TargetAddress); |
| | | //æä¸èèå¤è·¯å¾ |
| | | if (routers.Count > 0) |
| | | { |
| | | task.TaskState = (int)TaskOutStatusEnum.OutNew; |
| | | task.TaskState = (int)TaskStatusEnum.New; |
| | | task.CurrentAddress = item.SourceAddress; |
| | | task.NextAddress = routers.FirstOrDefault().ChildPosi; |
| | | } |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//å
¥åº |
| | | { |
| | | List<Dt_Router> routers = _routerService.QueryNextRoutes(item.SourceAddress, item.TargetAddress); |
| | | //æä¸èèå¤è·¯å¾ |
| | | if (routers.Count > 0) |
| | | { |
| | | task.TaskState = (int)TaskInStatusEnum.InNew; |
| | | task.TaskState = (int)TaskStatusEnum.New; |
| | | task.CurrentAddress = item.SourceAddress; |
| | | task.NextAddress = routers.FirstOrDefault().ChildPosi; |
| | | } |
| | |
| | | WebResponseContent content = new WebResponseContent(); |
| | | try |
| | | { |
| | | WMSTaskDTO taskDTO = new WMSTaskDTO() |
| | | { |
| | | TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")), |
| | | Grade = 1, |
| | | PalletCode = palletCode, |
| | | RoadWay = "SC01", |
| | | SourceAddress = sourceAddress, |
| | | TargetAddress = "SC01", |
| | | TaskState = (int)TaskInStatusEnum.InNew, |
| | | Id = 0, |
| | | TaskType = (int)TaskInboundTypeEnum.Inbound |
| | | }; |
| | | //åWMS请æ±ä»»å¡ |
| | | WMSTaskDTO taskDTO = new WMSTaskDTO(); |
| | | |
| | | content = ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO }); |
| | | } |
| | |
| | | /// <returns></returns> |
| | | public Dt_Task QueryConveyorLineTask(string deviceNo, string currentAddress) |
| | | { |
| | | return BaseDal.QueryFirst(x => (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.InNew || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.SC_OutFinish) && x.CurrentAddress == currentAddress, TaskOrderBy); |
| | | return BaseDal.QueryFirst(x => (TaskInboundTypes.Contains(x.TaskType) || TaskOutboundTypes.Contains(x.TaskType)) && x.TaskState == (int)TaskStatusEnum.Line_Execute && x.CurrentAddress == currentAddress, TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <returns></returns> |
| | | public Dt_Task QueryExecutingConveyorLineTask(int taskNum, string nextAddress) |
| | | { |
| | | return BaseDal.QueryFirst(x => x.TaskNum == taskNum && x.NextAddress == nextAddress && (x.TaskState == (int)TaskInStatusEnum.Line_InExecuting || x.TaskState == (int)TaskOutStatusEnum.Line_OutExecuting), TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®ä»»å¡å·ãå½åå°åæ¥è¯¢è¾éçº¿å®æçä»»å¡ |
| | | /// </summary> |
| | | /// <param name="taskNum">ä»»å¡å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns></returns> |
| | | public Dt_Task QueryCompletedConveyorLineTask(int taskNum, string currentAddress) |
| | | { |
| | | return BaseDal.QueryFirst(x => x.TaskNum == taskNum && x.CurrentAddress == currentAddress && (x.TaskState == (int)TaskInStatusEnum.Line_InFinish || x.TaskState == (int)TaskOutStatusEnum.Line_OutFinish), TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãä»»å¡ç±»ååç»(å¯é)æç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± æ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="taskTypeGroup">ä»»å¡ç±»ååç»(å¯é)</param> |
| | | /// <returns></returns> |
| | | public Dt_Task? QuertStackerCraneTask(string deviceNo, TaskTypeGroup? taskTypeGroup = null) |
| | | { |
| | | if (taskTypeGroup == null) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); |
| | | if (taskTypeGroup.Value == TaskTypeGroup.InboundGroup) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish, TaskOrderBy); |
| | | if (taskTypeGroup.Value == TaskTypeGroup.OutbondGroup) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew, TaskOrderBy); |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± æ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | public Dt_Task QueryStackerCraneTask(string deviceNo, string currentAddress = "") |
| | | { |
| | | if (string.IsNullOrEmpty(currentAddress)) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); |
| | | else |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && x.CurrentAddress == currentAddress && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± å
¥åºç±»åçæ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | public Dt_Task QueryStackerCraneInTask(string deviceNo, string currentAddress = "") |
| | | { |
| | | if (string.IsNullOrEmpty(currentAddress)) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish, TaskOrderBy); |
| | | else |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish && x.CurrentAddress == currentAddress, TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± åºåºç±»åçæ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | public Dt_Task QueryStackerCraneOutTask(string deviceNo, string currentAddress = "") |
| | | { |
| | | if (string.IsNullOrEmpty(currentAddress)) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew, TaskOrderBy); |
| | | else |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew && x.CurrentAddress == currentAddress, TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± åºåºç±»åçæ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡éåï¼å¯è½ä¸ºnull</returns> |
| | | public List<Dt_Task> QueryStackerCraneOutTasks(string deviceNo, List<string> outStationCodes) |
| | | { |
| | | return BaseDal.QueryData(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew && outStationCodes.Contains(x.CurrentAddress), TaskOrderBy); |
| | | return BaseDal.QueryFirst(x => x.TaskNum == taskNum && x.NextAddress == nextAddress && x.TaskState == (int)TaskStatusEnum.Line_Executing, TaskOrderBy); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); |
| | | if (task == null) return WebResponseContent.Instance.Error($"æªæ¾å°è¯¥ä»»å¡ä¿¡æ¯,ä»»å¡å·:ã{taskNum}ã"); |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) |
| | | { |
| | | task.TaskState = (int)TaskOutStatusEnum.OutPending; |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) |
| | | { |
| | | task.TaskState = (int)TaskInStatusEnum.InPending; |
| | | } |
| | | task.TaskState = (int)TaskStatusEnum.Pending; |
| | | task.ExceptionMessage = message; |
| | | task.ModifyDate = DateTime.Now; |
| | | BaseDal.UpdateData(task); |
| | |
| | | try |
| | | { |
| | | int oldState = task.TaskState; |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup || task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) |
| | | { |
| | | if (task.TaskState >= (int)TaskOutStatusEnum.OutFinish) |
| | | { |
| | | return content = WebResponseContent.Instance.Error($"该任å¡ç¶æä¸å¯è·³è½¬å°ä¸ä¸æ¥,ä»»å¡å·:ã{task.TaskNum}ã,ä»»å¡ç¶æ:ã{task.TaskState}ã"); |
| | | } |
| | | |
| | | int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskOutStatusEnum>(); |
| | | |
| | | task.TaskState = nextStatus; |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) |
| | | { |
| | | if (task.TaskState >= (int)TaskInStatusEnum.InFinish) |
| | | { |
| | | return content = WebResponseContent.Instance.Error($"该任å¡ç¶æä¸å¯è·³è½¬å°ä¸ä¸æ¥,ä»»å¡å·:ã{task.TaskNum}ã,ä»»å¡ç¶æ:ã{task.TaskState}ã"); |
| | | } |
| | | |
| | | int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>(); |
| | | task.TaskState = nextStatus; |
| | | |
| | | if (task.TaskState == (int)TaskInStatusEnum.Line_InFinish) |
| | | { |
| | | Random random = new Random(); |
| | | task.CurrentAddress = task.NextAddress; |
| | | task.NextAddress = $"{random.Next(1, 100).ToString().PadLeft(3, '0')}-{random.Next(1, 100).ToString().PadLeft(3, '0')}-{random.Next(1, 100).ToString().PadLeft(3, '0')}"; |
| | | task.TargetAddress = task.NextAddress; |
| | | } |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OtherGroup) |
| | | { |
| | | if (task.TaskState >= (int)TaskRobotStatusEnum.RobotNew) |
| | | { |
| | | return content = WebResponseContent.Instance.Error($"该任å¡ç¶æä¸å¯è·³è½¬å°ä¸ä¸æ¥,ä»»å¡å·:ã{task.TaskNum}ã,ä»»å¡ç¶æ:ã{task.TaskState}ã"); |
| | | } |
| | | |
| | | int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskRobotStatusEnum>(); |
| | | |
| | | int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskStatusEnum>(); |
| | | task.TaskState = nextStatus; |
| | | } |
| | | else |
| | |
| | | Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); |
| | | if (task == null) return WebResponseContent.Instance.Error($"æªæ¾å°è¯¥ä»»å¡ä¿¡æ¯,ä»»å¡å·:ã{taskNum}ã"); |
| | | |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup && task.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting) |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup && task.TaskState == (int)TaskStatusEnum.SC_Executing) |
| | | { |
| | | List<Dt_Router> routers = _routerService.QueryNextRoutes(task.NextAddress, task.TargetAddress); |
| | | if (!routers.Any()) return WebResponseContent.Instance.Error($"æªæ¾å°è®¾å¤è·¯ç±ä¿¡æ¯"); |
| | | |
| | | int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskOutStatusEnum>(); |
| | | task.TaskState = nextStatus; |
| | | task.TaskState = (int)TaskStatusEnum.SC_Finish; |
| | | task.CurrentAddress = task.NextAddress; |
| | | task.NextAddress = routers.FirstOrDefault().ChildPosi; |
| | | task.ModifyDate = DateTime.Now; |
| | | task.Modifier = "System"; |
| | | BaseDal.UpdateData(task); |
| | | |
| | | _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"å åæºåºåºå®æ"); |
| | | |
| | | //todo 忥å°WMS |
| | | |
| | | //æä¸èèå¤ä¸ªåºåºå£ |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup && task.TaskState == (int)TaskInStatusEnum.SC_InExecuting) |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup && task.TaskState == (int)TaskStatusEnum.SC_Executing) |
| | | { |
| | | //todo |
| | | int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>(); |
| | | task.TaskState = nextStatus; |
| | | task.TaskState = (int)TaskStatusEnum.Finish; |
| | | task.ModifyDate = DateTime.Now; |
| | | task.Modifier = "System"; |
| | | BaseDal.UpdateData(task); |
| | | _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"å åæºå
¥åºå®æ"); |
| | | |
| | | WMSTaskDTO taskDTO = new WMSTaskDTO() |
| | | { |
| | | TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")), |
| | | Grade = 1, |
| | | PalletCode = task.PalletCode + "S", |
| | | RoadWay = "SC01", |
| | | SourceAddress = task.TargetAddress, |
| | | TargetAddress = "CLOutAreaA", |
| | | TaskState = (int)TaskOutStatusEnum.OutNew, |
| | | Id = 0, |
| | | TaskType = (int)TaskOutboundTypeEnum.Outbound |
| | | }; |
| | | |
| | | content = ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO }); |
| | | //todo 忥å°WMS |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) |
| | | { |
| | | //todo è°ç¨WMSç§»åºå®æ |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OtherGroup) |
| | | { |
| | | } |
| | | else |
| | | { |
| | |
| | | { |
| | | Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); |
| | | if (task == null) return WebResponseContent.Instance.Error($"æªæ¾å°è¯¥ä»»å¡ä¿¡æ¯,ä»»å¡å·:ã{taskNum}ã"); |
| | | if (task.TaskState != (int)TaskInStatusEnum.InPending && task.TaskState != (int)TaskOutStatusEnum.OutPending) |
| | | if (task.TaskState != (int)TaskStatusEnum.Pending) |
| | | { |
| | | return content = WebResponseContent.Instance.Error($"该任å¡ç¶æä¸å¯æ¢å¤,ä»»å¡å·:ã{taskNum}ã,ä»»å¡ç¶æ:ã{task.TaskState}ã"); |
| | | } |
| | |
| | | { |
| | | if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) |
| | | { |
| | | task.TaskState = (int)TaskOutStatusEnum.OutNew; |
| | | task.TaskState = (int)TaskStatusEnum.New; |
| | | } |
| | | else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) |
| | | { |
| | | task.TaskState = (int)TaskInStatusEnum.InNew; |
| | | task.TaskState = (int)TaskStatusEnum.New; |
| | | } |
| | | //todo |
| | | } |
| | |
| | | List<Dt_Task> tasks = BaseDal.QueryData(x => taskKeys.Contains(x.TaskId)); |
| | | BaseDal.DeleteAndMoveIntoHty(tasks, OperateTypeEnum.人工å é¤); |
| | | return WebResponseContent.Instance.OK($"æåå é¤{tasks.Count}æ¡æ°æ®"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®è®¾å¤ç¼å·ãå½åå°åæç
§ä¼å
级以åå建æ¶é´æåºæ¥è¯¢ä»»å¡æ± æ°å¢çä»»å¡ |
| | | /// </summary> |
| | | /// <param name="deviceNo">设å¤ç¼å·</param> |
| | | /// <param name="currentAddress">å½åå°å</param> |
| | | /// <returns>è¿åä»»å¡å®ä½å¯¹è±¡ï¼å¯è½ä¸ºnull</returns> |
| | | public Dt_Task QueryRobotCraneTask(string deviceNo, string currentAddress = "") |
| | | { |
| | | if (string.IsNullOrEmpty(currentAddress)) |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskRobotTypes.Contains(x.TaskType) && x.TaskState <= (int)TaskRobotStatusEnum.RobotExecuting), TaskOrderBy); |
| | | else |
| | | return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskRobotTypes.Contains(x.TaskType) && x.CurrentAddress == currentAddress && x.TaskState <= (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy); |
| | | } |
| | | } |
| | | } |
| | |
| | | /// <summary> |
| | | /// è¿æ¥éåé¿åº¦ |
| | | /// </summary> |
| | | public int Backlog { get; set; } = 100; |
| | | public int Backlog { get; set; } = 1000; |
| | | |
| | | /// <summary> |
| | | /// ææ¬ç¼ç åç§°ï¼ä¾å¦: utf-8, gbkï¼ |
| | |
| | | /// æ¥å¿æä»¶è·¯å¾ï¼ç¸å¯¹äºç¨åºè¿è¡ç®å½ï¼ |
| | | /// </summary> |
| | | public string LogFilePath { get; set; } = "socketserver.log"; |
| | | |
| | | /// <summary> |
| | | /// æ¶æ¯å¤´æ è®° |
| | | /// </summary> |
| | | public string MessageHeader { get; set; } = "<"; |
| | | |
| | | /// <summary> |
| | | /// æ¶æ¯å°¾æ è®° |
| | | /// </summary> |
| | | public string MessageFooter { get; set; } = ">"; |
| | | } |
| | | } |
| | |
| | | { |
| | | public partial class TcpSocketServer |
| | | { |
| | | /// <summary> |
| | | /// æ£ç´¢å½å卿å¡ä¸æ³¨åçææå®¢æ·ç«¯æ è¯ç¬¦çåªè¯»å表ã |
| | | /// </summary> |
| | | /// <remarks>è¿åçå表表示è°ç¨æ¶å»å®¢æ·ç«¯IDçå¿«ç
§ãåç»å¯¹å®¢æ·ç«¯éåçæ´æ¹ä¸ä¼å½±åè¿åçåè¡¨ãæ¤æ¹æ³æ¯çº¿ç¨å®å
¨çã</remarks> |
| | | /// <returns>å
å«å®¢æ·ç«¯IDç<see cref="IReadOnlyList{String}"/>ãå¦ææ²¡æå®¢æ·ç«¯æ³¨åï¼å表å°ä¸ºç©ºã</returns> |
| | | public IReadOnlyList<string> GetClientIds() |
| | | { |
| | | lock (_syncRoot) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ£ç´¢ä¸æå®è®¾å¤æ è¯ç¬¦å
³èç客æ·ç«¯æ è¯ç¬¦ã |
| | | /// </summary> |
| | | /// <remarks>æ¤æ¹æ³æ¯çº¿ç¨å®å
¨çãå¦ææªæ¾å°è®¾å¤æ è¯ç¬¦ï¼æ¹æ³å°è¿ånullè䏿¯æåºå¼å¸¸ã</remarks> |
| | | /// <param name="deviceId">è¦æ£ç´¢å®¢æ·ç«¯æ è¯ç¬¦ç设å¤çå¯ä¸æ è¯ç¬¦ãä¸è½ä¸ºnullã</param> |
| | | /// <returns>䏿å®è®¾å¤æ è¯ç¬¦å
³èç客æ·ç«¯æ è¯ç¬¦ï¼å¦æä¸åå¨å
³èåè¿ånullã</returns> |
| | | public string? GetClientIdByDevice(string deviceId) |
| | | { |
| | | lock (_syncRoot) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 弿¥åæå®è®¾å¤åéæ¶æ¯ã |
| | | /// </summary> |
| | | /// <remarks>妿æå®è®¾å¤æªæ³¨åææ æ³æ¾å°ï¼åè¿å <see langword="false"/>ã</remarks> |
| | | /// <param name="deviceId">ç®æ 设å¤çå¯ä¸æ è¯ç¬¦ãä¸è½ä¸ºnullæç©ºã</param> |
| | | /// <param name="message">è¦åéç»è®¾å¤çæ¶æ¯ãä¸è½ä¸ºnullã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥æä½çä»»å¡ãå¦ææ¶æ¯æååéï¼ä»»å¡ç»æä¸º <see langword="true"/>ï¼ |
| | | /// å¦å为 <see langword="false"/>ã</returns> |
| | | public Task<bool> SendToDeviceAsync(string deviceId, string message) |
| | | { |
| | | var clientId = GetClientIdByDevice(deviceId); |
| | |
| | | return SendToClientAsync(clientId, message); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// éè¿TCPè¿æ¥å¼æ¥åæå®å®¢æ·ç«¯åéå¸¦å¸§çææ¬æ¶æ¯ã |
| | | /// </summary> |
| | | /// <remarks>妿客æ·ç«¯æªè¿æ¥æä¸åå¨ï¼æ¤æ¹æ³å°è¿å <see langword="false"/> ä¸ä¸åéæ¶æ¯ã |
| | | /// æ¶æ¯å°ä¼å
使ç¨å®¢æ·ç«¯é¦éçææ¬ç¼ç è¿è¡ç¼ç ï¼å¦å使ç¨é»è®¤ç¼ç ã |
| | | /// æ¤æ¹æ³å¯¹äºåä¸å客æ·ç«¯çå¹¶åè°ç¨æ¯çº¿ç¨å®å
¨çã</remarks> |
| | | /// <param name="clientId">è¦åéæ¶æ¯å°ç客æ·ç«¯çå¯ä¸æ è¯ç¬¦ãå¿
须对åºå·²è¿æ¥ç客æ·ç«¯ã</param> |
| | | /// <param name="message">è¦åéç»å®¢æ·ç«¯çææ¬æ¶æ¯ãä¸è½ä¸ºnullã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥æä½çä»»å¡ãå¦ææ¶æ¯æååéï¼ä»»å¡ç»æä¸º <see langword="true"/>ï¼ |
| | | /// å¦åï¼å¦æå®¢æ·ç«¯æªè¿æ¥æä¸åå¨ï¼ç»æä¸º <see langword="false"/>ã</returns> |
| | | public async Task<bool> SendToClientAsync(string clientId, string message) |
| | | { |
| | | TcpClient? client; |
| | |
| | | try |
| | | { |
| | | var ns = client.GetStream(); |
| | | var data = enc.GetBytes((message ?? string.Empty) + "\n"); |
| | | var framedMessage = BuildFramedMessage(message); |
| | | var data = enc.GetBytes(framedMessage); |
| | | await ns.WriteAsync(data, 0, data.Length); |
| | | } |
| | | finally |
| | |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 弿¥åææå·²è¿æ¥ç客æ·ç«¯åéæå®çæ¶æ¯ã |
| | | /// </summary> |
| | | /// <remarks>妿åæä¸ªå®¢æ·ç«¯åéæ¶æ¯æ¶åçé误ï¼å¼å¸¸å°è¢«æå¶å¹¶ç»§ç»åå
¶ä»å®¢æ·ç«¯å¹¿æã |
| | | /// 彿æåéæä½å®æåï¼æ¤æ¹æ³ç»æã</remarks> |
| | | /// <param name="message">è¦å¹¿æç»ææå®¢æ·ç«¯çæ¶æ¯ãä¸è½ä¸ºnullã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥å¹¿ææä½çä»»å¡ã</returns> |
| | | public async Task BroadcastAsync(string message) |
| | | { |
| | | List<TcpClient> clients; |
| | |
| | | |
| | | await Task.WhenAll(clients.Select(c => Task.Run(async () => |
| | | { |
| | | try { await SendAsync(c, message); } catch { } |
| | | try { await SendMessageAsync(c, message); } catch { } |
| | | }))); |
| | | } |
| | | |
| | | public static async Task SendAsync(TcpClient client, string message) |
| | | /// <summary> |
| | | /// éè¿ç½ç»æµå¼æ¥åæå®çTCP客æ·ç«¯åéå¸¦å¸§çææ¬æ¶æ¯ã |
| | | /// </summary> |
| | | /// <remarks>妿客æ·ç«¯ä¸ºnullææªè¿æ¥ï¼æ¤æ¹æ³å°ç«å³è¿åèä¸åéæ¶æ¯ã |
| | | /// æ¶æ¯å°ä½¿ç¨é
ç½®çææ¬ç¼ç è¿è¡ç¼ç å¹¶æ·»å 帧头åéè¿ç½ç»æµåéã</remarks> |
| | | /// <param name="client">è¦åéæ¶æ¯å°çTCP客æ·ç«¯ãå¿
é¡»å¤äºè¿æ¥ç¶æï¼å¦åæ¹æ³ä¸æ§è¡ä»»ä½æä½ã</param> |
| | | /// <param name="message">è¦åéç»å®¢æ·ç«¯çææ¬æ¶æ¯ãæ¶æ¯å¨ä¼ è¾åå°è¢«ç¼ç å¹¶æ·»å 帧头ã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥åéæä½çä»»å¡ã</returns> |
| | | private async Task SendMessageAsync(TcpClient client, string message) |
| | | { |
| | | if (client == null || !client.Connected) |
| | | { |
| | |
| | | } |
| | | |
| | | NetworkStream stream = client.GetStream(); |
| | | var data = Encoding.UTF8.GetBytes((message ?? string.Empty) + "\n"); |
| | | var framedMessage = BuildFramedMessage(message); |
| | | var data = _textEncoding.GetBytes(framedMessage); |
| | | await stream.WriteAsync(data, 0, data.Length); |
| | | } |
| | | } |
| | |
| | | { |
| | | public partial class TcpSocketServer |
| | | { |
| | | /// <summary> |
| | | /// éæ¾æå¡å¨ä½¿ç¨çææèµæºå¹¶åæ¢çå¬ä¼ å
¥è¿æ¥ã |
| | | /// </summary> |
| | | /// <remarks>å½ä¸åéè¦æå¡å¨æ¶è°ç¨æ¤æ¹æ³ï¼ä»¥ç¡®ä¿ææç¸å
³èµæºï¼å¦ç½ç»çå¬å¨å忥åè¯ï¼è¢«æ£ç¡®éæ¾ã |
| | | /// è°ç¨ <see cref="Dispose"/> åï¼æå¡å¨æ æ³éæ°å¯å¨æå次使ç¨ã</remarks> |
| | | public void Dispose() |
| | | { |
| | | _cts?.Cancel(); |
| | |
| | | using HslCommunication.Core.IMessage; |
| | | using System; |
| | | using System.Net.Sockets; |
| | | using System.Text; |
| | | using System.Text.Json; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | using WIDESEAWCS_QuartzJob; |
| | | using System.IO; |
| | | |
| | | namespace WIDESEAWCS_Tasks.SocketServer |
| | | { |
| | | public partial class TcpSocketServer |
| | | { |
| | | public async Task HandleClientAsync(TcpClient client, string clientId, CancellationToken cancellationToken, RobotSocketState robotCrane) |
| | | /// <summary> |
| | | /// 弿¥å¤çä¸å·²è¿æ¥çTCP客æ·ç«¯çéä¿¡ï¼å¤çæºå¨äººèµ·éæºä¼è¯ä¸çä¼ å
¥æ¶æ¯å客æ·ç«¯ç¶ææ´æ°ã |
| | | /// </summary> |
| | | /// <remarks>æ¤æ¹æ³ç®¡ç客æ·ç«¯è¿æ¥ççå½å¨æï¼å
æ¬è¯»åæ¶æ¯ãæ´æ°å®¢æ·ç«¯ç¶æåè°ç¨ç¸å
³äºä»¶ã |
| | | /// å½å¤çç»ææ¶ï¼å®¢æ·ç«¯åç¸å
³çç½ç»èµæºå°è¢«éæ¾ã妿å¯ç¨å¿è·³æç©ºé²è¶
æ¶éé¡¹ï¼ |
| | | /// å°åºç¨é¢å¤çåæ¶é»è¾ãäºä»¶è°ç¨æé´çå¼å¸¸å°è¢«æè·å¹¶æå¶ï¼ä»¥ç¡®ä¿ä¼è¯å¤çç鲿£æ§ã</remarks> |
| | | /// <param name="client">表示è¦å¤ççè¿ç¨è¿æ¥çTCP客æ·ç«¯ãæ¹æ³å®æåå°éæ¾æ¤å¯¹è±¡ã</param> |
| | | /// <param name="clientId">å·²è¿æ¥å®¢æ·ç«¯çå¯ä¸æ è¯ç¬¦ãç¨äºå¨æ´ä¸ªä¼è¯ä¸è·è¸ªåæ´æ°å®¢æ·ç«¯ç¶æã</param> |
| | | /// <param name="cancellationToken">å¯ç¨äºåæ¶å®¢æ·ç«¯å¤çæä½ç忶令çãå¦æè¯·æ±åæ¶ï¼æ¹æ³å°ç«å³ç»æ¢å¤çã</param> |
| | | /// <param name="stackerState">表示ä¸å®¢æ·ç«¯å
³èçæºå¨äººèµ·éæºçå½åç¶æå¯¹è±¡ãç¨äºä¸ºæ¶æ¯å¤çåäºä»¶è°ç¨æä¾ä¸ä¸æã</param> |
| | | /// <returns>表示å¤ç客æ·ç«¯è¿æ¥ç弿¥æä½çä»»å¡ãå½å®¢æ·ç«¯æå¼è¿æ¥æè¯·æ±åæ¶æ¶ä»»å¡å®æã</returns> |
| | | public async Task HandleClientAsync(TcpClient client, string clientId, CancellationToken cancellationToken, StackerSocketState stackerState) |
| | | { |
| | | using (client) |
| | | using (NetworkStream networkStream = client.GetStream()) |
| | |
| | | try |
| | | { |
| | | var ct = localCts?.Token ?? cancellationToken; |
| | | message = await reader.ReadLineAsync().WaitAsync(ct); |
| | | message = await ReceiveFullMessageAsync(networkStream, _textEncoding, ct); |
| | | //message = await reader.ReadLineAsync().WaitAsync(ct); |
| | | } |
| | | catch (OperationCanceledException) |
| | | { |
| | |
| | | { |
| | | try |
| | | { |
| | | |
| | | _ = MessageReceived.Invoke(message, false, client, robotCrane); |
| | | |
| | | // 夿æ¯å¦ä¸º JSON æ ¼å¼ |
| | | bool isJsonFormat = TryParseJsonSilent(message); |
| | | _ = MessageReceived.Invoke(message, isJsonFormat, client, stackerState); |
| | | } |
| | | catch { } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å°è¯å¤çæ¥èªå®¢æ·ç«¯çè®¾å¤æ³¨å请æ±ãè¿åä¸ä¸ªå¼æç¤ºè¯¥æ¶æ¯æ¯å¦è¢«ä½ä¸ºæ³¨å请æ±å¤çã |
| | | /// </summary> |
| | | /// <remarks>å¦ææ¶æ¯æ¯ææç注å请æ±ä¸å
å«é空çè®¾å¤æ è¯ç¬¦ï¼ |
| | | /// åå°è®¾å¤ç»å®å°å®¢æ·ç«¯å¹¶åé确认信æ¯ãæ¤æ¹æ³ä¸ä¼å æ ææ¶æ¯èæåºå¼å¸¸ï¼ |
| | | /// å®ä»
è¿å falseã</remarks> |
| | | /// <param name="messageLower">客æ·ç«¯æ¶æ¯çå°åçæ¬ï¼ç¨äºå¤ææ¶æ¯æ¯å¦ä¸ºæ³¨å请æ±ã</param> |
| | | /// <param name="message">å
嫿³¨åå½ä»¤åè®¾å¤æ è¯ç¬¦çåå§å®¢æ·ç«¯æ¶æ¯ã</param> |
| | | /// <param name="clientId">åéæ³¨å请æ±ç客æ·ç«¯çå¯ä¸æ è¯ç¬¦ã</param> |
| | | /// <param name="client">ä¸å®¢æ·ç«¯éä¿¡çTCP客æ·ç«¯è¿æ¥ã</param> |
| | | /// <param name="cancellationToken">å¯ç¨äºåæ¶æ³¨åæä½ç忶令çã</param> |
| | | /// <returns>å¦ææ¶æ¯è¢«è¯å«å¹¶ä½ä¸ºæ³¨å请æ±å¤çï¼åè¿å trueï¼å¦åè¿å falseã</returns> |
| | | private bool TryHandleRegister(string messageLower, string message, string clientId, NetworkStream networkStream, CancellationToken cancellationToken) |
| | | { |
| | | if (!messageLower.StartsWith("register,")) |
| | |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ´æ°å®¢æ·ç«¯ç¶æ |
| | | /// </summary> |
| | | /// <param name="clientId"></param> |
| | | /// <param name="message"></param> |
| | | private void UpdateClientStatus(string clientId, string message) |
| | | { |
| | | lock (_syncRoot) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// åå
¥æ¶æ¯å°å®¢æ·ç«¯ |
| | | /// </summary> |
| | | /// <param name="clientId"></param> |
| | | /// <param name="networkStream"></param> |
| | | /// <param name="message"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | private async Task WriteToClientAsync(string clientId, NetworkStream networkStream, string message, CancellationToken cancellationToken) |
| | | { |
| | | SemaphoreSlim? sem = null; |
| | |
| | | if (sem != null) await sem.WaitAsync(cancellationToken); |
| | | try |
| | | { |
| | | var data = enc.GetBytes(message + "\n"); |
| | | var framedMessage = BuildFramedMessage(message); |
| | | var data = enc.GetBytes(framedMessage); |
| | | await networkStream.WriteAsync(data, 0, data.Length, cancellationToken); |
| | | } |
| | | finally |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ·»å æ¶æ¯å¸§å¤´å°¾ |
| | | /// </summary> |
| | | /// <param name="message"></param> |
| | | /// <returns></returns> |
| | | private string BuildFramedMessage(string message) |
| | | { |
| | | var header = _options.MessageHeader ?? string.Empty; |
| | | var footer = _options.MessageFooter ?? string.Empty; |
| | | return header + (message ?? string.Empty) + footer; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// JSONæ ¼å¼å°è¯è§£æï¼éé»å¤±è´¥ï¼ |
| | | /// </summary> |
| | | /// <param name="message"></param> |
| | | /// <returns></returns> |
| | | private static bool TryParseJsonSilent(string message) |
| | | { |
| | | if (string.IsNullOrWhiteSpace(message)) return false; |
| | |
| | | try { JsonDocument.Parse(message); return true; } catch { return false; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// utf-8 å¯è½æ§æ£æµ |
| | | /// </summary> |
| | | /// <param name="data"></param> |
| | | /// <returns></returns> |
| | | private static bool IsLikelyUtf8(byte[] data) |
| | | { |
| | | int i = 0; |
| | |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 读å宿´æ¶æ¯ |
| | | /// </summary> |
| | | /// <param name="networkStream">åèæµ</param> |
| | | /// <param name="encoding">ç¼ç æ ¼å¼</param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | private async Task<string?> ReceiveFullMessageAsync(NetworkStream networkStream, Encoding encoding, CancellationToken cancellationToken) |
| | | { |
| | | var header = _options.MessageHeader ?? string.Empty; |
| | | var footer = _options.MessageFooter ?? string.Empty; |
| | | |
| | | var buffer = new byte[1024]; |
| | | var builder = new StringBuilder(); |
| | | |
| | | while (true) |
| | | { |
| | | int bytesRead = await networkStream.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellationToken); |
| | | if (bytesRead <= 0) |
| | | { |
| | | if (builder.Length == 0) return null; |
| | | return string.IsNullOrEmpty(header) && string.IsNullOrEmpty(footer) ? builder.ToString() : null; |
| | | } |
| | | |
| | | builder.Append(encoding.GetString(buffer, 0, bytesRead)); |
| | | |
| | | if (string.IsNullOrEmpty(header) && string.IsNullOrEmpty(footer)) |
| | | { |
| | | if (!networkStream.DataAvailable) |
| | | { |
| | | break; |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | var data = builder.ToString(); |
| | | var headerIndex = string.IsNullOrEmpty(header) ? 0 : data.IndexOf(header, StringComparison.Ordinal); |
| | | if (headerIndex < 0) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | var startIndex = headerIndex + header.Length; |
| | | var footerIndex = string.IsNullOrEmpty(footer) ? data.Length : data.IndexOf(footer, startIndex, StringComparison.Ordinal); |
| | | if (footerIndex >= 0) |
| | | { |
| | | return data.Substring(startIndex, footerIndex - startIndex); |
| | | } |
| | | } |
| | | |
| | | return builder.ToString(); |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | public partial class TcpSocketServer |
| | | { |
| | | /// <summary> |
| | | /// 弿¥å¯å¨TCPæå¡å¨ï¼ä½¿å
¶å¼å§æ¥åä¼ å
¥ç客æ·ç«¯è¿æ¥ã |
| | | /// </summary> |
| | | /// <remarks>妿æå¡å¨å·²å¨è¿è¡æéè¿é
ç½®ç¦ç¨ï¼æ¤æ¹æ³å°ç«å³è¿åèä¸å¯å¨æå¡å¨ã |
| | | /// åç»ç客æ·ç«¯çæ§åæ¥åæä½å¨åå°ä»»å¡ä¸è¿è¡ãæ¤æ¹æ³ä¸ä¼é»å¡è°ç¨çº¿ç¨ã</remarks> |
| | | /// <param name="cancellationToken">å¯ç¨äºè¯·æ±åæ¶æå¡å¨å¯å¨ååç»åå°æä½ç忶令çã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥å¯å¨æä½çä»»å¡ã彿å¡å¨å¼å§çå¬è¿æ¥æ¶ä»»å¡å®æã</returns> |
| | | public Task StartAsync(CancellationToken cancellationToken) |
| | | { |
| | | if (IsRunning || !_options.Enabled) |
| | |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | //// <summary> |
| | | /// 弿¥åæ¢æå¡å¨å¹¶çå¾
æææ´»å¨å®¢æ·ç«¯è¿æ¥å®æã |
| | | /// </summary> |
| | | /// <remarks>妿æå¡å¨æªè¿è¡ï¼æ¤æ¹æ³å°ç«å³è¿åè䏿§è¡ä»»ä½æä½ã |
| | | /// æ¤æ¹æ³ç¡®ä¿ææå®¢æ·ç«¯ä»»å¡å®æåæå°æå¡å¨æ è®°ä¸ºå·²åæ¢ã</remarks> |
| | | /// <param name="cancellationToken">å¯ç¨äºå¨å®æå忶忢æä½ç忶令çã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥åæ¢æä½çä»»å¡ã</returns> |
| | | public async Task StopAsync(CancellationToken cancellationToken) |
| | | { |
| | | if (!IsRunning) |
| | |
| | | IsRunning = false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æç»æ¥åä¼ å
¥çTCP客æ·ç«¯è¿æ¥ï¼ç´å°è¯·æ±åæ¶ã |
| | | /// </summary> |
| | | /// <remarks>æ¤æ¹æ³æ¨å¨åå°è¿è¡ä»¥å¤çæ°ç客æ·ç«¯è¿æ¥ã |
| | | /// 妿çå¬å¨è¢«éæ¾æéè¿æä¾ç令ç请æ±åæ¶ï¼å¾ªç¯å°éåºã</remarks> |
| | | /// <param name="cancellationToken">å¯ç¨äºè¯·æ±åæ¶æ¥å循ç¯ç令çãå½è¯·æ±åæ¶æ¶ï¼å¾ªç¯å°ç«å³ç»æ¢ã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥æ¥åå¾ªç¯æä½çä»»å¡ã</returns> |
| | | private async Task AcceptLoopAsync(CancellationToken cancellationToken) |
| | | { |
| | | while (!cancellationToken.IsCancellationRequested) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä»å
é¨éåä¸ç§»é¤æå®æ è¯ç¬¦ç客æ·ç«¯ï¼å¹¶éæ¾ç¸å
³èµæºã |
| | | /// </summary> |
| | | /// <remarks>æ¤æ¹æ³å
³é客æ·ç«¯è¿æ¥ï¼éæ¾ä»»ä½å
³èçéï¼å¹¶ç§»é¤å¯¹å®¢æ·ç«¯çææå¼ç¨ï¼ |
| | | /// å
æ¬è®¾å¤ç»å®åç¼ç ä¿¡æ¯ãéè¿å¯¹å
é¨åæ¥å¯¹è±¡å éç¡®ä¿çº¿ç¨å®å
¨ã</remarks> |
| | | /// <param name="clientId">è¦ç§»é¤ç客æ·ç«¯çå¯ä¸æ è¯ç¬¦ãä¸è½ä¸ºnullæç©ºã</param> |
| | | private void RemoveClient(string clientId) |
| | | { |
| | | lock (_syncRoot) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 弿¥çæ§å·²è¿æ¥ç客æ·ç«¯ï¼å¹¶æå¼è¶
è¿é
ç½®è¶
æ¶æ¶é´é²ç½®ç客æ·ç«¯è¿æ¥ã |
| | | /// </summary> |
| | | /// <remarks>æ¤æ¹æ³æç»æ£æ¥é²ç½®å®¢æ·ç«¯ï¼å¦æå
¶ä¸æ´»å¨æ¶é´è¶
è¿æå®ç空é²è¶
æ¶ï¼åæå¼è¿æ¥ã |
| | | /// çæ§å¾ªç¯å°æç»è¿è¡ï¼ç´å°éè¿æä¾ç令ç请æ±åæ¶ã</remarks> |
| | | /// <param name="cancellationToken">å¯ç¨äºè¯·æ±ç»æ¢çæ§å¾ªç¯ç忶令çã</param> |
| | | /// <returns>è¡¨ç¤ºå¼æ¥çæ§æä½çä»»å¡ã</returns> |
| | | private async Task MonitorClientsAsync(CancellationToken cancellationToken) |
| | | { |
| | | while (!cancellationToken.IsCancellationRequested) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// åºäºè¿ç¨ç»ç«¯ç¹è·åæå®TCP客æ·ç«¯çå¯ä¸æ è¯ç¬¦å符串ã |
| | | /// </summary> |
| | | /// <remarks>è¿åçæ è¯ç¬¦éç¨äºå¨æ¥å¿è®°å½æè·è¸ªåºæ¯ä¸åºå客æ·ç«¯ã |
| | | /// 妿客æ·ç«¯çè¿ç¨ç»ç«¯ç¹ä¸å¯ç¨ï¼å°çæGUID以确ä¿å¯ä¸æ§ã</remarks> |
| | | /// <param name="client">è¦è·åæ è¯ç¬¦çTCP客æ·ç«¯ãä¸è½ä¸ºnullã</param> |
| | | /// <returns>表示客æ·ç«¯è¿ç¨ç»ç«¯ç¹çå符串ï¼å¦æå¯ç¨ï¼ï¼å¦å为çæçæ°GUIDå符串ã</returns> |
| | | public static string GetClientId(TcpClient client) |
| | | { |
| | | return client.Client.RemoteEndPoint?.ToString() ?? Guid.NewGuid().ToString(); |
| | |
| | | public partial class TcpSocketServer : IDisposable |
| | | { |
| | | private readonly SocketServerOptions _options; |
| | | |
| | | /// <summary> |
| | | /// æä¾ä¸ä¸ªå¯ç¨äºåæ¥å¯¹å
å«å®ä¾ç访é®ç对象ã |
| | | /// </summary> |
| | | /// <remarks>å¨å¯¹å®ä¾å®ç°çº¿ç¨å®å
¨æä½æ¶ï¼å¯å°æ¤å¯¹è±¡ç¨ä½éå®ç®æ ãæ¤æ¨¡å¼é常ç¨äºé¿å
æ»éå¹¶ç¡®ä¿ä¸è´ç忥ã</remarks> |
| | | public readonly object _syncRoot = new(); |
| | | |
| | | private TcpListener? _listener; |
| | | |
| | | /// <summary> |
| | | /// 表示ç¨äºååºè¿è¡ä¸æä½çåæ¶è¯·æ±çåæ¶ä»¤çæºã |
| | | /// </summary> |
| | | /// <remarks>妿å½åæ²¡ææ´»å¨çåæ¶æºå¶ï¼æ¤å段å¯è½ä¸ºnullãä½¿ç¨æ¤ä»¤çæºåæ¶æ¯æåæ¶ç任塿æä½ã</remarks> |
| | | public CancellationTokenSource? _cts; |
| | | |
| | | /// <summary> |
| | | /// æä¾è¡¨ç¤ºæ´»å¨å®¢æ·ç«¯æä½çä»»å¡å表ã |
| | | /// </summary> |
| | | /// <remarks>æ¤å段ç¨äºå
é¨è·è¸ªå¼æ¥å®¢æ·ç«¯æ´»å¨ã宿¯åªè¯»çï¼ä¸åºå¨å
å«ç±»å¤é¨ç´æ¥ä¿®æ¹ã</remarks> |
| | | public readonly List<Task> _clientTasks = new(); |
| | | |
| | | /// <summary> |
| | | /// æä¾ä»å®¢æ·ç«¯æ è¯ç¬¦å°å
¶å
³èçTCP客æ·ç«¯è¿æ¥çæ å°ã |
| | | /// </summary> |
| | | /// <remarks>æ¤åå
¸å
许éè¿å¯ä¸å符串æ è¯ç¬¦è®¿é®æ´»å¨çTCP客æ·ç«¯ãå¨å¤çº¿ç¨åºæ¯ä¸ï¼å¯¹éåçä¿®æ¹åºå°å¿è¿è¡ä»¥é¿å
å¹¶åé®é¢ã</remarks> |
| | | public readonly Dictionary<string, TcpClient> _clients = new(); |
| | | |
| | | /// <summary> |
| | | /// æä¾ä»è®¾å¤æ è¯ç¬¦å°å
¶å¯¹åºç»å®å¼çæ å°ã |
| | | /// </summary> |
| | | /// <remarks>æ¤å段æ¯åªè¯»çï¼ç¨äºå
å«ç±»å
é¨ä½¿ç¨ãåºéè¿æå®çæ¹æ³æå±æ§å¯¹åå
¸è¿è¡ä¿®æ¹ä»¥ç¡®ä¿ä¸è´æ§ã</remarks> |
| | | public readonly Dictionary<string, string> _deviceBindings = new(); |
| | | |
| | | /// <summary> |
| | | /// æä¾ä»å®¢æ·ç«¯æ è¯ç¬¦å°å
¶å
³èéçæ å°ï¼ç¨äºåæ¥å¯¹å®¢æ·ç«¯ç¹å®èµæºç访é®ã |
| | | /// </summary> |
| | | /// <remarks>åå
¸ä¸çæ¯ä¸ªæ¡ç®å°ä¸ä¸ªå¯ä¸ç客æ·ç«¯IDä¸ä¸ä¸ª<see cref="SemaphoreSlim"/>å®ä¾å
³èï¼å®ç°æ¯ä¸ªå®¢æ·ç«¯ç线ç¨å®å
¨æä½ãæ¤éåç¨äºå
é¨åè°å¹¶å访é®ï¼ä¸åºç´æ¥ä¿®æ¹ã</remarks> |
| | | public readonly Dictionary<string, SemaphoreSlim> _clientLocks = new(); |
| | | |
| | | /// <summary> |
| | | /// æä¾ä»å®¢æ·ç«¯æ è¯ç¬¦å°å
¶å
³èææ¬ç¼ç çæ å°ã |
| | | /// </summary> |
| | | /// <remarks>æ¤åå
¸ç¨äºå
é¨è·è¸ªå·²è¿æ¥å®¢æ·ç«¯çç¼ç å好ãé®è¡¨ç¤ºå®¢æ·ç«¯æ è¯ç¬¦ï¼å¼æå®ç¨äºææ¬æä½ç对åº<see cref="System.Text.Encoding"/>ã</remarks> |
| | | public readonly Dictionary<string, Encoding> _clientEncodings = new(); |
| | | |
| | | /// <summary> |
| | | /// å卿¯ä¸ªå®¢æ·ç«¯æåæ´»å¨çæ¶é´æ³ï¼ä»¥å®¢æ·ç«¯æ è¯ç¬¦ä¸ºé®ã |
| | | /// </summary> |
| | | /// <remarks>æ¤å段ç¨äºå
é¨è·è¸ªå®¢æ·ç«¯æ´»å¨ãåå
¸å°å®¢æ·ç«¯æ è¯ç¬¦æ å°å°å¯¹åºçæåæ´»å¨æ¶é´ï¼UTCï¼ãç´æ¥ä¿®æ¹æ¤éåå¯è½å½±å客æ·ç«¯ä¼è¯ç®¡çé»è¾ã</remarks> |
| | | public readonly Dictionary<string, DateTime> _clientLastActive = new(); |
| | | |
| | | /// <summary> |
| | | /// æå®å
å«ç±»åä¸åç¬¦æ°æ®ä½¿ç¨çææ¬ç¼ç ã |
| | | /// </summary> |
| | | /// <remarks>ä½¿ç¨æ¤å段确å®å¤çåç¬¦æ°æ®æ¶å¦ä½ç¼ç æè§£ç ææ¬ãç¼ç å½±ååèå¦ä½è¢«è§£é为å符ï¼åä¹äº¦ç¶ã常è§çç¼ç å
æ¬UTF8ãASCIIåUnicodeã</remarks> |
| | | public readonly Encoding _textEncoding; |
| | | |
| | | /// <summary> |
| | | /// 表示èªå¨æ£æµå°çGB2312ç¼ç ï¼å¦æå¯ç¨ï¼ã |
| | | /// </summary> |
| | | /// <remarks>é常ä»è¾å
¥æ°æ®ç¡®å®ç¼ç æ¶è®¾ç½®æ¤å段ãå¦ææ£æµå¤±è´¥ææªæ§è¡æ£æµï¼å¼å¯è½ä¸ºnullã</remarks> |
| | | public readonly Encoding? _autoDetectedGb2312; |
| | | |
| | | private readonly string _logFile; |
| | | |
| | | private Task? _monitorTask; |
| | | |
| | | /// <summary> |
| | | /// ä½¿ç¨æå®çæå¡å¨é项åå§å TcpSocketServer ç±»çæ°å®ä¾ã |
| | | /// </summary> |
| | | /// <remarks>妿å¯ç¨äº AutoDetectEncoding éé¡¹ï¼æå¡å¨å°é»è®¤ä½¿ç¨ UTF-8 ç¼ç ï¼ |
| | | /// å¹¶å°è¯æ¯æ GBK ç¼ç è¿è¡èªå¨æ£æµã妿ç¼ç æ£æµå¤±è´¥ææä¾äºæ æçç¼ç åç§°ï¼ |
| | | /// å°åéä½¿ç¨ UTF-8 ç¼ç ãæ¥å¿æä»¶è·¯å¾ç± LogFilePath é项å³å®ï¼ |
| | | /// å¦ææªæå®ï¼åé»è®¤ä¸ºåºç¨ç¨åºåºç®å½ä¸ç 'socketserver.log' æä»¶ã</remarks> |
| | | /// <param name="options">奿¥åæå¡å¨çé
ç½®é项ãä¸è½ä¸º nullãæä¾ç¼ç è®¾ç½®ãæ¥å¿æä»¶è·¯å¾åèªå¨æ£æµè¡ä¸ºçé
ç½®ã</param> |
| | | public TcpSocketServer(IOptions<SocketServerOptions> options) |
| | | { |
| | | _options = options.Value; |
| | |
| | | |
| | | public bool IsRunning { get; private set; } |
| | | |
| | | public event Func<string, bool, TcpClient, RobotSocketState, Task<string?>>? MessageReceived; |
| | | public event Func<string, bool, TcpClient, StackerSocketState, Task<string?>>? MessageReceived; |
| | | |
| | | public event Func<string, Task<string?>>? RobotReceived; |
| | | |
| | | private void Log(string message) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using Quartz; |
| | | using System.Collections.Concurrent; |
| | | using System.Net.Sockets; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_ITaskInfoRepository; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob; |
| | | using WIDESEAWCS_QuartzJob.Service; |
| | | using WIDESEAWCS_Tasks.SocketServer; |
| | | |
| | | namespace WIDESEAWCS_Tasks |
| | | { |
| | | [DisallowConcurrentExecution] |
| | | public class StackerCraneJob : IJob |
| | | { |
| | | private readonly TcpSocketServer _TcpSocket; |
| | | private static readonly ConcurrentDictionary<string, StackerSocketState> _socketStates = new(); |
| | | private static int _eventSubscribedFlag; |
| | | private readonly ITaskService _taskService; |
| | | private readonly ITaskExecuteDetailService _taskExecuteDetailService; |
| | | private readonly ITaskRepository _taskRepository; |
| | | private readonly IRouterService _routerService; |
| | | |
| | | public StackerCraneJob(TcpSocketServer TcpSocket, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService) |
| | | { |
| | | _TcpSocket = TcpSocket; |
| | | _taskService = taskService; |
| | | _taskExecuteDetailService = taskExecuteDetailService; |
| | | _taskRepository = taskRepository; |
| | | _routerService = routerService; |
| | | } |
| | | |
| | | public async Task Execute(IJobExecutionContext context) |
| | | { |
| | | bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value); |
| | | StackerCraneDevice Crane = (StackerCraneDevice?)value ?? new StackerCraneDevice(); |
| | | if (!flag || Crane.IsNullOrEmpty()) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | string ipAddress = Crane.IPAddress; |
| | | |
| | | // è·åæåå»ºç¶æ |
| | | StackerSocketState state = _socketStates.GetOrAdd(ipAddress, _ => new StackerSocketState |
| | | { |
| | | IPAddress = ipAddress, |
| | | StackerCrane = Crane |
| | | }); |
| | | |
| | | // æ´æ°è®¾å¤ä¿¡æ¯ |
| | | state.StackerCrane = Crane; |
| | | |
| | | // æ£æ¥æ¯å¦æè¯¥å®¢æ·ç«¯è¿æ¥ |
| | | var clientIds = _TcpSocket.GetClientIds(); |
| | | if (!clientIds.Contains(ipAddress)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | // 订é
䏿¬¡ message äºä»¶ï¼å
¨å±ä¸æ¬¡ï¼ |
| | | if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0) |
| | | { |
| | | _TcpSocket.MessageReceived += _TcpSocket_MessageReceived; |
| | | _TcpSocket.RobotReceived += _TcpSocket_RobotReceived; |
| | | } |
| | | |
| | | if (!state.IsEventSubscribed) |
| | | { |
| | | _TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client); |
| | | Task clientTask = _TcpSocket.HandleClientAsync(client, Crane.IPAddress, _TcpSocket._cts.Token, state); |
| | | state.IsEventSubscribed = true; |
| | | } |
| | | // è·åå½åéä¸åä»»å¡å¹¶ç¼åå°ç¶æä¸ |
| | | Dt_Task? task = GetTask(Crane); |
| | | if (task != null && state.CurrentTask == null && state.StackerRunMode == (int)StackerModeEnum.Automatic && state.StackerError == (int)StackerErrorEnum.Normal && state.StackerTaskNum == 0) |
| | | { |
| | | SendStackerTask(task, state); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// äºä»¶ï¼å®¢æ·ç«¯æå¼è¿æ¥æ¶è§¦å |
| | | /// </summary> |
| | | /// <param name="clientId"></param> |
| | | /// <returns></returns> |
| | | private Task<string?> _TcpSocket_RobotReceived(string clientId) |
| | | { |
| | | _socketStates.TryRemove(clientId, out _); |
| | | return Task.FromResult<string?>(null); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// äºä»¶ï¼æ¶å°æ¶æ¯æ¶è§¦å |
| | | /// </summary> |
| | | /// <param name="message"></param> |
| | | /// <param name="isJson"></param> |
| | | /// <param name="client"></param> |
| | | /// <param name="state"></param> |
| | | /// <returns></returns> |
| | | private async Task<string?> _TcpSocket_MessageReceived(string message, bool isJson, TcpClient client, StackerSocketState state) |
| | | { |
| | | string messageLower = message.ToUpperInvariant(); |
| | | |
| | | //åºåå åæºåéå½ä»¤ |
| | | try |
| | | { |
| | | |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | /// <summary> |
| | | /// å åæºä»»å¡ä¸å |
| | | /// </summary> |
| | | private bool SendStackerTask(Dt_Task task, StackerSocketState state) |
| | | { |
| | | string message = "<"; |
| | | //è·å对起å§åç»ç¹ä½ç½®è¿è¡è§£æ |
| | | message += ">"; |
| | | return _TcpSocket.SendToDeviceAsync(state.IPAddress, message).Result; |
| | | } |
| | | |
| | | private Dt_Task? GetTask(StackerCraneDevice stackerCrane) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | public class StackerSocketState |
| | | { |
| | | public string IPAddress { get; set; } = string.Empty; |
| | | |
| | | /// <summary> |
| | | /// æ¯å¦å·²è®¢é
æ¶æ¯äºä»¶ |
| | | /// </summary> |
| | | public bool IsEventSubscribed { get; set; } |
| | | |
| | | /// <summary> |
| | | /// å åæºå½åä»»å¡å· |
| | | /// </summary> |
| | | public int? StackerTaskNum { get; set; } |
| | | |
| | | /// <summary> |
| | | /// å åæºè¿è¡æ¨¡å¼ |
| | | /// </summary> |
| | | public int? StackerRunMode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// å åæºæ
éç¶æ |
| | | /// </summary> |
| | | public int? StackerError { get; set; } |
| | | |
| | | /// <summary> |
| | | /// å åæºè®¾å¤ä¿¡æ¯ |
| | | /// </summary> |
| | | public StackerCraneDevice? StackerCrane { get; set; } |
| | | |
| | | /// <summary> |
| | | /// åè´§ä½ç½® |
| | | /// </summary> |
| | | public string? PickPosition { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æ¾è´§ä½ç½® |
| | | /// </summary> |
| | | public string? PutPosition{ get; set; } |
| | | |
| | | /// <summary> |
| | | /// å½åä»»å¡ |
| | | /// </summary> |
| | | public Dt_Task? CurrentTask { get; set; } |
| | | } |
| | | public enum StackerModeEnum |
| | | { |
| | | /// <summary> |
| | | /// èªå¨æ¨¡å¼ |
| | | /// </summary> |
| | | Automatic = 1, |
| | | /// <summary> |
| | | /// åæ¢æ¨¡å¼ |
| | | /// </summary> |
| | | Unkonw = 2, |
| | | /// <summary> |
| | | /// æå¨æ¨¡å¼ |
| | | /// </summary> |
| | | Manual = 3 |
| | | } |
| | | public enum StackerErrorEnum |
| | | { |
| | | /// <summary> |
| | | /// æ£å¸¸ |
| | | /// </summary> |
| | | Normal = 1, |
| | | /// <summary> |
| | | /// æ
é |
| | | /// </summary> |
| | | Fault = 2 |
| | | } |
| | | } |