using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using FLY.OBJComponents.Server; using FLY.OBJComponents.Common; using FLY.Thick.Blowing.IService.IBulkDBServicePack; using FLY.Thick.Blowing.IService; using FLY.Thick.Blowing.Common; namespace FLY.Thick.Blowing.Server { public class ScanWarning : Misc.ISaveToXml, INotifyPropertyChanged, IScanWarningService { private WarningSystem mWarning; private IBulkDBService mBulkDB; /// <summary> /// 使能 /// </summary> public bool Enable { get; set; } /// <summary> /// 目标值,绑定 profileparam.Target /// </summary> public double Target { get; set; } /// <summary> /// 产品公差,绑定 profileparam.TolerancePercent /// </summary> public double TolerancePercent { get; set; } /// <summary> /// 连续N个点,大于规格线(公差)才算报警 /// </summary> public int AlarmCnt_Tolerance { get; set; } = 10; enum CheckResult { Idle, ToleranceWarning, } CheckResult Check(double[] data) //数据是环形的。 { double tolerance = Target * TolerancePercent; int cnt_tolerance = 0; int start_tolerance = 0; int valid_index = -1;//第1个合格范围数据 for (int i = 0; i < data.Length; i++) { double d = data[i]; if (double.IsNaN(d)) continue; double delta = Math.Abs(d - Target); if (delta > tolerance) { //触发 if (cnt_tolerance == 0) start_tolerance = i; cnt_tolerance++; if (cnt_tolerance >= AlarmCnt_Tolerance) { //需要报警 return CheckResult.ToleranceWarning; } } else { cnt_tolerance = 0; if(valid_index==-1) valid_index = i; } } if (cnt_tolerance > 0) { for (int i = 0; i < valid_index; i++) { double d = data[i]; if (double.IsNaN(d)) continue; double delta = Math.Abs(d - Target); if (delta > tolerance) { //触发 cnt_tolerance++; if (cnt_tolerance >= AlarmCnt_Tolerance) { //需要报警 return CheckResult.ToleranceWarning; } } } } return CheckResult.Idle; } public void Apply() { Save(); } public ScanWarning() { Load(); } public void Init(WarningSystem warning, BlowingFixProfileParam profileParam, IBulkDBService bulkDB) { mWarning = warning; mBulkDB = bulkDB; Misc.BindingOperations.SetBinding( profileParam, "Target", this, "Target"); Misc.BindingOperations.SetBinding( profileParam, "TolerancePercent", this, "TolerancePercent"); mBulkDB.PropertyChanged += MBulkDB_PropertyChanged; } private void MBulkDB_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Count") { if (Enable) { if (mBulkDB.Count > 0) { int lastIndex = mBulkDB.Count - 1; mBulkDB.GetFrame( new Pack_GetFrameRequest() { Index = lastIndex, Count = 1 }, GetFrameCB, null); } } } } void GetFrameCB(object AyncContext, object retData) { Pack_GetFrameReponse reponse = retData as Pack_GetFrameReponse; CheckResult result; string accessory = ""; if (reponse.Values != null && reponse.Values.Count() > 0) { Model.LC_ScanData lc_ScanData = reponse.Values.First(); result = Check(lc_ScanData.Thicks); if(result!= CheckResult.Idle) accessory = Newtonsoft.Json.JsonConvert.SerializeObject(lc_ScanData.ID); } else { result = CheckResult.Idle; } switch (result) { case CheckResult.ToleranceWarning: //报警 mWarning.Add( ERRNOs.SCAN_ERRNO_OVERTOL.Code, ERRNOs.SCAN_ERRNO_OVERTOL.Descrption, ERR_STATE.ON, accessory ); break; case CheckResult.Idle: { //报警解除 mWarning.Add( ERRNOs.SCAN_ERRNO_OVERTOL.Code, ERRNOs.SCAN_ERRNO_OVERTOL.Descrption, ERR_STATE.OFF); } break; } } public void Save() { Misc.SaveToXmlHepler.Save("scanwarning.xml", this); } public bool Load() { return Misc.SaveToXmlHepler.Load("scanwarning.xml", this); } #region INotifyPropertyChanged 成员 public event PropertyChangedEventHandler PropertyChanged; #endregion public string[] GetSavePropertyNames() { return new string[]{ "Enable","AlarmCnt_Tolerance"}; } } }