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
}
}