using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SA_LTT.Alarm { public delegate void AlarmOccurredEvent(Alarm occurredAlarm); public delegate void AlarmClearedEvent(); public class AlarmManager { public AlarmManager() { _alarms.Clear(); OccurredAlarms.Clear(); ReadAlarmFile(); } private string fileName = "Alarms.csv"; private Dictionary _alarms = new Dictionary(); public List OccurredAlarms = new List(); public event AlarmOccurredEvent Occurred; public event AlarmClearedEvent Cleared; /// /// 알람 파일 읽기. /// private void ReadAlarmFile() { string path = Equipment.settingFilePath + fileName; // 파일 디렉토리 없으면 생성. if (Directory.Exists(Equipment.settingFilePath) == false) { Directory.CreateDirectory(Equipment.settingFilePath); } // 파일 없으면 Alarm list 생성 후 반환. if (File.Exists(path) == false) { _alarms.Clear(); foreach (AlarmCode code in Enum.GetValues(typeof(AlarmCode))) { Alarm alarm = new Alarm(); alarm.Code = code; alarm.Level = AlarmLevel.Heavy; alarm.Use = true; alarm.Description = "None"; alarm.OccurredTime = DateTime.Now; _alarms.Add(code, alarm); } WriteAlarmFile(); } string fileAlarmData = string.Empty; //파일 열려있어도 읽을 수 있도록 제작. using (FileStream fs = File.Open(path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fs, Encoding.Default)) { fileAlarmData = sr.ReadToEnd(); sr.Close(); } fs.Close(); } string[] fileAlarms = fileAlarmData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); // 파일에서 Alarm 정보 읽어옴. foreach (var line in fileAlarms) { Alarm alarm = new Alarm(); string[] items = line.Split(','); if (items.Length < 5) { continue; } AlarmCode code; string description; AlarmLevel level; bool use; DateTime time; if (Enum.TryParse(items[0], out code) == false) { continue; } description = items[1]; if (Enum.TryParse(items[2], out level) == false) { level = AlarmLevel.Heavy; } if(Boolean.TryParse(items[3], out use) == false) { use = true; } if (DateTime.TryParse(items[4], out time) == false) { time = DateTime.Now; } alarm.Code = code; alarm.Description = description; alarm.Level = level; alarm.Use = use; alarm.OccurredTime = time; if(_alarms.ContainsKey(code) == false) { _alarms.Add(code, alarm); } } // 파일에서 읽어온 Alarm 갯수와 실제 알람 갯수와 맞지 않으면 Alarm 생성. if (_alarms.Count != Enum.GetValues(typeof(AlarmCode)).Length) { // 파일에서 읽어온 Alarm에 없는 Alarm 생성. foreach (AlarmCode code in Enum.GetValues(typeof(AlarmCode))) { if (_alarms.ContainsKey(code) == false) { Alarm alarm = new Alarm(); alarm.Code = code; alarm.Description = "None"; alarm.Level = AlarmLevel.Heavy; alarm.Use = true; alarm.OccurredTime = DateTime.Now; _alarms.Add(code, alarm); } } // 알람 Key값 오름차순 정렬 _alarms = _alarms.OrderBy(i => i.Key).ToDictionary(i => i.Key, i => i.Value); } // 알람 정보 파일 저장. WriteAlarmFile(); } /// /// 알람 파일 쓰기. /// private void WriteAlarmFile() { string path = Equipment.settingFilePath + fileName; if (Directory.Exists(Equipment.settingFilePath) == false) { Directory.CreateDirectory(Equipment.settingFilePath); } StringBuilder sb = new StringBuilder(); foreach (Alarm alarm in _alarms.Values) { sb.AppendLine($"{alarm.Code},{alarm.Description},{alarm.Level},{alarm.Use},{alarm.OccurredTime.ToString("yyyy.MM.dd HH:mm:ss.fff")}"); } try { File.WriteAllText(path, sb.ToString(), Encoding.Default); } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } public void Occur(AlarmCode code) { if (OccurredAlarms.Exists(x => x.Code == code) == false) { Alarm alarm = _alarms[code]; alarm.OccurredTime = DateTime.Now; if (alarm.Use == true) { Alarm copiedAlarm = alarm.Clone(); OccurredAlarms.Add(copiedAlarm); EquipmentLogManager.Instance.WriteAlarmOccurredLog($"{$"{copiedAlarm.Code},{copiedAlarm.Description},{copiedAlarm.Level}"}"); Occurred?.Invoke(copiedAlarm); } } } public void Clear() { OccurredAlarms.Clear(); Cleared?.Invoke(); } public void Save(List alarms) { DateTime dt = DateTime.Now; foreach (Alarm alarm in alarms) { if(alarm != _alarms[alarm.Code]) { Alarm oldAlarm = _alarms[alarm.Code]; //Alarm 변경시 로그 어떻게 남길지 고민쓰. string differenceInfo = string.Empty; if(oldAlarm.Description != alarm.Description) differenceInfo += $"{oldAlarm.Description} -> {alarm.Description},"; else differenceInfo += $"{alarm.Description},"; if (oldAlarm.Level != alarm.Level) differenceInfo += $"{oldAlarm.Level} -> {alarm.Level},"; else differenceInfo += $"{alarm.Level},"; if (oldAlarm.Use != alarm.Use) differenceInfo += $"{oldAlarm.Use} -> {alarm.Use}"; else differenceInfo += $"{alarm.Use}"; //변경 알람 로그. EquipmentLogManager.Instance.WriteAlarmChangedLog($"{oldAlarm.Code},{differenceInfo}"); } _alarms[alarm.Code] = alarm; } TimeSpan ts = DateTime.Now - dt; WriteAlarmFile(); } public SortedList GetAlarms() { SortedList list = new SortedList(); foreach (Alarm alarm in _alarms.Values) { Alarm data = alarm.Clone(); list.Add(data.Code, data); } return list; } } }