using FLY.Thick.Base.Common; using FLY.Thick.Base.IService; using FLY.Thick.Base.Server; using FLY.Thick.Blowing.Common; using FLY.Thick.Blowing.Server; using FLY.Thick.Blowing.Server.Model; using FlyADBase; using FObjBase; using Misc; using NLog.Config; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Threading; using FlyADIODefine = FLY.Thick.BlowingScan.Common.FlyADIODefine; using HistoryDb = FLY.Thick.BlowingScan.Server.Model.HistoryDb; using OrgDbModel = FLY.Thick.BlowingScan.Server.Model.OrgDbModel; using ScanWarning = FLY.Thick.Blowing.Server.ScanWarning; namespace FLY.Thick.BlowingScan.Server { public class TDGage : ITDGageService { const int MARKNO_UPDATEV = 1; /// /// 参数目录 m_path;数据文件的 根目录默认是 "Gage1", 不能有 @"\" /// 目前也是对外的服务器目录 /// public string mParamDirectory; /// /// 当前基本简单参数 /// public DynArea DynArea => dynArea; /// /// 当前基本简单参数 /// DynArea dynArea; /// /// 设备参数 /// public InitParam initParam; /// /// 运行参数 /// public BlowingFixProfile profile; BlowingFixProfileParam profileParam; /// /// 边界查找,由 boltmap 独立出来的功能 /// public BorderSearch borderSearch; /// /// AD曲线 /// public CurveCollection curve; /// /// 报警系统 /// public FLY.OBJComponents.Server.WarningSystem2 warning; #region 运行模式 /// /// AD卡 /// public FlyADBase.FlyAD7 flyAd; public FlyAdService flyAdService; /// /// 样品修正 /// public GSample getSample; /// /// GM管理器 /// GageModeManager gmManager; /// /// 断开连接 /// GM_Disconnected gmDisconnected; /// /// 暂停扫描 /// GM_Pause gmPause; /// /// 自动启动扫描 /// GM_AutoScan gmAutoScan; /// /// 前进 /// GM_Forward gmForw; /// /// 后退 /// GM_Backward gmBackw; /// /// 归零 /// GM_Origin gmOrg; /// /// 停止 /// GM_Stop gmStop; /// /// 运行到目标位置 /// GM_Goto gmRunto; /// /// 机架校正模式,参数 /// public GM_ScanCorr gmScanCorr; /// /// 定点模式 /// public GM_Fix gmFix; /// /// 吹膜测厚模式.扫描 /// public GM_BlowingScan gmRenZiJiaScan; /// /// 扫描报警系统 /// public ScanWarning scanWarning; /// /// 机架信息,不同于机架校正 /// public GM_GageInfo gmGageInfo; #endregion /// /// 系统参数 /// public SysParam sysParam; /// /// 数据库对象 /// DbModel dbModel; ///// ///// 原始数据 数据库对象 ///// //OrgDbModel orgDbModel; /// /// 数据库写操作 /// public HistoryDb historyDb; /// /// 本地数据库 /// LocalDb localDb; /// /// 数据库读操作 /// public BulkDb bulkDb; public TDGage(string nam) { mParamDirectory = nam;// @"D:\" + m_name; if (!System.IO.Directory.Exists(mParamDirectory)) { System.IO.Directory.CreateDirectory(mParamDirectory); } System.Environment.CurrentDirectory = mParamDirectory; sysParam = new SysParam(null);//系统参数 initParam = new InitParam() { DbDirPath = @"D:\blowingdata" }; if (!initParam.Load()) initParam.Save(); initParam.HasHold = false; initParam.HasProfileSample = false; initParam.HasPunch = false; initParam.HasVSign = false; initParam.HasHSign = false; initParam.HasScanCorr = true; profile = new BlowingFixProfile();//运行配置参数 profileParam = profile.Param; borderSearch = new BorderSearchPlastic(null);//边界查找 curve = new CurveCollection(null);//AD转thick dbModel = new DbModel(); //orgDbModel = new OrgDbModel(); localDb = new LocalDb(); historyDb = new HistoryDb(); bulkDb = new BulkDb(); dynArea = new DynArea(); warning = new FLY.OBJComponents.Server.WarningSystem2(); scanWarning = new ScanWarning(); flyAd = new FlyAD7(); flyAdService = new FlyAdService(); gmManager = new GageModeManager(); gmFix = new GM_Fix(); gmAutoScan = new GM_AutoScan(); gmDisconnected = new GM_Disconnected(); gmPause = new GM_Pause(); gmForw = new GM_Forward(); gmBackw = new GM_Backward(); gmRunto = new GM_Goto(); gmOrg = new GM_Origin(); gmStop = new GM_Stop(); gmGageInfo = new GM_GageInfo(); gmScanCorr = new GM_ScanCorr(); getSample = new GSample(); gmRenZiJiaScan = new GM_BlowingScan(); } public async Task Init() { //数据库 配置---------------------------------------- #region await Task.Factory.StartNew(() => { dbModel.Init(); //删除不需要的备份数据 dbModel.KeepBackupSize(12); //备份上一个月之前的数据到 yyyy-MM 文件夹 dbModel.BackupBbInSize(12); //当前的数据库只保存上个月与这个月的数据 dbModel.KeepDBSize(1); }); historyDb.Init(dbModel, localDb); bulkDb.Init(historyDb, localDb, dbModel); //数据库备份检查 BackupDbCheckInit(); #endregion //BorderSearch 配置---------------------------------------- borderSearch.Init(warning); Misc.BindingOperations.SetBinding(borderSearch, new string[] { nameof(borderSearch.Width) }, () => { DynArea.Width = borderSearch.Width * initParam.Encoder1_mmpp; }); initParam.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(initParam.Encoder1_mmpp)) { DynArea.Width = borderSearch.Width * initParam.Encoder1_mmpp; } }; //有效范围 Misc.BindingOperations.SetBinding(initParam, new string[] { nameof(initParam.PosLength) }, () => { borderSearch.Valid = new RangeStruct(0, initParam.PosLength - 1); }); //DynArea 配置---------------------------------------- DynArea.PropertyChanged += new PropertyChangedEventHandler(mDynArea_PropertyChanged); //GageModeManager 配置---------------------------------------- Misc.BindingOperations.SetBinding( gmManager, nameof(gmManager.State), DynArea, nameof(DynArea.ControllerState)); //FlyAd7 配置---------------------------------------- if (!flyAd.Load()) flyAd.Save(); flyAd.Connect(); flyAdService.Init(flyAd, Ad2Thk); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.HardwareVersion), () => { FlyADIODefine.SetInstance(new FlyADIODefine()); FlyADIODefine.Instance.SerVersion(flyAd.HardwareVersion); }); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.PosLength), flyAd, nameof(flyAd.PosLen)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.IStatus), dynArea, nameof(dynArea.IStatus)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.OStatus), dynArea, nameof(dynArea.OStatus)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.Position), dynArea, nameof(dynArea.Position)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.Position), () => { DynArea.PosMm = flyAd.Position * initParam.Encoder1_mmpp;//mm }); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.Position2), dynArea, nameof(dynArea.Position2)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.Surplus), dynArea, nameof(dynArea.Hrs)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.IsConnected), dynArea, nameof(dynArea.FLYADIsConnect)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.PosOfGrid), initParam, nameof(initParam.PosOfGrid)); Misc.BindingOperations.SetBinding(flyAd, nameof(flyAd.Speed), () => { double speed = flyAd.Speed * initParam.Encoder1_mmpp;//mm/s speed = speed * 60 / 1000;//m/min DynArea.Velocity = speed; }); Misc.BindingOperations.SetBinding(initParam, new string[] { nameof(initParam.DataValidSrc) }, update_datavalid); Misc.BindingOperations.SetBinding(flyAd, new string[] { nameof(flyAd.Ratio02), nameof(flyAd.Ratio01) }, delegate () { initParam.Speed1Scale = (double)flyAd.Ratio02 / flyAd.Ratio01; }); Misc.BindingOperations.SetBinding(initParam, new string[] { nameof(initParam.SVelocity), nameof(initParam.ATime), nameof(initParam.DTime), nameof(initParam.HVelocity1), nameof(initParam.HVelocity2) }, delegate () { PollModule.Current.Poll_JustOnce(delegate () { flyAd.SetPosParam(0xffffffff, initParam.SVelocity, initParam.ATime, initParam.DTime, initParam.HVelocity1, initParam.HVelocity2); }, this, MARKNO_UPDATEV); }); Misc.BindingOperations.SetBinding(flyAd, new string[] { nameof(flyAd.IsConnected) }, delegate () { if (flyAd.IsConnected == true) { //还需要在flyad 重新连接上时,设置!!!!! PollModule.Current.Poll_JustOnce(delegate () { flyAd.SetPosParam(0xffffffff, initParam.SVelocity, initParam.ATime, initParam.DTime, initParam.HVelocity1, initParam.HVelocity2); }, this, MARKNO_UPDATEV); } }); //WarningSystem 配置---------------------------------------- warning.Init(historyDb.ErrorBuffer); warning.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(warning.IsRinging)) { flyAd.SetOutputBit(FlyADIODefine.Instance.OutNo_Alarm, !warning.IsRinging); } }; //--------------------------------------------------------------------------------------------------------------- //ScanWarning_Create scanWarning.Init(warning, historyDb); //GM_Fix 配置---------------------------------------- gmFix.Init(flyAd, dynArea, Ad2Thk); gmManager.AddGM(gmFix); //GM_AutoScan 配置---------------------------------------- gmAutoScan.Init(flyAd, StartP1); Misc.BindingOperations.SetBinding( gmAutoScan, nameof(gmAutoScan.Counter), DynArea, nameof(DynArea.AutoScanCounter)); gmManager.AddGM(gmAutoScan); //GM_Disconnected 配置---------------------------------------- gmDisconnected.Init(flyAd, DynArea, gmAutoScan); gmManager.AddGM(gmDisconnected); //GM_Pause 配置---------------------------------------- gmPause.Init(flyAd, dynArea, gmAutoScan); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.ReStartDelay), gmPause, nameof(gmPause.Delay)); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.AutoF1F3), gmPause, nameof(gmPause.Enable)); gmManager.AddGM(gmPause); //GM_Forward 配置---------------------------------------- gmForw.Init(flyAd); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.VJOG), gmForw, nameof(gmForw.Velocity)); gmManager.AddGM(gmForw); //GM_Backward 配置---------------------------------------- gmBackw.Init(flyAd); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.VJOG), gmBackw, nameof(gmBackw.Velocity)); gmManager.AddGM(gmBackw); //GM_Goto 配置---------------------------------------- gmRunto.Init(flyAd); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.VJOG), gmRunto, nameof(gmRunto.Velocity)); gmManager.AddGM(gmRunto); //GM_Origin 配置---------------------------------------- gmOrg.Init(flyAd); gmManager.AddGM(gmOrg); //GM_Stop 配置---------------------------------------- gmStop.Init(flyAd); gmManager.AddGM(gmStop); //GM_GageInfo 配置---------------------------------------- gmGageInfo.Init(flyAd, initParam); gmManager.AddGM(gmGageInfo); //GM_ScanCorr 配置---------------------------------------- gmScanCorr.Init(flyAd, initParam); gmManager.AddGM(gmScanCorr); flyAd.CorrectADs = gmScanCorr.CorrectADs; //GSample 配置---------------------------------------- getSample.Init(flyAd, gmGageInfo, warning); Misc.BindingOperations.SetBinding(getSample.Samples.First(), nameof(SampleCell.AD), borderSearch, nameof(borderSearch.CurrTempAD)); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.VAccuracy), getSample, nameof(getSample.Velocity)); getSample.SampleChangedEvent += getSample_SampleChangedEvent; //GM_Scan 配置---------------------------------------- gmRenZiJiaScan.Init(flyAd, getSample, initParam, warning, borderSearch, dynArea, Ad2Thk, profile.Param, historyDb, bulkDb); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.AutoOrgInterval), gmRenZiJiaScan, nameof(gmRenZiJiaScan.OrgInterval)); Misc.BindingOperations.SetBinding(initParam, nameof(initParam.VScan), gmRenZiJiaScan, nameof(gmRenZiJiaScan.Velocity)); Misc.BindingOperations.SetBinding(gmRenZiJiaScan.mPDetect, nameof(gmRenZiJiaScan.mPDetect.RollPerimeter), initParam, nameof(initParam.MmOfR), BindingOperations.BindingMode.TwoWay); Misc.BindingOperations.SetBinding(gmRenZiJiaScan.mPDetect, nameof(gmRenZiJiaScan.mPDetect.FilmVelocity), dynArea, nameof(dynArea.FilmVelocity)); gmManager.AddGM(gmRenZiJiaScan); ErrNoForCheckInit(); gmFix.Start(); } #region 异常检测 class ErrNoForCheckItem { public FLY.OBJComponents.Common.ERRNO errno; public Func conditional; /// /// 持续时间,单位s /// public int cnt; int timer = -1; public FLY.OBJComponents.Server.WarningSystem2 mWarning; public void Clear() { if (timer == 0) { mWarning.Remove(errno.Code); } timer = -1; } public void OnPoll() { if (conditional()) { if (timer < 0) timer = cnt; else { if (timer > 0) timer--; if (timer == 0) { mWarning.Add(errno.Code, errno.Descrption); } } } else { Clear(); } } } List ErrNoForCheckItems = new List(); public event PropertyChangedEventHandler PropertyChanged; void ErrNoForCheckInit() { #region 时间触发的报警 ErrNoForCheckItems.Add(//AD值太小 new ErrNoForCheckItem() { errno = ERRNOs.Instance.BASE_ERRNO_AD_MIN, cnt = 20, conditional = delegate () { return DynArea.AD < (DynArea.ADMax * 0.01); } }); ErrNoForCheckItems.Add(//AD值太大 new ErrNoForCheckItem() { errno = ERRNOs.Instance.BASE_ERRNO_AD_MAX, cnt = 20, conditional = delegate () { return (DynArea.AD > (DynArea.ADMax * 0.98)); } }); ErrNoForCheckItems.Add(//限位 new ErrNoForCheckItem() { errno = ERRNOs.Instance.BASE_ERRNO_LIMIT, cnt = 2, conditional = delegate () { if (flyAd.MotorType == FlyADBase.MOTORTYPE.VF0) return false; return ( (Misc.MyBase.CHECKBIT(DynArea.IStatus, FlyADIODefine.Instance.InNo_Limit_Forw) == true) || (Misc.MyBase.CHECKBIT(DynArea.IStatus, FlyADIODefine.Instance.InNo_Limit_Backw) == true)); } }); ErrNoForCheckItems.Add(//急停 new ErrNoForCheckItem() { errno = ERRNOs.Instance.BASE_ERRNO_EMERGENCY, cnt = 2, conditional = delegate () { return ( (Misc.MyBase.CHECKBIT(DynArea.IStatus, FlyADIODefine.Instance.InNo_Manual_Forw) == false) || (Misc.MyBase.CHECKBIT(DynArea.IStatus, FlyADIODefine.Instance.InNo_Manual_Backw) == false)); } }); foreach (ErrNoForCheckItem item in ErrNoForCheckItems) { item.mWarning = warning; } FObjBase.PollModule.Current.Poll_Config( FObjBase.PollModule.POLL_CONFIG.ADD, onpoll_checkErrNo, TimeSpan.FromSeconds(1)); #endregion #region 状态触发的报警 Misc.BindingOperations.SetBinding(DynArea, nameof(DynArea.Hrs), () => { if (DynArea.Hrs < 48 && DynArea.Hrs > 0)//授权限制提醒 { warning.Add( ERRNOs.Instance.BASE_ERRNO_LICENSE_TIP.Code, ERRNOs.Instance.BASE_ERRNO_LICENSE_TIP.Descrption); } else { warning.Remove(ERRNOs.Instance.BASE_ERRNO_LICENSE_TIP.Code); } }); Misc.BindingOperations.SetBinding(DynArea, nameof(DynArea.SecuteLock), () => { if (DynArea.SecuteLock) { warning.Add( ERRNOs.Instance.BASE_ERRNO_LICENSE.Code, ERRNOs.Instance.BASE_ERRNO_LICENSE.Descrption); } else { warning.Remove(ERRNOs.Instance.BASE_ERRNO_LICENSE.Code); } }); //AD盒连接断开 Misc.BindingOperations.SetBinding(DynArea, nameof(DynArea.FLYADIsConnect), () => { if (!DynArea.FLYADIsConnect) { warning.Add( ERRNOs.Instance.BASE_ERRNO_FLYAD7DISCONNECTED.Code, ERRNOs.Instance.BASE_ERRNO_FLYAD7DISCONNECTED.Descrption); } else { warning.Remove(ERRNOs.Instance.BASE_ERRNO_FLYAD7DISCONNECTED.Code); } }); #endregion } void onpoll_checkErrNo() //1秒执行一次 { if (!DynArea.FLYADIsConnect) { foreach (ErrNoForCheckItem item in ErrNoForCheckItems) item.Clear(); } else { foreach (ErrNoForCheckItem item in ErrNoForCheckItems) item.OnPoll(); } } #endregion void mDynArea_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(dynArea.FilmVelocity)) { update_datavalid(); } } void update_datavalid() { if (dynArea.FilmVelocity < initParam.FilmVThreshold) dynArea.DataValid = false; else dynArea.DataValid = true; } public double Ad2Thk(int ad) { if (!Misc.MyBase.ISVALIDATA(ad)) return double.NaN; double thk; if (getSample.Enable)//动态温修 thk = curve.AD2Value(ad, AD2ValueFlag.Revised); else thk = curve.AD2Value(ad, AD2ValueFlag.NoRevised); thk = profile.Param.K * thk; thk = Math.Round(thk, 2); return thk; } void getSample_SampleChangedEvent(object sender) { CurveCollection pCurve = curve; GSample gsample = getSample; if (gsample.OK()) { List list = new List(); for (int i = 0; i < gsample.Samples.Count(); i++) { var sample = gsample.Samples[i]; if ((sample.Enable) && (!sample.JustForCheck) && (sample.AD > 0)) { list.Add(new CurveCollection.ExChange() { OrgAD = sample.OrgAD, CurrAD = sample.AD }); } } pCurve.ModifyExChange(list); pCurve.ReviseCurve(); for (int i = 0; i < gsample.Samples.Count(); i++) { var sample = gsample.Samples[i]; if ((sample.Enable) && (sample.AD > 0)) { sample.SampleValue = curve.AD2Value(sample.AD, AD2ValueFlag.Revised); } } //历史数据保存 var sampleads = from sample in gsample.Samples where sample.Enable select sample.AD; if (sampleads.Count() > 0) { historyDb.AddSampleData( new Lc_Sample() { Time = DateTime.Now, SampleADs = sampleads.ToArray() }); } } } #region 数据库备份检测 DispatcherTimer backupDbTimer; DateTime StartupTime; void BackupDbCheckInit() { StartupTime = DateTime.Now; //定时检查提示 backupDbTimer = new DispatcherTimer(); backupDbTimer.Interval = TimeSpan.FromHours(1); backupDbTimer.Tick += BackupDbTimer_Tick; backupDbTimer.Start(); } private void BackupDbTimer_Tick(object sender, EventArgs e) { //只有在9:00 到 21:00 才会检查,避免深夜出问题 if (DateTime.Now.Hour < 9 || DateTime.Now.Hour > 20) return; if (DateTime.Now - StartupTime > TimeSpan.FromDays(28) && DateTime.Now.Month != StartupTime.Month) { //已经连续开机1个月,需要重新启动程序 warning.Add( ERRNOs.Instance.BASE_ERRNO_DB_BACKUP.Code, ERRNOs.Instance.BASE_ERRNO_DB_BACKUP.Descrption); } } #endregion #region ITDGageService /// /// /// public void StartP1() { gmRenZiJiaScan.Start(); } /// /// /// /// public void StartP2(STARTP2_MODE mode) { StartP2(mode, 0); } /// /// /// /// /// public void StartP2(STARTP2_MODE mode, int targetpos) { switch (mode) { case STARTP2_MODE.ORG: gmOrg.Start(); break; case STARTP2_MODE.STOP: gmStop.Start(); break; case STARTP2_MODE.FORW: case STARTP2_MODE.FORW_UNTIL_STOP: gmForw.Start(); break; case STARTP2_MODE.BACKW: case STARTP2_MODE.BACKW_UNTIL_STOP: gmBackw.Start(); break; case STARTP2_MODE.RUNTO: gmRunto.Start(targetpos); break; } } #endregion } }