Commit bbd5a68d authored by 潘栩锋's avatar 潘栩锋 🚴

还没完成,需要在GM_BlowingFix 写入数据库

parent 7d47e2b0
......@@ -15,22 +15,29 @@ namespace FLY.Thick.Blowing.Common
/// <summary>
/// 产品名称
/// </summary>
public string PName { get; set; }= "test_pname";
public string PName { get; set; }= "pname";
/// <summary>
/// 订单号
/// </summary>
public string OrderNo { get; set; } = "00000001";
/// <summary>
/// 卷号
/// </summary>
public string Number { get; set; } = "1";
/// <summary>
/// 目标值
/// </summary>
public int Target { get; set; } = 3000;
public double Target { get; set; } = 100;
/// <summary>
/// 上下限
/// 公差%
/// </summary>
public int Alarm { get; set; } = 100;
public double TolerancePercent { get; set; } = 0.03;
/// <summary>
/// 斜率补偿
/// </summary>
public double Comp { get; set; } = 1;
public double K { get; set; } = 1;
#endregion
......
......@@ -38,6 +38,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.Serialization" />
......@@ -56,7 +57,9 @@
<Compile Include="Common\ERRNOs.cs" />
<Compile Include="IService\IBlowingFixProfileService.cs" />
<Compile Include="IService\IBlowing.cs" />
<Compile Include="IService\IBulkDBService.cs" />
<Compile Include="IService\ICalFilmLen.cs" />
<Compile Include="IService\IShareDBService.cs" />
<Compile Include="OBJ_INTERFACE\BLOWINGFIX_PROFILE_OBJ_INTERFACE.cs" />
<Compile Include="OBJ_INTERFACE\BLOWING_DETECT_OBJ_INTERFACE.cs" />
<Compile Include="OBJ_INTERFACE\BLOWING_OBJ_INTERFACE.cs" />
......@@ -73,6 +76,12 @@
<Compile Include="Server.OBJProxy\OBJProxy.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Server\BlowingDetect.cs" />
<Compile Include="Server\Model\BulkDB.cs" />
<Compile Include="Server\Model\DBModel.cs" />
<Compile Include="Server\Model\DBTable.cs" />
<Compile Include="Server\Model\HistoryDB.cs" />
<Compile Include="Server\Model\LCTable.cs" />
<Compile Include="Server\Model\LocalDB.cs" />
<Compile Include="Server\TDGage.cs" />
</ItemGroup>
<ItemGroup>
......@@ -105,8 +114,15 @@
<Project>{2f88b5ec-85bc-4b5e-b254-06d2f2771f67}</Project>
<Name>FLY.Thick.BulkDataModule</Name>
</ProjectReference>
<ProjectReference Include="..\..\thick_public\Project.SQLiteHelper\SQLiteHelper\SQLiteHelper.csproj">
<Project>{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}</Project>
<Name>SQLiteHelper</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper">
<Version>8.1.1</Version>
</PackageReference>
<PackageReference Include="MathNet.Numerics">
<Version>4.8.1</Version>
</PackageReference>
......
......@@ -68,32 +68,62 @@ namespace FLY.Thick.Blowing.IService
/// <summary>
/// 测量数据开始时间
/// </summary>
public DateTime Time;
public DateTime Time { get; set; }
/// <summary>
/// 测量数据结束时间
/// </summary>
public DateTime EndTime;
public DateTime EndTime { get; set; }
/// <summary>
/// 旋转方向
/// 旋转方向 是反向
/// </summary>
public Misc.DIRECTION Direction;
public bool IsBackw { get; set; }
/// <summary>
/// 旋转1周的时间
/// </summary>
public TimeSpan RotatePeriod;
public TimeSpan RPeriod { get; set; }
/// <summary>
/// 旋转次数
/// </summary>
public int RotationCnt;
public int RCnt { get; set; }
/// <summary>
/// 复位区号
/// </summary>
public int OrgBoltNo { get; set; }
/// <summary>
/// 旋转角度 °
/// </summary>
public double RAngle { get; set; }
/// <summary>
/// 膜距离 m
/// </summary>
public double FilmLength { get; set; }
/// <summary>
/// 线速度
/// </summary>
public double FilmVelocity { get; set; }
/// <summary>
/// 斜率补偿
/// </summary>
public double K { get; set; }
/// <summary>
/// 1幅数据
/// </summary>
public int[] Frame;
public double[] Thicks { get; set; }
/// <summary>
/// 分区表
/// </summary>
public List<BoltMapCell> Boltmap { get; set; }
}
/// <summary>
......
using FLY.Thick.Blowing.IService.IBulkDBServicePack;
using FLY.Thick.Blowing.Server.Model;
using FObjBase;
using Misc;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.IService
{
/// <summary>
/// 基于DB 的 bulkdata
/// </summary>
public interface IBulkDBService : INotifyPropertyChanged
{
/// <summary>
/// 数据库中总数量,当它变化了,肯定有新数据
/// </summary>
int Count { get; }
/// <summary>
/// 开始产生数据时间
/// </summary>
DateTime StartTime { get; }
/// <summary>
/// 最后产生数据时间
/// </summary>
DateTime EndTime { get; }
/// <summary>
/// 当前生产,已经结束,已经下辊了
/// </summary>
bool IsFinished { get; }
/// <summary>
/// 临时数据改变
/// </summary>
event BulkDBTempFrameChangedEventHander TempFrameChanged;
/// <summary>
/// 获取N幅数据
/// </summary>
/// <param name="request"></param>
/// <param name="AsyncDelegate"></param>
/// <param name="AsyncContext"></param>
void GetFrame(
Pack_GetFrameRequest request,
AsyncCBHandler AsyncDelegate, object AsyncContext);
/// <summary>
/// 获取纵向趋势图
/// </summary>
/// <param name="request"></param>
/// <param name="AsyncDelegate"></param>
/// <param name="AsyncContext"></param>
void GetTrend(
Pack_GetTrendRequest request,
AsyncCBHandler AsyncDelegate, object AsyncContext);
/// <summary>
/// 完成
/// </summary>
void Finish();
}
}
namespace FLY.Thick.Blowing.IService.IBulkDBServicePack
{
public class Pack_GetFrameRequest
{
/// <summary>
/// 第1个数据 序号
/// </summary>
public Int64 ID;
/// <summary>
/// 从后向前获取N幅数据
/// </summary>
public int Count;
}
public class Pack_GetFrameReponse
{
public Pack_GetFrameRequest Request;
public List<LC_ScanData> Values;
}
public class Pack_GetTrendRequest
{
/// <summary>
/// 第1个数据 序号
/// </summary>
public Int64 ID;
/// <summary>
/// 长度
/// </summary>
public int Count;
}
public class Pack_GetTrendReponse
{
public Pack_GetTrendRequest Request;
public List<TrendValue> Values;
}
public class TrendValue
{
public DateTime Time { get; set; }
public double Value { get; set; }
public double Sigma { get; set; }
}
public class BulkDBTempFrameChangedEventArgs : EventArgs
{
/// <summary>
/// 开始位置
/// </summary>
public int StartIndex { get; set; }
/// <summary>
/// 数据
/// </summary>
public double[] D { get; set; }
}
public delegate void BulkDBTempFrameChangedEventHander(object sender, BulkDBTempFrameChangedEventArgs e);
}

using FLY.Thick.Blowing.IService.IShareDBServicePack;
using FLY.Thick.Blowing.Server.Model;
using FObjBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.IService
{
public interface IShareDBService
{
void GetProfile(AsyncCBHandler asyncDelegate, object asyncContext);
event ProfileChangedEventHandler ProfileChanged;
event ScanDataAddedEventHandler ScanDataAdded;
void FinishProfile();
}
}
namespace FLY.Thick.Blowing.IService.IShareDBServicePack
{
public class ProfileChangedEventArgs
{
/// <summary>
/// 不是insert,就是update
/// </summary>
public bool isInsert;
public DB_Profile profile;
}
public delegate void ProfileChangedEventHandler(object sender, ProfileChangedEventArgs e);
public class ScanDataAddedEventArgs
{
public LC_ScanData scandata;
}
public delegate void ScanDataAddedEventHandler(object sender, ScanDataAddedEventArgs e);
}
......@@ -18,13 +18,18 @@ using MathNet.Numerics.LinearAlgebra.Double;
using FObjBase;
using Newtonsoft.Json;
using FLY.Thick.Blowing.Common;
using FLY.Thick.Blowing.Server.Model;
namespace FLY.Thick.Blowing.Server
{
public class GM_BlowingFix : GM_Base, IBlowingFixService, ISaveToXml
{
const int MARKNO_PROFILE_ADD = 87;
const int MARKNO_PROFILE_CHANGED = 88;
HistoryDB mHistoryDB;
BulkDB mBulkDB;
#region 延时操作,markno
const int MARKNO_SAVE = 1;
......@@ -636,7 +641,7 @@ namespace FLY.Thick.Blowing.Server
IBulkDataServiceAdd mBulkData;
DynArea mDynArea;
BlowingFixProfileParam mProfileParam;
/// <summary>
/// 当前正在处理的 ADList 里面的数据.No
/// </summary>
......@@ -1209,12 +1214,28 @@ namespace FLY.Thick.Blowing.Server
}
}
public void Init(IBulkDataServiceAdd bulkdata, AD2ThickHandler func_ad2thick, DynArea dynarea )
public void Init(
IBulkDataServiceAdd bulkdata, AD2ThickHandler func_ad2thick, DynArea dynarea,
BlowingFixProfileParam profileParam,
HistoryDB historyDB, BulkDB bulkDB
)
{
AD2Thick = func_ad2thick;
mBulkData = bulkdata;
mDynArea = dynarea;
mProfileParam = profileParam;
mHistoryDB = historyDB;
mBulkDB = bulkDB;
Misc.BindingOperations.SetBinding(profileParam, "MMode", this, "MMode");
Misc.BindingOperations.SetBinding(profileParam, "FilmWidth", this, "FilmWidth");
Misc.BindingOperations.SetBinding(profileParam, "FilmPosH", this, "FilmPosH");
Misc.BindingOperations.SetBinding(profileParam, "BagFold0", this, "BagFold0");
Misc.BindingOperations.SetBinding(profileParam, "BagFold1", this, "BagFold1");
Misc.BindingOperations.SetBinding(mPDetect, "FilmVelocity", mDynArea, "FilmVelocity");
mDynArea.NBolts = NBolts;
mDynArea.FirstBoltNo = 1;
......@@ -1222,9 +1243,7 @@ namespace FLY.Thick.Blowing.Server
mDynArea.DataBoltNoEnd = NBolts;
mDynArea.ScanBoltNoBegin = 1;
mDynArea.ScanBoltNoEnd = NBolts;
Misc.BindingOperations.SetBinding(this, "FilmVelocity", mDynArea, "FilmVelocity");
PropertyChanged += (s, e) =>
{
if (e.PropertyName == "NBolts")
......@@ -1733,15 +1752,22 @@ namespace FLY.Thick.Blowing.Server
thicks = Misc.MyMath.Map(frameinfo.frame, map);
}
//推送数据出去
//当数据被修改,只推送最后一次的数据
DataEvent?.Invoke(this, new RenZiJiaDataEventArgs()
{
Time = frameinfo.StartTime,
EndTime = frameinfo.EndTime,
RotationCnt = frameinfo.rotationCnt,
Direction = frameinfo.direction,
RotatePeriod = mPDetect.RenZiJiaPeriod,
Frame = thicks
IsBackw = frameinfo.direction == DIRECTION.BACKWARD,
RPeriod = mPDetect.RenZiJiaPeriod,
RCnt = frameinfo.rotationCnt,
OrgBoltNo = OrgBoltNo,
RAngle = mPDetect.RAngle,
FilmLength = mPDetect.FilmLength,
FilmVelocity = mPDetect.FilmVelocity,
K = mProfileParam.K,
Thicks = ToRealThicks(thicks),
Boltmap = Map
});
//更新到下一个frameinfo
......@@ -1875,7 +1901,16 @@ namespace FLY.Thick.Blowing.Server
// }
//}
}
double[] ToRealThicks(int[] thicks)
{
return thicks.Select(t =>
{
if (Misc.MyBase.ISVALIDATA(t))
return t / 100.0;
else
return double.NaN;
}).ToArray();
}
protected override void OnPoll()
{
if (EPCType == RenZiJiaFixEPCType.EPCA10)
......@@ -1890,6 +1925,13 @@ namespace FLY.Thick.Blowing.Server
//以前的 Start()
IsRunning = true;
mBulkData.InitPush();
//清空临时数据
mBulkDB.SetTempFrame(0, null);
#region sqlite3 历史数据保存
CheckProfile();
mProfileParam.PropertyChanged += MProfileParam_PropertyChanged;
#endregion
FObjBase.PollModule.Current.Poll_Config(
FObjBase.PollModule.POLL_CONFIG.ADD,
......@@ -1897,7 +1939,99 @@ namespace FLY.Thick.Blowing.Server
TimeSpan.FromSeconds(1));
return true;
}
#region sqlite3 历史数据保存
string[] profile_propertynames_add = new string[]{
"PName",
"OrderNo",
"Number"
};
string[] profile_propertynames_update = new string[]{
"Target",
"TolerancePercent"
};
void CheckProfile()
{
if (mHistoryDB.localDB.IsProfileFinished)
{
//复位 膜纵向位置
AddProfile();
}
else
{
if (mHistoryDB.localDB.CurrProfile != null)
{
DB_Profile dB_Profile = mHistoryDB.localDB.CurrProfile;
if ((dB_Profile.PName != mProfileParam.PName) ||
(dB_Profile.OrderNo != mProfileParam.OrderNo) ||
(dB_Profile.Number != mProfileParam.Number))
{
AddProfile();
}
else
{
//继续上一次生产!!!!
UpdateProfile();
}
}
else
{
//异常
AddProfile();
}
}
}
void AddProfile()
{
mHistoryDB.AddProfile(new DB_Profile()
{
PName = mProfileParam.PName,
OrderNo = mProfileParam.OrderNo,
Number = mProfileParam.Number,
Target = mProfileParam.Target,
TolerancePercent = mProfileParam.TolerancePercent,
StartTime = DateTime.Now,
EndTime = DateTime.Now
});
}
void UpdateProfile()
{
mHistoryDB.UpdateProfile(new DB_Profile()
{
PName = mProfileParam.PName,
OrderNo = mProfileParam.OrderNo,
Number = mProfileParam.Number,
Target = mProfileParam.Target,
TolerancePercent = mProfileParam.TolerancePercent,
});
}
private void MProfileParam_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (profile_propertynames_add.Contains(e.PropertyName))
{
FObjBase.PollModule.Current.Poll_JustOnce(
() =>
{
if (!mHistoryDB.localDB.IsProfileFinished)
{
mHistoryDB.FinishProfile();
}
AddProfile();//新
}, this, MARKNO_PROFILE_ADD);
}
else if (profile_propertynames_update.Contains(e.PropertyName))
{
FObjBase.PollModule.Current.Poll_JustOnce(
() =>
{
UpdateProfile();//修改
}, this, MARKNO_PROFILE_CHANGED);
}
}
#endregion
bool Load()
{
return Misc.SaveToXmlHepler.Load("renzijiafix.xml",this);
......
using FLY.Thick.Blowing.IService;
using FLY.Thick.Blowing.IService.IBulkDBServicePack;
using FObjBase;
using Misc;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.Server.Model
{
/// <summary>
/// 提供接口,让别人获取 整理好的 当前生产,或之前生产的数据。
/// 从LocalDB 获取数据, 或从 直接从数据获取数据
///
/// 与HistoryDB,成对。
/// HistoryDB 是写
/// BulkDB 是读
/// </summary>
public class BulkDB : IBulkDBService
{
/// <summary>
/// 本地数据库最大容量
/// </summary>
int LocalDBCap = 400;
//动态的数据,不存在放在LocalDB!!!! 专门有个控件显示
LocalDB localDB;
DBModel dBModel;
IShareDBService shareDB;
/// <summary>
/// 数据库总数量,当它变化了,肯定有新数据
/// </summary>
public int Count { get; set; }
/// <summary>
/// 开始产生数据时间
/// </summary>
public DateTime StartTime { get; private set; }
/// <summary>
/// 最后产生数据时间
/// </summary>
public DateTime EndTime { get; private set; }
/// <summary>
/// 当前生产,已经结束,已经下辊了
/// </summary>
public bool IsFinished { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
public event BulkDBTempFrameChangedEventHander TempFrameChanged;
public BulkDB()
{
}
public void SetTempFrame(int startIndex, double[] D)
{
TempFrameChanged?.Invoke(this, new BulkDBTempFrameChangedEventArgs() { StartIndex = startIndex, D = D });
}
public void Init(DBModel dBModel, IShareDBService shareDB, LocalDB localDB)
{
this.localDB = localDB;
this.dBModel = dBModel;
this.shareDB = shareDB;
LocalDBLoad();
Misc.BindingOperations.SetBinding(localDB, "ProfileStartTime", this, "StartTime");
Misc.BindingOperations.SetBinding(localDB, "ProfileEndTime", this, "EndTime");
Misc.BindingOperations.SetBinding(localDB, "IsProfileFinished", this, "IsFinished");
shareDB.ScanDataAdded += ShareDB_ScanDataAdded;
}
private void ShareDB_ScanDataAdded(object sender, IService.IShareDBServicePack.ScanDataAddedEventArgs e)
{
Count++;
//await Task.Factory.StartNew(() =>
//{
// var n = dBModel.sqliteHelper.ExecuteScalar($"SELECT COUNT(*) FROM {dBModel.TbScanData.TableName}");
// Count = System.Convert.ToInt32(n);
//});
}
/// <summary>
/// 加载数据库中最后1次订单数据到 本地
/// </summary>
void LocalDBLoad()
{
var reponse = dBModel.sqliteHelper.ExecuteScalar($"SELECT MAX(ID) FROM {dBModel.TbProfile.TableName}");
if (reponse is DBNull)
{
localDB.ProfileStartTime = DateTime.MinValue;
localDB.ProfileEndTime = DateTime.MinValue;
localDB.IsProfileFinished = true;
}
else
{
long maxid = System.Convert.ToInt64(reponse);
var profile = dBModel.TbProfile.Find($"WHERE ID = {maxid}").First();
localDB.CurrProfile = profile;
localDB.ProfileStartTime = profile.StartTime;
localDB.ProfileEndTime = profile.EndTime;
localDB.IsProfileFinished = profile.IsFinished;
}
var n = dBModel.sqliteHelper.ExecuteScalar($"SELECT COUNT(*) FROM {dBModel.TbScanData.TableName}");
Count = System.Convert.ToInt32(n);
}
/// <summary>
/// 获取N幅数据,需要异步
/// </summary>
/// <param name="request"></param>
/// <param name="AsyncDelegate"></param>
/// <param name="AsyncContext"></param>
public async void GetFrame(Pack_GetFrameRequest request, AsyncCBHandler AsyncDelegate, object AsyncContext)
{
Pack_GetFrameReponse reponse = new Pack_GetFrameReponse();
reponse.Request = request;
reponse.Values = new List<LC_ScanData>();
if (request.Count > 10)//数量限制,避免死机
request.Count = 10;
await Task.Factory.StartNew(() =>
{
var db_scandatas = dBModel.TbScanData.Find($"WHERE ID >= {request.ID} ORDER BY ID LIMIT 0,{request.Count}");
var lc_scanDatas = AutoMapper.Mapper.Map<List<DB_ScanData>, List<LC_ScanData>>(db_scandatas);
reponse.Values.AddRange(lc_scanDatas);
});
AsyncDelegate(AsyncContext, reponse);
}
/// <summary>
/// 获取纵向趋势图
/// </summary>
/// <param name="request"></param>
/// <param name="AsyncDelegate"></param>
/// <param name="AsyncContext"></param>
public async void GetTrend(Pack_GetTrendRequest request, AsyncCBHandler AsyncDelegate, object AsyncContext)
{
//TODO 需要异步
Pack_GetTrendReponse reponse = new Pack_GetTrendReponse();
reponse.Request = request;
reponse.Values = new List<TrendValue>();
if (request.Count > 400)//数量限制,避免死机
request.Count = 400;
await Task.Factory.StartNew(() =>
{
var db_scandatas = dBModel.TbScanData.Find($"WHERE ID >= {request.ID} ORDER BY ID LIMIT 0,{request.Count}");
var lc_scanDatas = AutoMapper.Mapper.Map<List<DB_ScanData>, List<LC_ScanData>>(db_scandatas);
reponse.Values.AddRange(lc_scanDatas.Select(sd =>
{
double avg = sd.Thicks.AverageNoNull();
double sigma = sd.Thicks.Sigma();
return new TrendValue()
{
Sigma = sigma,
Value = avg,
Time = sd.Time
};
}));
});
AsyncDelegate(AsyncContext, reponse);
}
/// <summary>
/// 完成
/// </summary>
public void Finish()
{
shareDB.FinishProfile();
}
}
}
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.Server.Model
{
public class DBModel:SQLiteDbContext
{
public DBTable<DB_Profile> TbProfile { get; } = new DBTable<DB_Profile>();
public DBTable<DB_ScanData> TbScanData { get; } = new DBTable<DB_ScanData>();
public DBTable<DB_Error> TbError { get; } = new DBTable<DB_Error>();
public DBModel() : base(@"D:\flydata\thick_history.sqlite3")
{
}
}
}
using SQLite;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.Server.Model
{
/// <summary>
/// 订单记录
/// </summary>
[Table("Profile")]
public class DB_Profile
{
[Key]
[PropertyIndex(0)]
public Int64 ID { get; set; }
/// <summary>
/// 产品名称
/// </summary>
[PropertyIndex(1)]
public string PName { get; set; }
/// <summary>
/// 订单号
/// </summary>
[PropertyIndex(2)]
public string OrderNo { get; set; }
/// <summary>
/// 卷号
/// </summary>
[PropertyIndex(3)]
public string Number { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[PropertyIndex(4)]
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[PropertyIndex(5)]
public DateTime EndTime { get; set; }
/// <summary>
/// 已经结束
/// </summary>
[PropertyIndex(6)]
public bool IsFinished { get; set; }
/// <summary>
/// 目标值
/// </summary>
[PropertyIndex(7)]
public double Target { get; set; }
/// <summary>
/// 工艺%
/// </summary>
[PropertyIndex(8)]
public double TolerancePercent { get; set; }
}
/// <summary>
/// 厚度记录
/// </summary>
[Table("ScanData")]
public class DB_ScanData
{
[Key]
[PropertyIndex(0)]
public Int64 ID { get; set; }
/// <summary>
/// 订单记录ID
/// </summary>
[PropertyIndex(1)]
public Int64 ProfileID { get; set; }
/// <summary>
/// 测量数据开始时间
/// </summary>
[PropertyIndex(2)]
public DateTime Time { get; set; }
/// <summary>
/// 测量数据结束时间
/// </summary>
[PropertyIndex(3)]
public DateTime EndTime { get; set; }
/// <summary>
/// 旋转方向 是反向
/// </summary>
[PropertyIndex(4)]
public bool IsBackw { get; set; }
/// <summary>
/// 旋转1周的时间 min
/// </summary>
[PropertyIndex(5)]
public double RPeriod { get; set; }
/// <summary>
/// 旋转次数
/// </summary>
[PropertyIndex(6)]
public int RCnt { get; set; }
/// <summary>
/// 复位区号
/// </summary>
[PropertyIndex(7)]
public int OrgBoltNo { get; set; }
/// <summary>
/// 旋转角度 °
/// </summary>
[PropertyIndex(8)]
public double RAngle { get; set; }
/// <summary>
/// 膜距离 m
/// </summary>
[PropertyIndex(9)]
public double FilmLength { get; set; }
/// <summary>
/// 线速度
/// </summary>
[PropertyIndex(10)]
public double FilmVelocity { get; set; }
/// <summary>
/// 斜率补偿
/// </summary>
[PropertyIndex(11)]
public double K { get; set; }
/// <summary>
/// 1幅数据
/// </summary>
[PropertyIndex(12)]
public string Thicks { get; set; }
/// <summary>
/// 分区表
/// </summary>
[PropertyIndex(13)]
public string Boltmap { get; set; }
}
/// <summary>
/// 异常记录
/// </summary>
[Table("Error")]
public class DB_Error
{
[Key]
[PropertyIndex(0)]
public Int64 ID { get; set; }
/// <summary>
/// 发生的时间
/// </summary>
[PropertyIndex(1)]
public DateTime Time { get; set; }
/// <summary>
/// 异常代码
/// </summary>
[PropertyIndex(2)]
public int ErrCode { get; set; }
/// <summary>
/// true=异常是发生了,false=异常关闭
/// </summary>
[PropertyIndex(3)]
public bool IsOn { get; set; }
/// <summary>
/// 异常描述
/// </summary>
[PropertyIndex(4)]
public string Descrption { get; set; }
}
}

using FLY.Thick.Blowing.IService;
using FLY.Thick.Blowing.IService.IShareDBServicePack;
using FObjBase;
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.Server.Model
{
public class HistoryDB : IShareDBService
{
DBModel dBModel;
public LocalDB localDB;
#region IDBShareService
public event ProfileChangedEventHandler ProfileChanged;
public event ScanDataAddedEventHandler ScanDataAdded;
#endregion
/// <summary>
///
/// </summary>
/// <param name="dBModel"></param>
/// <param name="localDB"></param>
public void Init(DBModel dBModel, LocalDB localDB)
{
this.dBModel = dBModel;
this.localDB = localDB;
}
/// <summary>
/// 按时间删除数据库
/// </summary>
/// <param name="month"></param>
public void KeepDBSize(int month)
{
if (month <= 3)
month = 3;
DateTime del_time = DateTime.Now - TimeSpan.FromDays(month * 30);
List<string> sqls = new List<string>();
sqls.Add(
$"DELETE FROM {dBModel.TbProfile.TableName}" +
$" WHERE EndTime < {del_time.ToStringOfSQLiteFieldType()}");
sqls.Add(
$"DELETE FROM {dBModel.TbScanData.TableName}" +
$" WHERE Time < {del_time.ToStringOfSQLiteFieldType()}");
sqls.Add(
$"DELETE FROM {dBModel.TbError.TableName}" +
$" WHERE Time < {del_time.ToStringOfSQLiteFieldType()}");
dBModel.sqliteHelper.QueryTran(sqls);
}
/// <summary>
/// 保存产品参数
/// </summary>
public void AddProfile(
DB_Profile profile
)
{
//把上一次结束掉
if ((localDB.CurrProfile != null) && localDB.IsProfileFinished == false)
{
FinishProfile();
}
//添加 数据库必要的 field
localDB.ProfileStartTime = DateTime.Now;
localDB.ProfileEndTime = DateTime.Now;
localDB.IsProfileFinished = false;
profile.ID = dBModel.TbProfile.FreeID;
profile.StartTime = localDB.ProfileStartTime;
profile.EndTime = localDB.ProfileEndTime;
//SQL
List<string> sqls = new List<string>();
sqls.Add(SQLiteHelper.GetInsertCommandText(profile));
dBModel.sqliteHelper.QueryTranAsync(sqls);
//本地数据备份
localDB.CurrProfile = profile;
#region IDBShareService
ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
{
isInsert = true,
profile = profile
});
#endregion
}
/// <summary>
/// 修改产品参数
/// </summary>
/// <param name="profile"></param>
public void UpdateProfile(
DB_Profile profile
)
{
//添加 数据库必要的 field
profile.ID = localDB.CurrProfile.ID;
profile.StartTime = localDB.ProfileStartTime;
profile.EndTime = localDB.ProfileEndTime;
//SQL
List<string> sqls = new List<string>();
sqls.Add(SQLiteHelper.GetUpdateCommandText(profile, $"WHERE ID = {profile.ID}"));
dBModel.sqliteHelper.QueryTranAsync(sqls);
//本地数据备份
localDB.CurrProfile = profile;
#region IDBShareService
ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
{
profile = profile
});
#endregion
}
/// <summary>
/// 下辊,结束当前产品生产
/// </summary>
public void FinishProfile()
{
if (localDB.CurrProfile == null)
return;
//SQL
dBModel.sqliteHelper.ExecuteNonQuery(
$"UPDATE {dBModel.TbProfile.TableName} SET IsFinished = {true} WHERE ID = {localDB.CurrProfile.ID}");
localDB.IsProfileFinished = true;
localDB.CurrProfile.IsFinished = true;
#region IDBShareService
ProfileChanged?.Invoke(this, new ProfileChangedEventArgs()
{
profile = localDB.CurrProfile
});
#endregion
}
/// <summary>
/// 不需设置 DB_ScanData 内 ProfileID, 自动设置!
/// </summary>
public void AddScanData(
LC_ScanData scanData)
{
//添加 数据库必要的 field
scanData.ID = dBModel.TbScanData.FreeID;
scanData.ProfileID = localDB.CurrProfile.ID;
localDB.ProfileEndTime = scanData.Time;
//SQLs
List<string> sqls = new List<string>();
var db_scandata = AutoMapper.Mapper.Map<DB_ScanData>(scanData);
sqls.Add(SQLiteHelper.GetInsertCommandText(db_scandata));
string s_endtime = localDB.ProfileEndTime.ToStringOfSQLiteFieldType();
sqls.Add($"UPDATE {dBModel.TbProfile.TableName} SET EndTime={s_endtime} WHERE ID = {localDB.CurrProfile.ID}");
dBModel.sqliteHelper.QueryTranAsync(sqls);
//本地数据备份
localDB.CurrProfile.EndTime = localDB.ProfileEndTime;
#region IDBShareService
ScanDataAdded?.Invoke(this, new ScanDataAddedEventArgs()
{
scandata = scanData
});
#endregion
}
/// <summary>
///
/// </summary>
/// <param name="db_errorData"></param>
public void AddErrorData(
DB_Error db_errorData
)
{
//添加 数据库必要的 field
db_errorData.ID = dBModel.TbError.FreeID;
//SQLs
List<string> sqls = new List<string>();
sqls.Add(SQLiteHelper.GetInsertCommandText(db_errorData));
dBModel.sqliteHelper.QueryTranAsync(sqls);
}
#region IDBShareService
public void GetProfile(AsyncCBHandler asyncDelegate, object asyncContext)
{
if (localDB.CurrProfile != null)
{
asyncDelegate.Invoke(asyncContext, localDB.CurrProfile);
}
else
{
asyncDelegate.Invoke(asyncContext, null);
}
}
#endregion
}
}
using FLY.Thick.Blowing.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.Server.Model
{
/// <summary>
/// 厚度记录
/// </summary>
public class LC_ScanData
{
public Int64 ID { get; set; }
/// <summary>
/// 订单记录ID
/// </summary>
public Int64 ProfileID { get; set; }
/// <summary>
/// 测量数据开始时间
/// </summary>
public DateTime Time { get; set; }
/// <summary>
/// 测量数据结束时间
/// </summary>
public DateTime EndTime { get; set; }
/// <summary>
/// 旋转方向 是反向
/// </summary>
public bool IsBackw { get; set; }
/// <summary>
/// 旋转1周的时间
/// </summary>
public TimeSpan RPeriod { get; set; }
/// <summary>
/// 旋转次数
/// </summary>
public int RCnt { get; set; }
/// <summary>
/// 复位区号
/// </summary>
public int OrgBoltNo { get; set; }
/// <summary>
/// 旋转角度 °
/// </summary>
public double RAngle { get; set; }
/// <summary>
/// 膜距离 m
/// </summary>
public double FilmLength { get; set; }
/// <summary>
/// 线速度
/// </summary>
public double FilmVelocity { get; set; }
/// <summary>
/// 斜率补偿
/// </summary>
public double K { get; set; }
/// <summary>
/// 1幅数据
/// </summary>
public double[] Thicks { get; set; }
/// <summary>
/// 分区表
/// </summary>
public List<BoltMapCell> Boltmap { get; set; }
}
/// <summary>
/// LC 与 DB 类的映射关系, 会在程序入口处, 手动使用
/// var assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
/// var cfg = new MapperConfigurationExpression();
/// cfg.AddMaps(assemblies);
/// Mapper.Initialize(cfg);
///
/// 枚举全部程序集 中的AutoMapper.Profile 全部加载!!!
/// </summary>
public class LC_AutoMapperProfile : AutoMapper.Profile
{
public LC_AutoMapperProfile()
{
CreateMap<LC_ScanData, DB_ScanData>()
.ForMember(s => s.RPeriod, opt =>
{
opt.MapFrom(s => s.RPeriod.TotalMinutes);
})
.ForMember(s => s.Thicks, opt =>
{
opt.MapFrom(s => Newtonsoft.Json.JsonConvert.SerializeObject(s.Thicks));
})
.ForMember(s => s.Boltmap, opt =>
{
opt.MapFrom(s => Newtonsoft.Json.JsonConvert.SerializeObject(s.Boltmap));
})
.ReverseMap()
.ForMember(s => s.RPeriod, opt =>
{
opt.MapFrom(s => TimeSpan.FromMinutes(s.RPeriod));
})
.ForMember(s => s.Thicks, opt =>
{
opt.MapFrom(s => Newtonsoft.Json.JsonConvert.DeserializeObject<double[]>(s.Thicks));
})
.ForMember(s => s.Boltmap, opt =>
{
opt.MapFrom(s => Newtonsoft.Json.JsonConvert.DeserializeObject<List<BoltMapCell>>(s.Boltmap));
});
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Blowing.Server.Model
{
/// <summary>
/// 正在生产的数据,或之前生产完的数据
/// </summary>
public class LocalDB : INotifyPropertyChanged
{
public DB_Profile CurrProfile;
/// <summary>
/// 当前生产,开始产生数据时间
/// </summary>
public DateTime ProfileStartTime { get; set; }
/// <summary>
/// 当前生产,最后产生数据时间
/// </summary>
public DateTime ProfileEndTime { get; set; }
/// <summary>
/// 当前生产,已经结束,已经下辊了
/// </summary>
public bool IsProfileFinished { get; set; }
public LocalDB()
{
Init();
}
void Init()
{
CurrProfile = null;
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
......@@ -16,7 +16,7 @@ using FLY.Thick.Base.IService;
using FLY.Thick.Base.Server;
using FLY.Thick.RemoteHistory;
using FLY.Thick.BulkDataModule;
using FLY.Thick.Blowing.Server.Model;
namespace FLY.Thick.Blowing.Server
{
......@@ -104,6 +104,11 @@ namespace FLY.Thick.Blowing.Server
public BulkDataService mBulk;
public BulkDataServiceClientAdv mBulkClient;
DBModel mDBModel;
public HistoryDB mHistoryDB;
LocalDB mLocalDB;
public BulkDB mBulkDB;
#endregion
#endregion
......@@ -144,6 +149,18 @@ namespace FLY.Thick.Blowing.Server
mPassword = new Password(null);
mDBModel = new DBModel();
mDBModel.Init();
mLocalDB = new LocalDB();
mHistoryDB = new HistoryDB();
mHistoryDB.Init(mDBModel, mLocalDB);
mHistoryDB.KeepDBSize(6);
mBulkDB = new BulkDB();
mBulkDB.Init(mDBModel, mHistoryDB, mLocalDB);
#endregion
......@@ -209,13 +226,7 @@ namespace FLY.Thick.Blowing.Server
//---------------------------------------------------------------------------------------------------------------
//GM_RenZiJiaFix_Create
mGMRenZiJiaFix = new GM_BlowingFix(mFlyAD);
Misc.BindingOperations.SetBinding(mProfile.Param, "MMode", mGMRenZiJiaFix, "MMode");
Misc.BindingOperations.SetBinding(mProfile.Param, "FilmWidth", mGMRenZiJiaFix, "FilmWidth");
Misc.BindingOperations.SetBinding(mProfile.Param, "FilmPosH", mGMRenZiJiaFix, "FilmPosH");
Misc.BindingOperations.SetBinding(mProfile.Param, "BagFold0", mGMRenZiJiaFix, "BagFold0");
Misc.BindingOperations.SetBinding(mProfile.Param, "BagFold1", mGMRenZiJiaFix, "BagFold1");
Misc.BindingOperations.SetBinding(mGMRenZiJiaFix.mPDetect, "FilmVelocity", mDynArea, "FilmVelocity");
mGMManager.AddGM(mGMRenZiJiaFix);
//---------------------------------------------------------------------------------------------------------------
......@@ -223,10 +234,8 @@ namespace FLY.Thick.Blowing.Server
mBulk = new BulkDataService(mGMRenZiJiaFix.NBolts, 1, 400);
mBulkClient = new BulkDataServiceClientAdv(mBulk);
mGMRenZiJiaFix.Init(mBulk, new AD2ThickHandler(AD2Thick), mDynArea);
mGMRenZiJiaFix.Init(mBulk, new AD2ThickHandler(AD2Thick), mDynArea, mProfile.Param, mHistoryDB, mBulkDB );
mGMRenZiJiaFix.EPCSampled += new GM_BlowingFix.EPCSampledEventHandler(mGMRenZiJiaFix_EPCSampled);
......
......@@ -81,6 +81,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FLY.Thick.BlowingScan.UI.Cl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FLY.Thick.BlowingScan.UI.Server", "Project.FLY.Thick.BlowingScan\FLY.Thick.BlowingScan.UI.Server\FLY.Thick.BlowingScan.UI.Server.csproj", "{D42B0F14-C68A-415D-922B-B3BEACC75405}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLiteHelper", "thick_public\Project.SQLiteHelper\SQLiteHelper\SQLiteHelper.csproj", "{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -457,6 +459,18 @@ Global
{D42B0F14-C68A-415D-922B-B3BEACC75405}.Release|Mixed Platforms.Build.0 = Release|x86
{D42B0F14-C68A-415D-922B-B3BEACC75405}.Release|x86.ActiveCfg = Release|x86
{D42B0F14-C68A-415D-922B-B3BEACC75405}.Release|x86.Build.0 = Release|x86
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Debug|x86.ActiveCfg = Debug|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Debug|x86.Build.0 = Debug|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Release|Any CPU.Build.0 = Release|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Release|x86.ActiveCfg = Release|Any CPU
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -493,6 +507,7 @@ Global
{966D9971-7AA4-4B1B-ABB6-E09C3F04F6EE} = {58EB0B95-13F3-4D21-B6CD-B680E8D3D8AD}
{608CADD8-B4A0-46C9-A60E-A07FFFA9AAF0} = {58EB0B95-13F3-4D21-B6CD-B680E8D3D8AD}
{D42B0F14-C68A-415D-922B-B3BEACC75405} = {58EB0B95-13F3-4D21-B6CD-B680E8D3D8AD}
{4CBABFAA-1C62-4510-AC63-A51EE5FD50FF} = {2488C4FB-3677-405B-BE1B-C9F532708DE3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD78A3E8-6F11-4F24-AB5F-A9F25461F64F}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment