using FLY.OBJComponents.Common; using FLY.OBJComponents.IService; using FObjBase; using Misc; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FLY.OBJComponents.Server { public class ErrorConf { #region 延时推送 MARKNO const int MARKNO_DELAY_ISCONNECTED = 4; #endregion string plcName; /// <summary> /// 需要设置 /// </summary> IPLCProxySystemService PLCos; /// <summary> /// 报警系统 /// </summary> WarningSystem mWarning; public byte ErrCode=0; public ErrorConf(IPLCProxySystemService PLCos, WarningSystem mWarning, string plcName) { this.PLCos = PLCos; this.mWarning = mWarning; this.plcName = plcName; } #region 报警 public class ErrorAction { public List<ErrorInfo> error_property; public object state; public delegate void ErrorHandler(ref string msg, object state); public ErrorHandler action; } public class ErrorInfo { public string property; public byte code; public string msg; } Dictionary<INotifyPropertyChanged, ErrorAction> obj_error = new Dictionary<INotifyPropertyChanged, ErrorAction>(); public void AddErrorAction(INotifyPropertyChanged sender, ErrorAction.ErrorHandler errorHandler = null, object state = null) { //反射找出全部是报警的property List<ErrorInfo> error_property = new List<ErrorInfo>(); foreach (var propertyInfo in sender.GetType().GetProperties()) { if (propertyInfo.GetCustomAttributes(typeof(IsErrorAttribute), false).Count() > 0) { //肯定有,没有就让它出错!!! string desp = (propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).First() as DescriptionAttribute).Description; //报警如果是反向, 会被设置为放大=-1, 所以 最后属性 肯定是 true 时报警, offIsError没有用 ErrorInfo errorInfo = new ErrorInfo() { property = propertyInfo.Name, msg = desp, code = ErrCode }; error_property.Add(errorInfo); ErrCode++; } } obj_error.Add(sender, new ErrorAction() { error_property = error_property, action = errorHandler, state = state }); } /// <summary> /// 执行之前,需要调用 AddErrorAction, 向 obj_error 添加报警寄存器操作 /// </summary> public void InitError() { foreach (var obj in obj_error.Keys) { obj.PropertyChanged += Obj_PropertyChanged_ForError; } //-------------------------------------------------------------------------------- //添加任务 foreach (var kv in obj_error) { string objname = PLCos.ObjNames.First(_kv => _kv.Value == kv.Key).Key; PLCos.SetPlan(objname, kv.Value.error_property.Select(ei => ei.property).ToArray(), 0); } //-------------------------------------------------------------------------------- //连接断开事件 FObjBase.PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD, () => { Misc.BindingOperations.SetBinding(PLCos, nameof(PLCos.IsConnectedWithPLC), () => { bool b = !PLCos.IsConnectedWithPLC; ERR_STATE state = b ? ERR_STATE.ON : ERR_STATE.OFF; ERRNO errno = PlcErrNos.ERRNO_PLC_DISCONNECTED; byte errcode = errno.Code; string description = $"{plcName} "+errno.Descrption; mWarning.Add(errcode, description, state); }); }, TimeSpan.FromSeconds(3), true, false, this, MARKNO_DELAY_ISCONNECTED, true); //-------------------------------------------------------------------------------- //启动定时器,每1秒查报警,防止 以为报警复位了,但其实还在报警 //FObjBase.PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD, // () => // { // foreach(var objError in obj_error) // { // object sender = objError.Key; // ErrorAction errorAction = objError.Value; // foreach (var ei in errorAction.error_property) // { // //获取描述 // var type = sender.GetType(); // var property = type.GetProperty(ei.property); // bool b = (bool)property.GetValue(sender, null); // string desp = ei.msg; // ERR_STATE state = b ? ERR_STATE.ON : ERR_STATE.OFF; // byte errcode = ei.code;//每个报警必须不一样!! // string description = desp; // errorAction.action?.Invoke(ref description, errorAction.state); // mWarning.Add(errcode, description, state); // } // } // }, TimeSpan.FromSeconds(1)); } public void ResetError(INotifyPropertyChanged sender) { var type = sender.GetType(); foreach (var ei in obj_error[sender as INotifyPropertyChanged].error_property) { var property = type.GetProperty(ei.property); property.SetValue(sender, false); } } public void ResetError() { foreach (var sender in obj_error.Keys) { ResetError(sender); } } void Obj_PropertyChanged_ForError(object sender, PropertyChangedEventArgs e) { ErrorAction errorAction = obj_error[sender as INotifyPropertyChanged]; var eis = from ei in errorAction.error_property where ei.property == e.PropertyName select ei; if (eis.Count() > 0) { var ei = eis.First(); //获取描述 var type = sender.GetType(); var property = type.GetProperty(ei.property); bool b = (bool)property.GetValue(sender, null); string desp = ei.msg; ERR_STATE state = b ? ERR_STATE.ON : ERR_STATE.OFF; byte errcode = ei.code;//每个报警必须不一样!! string description = desp; errorAction.action?.Invoke(ref description, errorAction.state); mWarning.Add(errcode, description, state); } } #endregion } }