using FLY.FeedbackRenZiJia.Common; using FLY.FeedbackRenZiJia.IService; using FLY.FeedbackRenZiJia.OBJ_INTERFACE; using FObjBase; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; namespace FLY.FeedbackRenZiJia.Client { public class HeatBufServiceClient : FObjServiceClient, IHeatBufService { #region 属性,对外接口 #region 参数 /// <summary> /// 加热生效曲线,允许为空,则不生效 /// </summary> [PropertyChanged.DoNotCheckEquality] public List<int> HeatEffectCurve { get; set; } = new List<int>(); /// <summary> /// 厚度稳定范围 %, 偏差在范围内,都是稳定的 /// </summary> public int StableRange { get; set; } = 2; /// <summary> /// 厚度稳定范围 %, 加热量变化为0时,偏差在范围内,都是稳定的 /// </summary> public int StableRange0 { get; set; } = 2; /// <summary> /// 对位模式, 加热与厚度相关性阀值, 相关性 >=0.7 /// </summary> public double ThresholdR { get; set; } = 0.7; /// <summary> /// 对位模式 厚度%差 的极差 >= +4%-4%=8%, 单位% /// </summary> public int ThresholdMaxMin { get; set; } = 8; /// <summary> /// % /// 最大sigma, 只有当前的sigma 在 最大sigma 与 最小 sigma 内,才能控制 /// </summary> public int ThresholdSigmaMax { get; set; } = 20; /// <summary> /// % /// 最小sigma, 只有当前的sigma 在 最大sigma 与 最小 sigma 内,才能控制 /// </summary> public double ThresholdSigmaMin { get; set; } = 2; /// <summary> /// 使用这里独立的Kp, 与 HeatCell 不一样 /// </summary> public bool IsUsedLocalKp { get; set; } /// <summary> /// 本地Kp, 用于判断稳定性 /// </summary> public double LocalKp { get; set; } = 3; #endregion #region 状态 /// <summary> /// 总延时 =Delay+mRenZiJiaService.FilmLength/mRenZiJiaService.Velocity /// </summary> public TimeSpan Delay { get; set; } = TimeSpan.FromSeconds(100); #region 对位 /// <summary> /// 进入了对位模式 /// </summary> public bool IsIntoAutoONo { get; set; } /// <summary> /// 对位模式结果 /// </summary> public EAutoONoResult AutoONoResult { get; set; } = EAutoONoResult.Idle; /// <summary> /// 计算的最佳复位区号 /// </summary> public int BestOrgBoltNo { get; set; } = -1; /// <summary> /// 计算的最佳复位区号 对应的 加热/厚度 /// </summary> public double BestKp { get; set; } = -1; /// <summary> /// 计算的最佳复位区号 对应的 加热与厚度相关性 /// </summary> public double MaxR { get; set; } = -1; /// <summary> /// 计算的最佳复位区号 对应的 厚度%变化极差 单位% /// </summary> public double MaxMin { get; set; } = -1; #endregion #region 稳定性 /// <summary> /// 当前检测出来的厚度数据 稳定状态 /// </summary> public STABILITY Stability { get; protected set; } = STABILITY.IDLE; /// <summary> /// 当前检测出来的厚度数据 的稳定性 /// </summary> public double CurrR { get; protected set; } = -1; /// <summary> /// 当前检测出来的厚度数据 2Sigma /// </summary> public double Curr2Sigma { get; protected set; } = -1; /// <summary> /// 当前打散程度。 /// 连续N点都在平均值同一侧为一个块; /// 这些块的长度平均值/总长度, 为打散度; /// 打散度越小越好, 最小为 1/NBolts /// </summary> public double CurrBreakUp { get; protected set; } = 50; /// <summary> /// 当前检测出来的厚度数据,时间 /// </summary> public DateTime CurrTime { get; protected set; } = DateTime.MinValue; /// <summary> /// 当前检测出来的厚度数据,方向 /// </summary> public Misc.DIRECTION CurrDirection { get; protected set; } = Misc.DIRECTION.FORWARD; #endregion #region 列表 /// <summary> /// 列表最后1个BM /// </summary> public int LastBM { get; protected set; } /// <summary> /// 列表第1个BM /// </summary> public int FirstBM { get; protected set; } #endregion #region 每个分区状态 [PropertyChanged.DoNotCheckEquality] public bool[] BoltIsStable { get; protected set; } #endregion #endregion #endregion public HeatBufServiceClient(UInt32 serviceId) : base(serviceId) { } public HeatBufServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { } #region IFObj public override void ConnectNotify(IFConn from) { base.ConnectNotify(from); if (from.IsConnected) { FObjSys.Current.GetValueEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.GET_PARAMS); FObjSys.Current.GetValueEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.GET_STATE); FObjSys.Current.GetValueEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.GET_BM); FObjSys.Current.GetValueEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.GET_ISSTABLES); FObjSys.Current.SenseConfigEx(mConn, mServerID, ID, 0xffffffff, SENSE_CONFIG.ADD); } } public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata) { switch (memid) { case HEATBUF_OBJ_INTERFACE.GET_PARAMS: { string json = Misc.Converter.BytesToString(infodata); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<HEATBUF_OBJ_INTERFACE.Pack_Params>(json); HeatEffectCurve = p.HeatEffectCurve; StableRange = p.StableRange; StableRange0 = p.StableRange0; ThresholdR = p.ThresholdR; ThresholdMaxMin = p.ThresholdMaxMin; ThresholdSigmaMax = p.ThresholdSigmaMax; IsUsedLocalKp = p.IsUsedLocalKp; LocalKp = p.LocalKp; } break; case HEATBUF_OBJ_INTERFACE.GET_STATE: { string json = Misc.Converter.BytesToString(infodata); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<HEATBUF_OBJ_INTERFACE.Pack_Status>(json); Delay = p.Delay; IsIntoAutoONo = p.IsIntoAutoONo; AutoONoResult = p.AutoONoResult; BestOrgBoltNo = p.BestOrgBoltNo; BestKp = p.BestKp; MaxR = p.MaxR; MaxMin = p.MaxMin; Stability = p.Stability; CurrR = p.CurrR; Curr2Sigma = p.Curr2Sigma; CurrBreakUp = p.CurrBreakUp; CurrTime = p.CurrTime; CurrDirection = p.CurrDirection; } break; case HEATBUF_OBJ_INTERFACE.GET_BM: { string json = Misc.Converter.BytesToString(infodata); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<HEATBUF_OBJ_INTERFACE.Pack_BM>(json); FirstBM = p.firstbm; LastBM = p.lastbm; } break; case HEATBUF_OBJ_INTERFACE.GET_ISSTABLES: { string json = Misc.Converter.BytesToString(infodata); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<HEATBUF_OBJ_INTERFACE.Pack_IsStables>(json); BoltIsStable = p.isStables; } break; } } public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object AsyncDelegate, object AsyncState) { switch (funcid) { case HEATBUF_OBJ_INTERFACE.CALL_GETHEATDATA: { string json = Misc.Converter.BytesToString(retdata); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<FlyData_FeedbackHeat>(json); ((AsyncCBHandler)AsyncDelegate)(AsyncState, p); } break; case HEATBUF_OBJ_INTERFACE.CALL_GETBOLTHEATRECORD: { string json = Misc.Converter.BytesToString(retdata); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<FlyData_BoltHeatRecord>(json); ((AsyncCBHandler)AsyncDelegate)(AsyncState, p); } break; } } public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata) { PushGetValue(from, srcid, infoid, infodata); } #endregion public void Apply() { var p = new HEATBUF_OBJ_INTERFACE.Pack_Params() { HeatEffectCurve = HeatEffectCurve, StableRange = StableRange, StableRange0 = StableRange0, ThresholdR = ThresholdR, ThresholdMaxMin = ThresholdMaxMin, ThresholdSigmaMax = ThresholdSigmaMax, IsUsedLocalKp = IsUsedLocalKp, LocalKp = LocalKp }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(p); FObjSys.Current.SetValueEx( mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.SET_PARAMS, Misc.Converter.StringToBytes(json)); } public void GetHeatsData(int bookmark, AsyncCBHandler AsyncDelegate, object AsyncState) { var p = new HEATBUF_OBJ_INTERFACE.Pack_GetHeatsDataRequest() { bookmark = bookmark }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(p); CurrObjSys.CallFunctionEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.CALL_GETHEATDATA, Misc.Converter.StringToBytes(json), AsyncDelegate, AsyncState); } public void ClearBoltHeat() { CurrObjSys.CallFunctionEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.CALL_CLEARBOLTHEAT, null); } /// <summary> /// 获取每个分区的加热历史 返回 FlyData_BoltHeatRecord /// </summary> /// <param name="no">分区号</param> /// <param name="AsyncDelegate"></param> /// <param name="AsyncState"></param> public void GetBoltHeatRecord(int no, AsyncCBHandler AsyncDelegate, object AsyncState) { var p = new HEATBUF_OBJ_INTERFACE.Pack_GetBoltHeatRecordRequest() { no = no }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(p); CurrObjSys.CallFunctionEx(mConn, mServerID, ID, HEATBUF_OBJ_INTERFACE.CALL_GETBOLTHEATRECORD, Misc.Converter.StringToBytes(json), AsyncDelegate, AsyncState); } } }