private void btnOpen_Click(object sender, EventArgs e) { if (rbSrez.Checked) { dataTable = new DataTable("SrezTable"); SrezAdapter sa = new SrezAdapter(); sa.FileName = txtFileName.Text; sa.Fill(dataTable); } else if (rbEvent.Checked) { dataTable = new DataTable("EventTable"); EventAdapter ea = new EventAdapter(); ea.FileName = txtFileName.Text; ea.Fill(dataTable); } else // rbBase.Checked { dataTable = new DataTable("BaseTable"); BaseAdapter ba = new BaseAdapter(); ba.FileName = txtFileName.Text; ba.Fill(dataTable, true); } dataGridView.DataSource = dataTable; }
/// <summary> /// Цикл работы сервера (метод вызывается в отдельном потоке) /// </summary> private void Execute() { try { // запись информации о работе приложения workState = WorkStateNames.Normal; WriteInfo(); // выполнение действий модулей RaiseOnServerStart(); // инициализация адаптеров таблиц текущего среза и событий curSrezAdapter = new SrezAdapter(); curSrezCopyAdapter = new SrezAdapter(); eventAdapter = new EventAdapter(); eventCopyAdapter = new EventAdapter(); curSrezAdapter.FileName = ServerUtils.BuildCurFileName(Settings.ArcDir); curSrezCopyAdapter.FileName = ServerUtils.BuildCurFileName(Settings.ArcCopyDir); eventAdapter.Directory = Settings.ArcDir + "Events" + Path.DirectorySeparatorChar; eventCopyAdapter.Directory = Settings.ArcCopyDir + "Events" + Path.DirectorySeparatorChar; // инициализация кэша таблиц минутных и часовых срезов minSrezTableCache = new SortedList<DateTime, SrezTableCache>(); hrSrezTableCache = new SortedList<DateTime, SrezTableCache>(); // инициализация описания создаваемых срезов int cnlCnt = inCnls.Count; srezDescr = new SrezTable.SrezDescr(cnlCnt); for (int i = 0; i < cnlCnt; i++) srezDescr.CnlNums[i] = inCnls.Values[i].CnlNum; srezDescr.CalcCS(); // загрузка исходного текущего среза из файла SrezTableLight.Srez curSrezSrc = null; SrezTableLight tblCurSrezScr = new SrezTableLight(); try { if (File.Exists(curSrezAdapter.FileName)) { curSrezAdapter.Fill(tblCurSrezScr); if (tblCurSrezScr.SrezList.Count > 0) curSrezSrc = tblCurSrezScr.SrezList.Values[0]; } if (curSrezSrc == null) AppLog.WriteAction(Localization.UseRussian ? "Текущий срез не загружен" : "Current data are not loaded", Log.ActTypes.Action); else AppLog.WriteAction(Localization.UseRussian ? "Текущий срез загружен" : "Current data are loaded", Log.ActTypes.Action); } catch (Exception ex) { AppLog.WriteAction((Localization.UseRussian ? "Ошибка при загрузке текущего среза: " : "Error loading current data: ") + ex.Message, Log.ActTypes.Exception); } // инициализация текущего среза, предназначенного для формироваться данных сервера curSrez = new SrezTable.Srez(DateTime.MinValue, srezDescr, curSrezSrc); // инициализация данных для усреднения и времени активности каналов minAvgData = new AvgData[cnlCnt]; hrAvgData = new AvgData[cnlCnt]; activeDTs = new DateTime[cnlCnt]; DateTime nowDT = DateTime.Now; for (int i = 0; i < cnlCnt; i++) { minAvgData[i] = new AvgData() { Sum = 0.0, Cnt = 0 }; hrAvgData[i] = new AvgData() { Sum = 0.0, Cnt = 0 }; activeDTs[i] = nowDT; } // цикл работы сервера nowDT = DateTime.MaxValue; DateTime today = nowDT.Date; DateTime prevDT; DateTime writeCurSrezDT = DateTime.MinValue; DateTime writeMinSrezDT = DateTime.MinValue; DateTime writeHrSrezDT = DateTime.MinValue; DateTime calcMinDT = DateTime.MinValue; DateTime calcHrDT = DateTime.MinValue; DateTime clearCacheDT = nowDT; bool writeCur = Settings.WriteCur || Settings.WriteCurCopy; bool writeCurOnMod = Settings.WriteCurPer <= 0; bool writeMin = (Settings.WriteMin || Settings.WriteMinCopy) && Settings.WriteMinPer > 0; bool writeHr = (Settings.WriteHr || Settings.WriteHrCopy) && Settings.WriteHrPer > 0; curSrezMod = false; serverIsReady = true; while (!terminated) { prevDT = nowDT; nowDT = DateTime.Now; today = nowDT.Date; // расчёт времени записи срезов и вычисления значений дорасчётных каналов // при переводе времени назад или при первом проходе цикла if (prevDT > nowDT) { writeCurSrezDT = nowDT; writeMinSrezDT = CalcNextTime(nowDT, Settings.WriteMinPer); writeHrSrezDT = CalcNextTime(nowDT, Settings.WriteHrPer); calcMinDT = drmCnls.Count > 0 ? CalcNextTime(nowDT, 60) : DateTime.MaxValue; calcHrDT = drhCnls.Count > 0 ? CalcNextTime(nowDT, 3600) : DateTime.MaxValue; } // удаление устаревших файлов срезов и событий при изменении даты или при первом проходе цикла if (prevDT.Date != today) { ClearArchive(Settings.ArcDir + "Min", "m*.dat", today.AddDays(-Settings.StoreMinPer)); ClearArchive(Settings.ArcDir + "Hour", "h*.dat", today.AddDays(-Settings.StoreHrPer)); ClearArchive(Settings.ArcDir + "Events", "e*.dat", today.AddDays(-Settings.StoreEvPer)); ClearArchive(Settings.ArcCopyDir + "Min", "m*.dat", today.AddDays(-Settings.StoreMinPer)); ClearArchive(Settings.ArcCopyDir + "Hour", "h*.dat", today.AddDays(-Settings.StoreHrPer)); ClearArchive(Settings.ArcCopyDir + "Events", "e*.dat", today.AddDays(-Settings.StoreEvPer)); } lock (curSrez) { // установка недостоверности неактивных каналов SetUnreliable(); // вычисление дорасчётных каналов и выполнение действий модулей CalcDRCnls(drCnls, curSrez, true); RaiseOnCurDataCalculated(drCnlNums, curSrez); // вычисление минутных каналов и выполнение действий модулей if (calcMinDT <= nowDT) { CalcDRCnls(drmCnls, curSrez, true); RaiseOnCurDataCalculated(drmCnlNums, curSrez); calcMinDT = CalcNextTime(nowDT, 60); curSrezMod = true; } // вычисление часовых каналов и выполнение действий модулей if (calcHrDT <= nowDT) { CalcDRCnls(drhCnls, curSrez, true); RaiseOnCurDataCalculated(drhCnlNums, curSrez); calcHrDT = CalcNextTime(nowDT, 3600); curSrezMod = true; } // запись текущего среза if ((writeCurSrezDT <= nowDT || writeCurOnMod && curSrezMod) && writeCur) { if (writeCurOnMod) { WriteSrez(SrezTypes.Cur, nowDT); curSrezMod = false; writeCurSrezDT = DateTime.MaxValue; } else { WriteSrez(SrezTypes.Cur, writeCurSrezDT); writeCurSrezDT = CalcNextTime(nowDT, Settings.WriteCurPer); } } // запись минутного среза if (writeMinSrezDT <= nowDT && writeMin) { WriteSrez(SrezTypes.Min, writeMinSrezDT); writeMinSrezDT = CalcNextTime(nowDT, Settings.WriteMinPer); } // запись часового среза if (writeHrSrezDT <= nowDT && writeHr) { WriteSrez(SrezTypes.Hour, writeHrSrezDT); writeHrSrezDT = CalcNextTime(nowDT, Settings.WriteHrPer); } } // очистка устаревших данных кэша if (nowDT - clearCacheDT > CacheClearSpan || nowDT < clearCacheDT /*время переведено назад*/) { clearCacheDT = nowDT; ClearSrezTableCache(minSrezTableCache, MinCacheStorePer, MinCacheCapacity); ClearSrezTableCache(hrSrezTableCache, HourCacheStorePer, HourCacheCapacity); } // запись информации о работе приложения WriteInfo(); // задержка для экономиии ресурсов процессора Thread.Sleep(100); } } finally { // выполнение действий модулей RaiseOnServerStop(); // запись информации о работе приложения workState = WorkStateNames.Stopped; WriteInfo(); } }
/// <summary> /// Принять таблицу срезов от SCADA-Сервера /// </summary> public bool ReceiveSrezTable(string tableName, SrezTableLight srezTableLight) { Monitor.Enter(tcpLock); bool result = false; errMsg = ""; try { try { if (RestoreConnection()) { // определение директории таблицы Dirs dir = Dirs.Cur; if (tableName.Length > 0) { if (tableName[0] == 'h') dir = Dirs.Hour; else if (tableName[0] == 'm') dir = Dirs.Min; } // приём данных using (MemoryStream memStream = new MemoryStream()) { if (ReceiveFile(dir, tableName, memStream)) { SrezAdapter adapter = new SrezAdapter(); adapter.Stream = memStream; adapter.TableName = tableName; adapter.Fill(srezTableLight); result = true; } } } } finally { // очистка таблицы, если не удалось получить новые данные if (!result) { srezTableLight.Clear(); srezTableLight.TableName = tableName; } } } catch (Exception ex) { errMsg = (Localization.UseRussian ? "Ошибка при приёме таблицы срезов от SCADA-Сервера: " : "Error receiving data table from SCADA-Server: ") + ex.Message; WriteAction(errMsg, Log.ActTypes.Exception); } finally { Monitor.Exit(tcpLock); } return result; }
/// <summary> /// Заполнить таблицу срезов /// </summary> public static void FillSrezTable(SrezTable srezTable, SrezAdapter srezAdapter) { string fileName = srezAdapter.FileName; if (File.Exists(fileName)) { // определение времени последнего изменения файла таблицы срезов DateTime fileModTime = File.GetLastWriteTime(fileName); // загрузка данных, если файл был изменён if (srezTable.FileModTime != fileModTime) { srezAdapter.Fill(srezTable); srezTable.FileModTime = fileModTime; } } else { srezTable.Clear(); } }
/// <summary> /// Экспортировать архивные данные, загрузив их из файла /// </summary> private void ExportArcDataFromFile(Exporter exporter, DateTime dateTime) { // загрузка таблицы минутных срезов из файла SrezTableLight srezTable = new SrezTableLight(); SrezAdapter srezAdapter = new SrezAdapter(); srezAdapter.FileName = ServerUtils.BuildMinFileName(Settings.ArcDir, dateTime); try { srezAdapter.Fill(srezTable); } catch (Exception ex) { log.WriteAction(string.Format(Localization.UseRussian ? "Ошибка при загрузке таблицы минутных срезов из файла {0}: {1}" : "Error loading minute data table from file {0}: {1}", srezAdapter.FileName, ex.Message)); } // поиск среза на заданное время SrezTableLight.Srez srez = srezTable.GetSrez(dateTime); // добавление среза в очередь экспорта if (srez == null) { log.WriteAction(Localization.UseRussian ? "Отсутствуют архивные данные для экспорта" : "No archive data to export"); } else { exporter.EnqueueArcData(srez); log.WriteAction(Localization.UseRussian ? "Архивные данные добавлены в очередь экспорта" : "Archive data added to export queue"); } }
/// <summary> /// Экспортировать текущие данные, загрузив их из файла /// </summary> private void ExportCurDataFromFile(Exporter exporter) { // загрузка текущего среза из файла SrezTableLight srezTable = new SrezTableLight(); SrezAdapter srezAdapter = new SrezAdapter(); srezAdapter.FileName = ServerUtils.BuildCurFileName(Settings.ArcDir); try { srezAdapter.Fill(srezTable); } catch (Exception ex) { log.WriteAction(string.Format(Localization.UseRussian ? "Ошибка при загрузке текущего среза из файла {0}: {1}" : "Error loading current data from file {0}: {1}", srezAdapter.FileName, ex.Message)); } // добавление среза в очередь экспорта if (srezTable.SrezList.Count > 0) { SrezTableLight.Srez sourceSrez = srezTable.SrezList.Values[0]; SrezTableLight.Srez srez = CreateSrez(DateTime.Now, sourceSrez.CnlNums, sourceSrez); exporter.EnqueueCurData(srez); log.WriteAction(Localization.UseRussian ? "Текущие данные добавлены в очередь экспорта" : "Current data added to export queue"); } else { log.WriteAction(Localization.UseRussian ? "Отсутствуют текущие данные для экспорта" : "No current data to export"); } }
/// <summary> /// Загрузить таблицу срезов /// </summary> private static bool LoadSrezTable(SrezAdapter srezAdapter, Log errLog, ref SrezTable srezTable) { try { srezAdapter.Fill(srezTable); return true; } catch (Exception ex) { string errMsg = AppPhrases.LoadSrezTableError + ":\r\n" + ex.Message; if (errLog != null) errLog.WriteAction(errMsg, Log.ActTypes.Exception); ScadaUtils.ShowError(errMsg); return false; } finally { Cursor.Current = Cursors.Default; } }