using SHJX.Service.Control.Extends; using SHJX.Service.Control.Common.Assets; using shjxCamera; namespace SHJX.Service.Control.Schedules { [EnableScheduling] public class SearchTaskSchedule : IScheduler { private static readonly ILogger logger = LogFactory.BuildLogger(typeof(SearchTaskSchedule)); private static TaskExtend _extend; private static IDataManager _dataManager; private static ReadConfigUtil _readConfig; public SearchTaskSchedule(IDataManager dataManager, TaskExtend extend, ReadConfigUtil readConfig) { _extend = extend; _readConfig = readConfig; _dataManager = dataManager; } [Scheduled("SearchAddLiquidTask", 2000)] public void SearchAddLiquidTask() { EquipmentTask task = GetCanExecuteTask(1, PipeName.ADD_LIQUID, PipeName.ADD_LIQUID_GOBACK); if (task is null) { return; } if (task.RouteStep.Equals(PipeName.ADD_LIQUID)) { CheckRegionPositionIsEnable(AreaName.ADD_LIQUID_POSITION, out EquipmentArea area); if (area is null) { return; } task.From = task.Source; task.To = area.PointName; task.Target = nameof(task.From); OccupyDisplay(task.Source, area.PointName); } if (task.RouteStep.Equals(PipeName.ADD_LIQUID_GOBACK)) { task.From = task.To; task.To = task.Source; task.Target = nameof(task.From); } task.Status = TaskState.Waiting; int rows = _dataManager.Update(task); if (rows > 0) { WriteCache(task); } } [Scheduled("SearchDissolveTask", 1000)] public void SearchDissolveTask() { #region 判断消解温度 if (Globals.FirstDissolve) { Dictionary temperatureRes = EquipmentNames.DissolveHeating.HeatRead(); if (temperatureRes is null) { logger.LogDebug($"当前为程序运行后的首次消解,未读取到温度,返回"); return; } double settingTemperature = _readConfig.DissolveTemperatureValue; if (Convert.ToDouble(temperatureRes["pv"]) < settingTemperature) { logger.LogDebug($"当前为程序运行后的首次消解,温度未到达设定温度:{settingTemperature}度"); return; } else { Globals.FirstDissolve = false; } } #endregion EquipmentTask task = GetCanExecuteTask(2, PipeName.DISSOLVE ); if (task is null) { return; } if (task.RouteStep.Equals(PipeName.DISSOLVE)) { if (_dataManager.Query().Where(it => it.RouteStep.Equals(PipeName.DISSOLVE) && it.Source.Equals(task.Source)).Any()) { logger.LogDebug($"SearchDissolveMove - RouteCache --> {task.Source}"); return; } if (!_extend.SearchMoveCheckAheadFinishDissolveTask()) { logger.LogInformation("在SearchDissolveMove中,检测到有提前完成的任务,跳出SearchDissolveMove"); return; } if (!_extend.GetDissolveDateDifference(task.RouteStep, task.Source)) { return; } if (!_extend.EstimatedDissolveInterval()) { return; } CheckRegionPositionIsEnable(AreaName.DISSOLVE_POSITION, out EquipmentArea area); if (area is null) { return; } task.From = task.Source; task.To = area.PointName; task.Target = nameof(task.From); OccupyDisplay(task.Source, area.PointName); } task.Status = TaskState.Waiting; int rows = _dataManager.Update(task); if (rows > 0) { WriteCache(task); } } [Scheduled("SearchDissolveTask", 500)] public void SearchDissolveGoBackTask() { EquipmentTask task = GetCanExecuteTask(2, PipeName.DISSOLVE_GOBACK); if (task is null) { return; } if (task.RouteStep.Equals(PipeName.DISSOLVE_GOBACK)) { CheckRegionPositionIsEnable(AreaName.TITRATION_POSITION, out EquipmentArea area); if (area is null) { CheckRegionPositionIsEnable(AreaName.TITRATION_POSITION2, out EquipmentArea area2); if (area2 is null) { return; } task.From = task.To; task.To = area2.PointName; task.Target = nameof(task.From); OccupyDisplay(task.Source, area2.PointName); } else { task.From = task.To; task.To = area.PointName; task.Target = nameof(task.From); OccupyDisplay(task.Source, area.PointName); } } task.Status = TaskState.Waiting; int rows = _dataManager.Update(task); if (rows > 0) { WriteCache(task); } } [Scheduled("SearchTitrationTask", 1000)] public void SearchTitrationTask() { EquipmentTask task = GetCanExecuteTaskTitration(3, "D1", PipeName.TITRATION, PipeName.TITRATION_GOBACK); if (task is null) { return; } if (task.RouteStep.Equals(PipeName.TITRATION)) { EquipmentArea area = _dataManager.Query().Where(it => it.AreaName.Equals(AreaName.TITRATION_POSITION)).First(); if (area is null) { return; } area.Enable = false; _dataManager.Update(area); OccupyDisplay(task.Source, area.PointName); } else { task.From = task.To; task.To = task.Source; task.Target = nameof(task.From); } task.Status = TaskState.Waiting; int rows = _dataManager.Update(task); if (rows > 0) { WriteCache(task); } } [Scheduled("SetTitration1toTitration2Task", 1000)] public void SetTitration1toTitration2Task() { //CheckRegionPositionIsEnable("D1", out PositionHotlist area1); //CheckRegionPositionIsEnable("D2", out PositionHotlist area2); ////CheckRegionPositionIsEnable("L1", out PositionHotlist area); StringBuilder sqlBuilder = new(); sqlBuilder.Append("SELECT * From equipment_task "); sqlBuilder.Append("WHERE RouteID=@RouteID AND Status=@Status AND RouteStep='Titration' AND `To`='D2'");// AND WaveKey =@WaveKey"); sqlBuilder.Append("ORDER BY SerialKey ASC LIMIT 1"); string queryStr = sqlBuilder.ToString(); EquipmentTask task = _dataManager.Query(queryStr, new { RouteID = 3, Status = TaskState.New }).FirstOrDefault(); if (task is null) { return; } else { task.RouteStep = "Titration2"; task.RouteID = 4; _dataManager.Update(task); } } [Scheduled("SearchTitration2Task", 1000)] public void SearchTitration2Task() { EquipmentTask task = GetCanExecuteTaskTitration(4, "D2", PipeName.TITRATION2, PipeName.TITRATION2_GOBACK); if (task is null) { return; } if (task.RouteStep.Equals(PipeName.TITRATION2)) { EquipmentArea area = _dataManager.Query().Where(it => it.AreaName.Equals(AreaName.TITRATION_POSITION2)).First(); if (area is null) { return; } area.Enable = false; _dataManager.Update(area); OccupyDisplay(task.Source, area.PointName); } else { task.From = task.To; task.To = task.Source; task.Target = nameof(task.From); } task.Status = TaskState.Waiting; int rows = _dataManager.Update(task); if (rows > 0) { WriteCache(task); } } #region Common Method /// /// 检查区域位置是否可用 /// /// /// private void CheckRegionPositionIsEnable(string name, out EquipmentArea area) { area = _dataManager.Query().Where(it => it.AreaName.Equals(name) && it.Enable.Equals(true)).First(); if (area is null) { return; } //if (name == "AddLiquidPosition") //{ // PositionHotlist areaFree = _dataManager.Query().Where(it => it.PositionName.Equals("D2") && it.Enable.Equals(true)).First(); // if (areaFree is null) // { // return; // } //} //if (name == "TitrationPosition2") //{ // PositionHotlist areaFree = _dataManager.Query().Where(it => it.PositionName.Equals("L1") && it.Enable.Equals(true)).First(); // if (areaFree is null) // { // return; // } //} area.Enable = false; _dataManager.Update(area); } //private void CheckRegionPositionIsNotEnable(string name, out EquipmentArea area) //{ // area = _dataManager.Query().Where(it => it.AreaName.Equals(name) && it.Enable.Equals(true)).First(); // if (area is null) // { // return; // } // area.Enable = false; // _dataManager.Update(area); //} /// /// 位置表占用显示 /// /// /// private static void OccupyDisplay(string source, string pointName) { PositionHotlist position = _dataManager.Query().Where(it => it.PositionName.Equals(pointName)).First(); position.CurrentOccupy = source; position.Enable = false; _dataManager.Update(position); } private void CheckRegionPositionIsEnable(string name, out PositionHotlist area) { area = _dataManager.Query().Where(it => it.PositionName.Equals(name) && it.Enable.Equals(true) && it.CurrentOccupy.Equals(null)).First(); if (area is null) { return; } } /// /// 写入缓存 /// /// private void WriteCache(EquipmentTask task) { TaskPriority priority = _dataManager.Query().Where(it => it.Step.Equals(task.RouteStep)).First(); RouteCache route = new() { CreateTime = DateTime.Now, Source = task.Source, TaskKey= task.SerialKey, RouteID = task.RouteID, RouteStep = task.RouteStep, Priority= priority.Priority, Status = RouteCacheState.Waiting }; _dataManager.Add(route);//写入缓存表 } /// /// 获取可执行任务 /// /// /// /// /// private EquipmentTask GetCanExecuteTaskTitration(int id, string area,params string[] props) { StringBuilder sqlBuilder = new(); sqlBuilder.Append("SELECT TA.* From equipment_task AS TA,(SELECT SerialKey,"); sqlBuilder.Append("CASE RouteStep "); for (int i = 0; i < props.Length; i++) { sqlBuilder.Append($"WHEN '{props[i]}' THEN {i + 1} "); } sqlBuilder.Append("END as indexorder "); sqlBuilder.Append("From equipment_task "); sqlBuilder.Append("WHERE RouteID=@RouteID AND Status=@Status AND `To`=@ToWhere AND RouteStep IN "); StringBuilder inSql = new(); inSql.Append("("); for (int i = 0; i < props.Length; i++) { inSql.Append($"'{props[i]}'"); if (i + 1 < props.Length) { inSql.Append(","); } } inSql.Append(") "); sqlBuilder.Append(inSql); sqlBuilder.Append(") AS TB "); sqlBuilder.Append("WHERE TA.SerialKey=TB.SerialKey "); sqlBuilder.Append("AND NOT EXISTS(SELECT 1 From equipment_task WHERE RouteID=@RouteID AND `To`=@ToWhere AND Status NOT IN ("); string notInStr = id switch { 2 => "'1','4','7','10'", _ => "'1','4','10'" }; sqlBuilder.Append(notInStr); sqlBuilder.Append(") AND RouteStep IN "); sqlBuilder.Append(inSql); sqlBuilder.Append(") "); sqlBuilder.Append("ORDER BY TB.indexorder DESC LIMIT 1"); string queryStr = sqlBuilder.ToString(); return _dataManager.Query(queryStr, new { RouteID = id, Status = TaskState.New, ToWhere= area }).FirstOrDefault(); } private EquipmentTask GetCanExecuteTask(int id, params string[] props) { StringBuilder sqlBuilder = new(); sqlBuilder.Append("SELECT TA.* From equipment_task AS TA,(SELECT SerialKey,"); sqlBuilder.Append("CASE RouteStep "); for (int i = 0; i < props.Length; i++) { sqlBuilder.Append($"WHEN '{props[i]}' THEN {i + 1} "); } sqlBuilder.Append("END as indexorder "); sqlBuilder.Append("From equipment_task "); sqlBuilder.Append("WHERE RouteID=@RouteID AND Status=@Status AND RouteStep IN "); StringBuilder inSql = new(); inSql.Append("("); for (int i = 0; i < props.Length; i++) { inSql.Append($"'{props[i]}'"); if (i + 1 < props.Length) { inSql.Append(","); } } inSql.Append(") "); sqlBuilder.Append(inSql); sqlBuilder.Append(") AS TB "); sqlBuilder.Append("WHERE TA.SerialKey=TB.SerialKey "); sqlBuilder.Append("AND NOT EXISTS(SELECT 1 From equipment_task WHERE RouteID=@RouteID AND Status NOT IN ("); string notInStr = id switch { 2 => "'1','4','7','10'", _ => "'1','4','10'" }; sqlBuilder.Append(notInStr); sqlBuilder.Append(") AND RouteStep IN "); sqlBuilder.Append(inSql); sqlBuilder.Append(") "); sqlBuilder.Append("ORDER BY TB.indexorder DESC LIMIT 1"); string queryStr = sqlBuilder.ToString(); return _dataManager.Query(queryStr, new { RouteID = id, Status = TaskState.New }).FirstOrDefault(); } #endregion } }