initial commit
This commit is contained in:
363
Viewer/AlarmViewer/Class/CFDBA.cs
Normal file
363
Viewer/AlarmViewer/Class/CFDBA.cs
Normal file
@@ -0,0 +1,363 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
using System.Data;
|
||||
using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
using AR;
|
||||
using vmsnet;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Project;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace vmsnet
|
||||
{
|
||||
public class CFDBA
|
||||
{
|
||||
string _BaseDir;
|
||||
|
||||
public class ReadProgessArgs : EventArgs
|
||||
{
|
||||
public double value { get; set; }
|
||||
public ReadProgessArgs(double value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
public class MessageArgs : EventArgs
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public MessageArgs(string value)
|
||||
{
|
||||
Message = value;
|
||||
}
|
||||
}
|
||||
|
||||
//public event EventHandler<ReadProgessArgs> ReadingProgressValueChanged;
|
||||
public event EventHandler<MessageArgs> Message;
|
||||
|
||||
public CFDBA(params string[] dirarrays)
|
||||
{
|
||||
var dir = System.IO.Path.Combine(dirarrays);
|
||||
_BaseDir = dir;
|
||||
if (System.IO.Directory.Exists(_BaseDir) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(_BaseDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 데이터를 기록합니다.
|
||||
/// </summary>
|
||||
/// <param name="time">기록시간(파일명이 결정됨)</param>
|
||||
/// <param name="table">기록할테이블명(파일명)</param>
|
||||
/// <param name="buffer">기록할데이터(열데이터가 틀려서 고정할 수 없다)</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public bool InsertData(DateTime time, int ch, COMM.EALAMRAISETYPE raiseType, float volt, COMM.EALAMTYPE almType, float maxvolt, float minvolt, string am, string am2)
|
||||
{
|
||||
string DayStr = time.ToString("yyyyMMdd");
|
||||
System.IO.FileInfo fi = new System.IO.FileInfo(_BaseDir + "\\" + DayStr.Substring(0, 4) + "\\" + DayStr.Substring(4, 2) + "\\" + DayStr.Substring(6) + "\\" + (time.Hour + 1).ToString("00") + ".txt");
|
||||
if (!fi.Directory.Exists)
|
||||
{
|
||||
try
|
||||
{
|
||||
fi.Directory.Create();
|
||||
}
|
||||
catch
|
||||
{
|
||||
PUB.log.AddE($"fail:make directory value={fi.Directory.FullName}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
System.Text.StringBuilder StrBuf = new System.Text.StringBuilder();
|
||||
|
||||
////파일이 없다면 제목줄을 생성해준다.
|
||||
if (!fi.Exists)
|
||||
{
|
||||
|
||||
////헤더를 추가해야한다.
|
||||
System.Text.StringBuilder Header = new System.Text.StringBuilder();
|
||||
Header.Append("\t" + "ATIME CH RTYPE VOLT ATYPE MAXVOLT MINVOLT AM AM2");
|
||||
Header.AppendLine(); ////제목줄을 한칸띄운다
|
||||
StrBuf.Append(Header.ToString());
|
||||
}
|
||||
|
||||
////실제데이터를 추가
|
||||
int timeNumber = (int)(PUB.get_TimeNumber(time)); // time.Hour * 3600 + time.Minute * 60 + time.Second
|
||||
StrBuf.AppendLine($"\t{timeNumber}\t{ch}\t{(int)raiseType}\t{volt}\t{(int)almType}\t{maxvolt}\t{minvolt}\t{am}\t{am2}");
|
||||
|
||||
try
|
||||
{
|
||||
//fi.WriteText(StrBuf.ToString(), true); // 이전은 단독모드
|
||||
/* 작성자: 이재웅, 작성일: 2024-09-23, 작성내용: 접근모드를 공유모드로 전환 */
|
||||
using (FileStream fs = new FileStream(fi.FullName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
|
||||
using (StreamWriter writer = new StreamWriter(fs))
|
||||
{ writer.Write(StrBuf.ToString()); }
|
||||
|
||||
StrBuf.Clear();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
PUB.log.AddE($"fail:write aldata file={fi.FullName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////기간내 존재하는 파일을 반환합니다(테이블단위)
|
||||
public List<string> GetfileS(DateTime sd, DateTime ed)
|
||||
{
|
||||
|
||||
List<string> retval = new List<string>();
|
||||
int SttYear = sd.Year;
|
||||
int EndYear = ed.Year;
|
||||
if (EndYear < SttYear)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SttMonth = sd.Month;
|
||||
int EndMonth = ed.Month;
|
||||
|
||||
int SttDay = sd.Day;
|
||||
int EndDay = ed.Day;
|
||||
|
||||
int si = System.Convert.ToInt32(sd.ToString("yyyyMMdd"));
|
||||
int ei = System.Convert.ToInt32(ed.ToString("yyyyMMdd"));
|
||||
bool SameDay = si == ei ? true : false;
|
||||
|
||||
////20140101
|
||||
for (int dayinfo = si; dayinfo <= ei; dayinfo++)
|
||||
{
|
||||
string DayStr = dayinfo.ToString();
|
||||
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(_BaseDir + "\\" + DayStr.Substring(0, 4) + "\\" + DayStr.Substring(4, 2) + "\\" + DayStr.Substring(6));
|
||||
if (!dir.Exists)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
////폴더가 존재하므로 해당 테이블파일이 존재하는지 확인한다
|
||||
|
||||
if (SameDay)
|
||||
{
|
||||
////동일날짜라면 해당 시간대만 조회하면됨
|
||||
for (int hourinfo = int.Parse(sd.ToString("HH")); hourinfo <= int.Parse(ed.ToString("HH")); hourinfo++)
|
||||
{
|
||||
string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") + ".txt";
|
||||
if (System.IO.File.Exists(fn))
|
||||
{
|
||||
retval.Add(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dayinfo == si) ////시작일이라면 시작시간부터 24시까지 이다.
|
||||
{
|
||||
for (int hourinfo = int.Parse(sd.ToString("HH")); hourinfo <= 23; hourinfo++)
|
||||
{
|
||||
string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") + ".txt";
|
||||
if (System.IO.File.Exists(fn))
|
||||
{
|
||||
retval.Add(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dayinfo == ei) ////종료일이라면 1~ 종료시까지이다.
|
||||
{
|
||||
for (int hourinfo = 0; hourinfo <= int.Parse(ed.ToString("HH")); hourinfo++)
|
||||
{
|
||||
string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") + ".txt";
|
||||
if (System.IO.File.Exists(fn))
|
||||
{
|
||||
retval.Add(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
////중간에 끼어있는 날짜라면 1~24모두가 속한다.
|
||||
for (int hourinfo = 0; hourinfo <= 23; hourinfo++)
|
||||
{
|
||||
string fn = dir.FullName + "\\" + (hourinfo + 1).ToString("00") + ".txt";
|
||||
if (System.IO.File.Exists(fn))
|
||||
{
|
||||
retval.Add(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
retval.Sort();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 이번달이후의 데이터를 조회합니다.
|
||||
/// </summary>
|
||||
/// <param name="ch"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public (TimeSpan, DocumentElement.ALARMDataTable) GetAlarmData(int ch)
|
||||
{
|
||||
////이번달이후의 데이터를 가져온다.
|
||||
DateTime sd = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-01 00:00:00"));
|
||||
DateTime ed = DateTime.Now;
|
||||
return GetAlarmData(ch, sd, ed);
|
||||
}
|
||||
|
||||
public (TimeSpan, DocumentElement.ALARMDataTable) GetAlarmData(DateTime sd, DateTime ed)
|
||||
{
|
||||
return GetAlarmData(-1, sd, ed);
|
||||
}
|
||||
|
||||
public (TimeSpan, DocumentElement.ALARMDataTable) GetAlarmData(DateTime sd, DateTime ed, int rtypes, int rtypee)
|
||||
{
|
||||
return GetAlarmData(-1, sd, ed, rtypes, rtypee);
|
||||
}
|
||||
|
||||
public volatile bool cancel;
|
||||
private readonly object lockObject = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 지정된시간사이의 데이터를 조회합니다.
|
||||
/// </summary>
|
||||
/// <param name="stime">시작시간(20120319161800)</param>
|
||||
/// <param name="etime">종료시간(년월일시분초)</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public (TimeSpan, DocumentElement.ALARMDataTable) GetAlarmData(int ch, DateTime sd, DateTime ed, int rtypes = -1, int rtypee = -1)
|
||||
{
|
||||
DateTime dtStart = DateTime.Now;
|
||||
List<string> files = GetfileS(sd, ed);
|
||||
|
||||
//전체파일의 내용을 버퍼에 담는다
|
||||
Dictionary<string, string[]> lines = new Dictionary<string, string[]>();
|
||||
|
||||
foreach (var fn in files)
|
||||
{
|
||||
lines.Add(fn, System.IO.File.ReadAllLines(fn));
|
||||
}
|
||||
var totallines = lines.Sum(t => t.Value.Length);
|
||||
Message?.Invoke(this, new MessageArgs($"total : {totallines} lines"));
|
||||
|
||||
var progressMax = (double)totallines;
|
||||
var progressVal = 0.0;
|
||||
var currentline = 0;
|
||||
var alertprogress = 0.0;
|
||||
|
||||
|
||||
//ReadingProgressValueChanged?.Invoke(this, new ReadProgessArgs(0));
|
||||
|
||||
var alaramDT = new DocumentElement.ALARMDataTable();
|
||||
cancel = false;
|
||||
try
|
||||
{
|
||||
foreach (var line in lines)
|
||||
{
|
||||
foreach (string linedata in line.Value)
|
||||
{
|
||||
|
||||
lock (lockObject)
|
||||
{
|
||||
if (cancel)
|
||||
{
|
||||
//Console.WriteLine("작업이 취소되었습니다.");
|
||||
//token.ThrowIfCancellationRequested(); // OperationCanceledException을 발생시켜 작업을 종료합니다.
|
||||
//return (new TimeSpan(0), null);
|
||||
//cancel = true;
|
||||
Message?.Invoke(this, new MessageArgs($"job cancel"));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
currentline += 1;
|
||||
progressVal = currentline / progressMax;
|
||||
|
||||
if (progressVal - alertprogress >= 5)
|
||||
{
|
||||
alertprogress = progressVal;
|
||||
Message?.Invoke(this, new MessageArgs($"Progress : {progressVal} lines"));
|
||||
//ReadingProgressValueChanged?.Invoke(this, new ReadProgessArgs(progressVal));
|
||||
}
|
||||
|
||||
|
||||
if (linedata.Trim() == "") continue;
|
||||
|
||||
string[] buf = linedata.Split(System.Convert.ToChar("\t"));
|
||||
if (buf.GetUpperBound(0) < 8) continue; ////데이터수량이 안맞다.
|
||||
|
||||
string chStr = buf[2];
|
||||
if (chStr.IsNumeric() == false) continue; ////채널정보가 일치하지 않는경우
|
||||
|
||||
if (ch > -1 && chStr != ch.ToString()) continue;
|
||||
|
||||
if (rtypes != -1 && rtypee != -1) ////rtype도 검색한다.
|
||||
{
|
||||
if (buf[3] != rtypes.ToString() && buf[3] != rtypee.ToString()) continue;
|
||||
}
|
||||
|
||||
var v_atime = buf[1];
|
||||
var v_ch = short.Parse(buf[2]);
|
||||
var v_rtype = short.Parse(buf[3]);
|
||||
|
||||
//존재하는 데이터는 처리하지 않느낟.
|
||||
if (alaramDT.Where(t => t.ATIME == v_atime && t.CH == v_ch && t.RTYPE == v_rtype).Any() == false)
|
||||
{
|
||||
var newdr = alaramDT.NewALARMRow();
|
||||
newdr.ATIME = v_atime;// buf[1];
|
||||
newdr.TIME = PUB.get_TimeString(decimal.Parse(newdr.ATIME), line.Key);
|
||||
newdr.CH = v_ch;// short.Parse(buf[2]);
|
||||
newdr.RTYPE = v_rtype;// short.Parse(buf[3]);
|
||||
newdr.VOLT = float.Parse(buf[4]);
|
||||
newdr.ATYPE = short.Parse(buf[5]);
|
||||
newdr.MAXVOLT = float.Parse(buf[6]);
|
||||
newdr.MINVOLT = float.Parse(buf[7]);
|
||||
newdr.AM = buf[8];
|
||||
newdr.AM2 = buf[9];
|
||||
alaramDT.AddALARMRow(newdr);
|
||||
}
|
||||
else
|
||||
{
|
||||
//중복데이터
|
||||
PUB.log.AddAT($"알람중복데이터 atime={v_atime},ch={v_ch},rtype={v_rtype}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (cancel)
|
||||
{
|
||||
//Console.WriteLine("작업이 취소되었습니다.");
|
||||
//token.ThrowIfCancellationRequested(); // OperationCanceledException을 발생시켜 작업을 종료합니다.
|
||||
//return (new TimeSpan(0), null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Console.WriteLine("작업이 정상적으로 취소되었습니다.");
|
||||
throw; // 예외를 다시 던져 작업이 중지되도록 합니다.
|
||||
}
|
||||
|
||||
alaramDT.AcceptChanges();
|
||||
var ts = DateTime.Now - dtStart;
|
||||
return (ts, alaramDT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user