ScanWarning.cs 6.96 KB
Newer Older
1
using AutoMapper;
2
using FLY.OBJComponents.Server;
3
using FLY.Thick.Base.Common;
4
using FLY.Thick.Blowing.IService;
5
using FLY.Thick.Blowing.Server.Model;
6
using Misc;
7
using Newtonsoft.Json;
8 9 10
using System;
using System.ComponentModel;
using System.IO;
11 12 13

namespace FLY.Thick.Blowing.Server
{
14
    public class ScanWarning : INotifyPropertyChanged, IScanWarningService
15
    {
16
        private WarningSystem2 mWarning;
17
        private IShareDbService shareDb;
18

19 20 21 22 23 24
        /// <summary>
        /// 使能
        /// </summary>
        public bool Enable { get; set; }

        /// <summary>
25
        /// 自动目标值
26
        /// </summary>
27
        public bool IsAutoTarget { get; set; } = true;
28

29 30 31 32 33
        /// <summary>
        /// 连续N个点,大于规格线(公差)才算报警
        /// </summary>
        public int AlarmCnt_Tolerance { get; set; } = 10;

34 35 36
        public event ScanWarningCheckEventHandler ScanWarningCheck;


37
        public enum CheckResult
38 39 40 41
        {
            Idle,
            ToleranceWarning,
        }
42 43 44 45 46 47 48 49

        /// <summary>
        /// 数据是环形的。
        /// </summary>
        /// <param name="target"></param>
        /// <param name="tolerancePercent"></param>
        /// <param name="data"></param>
        /// <returns></returns>
50
        public CheckResult Check(double target, double tolerancePercent, double[] data)
51
        {
52 53 54 55 56 57 58 59 60
            double avg = data.AverageNoNull();
            if (double.IsNaN(avg))
                return CheckResult.Idle;

            if (IsAutoTarget)
                target = avg;


            double tolerance = target * tolerancePercent;
61 62 63
            int cnt_tolerance = 0;
            int valid_index = -1;//第1个合格范围数据

64
            for (int i = 0; i < data.Length; i++)
65 66 67 68
            {
                double d = data[i];
                if (double.IsNaN(d))
                    continue;
69
                double delta = Math.Abs(d - target);
70

71

72 73 74 75 76 77 78 79 80 81 82 83 84
                if (delta > tolerance)
                {
                    //触发
                    cnt_tolerance++;
                    if (cnt_tolerance >= AlarmCnt_Tolerance)
                    {
                        //需要报警
                        return CheckResult.ToleranceWarning;
                    }
                }
                else
                {
                    cnt_tolerance = 0;
85
                    if (valid_index == -1)
86 87 88 89 90 91 92 93 94 95
                        valid_index = i;
                }
            }
            if (cnt_tolerance > 0)
            {
                for (int i = 0; i < valid_index; i++)
                {
                    double d = data[i];
                    if (double.IsNaN(d))
                        continue;
96
                    double delta = Math.Abs(d - target);
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
                    if (delta > tolerance)
                    {
                        //触发
                        cnt_tolerance++;
                        if (cnt_tolerance >= AlarmCnt_Tolerance)
                        {
                            //需要报警
                            return CheckResult.ToleranceWarning;
                        }
                    }
                }
            }

            return CheckResult.Idle;
        }
112 113
        public void Apply()
        {
114 115
            Save();
        }
116
        public ScanWarning()
117 118 119 120
        {
            Load();
        }

121
        public void Init(WarningSystem2 warning, IShareDbService shareDB)
122 123
        {
            mWarning = warning;
124
            shareDb = shareDB;
125

126
            shareDb.ScanDataAdded += MshareDB_ScanDataAdded;
127 128
        }

129
        private void MshareDB_ScanDataAdded(object sender, EventArgs _e)
130
        {
131
            var e = (ScanDataAddedEventArgs)_e;
132 133
            if (!Enable)
                return;
134
            shareDb.GetProfile((asyncContext, retData) =>
135
            {
潘栩锋's avatar
潘栩锋 committed
136
                Db_Profile dB_Profile = retData as Db_Profile;
137 138
                if (dB_Profile == null)
                    return;
139

140 141
                GetFrameCB(dB_Profile, e.scandata);
            }, null);
142

143 144
        }

145
        void GetFrameCB(Db_Profile dB_Profile, Lc_ScanData lc_ScanData)
146
        {
147
            CheckResult result = Check(dB_Profile.Target, dB_Profile.TolerancePercent, lc_ScanData.Thicks);
148 149


150 151
            string accessory = "";
            if (result != CheckResult.Idle)
152
                accessory = Newtonsoft.Json.JsonConvert.SerializeObject(new { ScanDataID = lc_ScanData.ID });
153 154 155 156 157

            switch (result)
            {
                case CheckResult.ToleranceWarning:
                    //报警
158 159 160
                    mWarning.Update(
                        ERRNOs.Instance.SCAN_ERRNO_OVERTOL.Code,
                        ERRNOs.Instance.SCAN_ERRNO_OVERTOL.Descrption,
161 162 163 164 165 166
                        accessory
                        );
                    break;
                case CheckResult.Idle:
                    {
                        //报警解除
167
                        mWarning.Remove(ERRNOs.Instance.SCAN_ERRNO_OVERTOL.Code);
168 169 170
                    }
                    break;
            }
171

172 173 174 175 176 177 178
            ScanWarningCheck?.Invoke(this, new ScanWarningCheckEventArgs()
            {
                isWarning = (result != CheckResult.Idle),
                profile = dB_Profile,
                scandata = lc_ScanData
            });
        }
179 180


181 182
        string file_path = "scanwarning.json";
        public bool Load()
183
        {
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
            try
            {
                if (File.Exists(file_path))
                {
                    string json = File.ReadAllText(file_path);
                    var jsonDb = JsonConvert.DeserializeObject<ScanWarningJsonDb>(json);
                    ScanWarningJsonDb.Mapper.Map(jsonDb, this);
                    return true;
                }
            }
            catch
            {
                //异常,没有json 解码失败

            }
            return false;
200
        }
201 202

        bool Save()
203
        {
204 205 206 207 208 209 210 211 212 213 214 215 216
            try
            {
                var jsonDb = ScanWarningJsonDb.Mapper.Map<ScanWarningJsonDb>(this);
                string json = JsonConvert.SerializeObject(jsonDb, Formatting.Indented);
                File.WriteAllText(file_path, json);
                return true;
            }
            catch
            {
                //异常,没有json 编码失败

            }
            return false;
217
        }
218 219


220 221 222 223 224 225 226
        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }
227
    public class ScanWarningJsonDb
228
    {
229 230
        public static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
        {
231 232 233 234 235 236
            c.CreateMap<ScanWarning, ScanWarningJsonDb>().ReverseMap();
        }));
        public bool Enable;
        public bool IsAutoTarget;
        public int AlarmCnt_Tolerance;
    }
237 238 239
    public class ScanWarningCheckEventArgs
    {
        public bool isWarning;
潘栩锋's avatar
潘栩锋 committed
240 241
        public Db_Profile profile;
        public Lc_ScanData scandata;
242 243
    }
    public delegate void ScanWarningCheckEventHandler(object sender, ScanWarningCheckEventArgs e);
244 245


246
}