using Panuon.UI.Silver; using SHJX.Service.Control.Extends; using SHJX.Service.Control.Repository; using SHJX.Service.Control.Common.Assets; using SHJX.Service.Control.Utils; using shjxCamera; namespace SHJX.Service.Control.Service { public class MainService : IMainService { private static readonly ILogger logger = LogFactory.BuildLogger(typeof(MainService)); private readonly IEventAggregator _ea; private readonly IDataManager _dataManager; private readonly PortConnect _portConnect; private readonly Repositorys _repositorys; private readonly ReadConfigUtil _readConfig; private static bool TemperatureSettingResult; private readonly ExportFile _export; private static bool CameraState ; public MainService(IEventAggregator ea, IDataManager dataManager, PortConnect portConnect, ReadConfigUtil readConfig, Repositorys repositorys, ExportFile export) { _ea = ea; _export = export; _dataManager = dataManager; _readConfig = readConfig; _portConnect = portConnect; _repositorys = repositorys; } public IMainService InitRepositorys() { _repositorys.RegisterContainer(); _repositorys.InitializationBean(); return this; } public IMainService InitService() { CreateTask.Init(_dataManager); RegisterMessager(); ClientPort(); CameraState =GetCameraState(); CameraState = CameraState && GetCameraState2(); if (CameraState) { #region 下发任务前要配置相机参数 ColorDataGraber _graber = Globals.Graber; CameraValue explosion = _dataManager.Query().First(); _graber.PresetLightParammanual(explosion, explosion.Explosion); _graber.PresetLightParammanual(explosion, explosion.Explosion); ColorData2Graber _graber2 = Globals.Graber2; Camera2Value explosion2 = _dataManager.Query().First(); _graber2.PresetLightParammanual(explosion2, explosion2.Explosion); _graber2.PresetLightParammanual(explosion2, explosion2.Explosion); #endregion } GetPortClientState(); InitializationTemperatureValue(); AutoSettingSpeed(); SettingSampleDetails(); GetSettingTemperature(); //ReadHumiture(); return this; } /// /// 检查剩余任务 /// public async void CheckExistResidueTask() { List residueTask = _dataManager.Query().Where(it => it.Status.In ( TaskState.New, TaskState.Waiting, TaskState.Doing, TaskState.Hit, TaskState.AddLiquid, TaskState.Dissolve, TaskState.Titration, TaskState.Titration2, TaskState.Execute )).ToList(); if (!residueTask.Any()) { /* Mark: * 这里暂时设置状态为TaskState.Cancel,若后续有其他不可抗拒原因,则调整回TaskState.Finish * 使用TaskState.Cancel是因为后续计算结果时,若本次实验未进行标定、空白类型下发 * 计算时需向上检索最近的一次,TaskState.Finish为条件之一 */ _dataManager.Update().Invoke(it => it.Status.Set(TaskState.Cancel))(it => it.Status.In(TaskState.New, TaskState.Waiting, TaskState.Doing, TaskState.Hit, TaskState.AddLiquid, TaskState.Dissolve, TaskState.Titration, TaskState.Execute)); _dataManager.Update().SetValues(it => it.SampleSource.Set(string.Empty) && it.Start.Set(false)).Execute(); _dataManager.Update().SetValues(it => it.Enable.Set(true)).Execute(); _dataManager.Update().SetValues(it => it.TaskStatus.Set(DetailState.Init)).Execute(); _dataManager.Update().SetValues(it => it.CurrentOccupy.Set(string.Empty) && it.Enable.Set(true)).Execute(); //_dataManager.Update().SetValues(it => it.Status.Set(0)).Execute(); 此处代码移到上面了第67行 _dataManager.Update().SetValues(it => it.Value.Set(0)).Execute(); _dataManager.Delete().Execute(); } if (residueTask.Any() && UMessageBox.Info("检测到剩余任务,请问是否继续执行").Equals(MessageBoxResult.No)) { /* Mark: * 这里暂时设置状态为TaskState.Cancel,若后续有其他不可抗拒原因,则调整回TaskState.Finish * 使用TaskState.Cancel是因为后续计算结果时,若本次实验未进行标定、空白类型下发 * 计算时需向上检索最近的一次,TaskState.Finish为条件之一 */ _dataManager.Update().Invoke(it => it.Status.Set(TaskState.Cancel))(it => it.Status.In(TaskState.New, TaskState.Waiting, TaskState.Doing, TaskState.Hit, TaskState.AddLiquid, TaskState.Dissolve, TaskState.Titration, TaskState.Titration2, TaskState.Execute)); _dataManager.Update().SetValues(it => it.SampleSource.Set(string.Empty) && it.Start.Set(false)).Execute(); _dataManager.Update().SetValues(it => it.Enable.Set(true)).Execute(); _dataManager.Update().SetValues(it => it.TaskStatus.Set(DetailState.Init)).Execute(); _dataManager.Update().SetValues(it => it.CurrentOccupy.Set(string.Empty) && it.Enable.Set(true)).Execute(); _dataManager.Update().SetValues(it => it.Status.Set(0)).Execute(); _dataManager.Update().SetValues(it => it.Value.Set(0)).Execute(); _dataManager.Delete().Execute(); _dataManager.Delete().Execute(); } else { _ea.GetEvent().Publish(residueTask.Count()); //继续任务的话,做待执行时间的显示 await Task.Factory.StartNew(() => { List executeTasks = _dataManager.Query().Where(it => it.Status.Equals(TaskState.Execute)).ToList(); foreach (EquipmentTask item in executeTasks) { string type = string.Empty; if (item.RouteStep.Equals(PipeName.ADD_LIQUID)) { type = item.AcidBaseProp switch { AcidBase.Acid => PipeName.ACID_ADD_LIQUID, AcidBase.Alkali => PipeName.ALKALI_ADD_LIQUID, _ => throw new ArgumentNullException(nameof(item.AcidBaseProp)), }; } if (item.RouteStep.Equals(PipeName.TITRATION)) { type = item.AcidBaseProp switch { AcidBase.Acid => PipeName.ACID_TITRATION, AcidBase.Alkali => PipeName.ALKALI_TITRATION, _ => throw new ArgumentNullException(nameof(item.AcidBaseProp)), }; } _repositorys.ExecuteTaskByVirtualPipe(type, item); List names = new List(); names.Add(item.Source); _ea.GetEvent().Publish(names); } EquipmentTask task = _dataManager.Query().Where(it => it.Status.In(TaskState.Hit)).First(); if (task is not null) { _repositorys.ExecuteTaskByVirtualPipe(task); } }); } if (UMessageBox.Info("设备是否需要返回原点?").Equals(MessageBoxResult.Yes)) { bool res = await MotorGoBack(); _dataManager.Update().SetValues(it => it.Status.Set(0)).Execute(); string showStr = $"设备返回原点{(res ? "成功" : "失败")}!"; Notice.Show(showStr, "Info", 3, MessageBoxIcon.Info); logger.LogInformation(showStr); } _repositorys.StartTaskProcesser(); } public void RegisterMessager() { Messager.Register("TaskFinish", ExecuteTaskFinish); Messager.Register("TaskResult", ExecuteTaskRegister); Messager.Register("AllTaskFinish", ExecuteAllTaskFinish); } public void ExecuteAllTaskFinish(string arg) { _ea.GetEvent().Publish(0); } public void ExecuteTaskFinish(string arg) { _ea.GetEvent().Publish(arg); } public void ExecuteTaskRegister(TaskResultArgs arg) { _ea.GetEvent().Publish(arg); } public IEnumerable GetData() where T : class { return _dataManager.Query().ToList(); } /// /// 设置样品详细 /// private void SettingSampleDetails() { List sampleDetails = _dataManager.Query().Where(it => it.TaskStatus.Unequal(DetailState.Init)).ToList(); List newSampleDetails = sampleDetails.Where(item => item.TaskStatus.Equals(DetailState.New)).ToList(); if (newSampleDetails.Any()) { _dataManager.Update().Invoke(it => it.TaskStatus.Set(DetailState.Init))(it => it.TaskStatus.Equals(DetailState.New)); } if (!sampleDetails.Where(detail => detail.TaskStatus.Equals(DetailState.Doing)).Any()) { _dataManager.Update().SetValues(it => it.TaskStatus.Set(DetailState.Init)).Execute(); } } /// /// 启动后自动设置速度 /// private void AutoSettingSpeed() { List settingSpeedInfos = _dataManager.Query().Where(it => it.ConnectAutoUpdate.Equals(true)).ToList(); StringBuilder successfulSb = new(); foreach (MotorSpeed speed in settingSpeedInfos) { bool res = speed.SystemName.WriteSpeed(speed.Speed); res = res && speed.SystemName.WriteAcSpeed(speed.AcSpeed); res = res && speed.SystemName.WriteDeSpeed(speed.DeSpeed); if (res) { successfulSb.Append($"{speed.DetailName}、"); } } if (successfulSb is null or { Length: 0 }) { Notice.Show("自动设置速度失败,请在手动模式下设置!", "Error", 3, MessageBoxIcon.Error); return; } Notice.Show($"点位:{successfulSb}自动设置速度成功!", "Info", 3, MessageBoxIcon.Info); } public void TaskSend() { try { if (!CameraState) { UMessageBox.Error("滴定相机未检出,请联系统售后处理后,再开始实验!"); return; } Dictionary temperatureRes = EquipmentNames.DissolveHeating.HeatRead(); Globals.FirstDissolve = true; InitializationTemperatureValue(); List samples = _dataManager.Query().Where(it => it.TaskStatus.Equals(DetailState.New)).ToList(); if (!samples.Any()) { UMessageBox.Error("未选择样品,无法进行任务下发!"); return; } List residueTask = _dataManager.Query().Where(it => it.Status.In ( TaskState.New, TaskState.Waiting, TaskState.Doing, TaskState.Hit, TaskState.AddLiquid, TaskState.Dissolve, TaskState.Titration, TaskState.Titration2, TaskState.Execute )).ToList(); var reserveLiquids = _dataManager.Query().ToList(); var totalLiquids = _dataManager.Query().ToList(); double sodiumOxalate = samples.Count * 10;//草酸钠 double SodiumHydroxide = samples.Where(it => it.AcidBaseProp.Equals(AcidBase.Alkali)).ToList().Count * 0.5;//氢氧化钠 double Vitriol = samples.Count * 5;//硫酸 double PotassiumPermanganate = samples.Count * 25;//高锰酸钾 string[] liquidNames = new string[] { "SodiumOxalate", "SodiumHydroxide", "PotassiumPermanganate", "Vitriol" }; bool measure = true; foreach (var name in liquidNames) { double needValue = reserveLiquids.FirstOrDefault(it => it.LiquidName.Equals(name)).Value; needValue += name switch { "SodiumOxalate" => sodiumOxalate, "SodiumHydroxide" => SodiumHydroxide, "PotassiumPermanganate" => PotassiumPermanganate, "Vitriol" => Vitriol, _ => 0, }; double total = totalLiquids.FirstOrDefault(it => it.LiquidName.Equals(name)).Total; measure = measure && (needValue <= total); } if (!measure) { MessageBox.Show("警告: 剩余试剂量 不足 ,请确保试剂 充足 后重试~"); return; } int acidCount = 0; int calibrationCount = 0; int blankCount = 0; foreach (var item in samples) { if (item.AcidBaseProp == AcidBase.Acid) acidCount++; if (item.IsCalibration ==true) calibrationCount++; if (item.SampleType == "空白") blankCount++; } var sb = new StringBuilder(); sb.Append($"当前下发任务数量共计:{samples.Count}条\n\n"); sb.Append($"共需试剂数量如下:\n"); sb.Append($"草酸钠:{(samples.Count+ calibrationCount) * 10 }ml\n"); sb.Append($"高锰酸钾:{(samples.Count - blankCount) * 17 + (calibrationCount + blankCount) * 12}ml\n"); sb.Append($"硫酸:{(samples.Count - acidCount) * 10 + acidCount * 5}ml\n"); sb.Append($"氢氧化钠:{(samples.Count - acidCount) * 0.5}ml\n"); sb.Append("请确定任务是否下发?"); var result = UMessageBox.Info(sb.ToString()); if (result.Equals(MessageBoxResult.No)) return; foreach (var name in liquidNames) { double needValue = reserveLiquids.FirstOrDefault(it => it.LiquidName.Equals(name)).Value; needValue += name switch { "SodiumOxalate" => sodiumOxalate, "SodiumHydroxide" => SodiumHydroxide, "PotassiumPermanganate" => PotassiumPermanganate, "Vitriol" => Vitriol, _ => 0, }; _dataManager.Update().Invoke(it => it.Value.Set(needValue))(it => it.LiquidName.Equals(name)); } IEnumerable resInfo = SendSampleToControl(samples); _ea.GetEvent().Publish(residueTask.Count() + samples.Count()); //继续任务的话,做待执行时间的显示 foreach (ResponseData item in resInfo) { switch (item.Code) { case 200: Notice.Show(item.Message, "Success", 5, MessageBoxIcon.Success); List sendSeccessfulSampleTask = samples.Where(sample => item.Data.Contains(sample.NodeName)).ToList(); foreach (SampleDetail sampleTask in sendSeccessfulSampleTask) { sampleTask.TaskStatus = DetailState.Doing; _dataManager.Update(sampleTask); } _ea.GetEvent().Publish(item.Data); break; case 404: Notice.Show(item.Message, "Error", 3, MessageBoxIcon.Error); break; } } } catch (Exception ex) { logger.LogError(ex.ToString()); } } /// /// 下发样品任务 /// /// /// /// public IEnumerable SendSampleToControl(List args) { List tasks = new(); List resList = new(); ResponseData successData = new(); ResponseData errorData = new(); StringBuilder successSend = new(); StringBuilder repetitionSend = new(); string waveKey = CreateTask.GetWavekey(); foreach (SampleDetail item in args) { if (_dataManager.Query().Where(it => it.Source.Equals(item.NodeName) && it.Status.In(TaskState.New, TaskState.Doing)).Any()) { repetitionSend.AppendFormat("{0} ", item.NodeName); continue; } successSend.AppendFormat("{0} ", item.NodeName); EquipmentTask task = item.CreateSampleTask(waveKey); tasks.Add(task); successData.Data.Add(item.NodeName); } int rows = _dataManager.Add(tasks); if (successSend.Length > 0 && rows > 0) { successData.Code = 200; successData.Message = string.Concat(successSend.ToString(), "任务下发成功!"); resList.Add(successData); } if (repetitionSend.Length <= 0) return resList; errorData.Code = 404; errorData.Message = string.Concat(repetitionSend.ToString(), "地址有在执行的任务,请勿重复下发任务!"); resList.Add(errorData); return resList; } public async Task MotorGoBack() { bool respose = await Task.Factory.StartNew(() => { string[] typeNames = { EquipmentNames.AxisZ, EquipmentNames.AxisY, EquipmentNames.AxisX, EquipmentNames.AxisD }; bool res = true; foreach (string item in typeNames) { if(item == EquipmentNames.AxisY) { int register = ConfigInstance.GetPortRegister(item); char[] judgeRes = item.MotorRead(); if (judgeRes is null or { Length: 0 }) { continue; } if( judgeRes[register - 1].Equals('0')) continue; } res = res && ExecuteCommand.MotorGoBackExecute(item); } ManualService.DropperPoint("Titration"); //四个泵回原点代码 //string[] typeNames1 = { EquipmentNames.Sodium1Oxalate, EquipmentNames.Sodium2Oxalate }; //bool res1 = true; //foreach (string item in typeNames1) //{ // LiquidPipeSwitchOxalate.StartNew.SetLiquidName(item).CheckWhetherArriveEndPointOxalate(); //} //string[] typeNames2 = { EquipmentNames.TitrationPotassiumPermanganate, EquipmentNames.Titration2PotassiumPermanganate}; //bool res2 = true; //foreach (string item in typeNames2) //{ // LiquidPipeSwitch.StartNew.SetLiquidName(item).CheckWhetherArriveEndPoint(); //} return res; }); return respose; } public bool TaskRunning => _readConfig.TaskRunning; public void UpdateTaskRunning(bool value) => _readConfig.UpdateTaskRunning(value); public List OtherPositions => _readConfig.OtherPositionArgs; public void FreshClient() => ClientPort(); public void FreshCamera() { GetCameraState(); GetCameraState2(); } public void CloseCamera() { try { if (Globals.Camera is not null && Globals.Camera.IsOpened) { Globals.Camera?.CloseCamera(); } if (Globals.Camera2 is not null && Globals.Camera2.IsOpened) { Globals.Camera2?.CloseCamera(); } } catch (Exception ex) { logger.LogError(ex.ToString()); } } public void ResettingTemperature() { InitializationTemperatureValue(); } private void ClientPort() { _portConnect.Open(); } public void GetPortClientState() { _ = Task.Factory.StartNew(() => { while (true) { _ea.GetEvent().Publish((_portConnect.PortName, _portConnect.PortState)); Thread.Sleep(5 * 1000); } }); } public bool GetCameraState() { _ = Task.Factory.StartNew(() => { while (true) { _ea.GetEvent().Publish(CreatCamera.HadWebcams); Thread.Sleep(5 * 1000); } }); return CreatCamera.HadWebcams; } public bool GetCameraState2() { _ = Task.Factory.StartNew(() => { while (true) { _ea.GetEvent().Publish(CreatCamera2.HadWebcams); Thread.Sleep(5 * 1000); } }); return CreatCamera2.HadWebcams; } public void GetSettingTemperature() { _ = Task.Factory.StartNew(() => { while (true) { _ea.GetEvent().Publish(TemperatureSettingResult); Thread.Sleep(5 * 1000); } }); } public void ReadHumiture() { ushort[] res = PortExecute.HumitureRead(); if (res is null or { Length: 0 }) { return; } double temp = res[0] / 10.0; double humidi = res[1] / 10.0; _ea.GetEvent().Publish((Temperature: temp, Humidity: humidi)); } public void StopHeating(string name) { SettingTemperatureValue(name, -100); } /// /// 温度设置 /// /// private void SettingTemperatureValue(string name, double value) { if (_portConnect.PortState) { bool res = name.WritePid(); TemperatureSettingResult = res && name.WriteTemperature(value); logger.LogDebug($"{name}设定温度{value},温度设置{(TemperatureSettingResult ? "成功" : "失败")}"); } } public void ExportResult(string key) { try { if (string.IsNullOrWhiteSpace(_readConfig.ResultFilePath)) { UMessageBox.SingleBtnInfo("导出结果地址为空,请设置!"); return; } List tasks = _dataManager.Query().Where(it => it.WaveKey.Equals(key) && it.Status.Equals(TaskState.Finished)).ToList(); if (tasks is null or { Count: 0 }) { UMessageBox.SingleBtnInfo("未找到符合数据,导出结果失败"); } if (_readConfig.ExportTypeByExcel) { _export.ExportExcel(tasks); } else if (_readConfig.ExportTypeByWord) { _export.ExportWord(tasks); } Notice.Show("导出结果成功!", "Info", 3, MessageBoxIcon.Info); } catch (Exception ex) { logger.LogError(ex.ToString()); } } public async Task CreatWashTask() { return await Task.Factory.StartNew(() => { string TaskType = TaskTypeName.WASH_ZH; EquipmentTask task = TaskType.CreateWashTask(); foreach (PipelineContent item in PipelineConfig.Instance.PipelineContents) { if (item.Alias.Equals(task.RouteStep)) { _repositorys.ExecuteTaskByVirtualPipe(task, item.Nodes); } } return true; }); } private void InitializationTemperatureValue() { SettingTemperatureValue(EquipmentNames.DissolveHeating, _readConfig.DissolveTemperatureValue); Thread.Sleep(500); SettingTemperatureValue(EquipmentNames.TitrationHeating, _readConfig.TitrationTemperatureValue); } } }