using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Runtime.InteropServices; using System.Threading; using System.IO.Ports; using System.Windows.Forms; using LFP_Manager.DataStructure; using LFP_Manager.Function; using LFP_Manager.Utils; using System.Data.SQLite; namespace LFP_Manager.Threads { public delegate void DbDataPrint(object sender, string msg); class csDbThread { #region VARIABLES CommConfig Config; DeviceSystemData SystemData; short[] Status, oldStatus; bool Active = false; Thread dbProc = null; int CellDivUnit = csConstData.Unit.CELL_DIV_P3; //////////////////////////////////////// bool DbThreadEnd = true; public event DbDataPrint OnPrint = null; #endregion #region CONSTRUCTORS public csDbThread(ref CommConfig aConfig, ref DeviceSystemData aSystemData) { Status = new short[2]; oldStatus = new short[2]; Config = aConfig; SystemData = aSystemData; dbProc = new Thread(dbThreadProcess); } public void disposeThread() { DbThreadEnd = true; if (dbProc != null) { if (dbProc.IsAlive) { dbProc.Abort(); } dbProc = null; } } public unsafe bool Start(CommConfig aConfig) { bool result = false; Config = aConfig; switch (Config.TargetModelIndex) { case 0: // PR-57150 CellDivUnit = csConstData.Unit.CELL_DIV_P3; break; case 1: // PR-64150 CellDivUnit = csConstData.Unit.CELL_DIV_P4; break; case 2: // LFPM-57080 CellDivUnit = csConstData.Unit.CELL_DIV_P4; break; case 3: // PR-102150 CellDivUnit = csConstData.Unit.CELL_DIV_P4; break; case 4: // PR-115300 CellDivUnit = csConstData.Unit.CELL_DIV_P4; break; case 5: // PR-67150 CellDivUnit = csConstData.Unit.CELL_DIV_P4; break; default: CellDivUnit = csConstData.Unit.CELL_DIV_P3; break; } // DB Create with Path Create csHistoryFunction.DbCreate(Path.GetDirectoryName(Application.ExecutablePath)); try { DbThreadEnd = false; dbProc.Start(); Active = true; } catch (Exception ex) { OnPrint?.Invoke(this, ex.Message); } return result; } public void Stop() { DbThreadEnd = true; Active = false; } public void UpdateStatus(short st1, short st2) { Status[0] = st1; Status[1] = st2; } #region UPDATE DATA public void UpdateData(ref DeviceSystemData aSystemData) { SystemData = aSystemData; } #endregion #endregion #region MAKE ALARM HISTORY private void CheckAlarm() { bool[] Data1 = csUtils.Int16ToBitArray((short)Status[0]); bool[] Data2 = csUtils.Int16ToBitArray((short)Status[1]); bool[] oData1 = csUtils.Int16ToBitArray((short)oldStatus[0]); bool[] oData2 = csUtils.Int16ToBitArray((short)oldStatus[1]); // Cell Over Voltage if (oData2[0] != Data2[0]) { if (Data2[0] == true) { IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_TRIP); } else { if (oData1[0] != Data1[0]) { if (Data1[0] == true) IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_WARNING); else IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_RELEASE); } else { if (Data1[0] == false) IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_RELEASE); } } } else { if (oData1[0] != Data1[0]) { if (Data1[0] == true) IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_WARNING); else IDInsert("", csDbConstData.DB_ALARM.CELL_UNDER_VOLTAGE, csDbConstData.DB_ALARM.FLAG_RELEASE); } } oldStatus = Status; } #endregion #region DB INSERT DATA private void IDInsert(string mPath, int aCode, int fCode) { //string dbFilename = mPath + csDbConstData.DataBase.FileName; string dbFilename = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + csDbConstData.DataBase.FileName; // Open database string strConn = @"Data Source=" + dbFilename; using (var connection = new SQLiteConnection(strConn)) { connection.Open(); try { // Insert data using (SQLiteCommand command = connection.CreateCommand()) { command.CommandText = "BEGIN;"; //명시적 트렌젝션 시작 command.ExecuteNonQuery(); //sSQL = "insert into TrendTable ( TrendStamp, TagName, TagValue) Values ( " + IntToStr(stamp) + "," + name + "," + value + ");"; command.CommandText = "INSERT INTO " + csDbConstData.DataBase.TableName + "(HTime, model, sno, alarm_name, alarm_code, flag_name, flag, param1, param2) " + " Values (@HTime, @model, @sno, @alarm_name, @alarm_code, @flag_name, @flag, @param1, @param2);"; SQLiteParameter[] p = new SQLiteParameter[] { new SQLiteParameter("@HTime", DbType.DateTime), new SQLiteParameter("@model", DbType.String), new SQLiteParameter("@sno", DbType.Int16), new SQLiteParameter("@alarm_name", DbType.String), new SQLiteParameter("@alarm_code", DbType.Int16), new SQLiteParameter("@flag_name", DbType.String), new SQLiteParameter("@flag", DbType.Int16), new SQLiteParameter("@param1", DbType.Decimal), new SQLiteParameter("@param2", DbType.Decimal), }; // end SQLiteParameter command.Parameters.AddRange(p); int result = 0; p[0].Value = DateTime.Now; // DateTime p[1].Value = "AAA"; // Model Name p[2].Value = 1; // System No p[3].Value = csDbConstData.DB_ALARM.ALARM_NAME[aCode]; // alarm_name p[4].Value = aCode; // alarm_code p[5].Value = csDbConstData.DB_ALARM.FLAG_NAME[fCode]; // flag_name p[6].Value = fCode; // flag_code p[7].Value = 0.0; // param1 p[8].Value = 0.0; // param2 try { result = command.ExecuteNonQuery(); } catch (Exception) { } command.CommandText = "COMMIT;"; //명시적 트렌젝션 시작 } } catch (Exception) { //MessageBox.Show(e.ToString()); } finally { connection.Close(); } } } #endregion #region DB THREAD private void dbThreadProcess() { DateTime bakDateTime = DateTime.Now; int ss = Config.DbLogPeriod; while (DbThreadEnd == false) { if (Active) { DateTime cDate = DateTime.Now; if ( ((bakDateTime.Minute != cDate.Minute) || (bakDateTime.Second != cDate.Second)) && ((cDate.Second % ss) == 0) ) { // Database Log Process try { csDbUtils.LogDbCreate(csConstData.CommType.CAN_MODEL[Config.TargetModelIndex]); csDbUtils.BmsLogDataInsert(ref Config, ref SystemData, cDate, CellDivUnit); bakDateTime = cDate; } catch (Exception ex) { MessageBox.Show(ex.Message); } } } Thread.Sleep(100); } } #endregion } }