123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899 |
- using ProjectManagementSystem.Common.Config;
- using ProjectManagementSystem.Common.Extenions;
- using ProjectManagementSystem.Common.Function;
- using ProjectManagementSystem.Common.Logger;
- using ProjectManagementSystem.Common.Models;
- using ProjectManagementSystem.Common.Models.Crms;
- using ProjectManagementSystem.Common.Service;
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- namespace ProjectManagementSystem.Common.Core
- {
- public class PackControlCrms
- {
- private static PackControlCrms m_instance;
- private bool firstStart = true;
- private bool agvHeartbeat;
- private uint counter;
- private bool[] forceWrite = new bool[20];
- public double TimeConsumption { get; private set; }
- public ConcurrentDictionary<string, PackStationV2> StationDictionary { get; set; } = new ConcurrentDictionary<string, PackStationV2>();
- public static PackControlCrms Instance
- {
- get
- {
- if (m_instance == null)
- {
- m_instance = new PackControlCrms();
- if (!m_instance.Initialize())
- {
- m_instance = null;
- }
- }
- return m_instance;
- }
- }
- private PackControlCrms()
- {
- }
- private bool Initialize()
- {
- try
- {
- var assemblyName = this.GetType().Assembly.GetName().Name;
- var nameSpace = this.GetType().Namespace;
- string fullClassName = $"{nameSpace}.PackInteractionCrmsBase";
- var packInteration = InstanceConstructor.GetInstance<IPackInteractionCrms>(assemblyName, fullClassName);
- if (packInteration == null)
- {
- throw new NullReferenceException("创建的对象为null");
- }
- var configList = ExcelConfig.Instance.RouteConfigList;
- for (int i = 0; i < configList.Count; i++)
- {
- var config = configList[i];
- var data = StationDictionary.TryGetValue(config.LocationCode, out var station) ? station : new PackStationV2();
- data.Id = config.LocationCode;
- data.Config = config;
- var sClassName = config.LocationCode.GetLocationMember("PACK对接类");
- if (!string.IsNullOrEmpty(sClassName))
- {
- var sPackInteraction = InstanceConstructor.GetInstance<IPackInteractionCrms>(assemblyName, $"{nameSpace}.{sClassName}");
- if (sPackInteraction == null)
- {
- throw new NullReferenceException("创建的对象为null");
- }
- data.Interaction = sPackInteraction;
- }
- else
- {
- data.Interaction = packInteration;
- }
- StationDictionary.AddOrUpdate(data.Id, data, (key, value) => data);
- }
- Task.Factory.StartNew(UserThread, TaskCreationOptions.LongRunning);
- return true;
- }
- catch (Exception ex)
- {
- CLog.Instance.SystemLog.WriteException("PackControl Initialize", ex);
- }
- return false;
- }
- private void UpdateStationDict()
- {
- var packStationInfos = Crms.PmsApi.GetPackStationAGVAll();
- if (packStationInfos == null)
- {
- Thread.Sleep(5000);
- return;
- }
- var agvDataList = Crms.PmsApi.GetAllCarrier();
- if (agvDataList == null) return;
- var taskList = Crms.PmsApi.GetTaskList();
- if (taskList == null) return;
- var agvDataOnlineList = agvDataList.Where(d => d.Online);
- var agvDataDict = agvDataList.ToDictionary(d => d.AgvID);
- var packStationInfoDict = packStationInfos.ToDictionary(d => d.id);
- foreach (var item in packStationInfos)
- {
- if (item.carrierPackStatuses != null)
- {
- foreach (var item2 in item.carrierPackStatuses)
- {
- agvDataDict.TryGetValue(item2.carrier, out var agvData);
- item2.AgvData = agvData ?? null;
- }
- }
- }
- var callHeartbeat = counter % 2 == 0;
- if (callHeartbeat)
- {
- agvHeartbeat = !agvHeartbeat;
- }
- DateTime start = DateTime.Now;
- Parallel.ForEach(StationDictionary.Values, delegate (PackStationV2 data, ParallelLoopState loopState)
- {
- try
- {
- if (callHeartbeat)
- {
- data.Interaction.Heartbeat(data, agvHeartbeat);
- }
- packStationInfoDict.TryGetValue(data.Id, out var packStationInfo);
- data.AgvList = packStationInfo?.carrierPackStatuses;
- //工位AGV状态变化
- if (data.AgvList?.Count > 0)
- {
- foreach (var item in data.AgvList)
- {
- var lastItem = data.LastAgvList?.FirstOrDefault(d => d.carrier == item.carrier);
- if (item.agvPositionStatus != lastItem?.agvPositionStatus)
- {
- data.Interaction.AgvPositionStatusChanged(data, item, lastItem, taskList);
- }
- if (item.agvStationStatus != lastItem?.agvStationStatus)
- {
- data.Interaction.AgvStationStatusChanged(data, item, lastItem, taskList);
- }
- }
- }
- else if (data.LastAgvList?.Count > 0)
- {
- foreach (var lastItem in data.LastAgvList)
- {
- data.Interaction.AgvPositionStatusChanged(data, null, lastItem, taskList);
- data.Interaction.AgvStationStatusChanged(data, null, lastItem, taskList);
- }
- }
- data.LastAgvList = data.AgvList;
- //小车数据
- data.AgvApproachingData = data.AgvList?.FirstOrDefault(d => d.agvPositionStatus == EPackAgvPositionStatus.BeforeRequest);
- data.AgvRequestEnterData = data.AgvList?.FirstOrDefault(d => d.agvPositionStatus == EPackAgvPositionStatus.RequestVertex);
- data.AgvEnteringData = data.AgvList?.FirstOrDefault(d => d.agvPositionStatus == EPackAgvPositionStatus.Entering);
- data.AgvAtStationData = data.AgvList?.FirstOrDefault(d => d.agvPositionStatus == EPackAgvPositionStatus.StationVertex);
- data.AgvLeavingData = data.AgvList?.FirstOrDefault(d => d.agvPositionStatus == EPackAgvPositionStatus.Leaving);
- data.AgvLeaveDoneData = data.AgvList?.FirstOrDefault(d => d.agvPositionStatus == EPackAgvPositionStatus.ReleaseVertex);
- data.AgvIdApproaching = data.AgvApproachingData?.carrier ?? 0;
- data.AgvIdRequestEnter = data.AgvRequestEnterData?.carrier ?? 0;
- data.AgvIdEntering = data.AgvEnteringData?.carrier ?? 0;
- data.AgvIdAtStation = data.AgvAtStationData?.carrier ?? 0;
- data.AgvIdLeaving = data.AgvLeavingData?.carrier ?? 0;
- data.AgvIdLeaveDone = data.AgvLeaveDoneData?.carrier ?? 0;
- data.Interaction.CustomProcess(data, firstStart, forceWrite);
- //工位AGV状态对接
- if (data.AgvList != null)
- {
- foreach (var item in data.AgvList)
- {
- switch (item.agvStationStatus)
- {
- case EPackAgvStationStatus.None:
- break;
- case EPackAgvStationStatus.WaitTask:
- data.Interaction.WaitTask(data, item, taskList);
- break;
- case EPackAgvStationStatus.WaitEnter:
- data.Interaction.WaitEnter(data, item, taskList);
- break;
- case EPackAgvStationStatus.AtRequest:
- data.Interaction.AtRequest(data, item, taskList);
- break;
- case EPackAgvStationStatus.WaitRequest:
- data.Interaction.WaitRequest(data, item, taskList);
- break;
- case EPackAgvStationStatus.Entering:
- data.Interaction.Entering(data, item, taskList);
- break;
- case EPackAgvStationStatus.AtStation:
- data.Interaction.AtStation(data, item, taskList);
- break;
- case EPackAgvStationStatus.WaitStation:
- data.Interaction.WaitStation(data, item, taskList);
- break;
- case EPackAgvStationStatus.Leaving:
- data.Interaction.Leaving(data, item, taskList);
- break;
- case EPackAgvStationStatus.AtLeave:
- data.Interaction.AtLeave(data, item, taskList);
- break;
- case EPackAgvStationStatus.WaitLeave:
- data.Interaction.WaitLeave(data, item, taskList);
- break;
- default:
- break;
- }
- }
- }
- data.Interaction.LastProcess(data);
- }
- catch (Exception ex)
- {
- data.Message = ex.Message;
- }
- data.TimeConsumption = Math.Round((DateTime.Now - start).TotalMilliseconds);
- });
- Parallel.ForEach(agvDataOnlineList, delegate (ResultAgvData agvData, ParallelLoopState loopState)
- {
- try
- {
- PlcStopAgv(agvData);
- }
- catch (Exception)
- {
- }
- });
- }
- private void PlcStopAgv(ResultAgvData agvData)
- {
- //查找AGV所在的正在进入和正在离开的所有工位
- var stations = StationDictionary.Values.Where(d =>
- {
- if (d.AgvList == null || d.AgvList.Count == 0) return false;
- return d.AgvList.Exists(s => s.carrier == agvData.AgvID && (s.agvPositionStatus == EPackAgvPositionStatus.Entering || s.agvPositionStatus == EPackAgvPositionStatus.Leaving));
- }).ToList();
- if (stations.Count == 0)
- {
- return;
- }
- string msg = null;
- //从AGV所在的工位中,获取需要停车的工位
- var stopStation = stations.FirstOrDefault(d =>
- {
- if (d.AgvList.Exists(s => s.carrier == agvData.AgvID && s.agvPositionStatus == EPackAgvPositionStatus.Entering))
- {
- var result = d.Interaction.StopAgvEntering(d, out string tempMsg);
- msg += $"{d.Config.LocationCode} {tempMsg}; ";
- if (result)
- {
- return true;
- }
- }
- if (d.AgvList.Exists(s => s.carrier == agvData.AgvID && s.agvPositionStatus == EPackAgvPositionStatus.Leaving))
- {
- var result = d.Interaction.StopAgvLeaving(d, out string tempMsg);
- msg += $"{d.Config.LocationCode} {tempMsg}; ";
- if (result)
- {
- return true;
- }
- }
- return false;
- });
- bool needPauseAgv = stopStation != null;
- bool agvPaused = agvData.AlarmList?.Exists(d => d.alarmId == 36) ?? false;
- if (needPauseAgv)
- {
- if (!agvPaused)
- {
- bool result = Crms.PmsApi.CarrierPause(agvData.AgvID);
- CLog.Instance.TaskLog.WriteInfo($"{stopStation?.Id} {agvData.AgvID}# 暂停小车{result.ToChineseString()} ({msg})");
- }
- }
- else
- {
- if (agvPaused)
- {
- bool result = Crms.PmsApi.CarrierResume(agvData.AgvID);
- CLog.Instance.TaskLog.WriteInfo($"{stations.FirstOrDefault()?.Id} {agvData.AgvID}# 恢复小车{result.ToChineseString()} ({msg})");
- }
- }
- }
- private void UserThread()
- {
- CLog.Instance.SystemLog.WriteDebug($"PackControlCrms已启动");
- while (true)
- {
- DateTime loopStartTime = DateTime.Now;
- try
- {
- //错开刷新
- var mod = counter % 20;
- if (mod >= 0 && mod <= forceWrite.Length)
- {
- for (int i = 0; i < forceWrite.Length; i++)
- {
- forceWrite[i] = mod == i;
- }
- }
- //DateTime start = DateTime.Now;
- UpdateStationDict();
- //System.Diagnostics.Trace.WriteLine($"UpdateStationDict {string.Join(" ", forces.Select(d => { return d ? "1" : "0"; }))} 耗时:{(DateTime.Now - start).TotalMilliseconds:F1} ms");
- }
- catch (Exception ex)
- {
- CLog.Instance.SystemLog.WriteException("PackControlCrms", ex);
- Thread.Sleep(5000);
- }
- firstStart = false;
- counter++;
- TimeConsumption = (DateTime.Now - loopStartTime).TotalMilliseconds;
- Thread.Sleep(500);
- }
- }
- }
- public class PackStationV2
- {
- public string Id { get; set; }
- public RouteConfig Config { get; set; }
- public IPackInteractionCrms Interaction { get; set; }
- public DateTime LastTaskAddTime { get; set; }
- public DateTime LastPreTaskAddTime { get; set; }
- public bool TaskAddCooled { get { return Math.Abs((DateTime.Now - LastTaskAddTime).TotalSeconds) > 5; } }
- public bool PreTaskAddCooled { get { return Math.Abs((DateTime.Now - LastPreTaskAddTime).TotalSeconds) > 5; } }
- public List<PackCarrier> LastAgvList { get; set; }
- public List<PackCarrier> AgvList { get; set; }
- public PackCarrier AgvApproachingData { get; set; }
- public PackCarrier AgvRequestEnterData { get; set; }
- public PackCarrier AgvEnteringData { get; set; }
- public PackCarrier AgvAtStationData { get; set; }
- public PackCarrier AgvLeavingData { get; set; }
- public PackCarrier AgvLeaveDoneData { get; set; }
- public int AgvIdApproaching { get; set; }
- public int AgvIdRequestEnter { get; set; }
- public int AgvIdEntering { get; set; }
- public int AgvIdAtStation { get; set; }
- public int AgvIdLeaving { get; set; }
- public int AgvIdLeaveDone { get; set; }
- public bool AgvApproaching { get; set; }
- public bool AgvRequestEnter { get; set; }
- public bool AgvEntering { get; set; }
- public bool AgvAtStation { get; set; }
- public bool AgvLeaving { get; set; }
- public bool AgvLeaveDone { get; set; }
- public bool AgvInArea { get { return AgvEntering || AgvAtStation || AgvLeaving; } }
- public bool AgvAtStationRise { get; set; }
- public bool AgvAtStationFall { get; set; }
- public int AgvAtStationAgvId { get; set; }
- public int AgvAtStationAlarmId { get; set; }
- public bool AgvAtStationAlarm { get; set; }
- public string AgvAtStationMaterial { get; set; }
- public string Message { get; set; }
- public string MessageWaitRequest { get; set; }
- public string MessageWaitStation { get; set; }
- public string MessageWaitLeave { get; set; }
- public double TimeConsumption { get; set; }
- }
- public interface IPackInteractionCrms
- {
- void Heartbeat(PackStationV2 data, bool agvHeartbeat);
- void CustomProcess(PackStationV2 data, bool firstStart, bool[] forceWrite);
- void LastProcess(PackStationV2 data);
- string GetNextLocation(PackStationV2 data, out string templateName, out string msg);
- bool StopAgvEntering(PackStationV2 data, out string msg);
- bool StopAgvLeaving(PackStationV2 data, out string msg);
- void AgvPositionStatusChanged(PackStationV2 data, PackCarrier agv, PackCarrier lastAgv, List<TaskData> taskList);
- void AgvStationStatusChanged(PackStationV2 data, PackCarrier agv, PackCarrier lastAgv, List<TaskData> taskList);
- void WaitTask(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void WaitEnter(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void AtRequest(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void WaitRequest(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void Entering(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void AtStation(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void WaitStation(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void Leaving(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void AtLeave(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void WaitLeave(PackStationV2 data, PackCarrier agv, List<TaskData> taskList);
- void HandleAgvToPlc<T>(PackStationV2 data, PackCarrier agv, string plcAddrDesc, T agvValue);
- }
- public class PackInteractionCrmsBase : IPackInteractionCrms
- {
- protected int successCode = 20000;
- protected int unnecessaryCode = -20000;
- protected int failedCode = -1;
- protected bool ReadValue<T>(RouteConfig config, string plcAddrDesc, T plcValue, out T readValue, out string msg)
- {
- readValue = default(T);
- if (string.IsNullOrEmpty(config.PlcIpAddr))
- {
- msg = $"没有配置IP地址(PLC)";
- return false;
- }
- var plcAddr = config.LocationCode.GetLocationMember(plcAddrDesc);
- if (string.IsNullOrEmpty(plcAddr))
- {
- msg = $"没有配置地址:{plcAddrDesc}";
- return false;
- }
- if (!config.PlcConnected)
- {
- msg = $"PLC未连接";
- return false;
- }
- var result = config.PlcReadWrite.ReadValue(plcAddr, plcValue, out var read);
- if (!read.IsSuccess)
- {
- msg = $"读取{plcAddrDesc} {plcAddr}失败 Code:{read.ErrorCode} Message:{read.Message}";
- return false;
- }
- msg = $"读取{plcAddrDesc} {plcAddr} = {read.Content}";
- readValue = read.Content;
- return result;
- }
- protected int ReadPlcValue(RouteConfig config, string plcAddrDesc, out string msg)
- {
- if (string.IsNullOrEmpty(config.PlcIpAddr))
- {
- msg = $"没有配置IP地址(PLC)";
- return unnecessaryCode;
- }
- var plcAddr = config.LocationCode.GetLocationMember(plcAddrDesc);
- if (string.IsNullOrEmpty(plcAddr))
- {
- msg = $"没有配置地址:{plcAddrDesc}";
- return unnecessaryCode;
- }
- if (!config.PlcConnected)
- {
- msg = $"PLC未连接";
- return failedCode;
- }
- var read = config.PlcReadWrite.ReadBool(plcAddr);
- if (!read.IsSuccess)
- {
- msg = $"读取{plcAddrDesc} {plcAddr}失败 Code:{read.ErrorCode} Message:{read.Message}";
- return failedCode;
- }
- msg = $"读取{plcAddrDesc} {plcAddr} = {read.Content}";
- return read.Content ? successCode : 0;
- }
- protected string GetAgvDataString(ResultAgvData agvData)
- {
- return agvData == null ? null : $"({agvData.AgvID}# 路段:{agvData.GraphEdge} 导航点:{agvData.GraphVertex})";
- }
- protected string GetAllowStatusString(int allowStatus)
- {
- return allowStatus == 1 ? "通行" : "管制";
- }
- public virtual void Heartbeat(PackStationV2 data, bool agvHeartbeat)
- {
- //心跳信号处理
- var config = data.Config;
- if (config.PlcConnected
- && config.PlcReadWrite != null
- && !string.IsNullOrEmpty(config.PlcHeartbearAddr_AGV))
- {
- var tempResult2 = config.PlcReadWrite.Write(config.PlcHeartbearAddr_AGV, agvHeartbeat);
- if (!tempResult2.IsSuccess)
- {
- CLog.Instance.SystemLog.WriteInfo($"{config.LocationCode} {config.PlcIpAddr} 写入AGV心跳:{tempResult2.IsSuccess.ToChineseString()} {config.PlcHeartbearAddr_AGV} Code:{tempResult2.ErrorCode} Message:{tempResult2.Message}");
- }
- }
- }
- public virtual void CustomProcess(PackStationV2 data, bool firstStart, bool[] forceWrite)
- {
- //先处理到位AGV相关信息
- var agvId = data.AgvAtStationData == null ? 0 : data.AgvAtStationData.carrier;
- if (data.AgvAtStationAgvId != agvId || firstStart || forceWrite[8])
- {
- data.AgvAtStationAgvId = agvId;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV编号", (short)data.AgvAtStationAgvId);
- }
- var alarmId = data.AgvAtStationData?.AgvData?.AlarmList == null || data.AgvAtStationData.AgvData.AlarmList.Count == 0 ?
- 0 : data.AgvAtStationData.AgvData.AlarmList.OrderByDescending(d => d.alarmLevel).FirstOrDefault().alarmId;
- if (data.AgvAtStationAlarmId != alarmId || firstStart || forceWrite[9])
- {
- data.AgvAtStationAlarmId = alarmId;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV报警代码", (short)data.AgvAtStationAlarmId);
- }
- var agvAlarm = alarmId > 0;
- if (data.AgvAtStationAlarm != agvAlarm || firstStart || forceWrite[10])
- {
- data.AgvAtStationAlarm = agvAlarm;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV报警", data.AgvAtStationAlarm);
- }
- if (!string.IsNullOrWhiteSpace(data.Id.GetLocationMember("AGV物料")))
- {
- string agvMaterial = string.Empty;
- if (agvId > 0)
- {
- var res = Crms.PmsTaskService.GetAgvMaterial(new AgvMaterialDto { AgvId = agvId });
- var agvMaterialDto = res?.data as AgvMaterialDto;
- agvMaterial = agvMaterialDto?.MaterialBarcode ?? string.Empty;
- }
- if (data.AgvAtStationMaterial != agvMaterial || firstStart || forceWrite[11])
- {
- data.AgvAtStationMaterial = agvMaterial;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV物料", data.AgvAtStationMaterial);
- }
- }
- //工位相关信号
- var result = data.AgvApproachingData != null;
- if (data.AgvApproaching != result || firstStart || forceWrite[0])
- {
- data.AgvApproaching = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvApproachingData, "AGV正在接近", data.AgvApproaching);
- }
- result = data.AgvRequestEnterData != null;
- if (data.AgvRequestEnter != result || firstStart || forceWrite[1])
- {
- data.AgvRequestEnter = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvRequestEnterData, "AGV请求进入", data.AgvRequestEnter);
- }
- result = data.AgvEnteringData != null;
- if (data.AgvEntering != result || firstStart || forceWrite[2])
- {
- data.AgvEntering = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvEnteringData, "AGV正在进入", data.AgvEntering);
- }
- result = data.AgvAtStationData != null;
- if (data.AgvAtStation != result || firstStart || forceWrite[3])
- {
- data.AgvAtStation = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV到位", data.AgvAtStation);
- }
- result = data.AgvLeavingData != null;
- if (data.AgvLeaving != result || firstStart || forceWrite[4])
- {
- data.AgvLeaving = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvLeavingData, "AGV正在离开", data.AgvLeaving);
- }
- result = data.AgvLeaveDoneData != null;
- if (data.AgvLeaveDone != result || firstStart || forceWrite[5])
- {
- data.AgvLeaveDone = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvLeaveDoneData, "AGV离开完成", data.AgvLeaveDone);
- }
- //LogicBit 9 上升到位状态 512
- //LogicBit 10 下降到位状态 1024
- result = data.AgvAtStationData?.AgvData != null ? data.AgvAtStationData.AgvData.LogicBits.GetBitVaule(9) : false;
- if (data.AgvAtStationRise != result || firstStart || forceWrite[6])
- {
- data.AgvAtStationRise = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV上升到位", data.AgvAtStationRise);
- }
- result = data.AgvAtStationData?.AgvData != null ? data.AgvAtStationData.AgvData.LogicBits.GetBitVaule(10) : false;
- if (data.AgvAtStationFall != result || firstStart || forceWrite[7])
- {
- data.AgvAtStationFall = result;
- data.Interaction.HandleAgvToPlc(data, data.AgvAtStationData, "AGV下降到位", data.AgvAtStationFall);
- }
- }
- public virtual void LastProcess(PackStationV2 data)
- {
- //消息清理
- if (data.AgvIdAtStation == 0)
- {
- data.Message = null;
- }
- if (data.AgvIdApproaching == 0 && data.AgvIdRequestEnter == 0)
- {
- data.MessageWaitRequest = null;
- }
- if (data.AgvIdEntering == 0 && data.AgvIdAtStation == 0)
- {
- data.MessageWaitStation = null;
- }
- if (data.AgvIdLeaving == 0 && data.AgvIdLeaveDone == 0)
- {
- data.MessageWaitLeave = null;
- }
- }
- public virtual string GetNextLocation(PackStationV2 data, out string templateName, out string msg)
- {
- var config = data.Config;
- templateName = null;
- var result = ReadPlcValue(config, "PLC放行", out msg);
- if (result <= 0)
- {
- return null;
- }
- string nextLocation = config.LocationCode.GetLocationMember("下个工位");
- if (string.IsNullOrWhiteSpace(nextLocation))
- {
- msg = $"{msg} 没配置下个工位";
- return null;
- }
- nextLocation = nextLocation.ToValueArray<string>()[0];
- //有放行信号
- var result2 = ReadPlcValue(config, "PLC返修", out var msg2);
- msg = $"{msg} {msg2}";
- if (result2 == unnecessaryCode || result2 == 0)
- {
- templateName = config.LocationCode.GetLocationMember("后任务模板");
- return nextLocation;
- }
- if (result2 < 0)
- {
- return null;
- }
- string ngLocation = config.LocationCode.GetLocationMember("返修工位");
- if (string.IsNullOrWhiteSpace(ngLocation))
- {
- msg = $"{msg} 没配置返修工位";
- return null;
- }
- templateName = config.LocationCode.GetLocationMember("返修任务模板");
- return ngLocation.ToValueArray<string>()[0];
- }
- public virtual bool StopAgvEntering(PackStationV2 data, out string msg)
- {
- var result = ReadPlcValue(data.Config, "PLC急停", out msg);
- if (result == failedCode || result == 0)
- {
- return true;
- }
- result = ReadPlcValue(data.Config, "PLC进入互锁", out msg);
- if (result == failedCode || result == 0)
- {
- return true;
- }
- return false;
- }
- public virtual bool StopAgvLeaving(PackStationV2 data, out string msg)
- {
- var result = ReadPlcValue(data.Config, "PLC急停", out msg);
- if (result == failedCode || result == 0)
- {
- return true;
- }
- result = ReadPlcValue(data.Config, "PLC离开互锁", out msg);
- if (result == failedCode || result == 0)
- {
- return true;
- }
- return false;
- }
- public virtual void AgvPositionStatusChanged(PackStationV2 data, PackCarrier agv, PackCarrier lastAgv, List<TaskData> taskList)
- {
- var config = data.Config;
- CLog.Instance.TaskLog.WriteDebug($"{config.LocationCode} 位置状态 {lastAgv?.agvPositionStatus} -> {agv?.agvPositionStatus} {GetAgvDataString(agv?.AgvData)}");
- }
- public virtual void AgvStationStatusChanged(PackStationV2 data, PackCarrier agv, PackCarrier lastAgv, List<TaskData> taskList)
- {
- var config = data.Config;
- CLog.Instance.TaskLog.WriteDebug($"{config.LocationCode} 工位状态 {lastAgv?.agvStationStatus} -> {agv?.agvStationStatus} {GetAgvDataString(agv?.AgvData)}");
- }
- public virtual void WaitTask(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- if (!data.PreTaskAddCooled) return;
- if (agv.AgvData?.Status != 0) return;
- if (taskList.FirstOrDefault(d => d.Carrier == agv.carrier || d.BindingAGVNumber == agv.carrier) != null) return;
- var config = data.Config;
- CLog.Instance.TaskLog.WriteInfo($"{config.LocationCode} 添加前置任务 {GetAgvDataString(agv.AgvData)}");
- PmsTaskInfoDto dto = new PmsTaskInfoDto();
- dto.LocationCode = data.Id;
- dto.TargetLocationCode = data.Id;
- dto.Carrier = agv.carrier;
- dto.CarrierType = "0";
- dto.TemplateName = config.LocationCode.GetLocationMember("前任务模板");
- Crms.PmsTaskService.TaskAddNoCheck(dto, new string[] { });
- data.LastPreTaskAddTime = DateTime.Now;
- }
- public virtual void WaitEnter(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- }
- public virtual void AtRequest(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- }
- public virtual void WaitRequest(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- if (agv.enter == 1) return;
- var config = data.Config;
- var result = ReadPlcValue(config, "PLC允许进入", out var msg);
- var allowStatus = result > 0 ? 1 : 0;
- msg = $"{msg} {GetAgvDataString(agv.AgvData)}";
- if (agv.enter != allowStatus)
- {
- var result2 = Crms.PmsApi.AllowAgv(data.Id, agv.carrier, allowStatus, 0, 0);
- msg = $"{msg} 请求点{GetAllowStatusString(allowStatus)}{result2.ToChineseString()}";
- }
- if (data.MessageWaitRequest != msg)
- {
- CLog.Instance.TaskLog.WriteInfo($"{config.LocationCode} {msg}");
- }
- data.MessageWaitRequest = msg;
- }
- public virtual void Entering(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- }
- public virtual void AtStation(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- if (!data.TaskAddCooled) return;
- if (taskList.FirstOrDefault(d => d.TaskType != ETaskType.Charge && (d.Carrier == agv.carrier || d.BindingAGVNumber == agv.carrier)) != null) return;
- var nextLocation = GetNextLocation(data, out var templateName, out var msg);
- if (data.Message != msg)
- {
- CLog.Instance.TaskLog.WriteInfo($"{data.Id} {msg} {GetAgvDataString(agv.AgvData)}");
- }
- data.Message = msg;
- if (string.IsNullOrWhiteSpace(nextLocation))
- {
- return;
- }
- PmsTaskInfoDto dto = new PmsTaskInfoDto();
- dto.LocationCode = data.Id;
- dto.TargetLocationCode = nextLocation;
- dto.Carrier = agv.carrier;
- dto.CarrierType = "0";
- dto.TemplateName = templateName;
- Crms.PmsTaskService.TaskAddNoCheck(dto, new string[] { });
- data.LastTaskAddTime = DateTime.Now;
- data.Message = null;
- }
- public virtual void WaitStation(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- if (agv.leaver == 1) return;
- var config = data.Config;
- var result = ReadPlcValue(config, "PLC放行", out var msg);
- var allowStatus = result > 0 ? 1 : 0;
- msg = $"{msg} {GetAgvDataString(agv.AgvData)}";
- if (agv.leaver != allowStatus)
- {
- var result2 = Crms.PmsApi.AllowAgv(data.Id, agv.carrier, 0, allowStatus, 0);
- msg = $"{msg} 工位点{GetAllowStatusString(allowStatus)}{result2.ToChineseString()}";
- }
- if (data.MessageWaitStation != msg)
- {
- CLog.Instance.TaskLog.WriteInfo($"{config.LocationCode} {msg}");
- }
- data.MessageWaitStation = msg;
- }
- public virtual void Leaving(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- }
- public virtual void AtLeave(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- }
- public virtual void WaitLeave(PackStationV2 data, PackCarrier agv, List<TaskData> taskList)
- {
- if (agv.release == 1) return;
- var config = data.Config;
- var result = ReadPlcValue(config, "PLC离开完成", out var msg);
- var allowStatus = result > 0 ? 1 : 0;
- msg = $"{msg} {GetAgvDataString(agv.AgvData)}";
- if (agv.release != allowStatus)
- {
- var result2 = Crms.PmsApi.AllowAgv(data.Id, agv.carrier, 0, 0, allowStatus);
- msg = $"{msg} 释放点{GetAllowStatusString(allowStatus)}{result2.ToChineseString()}";
- }
- if (data.MessageWaitLeave != msg)
- {
- CLog.Instance.TaskLog.WriteInfo($"{config.LocationCode} {msg}");
- }
- data.MessageWaitLeave = msg;
- }
- public virtual void HandleAgvToPlc<T>(PackStationV2 data, PackCarrier agv, string plcAddrDesc, T agvValue)
- {
- var config = data.Config;
- if (!config.PlcConnected || config.PlcReadWrite == null) return;
- string plcAddr = config.LocationCode.GetLocationMember(plcAddrDesc);
- if (string.IsNullOrWhiteSpace(plcAddr)) return;
- var readResult = config.PlcReadWrite.ReadValue(plcAddr, agvValue, out var _);
- if (readResult) return;
- var result = config.PlcReadWrite.WriteValue(plcAddr, agvValue);
- var agvInfo = GetAgvDataString(agv?.AgvData);
- CLog.Instance.TaskLog.WriteInfo($"{config.LocationCode} {plcAddrDesc} {plcAddr} = {agvValue} 写入{result.IsSuccess.ToChineseString()} {agvInfo}");
- }
- }
- }
|