/// <summary> /// 责任人员现场签到,用于网页端 /// </summary> /// <param name="logItem">异常监控队列</param> /// <param name="cfgItem">设备编码</param> /// <returns></returns> public ErrorObject AckErrorLogPersonForWeb(error_log logItem, error_config cfgItem) { ErrorTypeService errorTypeService = new ErrorTypeService(); person person = null; material_request_info reInfo = null; ErrorObject errorObject = null; errorObject = LoadErrorLogObject(logItem, cfgItem); if (errorObject.ELog != null && errorObject.eConfig != null) { Dictionary <string, object> dic = new Dictionary <string, object>(); if (errorObject.eConfig.check_arrival == (int)ArrivalModeEnum.CardArrival) { errorObject.eSignedPersons.Add(person); //记录签到的人员 errorObject.ELog.arrival_person_id = person.id; //更新具体的id信息 dic.Add("arrival_person_id", logItem.arrival_person_id); errorObject.eSignedPersons.Add(person); //签到人员记录 } dic.Add("arrival_time", errorObject.ELog.arrival_time); errorLogManager.Update(errorObject.ELog, dic); //提交数据库 Console.WriteLine("AckErrorLogPerson,执行结束,id=" + errorObject.ELog.id); return(errorObject); } return(null); }
/// <summary> /// 根据异常log记录加载所有信息.初始化加载和web页面确认使用 /// </summary> /// <param name="eLogObject">error_log对象</param> /// <param name="unit_no">制程工序</param> /// <param name="line_id">线别id</param> /// <returns></returns> public ErrorObject LoadErrorLogObject(error_log eLogObject, error_config eCfgObject = null) { ErrorObject errorObject = new ErrorObject(); errorObject.ELog = eLogObject; if (eCfgObject == null) { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(eLogObject.system_tag_code, eLogObject.unit_no, eLogObject.line_id); if (errorObject.eConfig == null) //未查询到,同时line非0,则以制程查询尝试 { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(eLogObject.system_tag_code, eLogObject.unit_no); } } else { errorObject.eConfig = eCfgObject; } if (errorObject.eConfig != null) { errorObject.eCfgPersonList = errorPersonManager.GetCfgPersonList(errorObject.eConfig.id); //需通知的配置人员加载 List <error_config_pn> eCfgPns = errorConfigPnManager.GetCfgPns(errorObject.eConfig.id); errorObject.eCfgPnList = eCfgPns; //关联的机种信息加载 //已通知人员加载 errorObject.eMsgedPersonList = errorPersonManager.GetErrorLogPersonList(errorObject.ELog.id); } return(errorObject); }
/// <summary> /// 用于网页模式下的解除.时间均在外部维护 /// </summary> /// <param name="logItem">记录对象</param> /// <param name="cfgItem">配置对象</param> /// <param name="error_code">解除编码</param> /// <param name="defectives_count">不良品数量</param> /// <returns>正确执行返回ErrorObject,错误执行返回null</returns> public ErrorObject AckErrorLogDetails(error_log logItem, error_config cfgItem) { ErrorObject errorObject = null; Dictionary <string, object> dic = new Dictionary <string, object>();//加入需要更新的字段信息 errorObject = LoadErrorLogObject(logItem, cfgItem); if (errorObject != null && errorObject.ELog != null) { if (errorObject.eConfig.check_ack == (int)AckModeEnum.CodeAck) { dic.Add("maintenance_time", errorObject.ELog.maintenance_time); dic.Add("error_type_id", errorObject.ELog.error_type_id);//未确认原因的再给值。物料呼叫监测typeid会提前赋值 } dic.Add("defectives_count", errorObject.ELog.defectives_count); dic.Add("release_time", errorObject.ELog.release_time); int count = errorLogManager.Update(errorObject.ELog, dic); //提交数据库 if (count > 0) { Console.WriteLine("AckErrorLogDetails,确认成功,id=" + errorObject.ELog.id); } else { Console.WriteLine("安灯解除更新数据失败!"); } return(errorObject); } else { Console.WriteLine("安灯解除出错,errorObject != null && errorObject.ELog !=null 失败!"); } return(null); }
/// <summary> /// 根据提供的设备id和tag_code记录加载所有信息 /// </summary> /// <param name="device_id">装置id</param> /// <param name="system_tag_code">系统编码</param> /// <param name="unit_no">制程</param> /// <param name="line_id">线别</param> /// <returns></returns> public ErrorObject LoadErrorLogObject(int device_id, string system_tag_code, string unit_no, int line_id) { ErrorObject errorObject = new ErrorObject(); error_log eLogObject; eLogObject = errorLogManager.GetUnAckLogByDeviceId(device_id, system_tag_code);//查找error_log记录 if (eLogObject != null) { errorObject.ELog = eLogObject; } //先按照最小单位查询 errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(system_tag_code, unit_no, line_id); if (errorObject.eConfig == null) //未查询到,则以制程查询尝试 { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(system_tag_code, unit_no); } if (errorObject.eConfig != null && errorObject.ELog != null) { errorObject.eCfgPersonList = errorPersonManager.GetCfgPersonList(errorObject.eConfig.id); //需通知的配置人员加载 List <error_config_pn> eCfgPns = errorConfigPnManager.GetCfgPns(errorObject.eConfig.id); errorObject.eCfgPnList = eCfgPns; //关联的机种信息加载 //已通知人员加载 errorObject.eMsgedPersonList = errorPersonManager.GetErrorLogPersonList(errorObject.ELog.id); } return(errorObject); }
/// <summary> /// Web页面处理异常解除 /// </summary> /// <param name="logItem">记录对象</param> /// <param name="cfgItem">配置对象</param> /// <param name="error_code">确认代码</param> /// <param name="defectives_count">不良品数量</param> public static void HandleErrorAck(error_log logItem, error_config cfgItem, ErrorObject errorObj = null) { string subject = string.Empty, content = string.Empty; ErrorObject errorObject = null; if (errorObj != null) { errorObject = errorObj; } else { errorObject = andonErrorManager.AckErrorLogDetails(logItem, cfgItem); } if (errorObject != null && errorObject.eConfig != null) { if (errorObject.eConfig.trigger_message_type > (int)ErrorMsgType.None)//需要消息通知 { subject = "安灯系统" + errorObject.ELog.error_name; if (errorObject.eTypeDetails != null) { content = String.Format("{0}已解除{1},原因为{2}" + MessageAdditional, logItem.machine_code, subject, errorObject.eTypeDetails.code_name_cn); } else if (errorObject.RequireMat != null) { content = String.Format("{0}已解除{1},呼叫的物料id为{2}" + MessageAdditional, logItem.machine_code, subject, errorObject.RequireMat.material_id); } else { content = String.Format("{0}已解除{1}" + MessageAdditional, logItem.machine_code, subject); } errorMessageManager.SendErrorMessageAsync(errorObject, (int)MessageLevel.Level1, EventHandleFlowEnum.Event_Ack, subject, content, true);//发送消息通知 } if (errorObject.eConfig.arrival_out_color > (int)LightTowerEnum.None && errorObject.eConfig.check_arrival > (int)ArrivalModeEnum.NoArrival) //签到灯颜色复位 { //写值 lightTowerTagManager.WriteLightColorAsync(logItem.station_id, errorObject.eConfig.arrival_out_color, tagAreaAttributeMode, 0); lightTowerTagManager.GreenStatusLightOutAsync(logItem.station_id, tagAreaAttributeMode); //绿灯状态切换 } if (errorObject.eConfig.trigger_out_color > (int)LightTowerEnum.None) //警示灯颜色复位 { //写值 lightTowerTagManager.WriteLightColorAsync(logItem.station_id, errorObject.eConfig.trigger_out_color, tagAreaAttributeMode, 0); lightTowerTagManager.GreenStatusLightOutAsync(logItem.station_id, tagAreaAttributeMode);//绿灯状态切换 } } else { Console.WriteLine("安灯解除记录失败,errorObject != null && errorObject.eConfig != null 失败!"); if (errorObject.eConfig == null) { Console.WriteLine("安灯解除记录失败,errorObject.eConfig == null" + logItem.system_tag_code); } } }
/// <summary> /// 异常通知 /// </summary> /// <param name="errorObject"></param> /// <param name="Level">层级</param> /// <param name="EventFlow">事件流程</param> /// <param name="Subject">主题</param> /// <param name="Content">内容</param> /// <param name="FinishedMode">最后完成模式,通知已通知人员</param> public async Task SendErrorMessageAsync(ErrorObject errorObject, int Level, EventHandleFlowEnum EventFlow, string Subject, string Content, bool FinishedMode = false) { List <person> persons; List <string> infoList = new List <string>(); persons = GetMsgedPersonList(errorObject, Level, EventFlow, FinishedMode); //获取需要通知的人员列表 bool res = await PostMessageToLuyuan(errorObject, EventFlow, persons); //对外发送信息 if (errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.All || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.WeChat || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.WeChat_Broadcast || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.WeChat_Email) { //微信通知 foreach (person p in persons) { infoList.Add(p.user_name); } WeChatHelper.SendWeChatMessage(infoList, Content); } if (errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.All || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.Email || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.Email_Broadcast || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.WeChat_Email) { infoList = new List <string>(); //邮件通知 foreach (person p in persons) { infoList.Add(p.user_email); } MailHelper.SendMail(infoList, Subject, Content); } if (errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.All || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.Broadcast || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.Email_Broadcast || errorObject.eConfig.trigger_message_type == (int)ErrorMsgType.WeChat_Broadcast) { //语音通知 //speechSynth.Speak(Content); if (SpeechTag != null) { if (ScadaAPIConfig.EnableScadaApi) { ScadaAPIHelper.WriteValueAsync(SpeechTag.tag_code, Content); } else { //MqttManager.MqttHelper.WriteValueToWA(SpeechTag.tag_code, Content, true);//输出语音播报文本信息 } } } }
/// <summary> /// 人员签到处理.以Tag点形式上抛的。方案待优化!!!!!!!!!!!!!!!!!!! /// </summary> /// <param name="machineCode"></param> /// <param name="stationId"></param> /// <param name="deviceTagValueInfo"></param> /// <param name="tagAreaAttributeEnum"></param> public static void HandlePersonArrivalForTag(string machineCode, int stationId, DeviceTagValueInfo deviceTagValueInfo, TagAreaAttributeEnum tagAreaAttributeEnum = TagAreaAttributeEnum.station_info) { string subject = string.Empty, content = string.Empty; ErrorObject errorObject = andonErrorManager.AckErrorLogPerson(machineCode, stationId, deviceTagValueInfo, tagAreaAttributeEnum); if (errorObject != null) { HandlePersonArrival(null, null, errorObject); } }
/// <summary> /// 处理异常解除,以tag点方式,待实际场合进一步优化代码!!!!!!!!!!!!!!!!!!!!!!!!!!1 /// </summary> /// <param name="machineCode"></param> /// <param name="stationId"></param> /// <param name="deviceTagValueInfo"></param> /// <param name="tagAreaAttributeEnum"></param> public static void HandleErrorAckForTag(string machineCode, int stationId, DeviceTagValueInfo deviceTagValueInfo, TagAreaAttributeEnum tagAreaAttributeEnum = TagAreaAttributeEnum.station_info) { string subject = string.Empty, content = string.Empty; ErrorObject errorObject = null; if (deviceTagValueInfo.system_tag_code == SystemTagCodeEnum.material_require.ToString()) { errorObject = andonErrorManager.AckErrorLogDetailsForMat(machineCode, stationId, deviceTagValueInfo, tagAreaAttributeEnum); } else { errorObject = andonErrorManager.AckErrorLogDetails(machineCode, stationId, deviceTagValueInfo, tagAreaAttributeEnum); } HandleErrorAck(null, null, errorObject); }
/// <summary> /// 人员签到处理 /// </summary> /// <param name="logItem"></param> /// <param name="cfgItem"></param> /// <param name="errorObj"></param> public static void HandlePersonArrival(error_log logItem, error_config cfgItem, ErrorObject errorObj = null) { string subject = string.Empty, content = string.Empty; ErrorObject errorObject; if (errorObj != null) { errorObject = errorObj; } else { errorObject = andonErrorManager.AckErrorLogPersonForWeb(logItem, cfgItem); } if (errorObject != null && errorObject.eConfig != null) { if (errorObject.eConfig.arrival_message_type > (int)ErrorMsgType.None)//需要消息通知 { if (errorObject.eConfig.check_arrival == (int)ArrivalModeEnum.CardArrival) { subject = "安灯系统" + errorObject.ELog.error_name; if (errorObject.eSignedPersons.Count > 0) { content = String.Format("{0}发生{1},签到人员为{2}" + MessageAdditional, errorObject.ELog.machine_code, subject, errorObject.eSignedPersons[0].user_name); } else { content = String.Format("{0}发生{1},人员已签到" + MessageAdditional, errorObject.ELog.machine_code, subject); } } else { subject = "安灯系统" + errorObject.ELog.error_name; content = String.Format("{0}发生{1},人员已签到" + MessageAdditional, errorObject.ELog.machine_code, subject); } errorMessageManager.SendErrorMessageAsync(errorObject, (int)MessageLevel.Level1, EventHandleFlowEnum.Event_SignIn, subject, content); //发送消息通知,人员签到在第一层级?? } if (errorObject.eConfig.arrival_out_color > (int)LightTowerEnum.None) //灯颜色输出 { //写值 lightTowerTagManager.WriteLightColorAsync(errorObject.ELog.station_id, errorObject.eConfig.arrival_out_color, tagAreaAttributeMode, 1); lightTowerTagManager.GreenStatusLightOutAsync(errorObject.ELog.station_id, tagAreaAttributeMode);//绿灯状态切换 } } }
/// <summary> /// 获取发送通知的人员列表 /// </summary> /// <param name="errorObject">异常对象</param> /// <param name="Level">等级</param> /// <param name="EventFlow">事件流程点</param> /// <param name="FinishedMode">完成模式</param> /// <returns></returns> public List <person> GetMsgedPersonList(ErrorObject errorObject, int Level, EventHandleFlowEnum EventFlow, bool FinishedMode = false) { List <person> persons = new List <person>(); List <string> infoList = new List <string>(); List <ErrorCfgPerson> ePersons = new List <ErrorCfgPerson>(); string classNo = classInfoManager.GetCurrentClassNo();//当前班次 if (FinishedMode == false) { if (EventFlow == EventHandleFlowEnum.Event_Timeout)//超时加载人员为当前级别以及向下一级 { ePersons = errorObject.eCfgPersonList.Where(x => (x.eCfgPerson.person_level == Level || x.eCfgPerson.person_level == (Level - 1)) && x.eCfgPerson.class_no.Equals(classNo)).ToList();//获取多级配置人员列表 } else { if (errorObject.eConfig.message_multilevel == 1 && Level < (int)MessageLevel.Level3)//多级人员发送模式 { ePersons = errorObject.eCfgPersonList.Where(x => (x.eCfgPerson.person_level == Level || x.eCfgPerson.person_level == Level + 1) && x.eCfgPerson.class_no.Equals(classNo)).ToList();//获取多级配置人员列表 } else { ePersons = errorObject.eCfgPersonList.Where(x => x.eCfgPerson.person_level == Level && x.eCfgPerson.class_no.Equals(classNo)).ToList(); //获取当前级别配置人员列表 } } foreach (var item in ePersons) { if (item.ePerson != null) { //判断此人员是否已经通知过,通知过则去除不重复通知 if (errorObject.eMsgedPersonList.Any(x => x.eLogPerson.error_log_id == errorObject.ELog.id && x.eLogPerson.person_id == item.ePerson.id && x.eLogPerson.message_flow == EventFlow.ToString() && x.eLogPerson.message_level == item.eCfgPerson.person_level) == false) { persons.Add(item.ePerson); ErrorLogPerson eLogPersonObject = new ErrorLogPerson(); //记录已通知人员 error_log_person ePerson = errorLogPersonManager.InsertMessagePerson(errorObject.ELog.id, item.ePerson.id, item.eCfgPerson.person_level, EventFlow); eLogPersonObject.ePerson = item.ePerson; eLogPersonObject.eLogPerson = ePerson; errorObject.eMsgedPersonList.Add(eLogPersonObject); } } } } else { //结束模式需去除已经为事件确认标识的人员 foreach (var item in errorObject.eMsgedPersonList.Where(x => x.eLogPerson.message_flow != EventFlow.ToString())) //为结束模式,则取出已通知的人员 { if (!persons.Any(x => x.id == item.ePerson.id)) //去除重复项 { errorLogPersonManager.InsertMessagePerson(errorObject.ELog.id, item.ePerson.id, item.eLogPerson.message_level, EventFlow); persons.Add(item.ePerson); } } } return(persons); }
/// <summary> /// 人员通知时向绿源抛送信息,此接口为定制 /// </summary> /// <param name="errorObject">安灯对象</param> /// <param name="EventFlow">流程节点</param> /// <param name="Persons">人员清单</param> /// <returns></returns> public async Task <bool> PostMessageToLuyuan(ErrorObject errorObject, EventHandleFlowEnum EventFlow, List <person> Persons) { if (EventFlow != EventHandleFlowEnum.Event_Trigger && EventFlow != EventHandleFlowEnum.Event_Timeout)//只有事件发生时需要通知 { return(false); } try { string ApiBaseUrl = "https://api.luyuan.cn/MESApi/GetErrorMsg"; line_info line = AndonGlobalCfg.LinesList.FirstOrDefault(x => x.line_id == errorObject.ELog.line_id); //ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; foreach (person p in Persons) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ApiBaseUrl); request.ContentType = "application/json; charset=utf-8"; request.Method = "POST"; request.Headers.Add("api-key", "23333"); request.Headers.Add("api-sign", "463fbc8ffc4f1da5bbc94ffc5b911ae5b76ff3cd0ee1196ef978b079f74acce7"); String Body = "{\"触发时间\":\"" + errorObject.ELog.start_time + "\"," + "\"呼叫用户姓名\":\"" + p.user_name + "\"," + "\"呼叫号码\":\"" + p.mobile_phone + "\"," + "\"流水线名称\":\"" + line.line_name_en + "\"," + "\"站别名称\":\"" + errorObject.DeviceCode + "\"," + "\"问题类型\":\"" + errorObject.ELog.error_name + "\"}"; byte[] buffer = Encoding.UTF8.GetBytes(Body); //request.ContentLength = buffer.Length; //request.GetRequestStream().Write(buffer, 0, buffer.Length); Stream newStream = await request.GetRequestStreamAsync().ConfigureAwait(false); newStream.Write(buffer, 0, buffer.Length); newStream.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { string ret = reader.ReadToEnd(); if (ret.ToLower().Trim().Contains("statuscode: 200")) { //continue; } else { srpLogManager.Insert("PostMessageToLuyuan failed=" + Body); } Console.WriteLine("PostMessageToLuyuan=" + ret); } response.Close(); } catch (WebException ex) { Console.WriteLine("PostMessageToLuyuan error=" + ex.Message); srpLogManager.Insert("PostMessageToLuyuan error=" + ex.Message); WebResponse errResp = ex.Response; using (Stream respStream = errResp.GetResponseStream()) { StreamReader reader = new StreamReader(respStream); string text = reader.ReadToEnd(); Console.WriteLine(text); srpLogManager.Insert("PostMessageToLuyuan error=" + text); } return(false); } } return(true); } catch (Exception ex) { Console.WriteLine("PostMessageToLuyuan error=" + ex.Message); srpLogManager.Insert("PostMessageToLuyuan error=" + ex.Message); } return(false); }
/// <summary> /// 异常判断与处理 /// </summary> /// <param name="deviceTagValueItem">设备Tag值</param> /// <param name="stationTagValueItem">站位Tag值</param> private static void ErrorHandle(DeviceTagValueInfo deviceTagValueItem, TagAreaAttributeEnum tagAreaAttributeEnum, string DetailsInfo = "", int MaterialId = -1) { bool dbExist = false; //根据类型检索是否已经存在 if (deviceTagValueItem.system_tag_code != SystemTagCodeEnum.machine_time_error.ToString()) //工时异常不查询数据库 { if (MaterialId > 0) //物料呼叫有传入id则特殊处理 { if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info) { dbExist = errorLogManager.CheckMaterialRequireExist(deviceTagValueItem.system_tag_code, MaterialId, deviceTagValueItem.device_code); } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info) { dbExist = errorLogManager.CheckMaterialRequireExist(deviceTagValueItem.system_tag_code, MaterialId, "", deviceTagValueItem.device_id); } } else { if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info) { dbExist = errorLogManager.CheckExist(deviceTagValueItem.system_tag_code, deviceTagValueItem.device_code); } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info) { dbExist = errorLogManager.CheckExist(deviceTagValueItem.system_tag_code, "", deviceTagValueItem.device_id); //list = ErrorWatchList.Where(x => x.ELog.station_id == deviceTagValueItem.device_id && // x.ELog.system_tag_code == deviceTagValueItem.system_tag_code).ToList(); } } } //查找当前是否配置有关联的机种信息 ErrorObject errorObject = andonErrorManager.LoadErrorObject(deviceTagValueItem, tagAreaAttributeEnum); //获取到配置,并不存在 if (errorObject != null && errorObject.eConfig != null && errorObject.eConfig.error_active == 1 && dbExist == false) //不存在,且激活,则新增 { errorObject = andonErrorManager.AddNewErrorLog(deviceTagValueItem, errorObject, tagAreaAttributeEnum); //记录增加至数据库 if (errorObject != null && errorObject.eConfig != null) { if (errorObject.eConfig.check_ack > (int)AckModeEnum.NoAck) //只是记录,不需要确认,返回空对象 { if (errorObject.eConfig.trigger_message_type > (int)ErrorMsgType.None) //异常发生时需要消息通知 { string subject = "安灯系统" + deviceTagValueItem.system_code_name_cn + DetailsInfo; string content = String.Format("{0}发生{1},请相关人员尽快前往解决!" + MessageAdditional, deviceTagValueItem.device_code, subject); errorMessageManager.SendErrorMessageAsync(errorObject, (int)MessageLevel.Level1, EventHandleFlowEnum.Event_Trigger, subject, content); //发送消息通知 } if (errorObject.eConfig.trigger_out_color > (int)LightTowerEnum.None) //灯颜色输出.需要确认解除的才亮灯 { //写值 lightTowerTagManager.WriteLightColorAsync(deviceTagValueItem.device_id, errorObject.eConfig.trigger_out_color, tagAreaAttributeEnum, 1); lightTowerTagManager.GreenStatusLightOutAsync(deviceTagValueItem.device_id, tagAreaAttributeEnum);//绿灯状态切换 Console.WriteLine("error handle finish,time= " + DateTime.Now.ToLongTimeString() + " " + errorObject.DeviceCode + " " + errorObject.DeviceId + " " + errorObject.eConfig.system_tag_code); } } } } }
/// <summary> /// 队列超时监测 /// </summary> private static void TimeoutWatch(TagAreaAttributeEnum tagAreaAttributeEnum) { DateTime dateTime = DateTime.Now.AddHours(GlobalDefine.SysTimeZone);//此处需要加上时区 int timeDiffMin = 0, ratio = 0; string subject = string.Empty, content = string.Empty; AndonGlobalCfg.ErrorWatchList.Clear(); var list = errorLogManager.GetAllUnfinishedByDeviceCode(null); if (list != null && list.Count > 0) { foreach (var item in list) { var errObject = andonErrorManager.LoadErrorLogObject(item); AndonGlobalCfg.ErrorWatchList.Add(errObject); } } try { for (int i = 0; i < AndonGlobalCfg.ErrorWatchList.Count; i++) { ErrorObject errItem = AndonGlobalCfg.ErrorWatchList[i]; if (errItem.eConfig == null) { continue; } TimeSpan interval = dateTime - errItem.ELog.start_time; timeDiffMin = interval.Days * 24 + interval.Hours * 60 + interval.Minutes; subject = "安灯系统" + errItem.ELog.error_name; content = String.Format("{0}发生{1},已持续{2}分钟,已经超时!" + MessageAdditional, errItem.DeviceCode, subject, timeDiffMin); if (errItem.eMsgedPersonList.Any(x => x.eLogPerson.message_level == (int)MessageLevel.Level1 && x.eLogPerson.message_flow == EventHandleFlowEnum.Event_Trigger.ToString()) == false) { errorMessageManager.SendErrorMessageAsync(errItem, (int)MessageLevel.Level1, EventHandleFlowEnum.Event_Trigger, subject, content);//一级人员通知,此处是补充通知,如果系统down机情况 } if (timeDiffMin >= errItem.eConfig.timeout_setting)//大于超时时间 { ratio = (timeDiffMin / errItem.eConfig.timeout_setting) + 1; if (ratio > (int)MessageLevel.Level3)//最大级别限制 { ratio = (int)MessageLevel.Level3; } if (ratio > (int)MessageLevel.Level1 && ratio <= (int)MessageLevel.Level3) //限定在2-3级 { if (errItem.eCfgPersonList.Any(x => x.eCfgPerson.person_level == ratio)) //存在该级别的人员 { if (errItem.eMsgedPersonList.Any(x => x.eLogPerson.message_level == ratio && x.eLogPerson.message_flow == EventHandleFlowEnum.Event_Timeout.ToString()) == false) { error_log logItem = errorLogManager.GetErrorLogById(errItem.ELog.id); if (logItem != null)//检查数据库是否还存在 { Console.WriteLine("error timeout level2,time= " + DateTime.Now.ToLongTimeString() + " " + errItem.DeviceCode + " " + errItem.eConfig.error_name); errorMessageManager.SendErrorMessageAsync(errItem, ratio, EventHandleFlowEnum.Event_Timeout, subject, content); } else { AndonGlobalCfg.ErrorWatchList.RemoveAll(x => x.ELog.id == errItem.ELog.id); } } } } } } } catch (Exception ex) { srpLogManager.Insert("TimeoutWatch error:" + ex.Message); } }
/// <summary> /// 责任人员现场签到 /// 现场提交有3格式:card或者id&card,id&card&M /// 格式1:只有card内容时,为HMI触控屏发送的格式,此方式只能确认第一条记录,HMI触控屏无物料呼叫列表; /// 格式2:id&card格式:为Web网页异常呼叫时传递内容。Id为error_log表id,card为人员卡号; /// 格式3:id&card&M:为web网页物料呼叫传递内容,id为material_require_info表id,card为人员卡号,M为特殊标识符 /// </summary> /// <param name="ErrorWatchList">异常监控队列</param> /// <param name="MachineCode">设备编码</param> /// <param name="StationId">站位id</param> /// <param name="TagValueInItem">标签值对象</param> /// <returns></returns> public ErrorObject AckErrorLogPerson(string MachineCode, int StationId, DeviceTagValueInfo TagValueInItem, TagAreaAttributeEnum tagAreaAttributeEnum = TagAreaAttributeEnum.station_info) { ErrorTypeService errorTypeService = new ErrorTypeService(); person person = null; ErrorObject errorObject = null; string PersonCardId = String.Empty; int errorLogId = -1; material_request_info reInfo = null; TagIdAndValue valueObject = tagService.GetTagValue(TagValueInItem.tag_value); if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info) { MachineInfo machine = AndonGlobalCfg.MachinesList.FirstOrDefault(x => x.machine_code == MachineCode); errorObject = LoadErrorLogObject(TagValueInItem.device_id, TagValueInItem.system_tag_code, machine.unit_no, machine.line_id); } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info) { station_info station = AndonGlobalCfg.StationsList.FirstOrDefault(x => x.station_id == StationId); errorObject = LoadErrorLogObject(TagValueInItem.device_id, TagValueInItem.system_tag_code, station.unit_no, station.line_id); } if (valueObject.value == null || valueObject.value.Trim().Length == 0) { return(null); //值无效 } else { if (valueObject.id >= 0 && valueObject.value.Length > 0 && valueObject.value2.Length == 0) { errorLogId = valueObject.id; PersonCardId = valueObject.value; Console.WriteLine("AckErrorLogPerson,errorLogId=" + errorLogId + ",PersonCardId=" + PersonCardId); } else if (valueObject.id >= 0 && valueObject.value.Length > 0 && valueObject.value2.Length > 0)//物料呼叫传递内容 { reInfo = materialRequestInfoManager.SelectById(valueObject.id); PersonCardId = valueObject.value; Console.WriteLine("AckErrorLogPerson,物料呼叫传递,PersonCardId=" + PersonCardId); } else if (valueObject.id < 0 && valueObject.value.Length > 0) { PersonCardId = valueObject.value; Console.WriteLine("AckErrorLogPerson,PersonCardId=" + PersonCardId); } } if (errorObject.eConfig.check_arrival == (int)ArrivalModeEnum.CardArrival) //以卡信息签到 { if (PersonCardId.Length > 0) //获取具体的描述对象 { person = personManager.GetPersonByCardId(PersonCardId); if (person == null) { return(null); } } else { return(null); } } if (errorObject != null && errorObject.ELog != null) { errorObject.ELog.arrival_time = TagValueInItem.insert_time.AddHours(GlobalDefine.SysTimeZone); //时间加8小时,更新结束时间 Dictionary <string, object> dic = new Dictionary <string, object>(); if (errorObject.eConfig.check_arrival == (int)ArrivalModeEnum.CardArrival) { errorObject.eSignedPersons.Add(person); //记录签到的人员 errorObject.ELog.arrival_person_id = person.id; //更新具体的id信息 dic.Add("arrival_person_id", errorObject.ELog.arrival_person_id); errorObject.eSignedPersons.Add(person); //签到人员记录 } dic.Add("arrival_time", errorObject.ELog.arrival_time); errorLogManager.Update(errorObject.ELog, dic); //提交数据库 Console.WriteLine("AckErrorLogPerson,执行结束,id=" + errorObject.ELog.id); return(errorObject); } return(null); }
/// <summary> /// 确认并解除异常记录,用于现场提交解除. /// 格式1:id&M&M:为web网页物料呼叫传递内容,id为material_require_info表id,M为特殊标识符 /// 格式2:id:为web网页物料呼叫传递内容,id为error_log表id /// </summary> /// <param name="ErrorWatchList">当前监控队列</param> /// <param name="MachineCode">设备编码</param> /// <param name="StationId">站位id</param> /// <param name="TagValueInItem">标签值对象</param> /// <returns>正确执行返回ErrorObject,错误执行返回null</returns> public ErrorObject AckErrorLogDetailsForMat(string MachineCode, int StationId, DeviceTagValueInfo TagValueInItem, TagAreaAttributeEnum tagAreaAttributeEnum) { ErrorTypeService errorTypeService = new ErrorTypeService(); ErrorObject errorObject = null; int errorLogId = -1; material_request_info reInfo = null; //支持两种格式,sn或者id&sn,id为异常记录的唯一标识号 TagIdAndValue valueObject = tagService.GetTagValue(TagValueInItem.tag_value); if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info) { MachineInfo machine = AndonGlobalCfg.MachinesList.FirstOrDefault(x => x.machine_code == MachineCode); errorObject = LoadErrorLogObject(TagValueInItem.device_id, TagValueInItem.system_tag_code, machine.unit_no, machine.line_id); } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info) { station_info station = AndonGlobalCfg.StationsList.FirstOrDefault(x => x.station_id == StationId); errorObject = LoadErrorLogObject(TagValueInItem.device_id, TagValueInItem.system_tag_code, station.unit_no, station.line_id); } if (valueObject.value != null && valueObject.value.Trim().Length >= 0) { if (AndonGlobalCfg.MaterialType == 0) { errorLogId = valueObject.id; } else { if (valueObject.id >= 0 && valueObject.value.Length > 0 && valueObject.value2.Length > 0)//物料呼叫确认 { reInfo = materialRequestInfoManager.SelectById(valueObject.id); Console.WriteLine("AckErrorLogDetails,errorLogId=" + errorLogId); Console.WriteLine("AckErrorLogDetails,物料呼叫=" + valueObject.id); } } } if (errorObject != null && errorObject.ELog != null) { if (reInfo != null) //物料呼叫确认的对象 { errorObject.ELog.error_type_id = reInfo.material_id; //更新为物料id信息 errorObject.ELog.maintenance_time = TagValueInItem.insert_time.AddHours(GlobalDefine.SysTimeZone); errorObject.RequireMat = reInfo; } else { errorObject.ELog.error_type_id = -1; //只有呼叫,无具体信息 errorObject.eTypeDetails = null; } errorObject.ELog.release_time = TagValueInItem.insert_time.AddHours(GlobalDefine.SysTimeZone); //以变量值的时间更新结束时间 Dictionary <string, object> dic = new Dictionary <string, object>(); //加入需要更新的字段信息 if (errorObject.ELog.error_type_id > 0) { dic.Add("error_type_id", errorObject.ELog.error_type_id);//未确认原因的再给值。物料呼叫监测typeid会提前赋值 dic.Add("maintenance_time", errorObject.ELog.maintenance_time); } dic.Add("release_time", errorObject.ELog.release_time); errorLogManager.Update(errorObject.ELog, dic); //提交数据库 Console.WriteLine("AckErrorLogDetails,确认成功,id=" + errorObject.ELog.id); return(errorObject); } return(null); }
/// <summary> /// 根据Tag值信息加载所有信息.外部处理进入,需要确认和优化?????????? /// </summary> /// <param name="TagValueObject"></param> /// <param name="tagAreaAttributeEnum"></param> /// <returns></returns> public ErrorObject LoadErrorObject(DeviceTagValueInfo TagValueObject, TagAreaAttributeEnum tagAreaAttributeEnum) { ErrorObject errorObject = new ErrorObject(); List <error_config_pn> eCfgPns; string partNo = string.Empty;//当前机种 Pro_schedule_machine deviceSchedule = null; if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info)//设备形式 { MachineInfo machine = AndonGlobalCfg.MachinesList.FirstOrDefault(x => x.machine_id == TagValueObject.device_id); if (machine != null) { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(TagValueObject.system_tag_code, machine.unit_no, machine.line_id); if (errorObject.eConfig == null) { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(TagValueObject.system_tag_code, machine.unit_no); } } } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info)//站位形式 { station_info station = AndonGlobalCfg.StationsList.FirstOrDefault(x => x.station_id == TagValueObject.device_id); if (station != null) { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(TagValueObject.system_tag_code, station.unit_no, station.line_id); if (errorObject.eConfig == null) { errorObject.eConfig = errorConfigManager.GetFirstErrorConfig(TagValueObject.system_tag_code, station.unit_no); } } } if (errorObject.eConfig == null) { return(errorObject); } errorObject.DeviceCode = TagValueObject.device_code; if (TagValueObject.system_type_code == SystemTagCodeEnum.quality_error.ToString()) { eCfgPns = errorConfigPnManager.GetCfgPns(errorObject.eConfig.id);//获取该异常配置的机种信息 deviceSchedule = proScheduleMachineManager.SelectOnLineWorkorder(TagValueObject.device_code); if (deviceSchedule != null) { partNo = deviceSchedule.part_num;//获取当前机种 } if (eCfgPns != null && eCfgPns.Count > 0) { if (eCfgPns.Any(x => x.part_num.Equals(partNo))) //当前机种在此配置里面 { errorObject.eCfgPnList = eCfgPns; } } } if (errorObject.eConfig != null) { errorObject.eCfgPersonList = errorPersonManager.GetCfgPersonList(errorObject.eConfig.id); //需通知的配置人员加载 eCfgPns = errorConfigPnManager.GetCfgPns(errorObject.eConfig.id); errorObject.eCfgPnList = eCfgPns; //关联的机种信息加载 } return(errorObject); }
/// <summary> /// 确认并解除异常记录,用于现场提交解除. /// 支持三种格式:sn或者id&sn,id&M&M /// 格式1:只有card内容时,为HMI触控屏发送的格式,此方式只能确认第一条记录,HMI触控屏无物料呼叫列表; /// </summary> /// <param name="ErrorWatchList">当前监控队列</param> /// <param name="MachineCode">设备编码</param> /// <param name="StationId">站位id</param> /// <param name="TagValueInItem">标签值对象</param> /// <returns>正确执行返回ErrorObject,错误执行返回null</returns> public ErrorObject AckErrorLogDetails(string MachineCode, int StationId, DeviceTagValueInfo TagValueInItem, TagAreaAttributeEnum tagAreaAttributeEnum) { ErrorTypeService errorTypeService = new ErrorTypeService(); error_type_details eDetails = null; ErrorObject errorObject = null; string TypeSn = string.Empty; int errorLogId = -1; Dictionary <string, object> dic = new Dictionary <string, object>();//加入需要更新的字段信息 //支持两种格式,sn或者id&sn,id为异常记录的唯一标识号 TagIdAndValue valueObject = tagService.GetTagValue(TagValueInItem.tag_value); if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info) { MachineInfo machine = AndonGlobalCfg.MachinesList.FirstOrDefault(x => x.machine_code == MachineCode); errorObject = LoadErrorLogObject(TagValueInItem.device_id, TagValueInItem.system_tag_code, machine.unit_no, machine.line_id); } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info) { station_info station = AndonGlobalCfg.StationsList.FirstOrDefault(x => x.station_id == StationId); errorObject = LoadErrorLogObject(TagValueInItem.device_id, TagValueInItem.system_tag_code, station.unit_no, station.line_id); } if (errorObject != null && errorObject.eConfig != null && errorObject.eConfig.check_ack == (int)AckModeEnum.CodeAck) { if (valueObject.value != null && valueObject.value.Trim().Length >= 0) { if (valueObject.id >= 0 && valueObject.value.Length > 0 && valueObject.value2.Length == 0) { errorLogId = valueObject.id; TypeSn = valueObject.value; Console.WriteLine("AckErrorLogDetails,errorLogId=" + errorLogId + ",TypeSn=" + TypeSn); } else if (valueObject.id < 0 && valueObject.value.Length > 0) { TypeSn = valueObject.value; Console.WriteLine("AckErrorLogDetails,TypeSn=" + TypeSn); } } if (TypeSn.Length > 0)//获取具体的描述对象 { eDetails = errorTypeService.GetTypeDetails(-1, TypeSn); if (eDetails == null) { return(null); } } else { return(null); } } else if (errorObject != null && errorObject.eConfig != null && errorObject.eConfig.check_ack == (int)AckModeEnum.WithoutCodeAck)//不需要代码解除的 { int.TryParse(valueObject.value, out errorLogId); if (errorLogId != errorObject.ELog.id)//传递的id不匹配 { Console.WriteLine("安灯解除出错,id不匹配退出:errorLogId=" + errorLogId + "errorObject.ELog.id=" + errorObject.ELog.id); return(null); } } if (errorObject != null && errorObject.ELog != null) { if (errorObject.eConfig.check_ack == (int)AckModeEnum.CodeAck) { errorObject.ELog.error_type_id = eDetails.id; //更新具体的id信息 errorObject.eTypeDetails = eDetails; //记录详细原因 errorObject.ELog.maintenance_time = TagValueInItem.insert_time.AddHours(GlobalDefine.SysTimeZone); dic.Add("maintenance_time", errorObject.ELog.maintenance_time); dic.Add("error_type_id", errorObject.ELog.error_type_id);//未确认原因的再给值。物料呼叫监测typeid会提前赋值 } errorObject.ELog.release_time = TagValueInItem.insert_time.AddHours(GlobalDefine.SysTimeZone); //以变量值的时间更新结束时间 dic.Add("release_time", errorObject.ELog.release_time); int count = errorLogManager.Update(errorObject.ELog, dic); //提交数据库 if (count > 0) { Console.WriteLine("AckErrorLogDetails,确认成功,id=" + errorObject.ELog.id); } else { Console.WriteLine("安灯解除更新数据失败!"); } return(errorObject); } else { Console.WriteLine("安灯解除出错,errorObject != null && errorObject.ELog !=null 失败!"); } return(null); }
/// <summary> /// 增加设备新的异常记录。会将该异常的所有配置,记录,人员,类型对象一次性加载并返回 /// </summary> /// <param name="TagValueObject"></param> /// <param name="eCodeDeatials"></param> /// <returns>ErrorObject:包含该异常的配置,记录,需要通知的人员,以及类型</returns> public ErrorObject AddNewErrorLog(DeviceTagValueInfo TagValueObject, ErrorObject errorObject, TagAreaAttributeEnum tagAreaAttributeEnum, string AppendDetailsInfo = "") { int id = -1; error_log eLog = new error_log(); MachineInfo machine = null; station_info station = null; Pro_schedule_machine deviceSchedule = null; if (tagAreaAttributeEnum == TagAreaAttributeEnum.machine_info)//设备形式 { machine = AndonGlobalCfg.MachinesList.FirstOrDefault(x => x.machine_code == TagValueObject.device_code); deviceSchedule = proScheduleMachineManager.SelectOnLineWorkorder(TagValueObject.device_code); } else if (tagAreaAttributeEnum == TagAreaAttributeEnum.station_info)//站位形式 { station = AndonGlobalCfg.StationsList.FirstOrDefault(x => x.station_id == TagValueObject.device_id); deviceSchedule = proScheduleMachineManager.SelectOnLineWorkorder(TagValueObject.device_code); } if (machine != null || station != null) { if (deviceSchedule != null)//从在制进度中获取工单机种 { eLog.pn = deviceSchedule.part_num; eLog.work_order = deviceSchedule.work_order; } if (TagValueObject.system_tag_code == SystemTagCodeEnum.machine_time_error.ToString()) //工时异常类型 { eLog.start_time = TagValueObject.insert_time; //CT从CT模块过来,无时差 } else if (TagValueObject.system_tag_code == SystemTagCodeEnum.material_require.ToString()) //物料呼叫类型 { eLog.start_time = TagValueObject.insert_time.AddHours(GlobalDefine.SysTimeZone); //加上时区 int requireCount = 0, materialId = 0; //支持两种格式:数量,数量&物料id TagIdAndValue valueObject = tagService.GetTagValue(TagValueObject.tag_value); if (valueObject.id > 0 && valueObject.value.Length > 0) { requireCount = valueObject.id; int.TryParse(valueObject.value, out materialId); //id为物料呼叫的id eLog.error_type_id = materialId; //物料呼叫的id直接给到error_type_id字段 } } else { eLog.start_time = TagValueObject.insert_time.AddHours(GlobalDefine.SysTimeZone); //加上时区 } eLog.arrival_time = default(DateTime); //分配默认时间 eLog.release_time = default(DateTime); //分配默认时间 eLog.maintenance_time = default(DateTime); //分配默认时间 if (machine != null) { eLog.machine_code = TagValueObject.device_code; eLog.station_id = machine.station_id; eLog.line_id = machine.line_id; eLog.unit_no = machine.unit_no; } else { eLog.station_id = station.station_id; eLog.machine_code = station.station_name_en; eLog.line_id = station.line_id; eLog.unit_no = station.unit_no; } eLog.system_tag_code = TagValueObject.system_tag_code; eLog.error_name = errorObject.eConfig.error_name + AppendDetailsInfo; if (errorObject.eConfig.check_ack == (int)AckModeEnum.NoAck)//只是记录,不需要确认 { eLog.release_time = eLog.start_time; } eLog.ack_person_id = -1;//确认人员为空 if (eLog.error_type_id == 0) { eLog.error_type_id = -1;//确认编码为空 } id = errorLogManager.Insert(eLog); //插入数据库 if (id > 0) { eLog.id = id; //id记录 errorObject.ELog = eLog; } } return(errorObject); }