Пример #1
0
        /// <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       = new SrezTableLight.Srez(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");
            }
        }
Пример #2
0
        /// <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");
            }
        }
Пример #3
0
        /// <summary>
        /// Начальная обработка дерева XML-документа
        /// </summary>
        protected override void StartXmlDocProc()
        {
            genDT = DateTime.Now;

            if (tableView == null)
            {
                hourTable = null;
            }
            else
            {
                AppData.MainData.RefreshData(date, out hourTable);
            }

            if (eventOut <= 0)
            {
                eventTable = null;
            }
            else
            {
                AppData.MainData.RefreshEvents(date, out eventTable);
            }

            templItemRow  = null;
            templEventRow = null;
            item          = null;
            eventView     = null;
        }
Пример #4
0
        /// <summary>
        /// Конструктор
        /// </summary>
        public DataCache(ServerComm serverComm, Log log)
        {
            if (serverComm == null)
            {
                throw new ArgumentNullException("serverComm");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }

            this.serverComm = serverComm;
            this.log        = log;

            baseLock    = new object();
            curDataLock = new object();

            baseRefrDT    = DateTime.MinValue;
            tblCur        = new SrezTableLight();
            curDataRefrDT = DateTime.MinValue;

            BaseTables      = new BaseTables();
            CnlProps        = new InCnlProps[0];
            CtrlCnlProps    = new CtrlCnlProps[0];
            CnlStatProps    = new SortedList <int, CnlStatProps>();
            HourTableCache  = new Cache <DateTime, SrezTableLight>(HourCacheStorePeriod, HourCacheCapacity);
            EventTableCache = new Cache <DateTime, EventTableLight>(EventCacheStorePeriod, EventCacheCapacity);
        }
Пример #5
0
        /// <summary>
        /// Конструктор
        /// </summary>
        public DataCache(ServerComm serverComm, Log log)
        {
            if (serverComm == null)
            {
                throw new ArgumentNullException("serverComm");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }

            this.serverComm = serverComm;
            this.log        = log;

            baseLock    = new object();
            curDataLock = new object();

            baseRefrDT = DateTime.MinValue;
            baseAge    = DateTime.MinValue;
            tblCur     = new SrezTableLight();
            curRefrDT  = DateTime.MinValue;

            BaseTables   = new BaseTables();
            CnlProps     = new InCnlProps[0];
            CtrlCnlProps = new CtrlCnlProps[0];
        }
Пример #6
0
 public List <MQTTPubTopic> GetValues(List <MQTTPubTopic> MqttPTs)
 {
     if (cn)
     {
         SrezTableLight stl = new SrezTableLight();
         IsCurr = rsrv.ReceiveSrezTable("current.dat", stl);
         SrezTableLight.Srez srez = stl.SrezList.Values [0];
         bool found;
         SrezTableLight.CnlData cnlData;
         foreach (MQTTPubTopic MqttPT in MqttPTs)
         {
             found = srez.GetCnlData(MqttPT.NumCnl, out cnlData);
             if (found)
             {
                 if (MqttPT.PubBehavior == "OnChange")
                 {
                     if (MqttPT.Value != cnlData.Val)
                     {
                         MqttPT.IsPub = true;
                     }
                 }
                 if (MqttPT.PubBehavior == "OnAlways")
                 {
                     MqttPT.IsPub = true;
                 }
                 MqttPT.Value = cnlData.Val;
             }
         }
     }
     return(MqttPTs);
 }
Пример #7
0
        /// <summary>
        /// Get a table of hourly data per day from the cache or from the server
        /// </summary>
        /// <remarks>The returned table after loading is not changed by an instance of this class,
        /// thus, reading its data is thread safe.
        /// The method always returns a non-null object.</remarks>
        public SrezTableLight GetHourTable(DateTime date)
        {
            try {
                // getting the table of hourly slices from the cache
                date = date.Date;
                var utcNowDT  = DateTime.UtcNow;
                var cacheItem = HourTableCache.GetOrCreateItem(date, utcNowDT);

                // block access to only one table of hourly slices
                lock (cacheItem) {
                    var  table           = cacheItem.Value;               // table to get
                    var  tableAge        = cacheItem.ValueAge;            // table file change time
                    bool tableIsNotValid =
                        utcNowDT - cacheItem.ValueRefrDT > DataValidSpan; // the table might be out of date

                    // getting time slice table from server
                    if (table == null || tableIsNotValid)
                    {
                        string tableName   = SrezAdapter.BuildHourTableName(date);
                        var    newTableAge = serverComm.ReceiveFileAge(ServerComm.Dirs.Hour, tableName);

                        if (newTableAge == DateTime.MinValue)
                        {
                            // the table file does not exist or there is no connection to the server
                            table = null;
                            // do not clog the log
                            //log.WriteError($"Unable to receive modification time of the hourly data table {tableName}");
                        }
                        else if (newTableAge != tableAge)     // table file changed
                        {
                            table = new SrezTableLight();
                            if (serverComm.ReceiveSrezTable(tableName, table))
                            {
                                table.FileModTime  = newTableAge;
                                table.LastFillTime = utcNowDT;
                            }
                            else
                            {
                                throw new ScadaException("Unable to receive hourly data table.");
                            }
                        }

                        if (table == null)
                        {
                            table = new SrezTableLight();
                        }

                        // update table in cache
                        HourTableCache.UpdateItem(cacheItem, table, newTableAge, utcNowDT);
                    }

                    return(table);
                }
            } catch (Exception ex) {
                log.WriteException(ex, "Error getting hourly data table for {0} from the cache or from the server",
                                   date.ToLocalizedDateString());
                return(new SrezTableLight());
            }
        }
Пример #8
0
 /// <summary>
 /// Предварительно обработать дерево XML-документа
 /// </summary>
 protected override void StartXmlDocProc()
 {
     genDT             = DateTime.Now;
     itemRowTemplate   = null;
     viewItem          = null;
     reqDateHourTable  = null;
     prevDateHourTable = null;
 }
Пример #9
0
 public SrezTableLight.Srez GetCurrSrez()
 {
     lock (rssrv)
     {
         SrezTableLight stl = new SrezTableLight();
         bool           rec;
         rec = rssrv.ReceiveSrezTable("current.dat", stl);
         return(stl.SrezList.Values [0]);
     }
 }
Пример #10
0
        /// <summary>
        /// Окончательно обработать дерево XML-документа
        /// </summary>
        protected override void FinalXmlDocProc()
        {
            // проверка шаблона
            if (workbook.Worksheets.Count == 0 || itemRowTemplate == null)
            {
                throw new Exception(WebPhrases.IncorrectRepTemplate);
            }

            // перевод наименования листа
            workbook.Worksheets[0].Name = PlgPhrases.HourDataWorksheet;

            // удаление лишних атрибутов таблицы
            Table table = itemRowTemplate.ParentTable;

            table.RemoveTableNodeAttrs();

            // скрытие неиспользуемых столбцов
            HideUnusedColumns(table);

            // удаление строки-шаблона
            int itemRowIndex = table.Rows.IndexOf(itemRowTemplate);

            table.RemoveRow(itemRowIndex);

            // получение часовых данных
            reqDateHourTable = dataAccess.DataCache.GetHourTable(date);
            if (startHour < 0)
            {
                prevDateHourTable = dataAccess.DataCache.GetHourTable(date.AddDays(-1));
            }

            // вывод данных в отчёт
            for (int i = 0, cnt = tableView.Items.Count; i < cnt; i++)
            {
                viewItem = tableView.Items[i];
                if (!viewItem.Hidden)
                {
                    cnlProps = viewItem.CnlNum > 0 ? dataAccess.GetCnlProps(viewItem.CnlNum) : null;
                    Row newRow = itemRowTemplate.Clone();
                    ExcelProc(newRow);
                    table.AppendRow(newRow);
                }
            }
        }
Пример #11
0
        public void SendCurrSrez(List <Cnl> cnls)
        {
            bool     res = false;
            DateTime dt  = DateTime.Now;

            foreach (Cnl cnl in cnls)
            {
                RSServer RSSrv = GetRSSrvId(cnl.ID);

                SrezTableLight      stl        = new SrezTableLight();
                SrezTableLight.Srez curSrezSrc = new SrezTableLight.Srez(dt, 1);
                curSrezSrc.CnlNums [0] = cnl.Num;
                curSrezSrc.CnlData [0] = new SrezTableLight.CnlData()
                {
                    Val = cnl.Value, Stat = cnl.State
                };

                res = RSSrv.SendSrez(curSrezSrc, out res);
            }
        }
Пример #12
0
        private SrezTableLight prevDateHourTable;     // таблица часовых данных за предыдущую дату


        /// <summary>
        /// Конструктор
        /// </summary>
        public HourDataRepBuilder(DataAccess dataAccess)
            : base()
        {
            if (dataAccess == null)
            {
                throw new ArgumentNullException("dataAccess");
            }

            this.dataAccess = dataAccess;
            dataFormatter   = new DataFormatter();

            tableView = null;
            date      = DateTime.MinValue;
            startHour = 0;
            endHour   = 23;

            genDT             = DateTime.MinValue;
            itemRowTemplate   = null;
            viewItem          = null;
            reqDateHourTable  = null;
            prevDateHourTable = null;
        }
Пример #13
0
        public override void OnCurDataProcessed(int[] cnlNums, SrezTableLight.Srez curSrez)
        {
            // the method executes when new current data have been processed by the server,
            // the channel numbers are sorted in ascending order
            // метод выполняется после обработки новых текущих данных сервером,
            // номера каналов упорядочены по возрастанию
            const int MyCnlNum = 1;
            const int MyKpNum = 1;
            const int MyCmdNum = 1;
            const double MyCmdVal = 1.0;

            // send a command if the value of MyCnlNum channel greater than 200
            WriteToLog("Process current data by the module " + Name, Log.ActTypes.Action);
            SrezTableLight.CnlData cnlData;
            if (curSrez.GetCnlData(MyCnlNum, out cnlData) && cnlData.Val > 200)
            {
                WriteToLog("Send command by the module " + Name, Log.ActTypes.Action);
                Command cmd = new Command(BaseValues.CmdTypes.Standard);
                cmd.KPNum = MyKpNum;
                cmd.CmdNum = MyCmdNum;
                cmd.CmdVal = MyCmdVal;
                PassCommand(cmd);
            }
        }
Пример #14
0
 /// <summary>
 /// Выполнить действия после обработки новых текущих данных
 /// </summary>
 /// <remarks>Номера каналов упорядочены по возрастанию.
 /// Вычисление дорасчётных каналов текущего среза в момент вызова метода не выполнено</remarks>
 public virtual void OnCurDataProcessed(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
 }
Пример #15
0
        public override TaskStatus Run()
        {
            Info("Start Comparator task");

            bool success = false;

            bool IsIndata = false;

            try
            {
                if (indata == "file")
                {
                    foreach (FileInf fi in SelectFiles())
                    {
                        SrezTableLight stl = new SrezTableLight();
                        sa.FileName = fi.Path;
                        sa.Fill(stl);
                        int id = int.Parse(fi.FileName.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)[1]);
                        stls.AddSrez(id, stl.SrezList.Values[0]);
                    }
                    IsIndata = true;
                }

                if (indata == "mem")
                {
                    foreach (RSServer srv in srvs.GetRSServers())
                    {
                        stls.AddSrez(srv.Id, srv.GetCurrSrez());
                    }
                    IsIndata = true;
                }

                if (IsIndata)
                {
                    foreach (Cnl cnl in Cnls)
                    {
                        Argument cArg = new Argument(cnl.ToString(), stls.GetCnlData(cnl.ID, cnl.Num));
                        CalcArgs.Add(cArg);
                    }
                    CalcArgs.AddRange(xArgs);

                    foreach (Argument arg in CalcArgs)
                    {
                        Info(arg.getArgumentName() + "   " + arg.getArgumentValue().ToString());
                    }

                    Expression expr = new Expression(condition, CalcArgs.ToArray());

                    double pvExpr = expr.calculate();

                    if (pvExpr == 0)
                    {
                        success = false;
                    }
                    else if (pvExpr == 1)
                    {
                        success = true;
                    }

                    if (success)
                    {
                        foreach (Argument arg in odts)
                        {
                            arg.addDefinitions(CalcArgs.ToArray());
                        }
                    }


                    InfoFormat("Condition: {0}", condition);
                    InfoFormat("Result calculate: {0}", expr.calculate());
                    InfoFormat("Success value: {0}", success);
                }
                else
                {
                    Info("Not set parametr indata");
                }

                CalcArgs.Clear();
                stls.ClearSrez();
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception ex)
            {
                ErrorFormat("Ann error calc comparator. Error: {0}", ex.Message);
            }

            Info("Task RSComparator finished.");
            return(new TaskStatus(Status.Success, success));
        }
Пример #16
0
        /// <summary>
        /// Обработать директиву, связанную со значением ячейки
        /// </summary>
        protected override void ProcVal(Cell cell, string valName)
        {
            string nodeText = null;

            if (valName == "Title")
            {
                nodeText = string.Format(TablePhrases.HourDataTitle,
                                         tableView.Title,
                                         date.ToLocalizedDateString(),
                                         WFrmTable.GetLocalizedHour(startHour) + " - " + WFrmTable.GetLocalizedHour(endHour));
            }
            else if (valName == "Gen")
            {
                nodeText = TablePhrases.HourDataGen + genDT.ToLocalizedString();
            }
            else if (valName == "ItemCol")
            {
                nodeText = TablePhrases.ItemCol;
            }
            else if (valName.StartsWith("H"))
            {
                // заголовок таблицы часовых данных
                if (int.TryParse(valName.Substring(1), out int hour))
                {
                    nodeText = WFrmTable.GetLocalizedHour(hour);
                }
            }
            else if (viewItem != null)
            {
                if (valName == "Name")
                {
                    nodeText = viewItem.Caption;
                }
                else if (valName.StartsWith("h"))
                {
                    // часовые данные
                    if (int.TryParse(valName.Substring(1), out int hour))
                    {
                        if (viewItem.CnlNum > 0 && startHour <= hour && hour <= endHour)
                        {
                            DateTime       colDT     = date.AddHours(hour);
                            SrezTableLight hourTable = hour >= 0 ? reqDateHourTable : prevDateHourTable;
                            hourTable.SrezList.TryGetValue(colDT, out SrezTableLight.Srez snapshot);

                            if (dataFormatter.HourDataVisible(colDT, genDT, snapshot != null, out string emptyVal))
                            {
                                // получение данных
                                snapshot.GetCnlData(viewItem.CnlNum, out double val, out int stat);

                                // форматирование данных
                                dataFormatter.FormatCnlVal(val, stat, viewItem.CnlProps, ".", "",
                                                           out string text, out string textWithUnit, out bool textIsNumber);
                                string color = dataFormatter.GetCnlValColor(val, stat, viewItem.CnlProps,
                                                                            dataAccess.GetCnlStatProps(stat));

                                // вывод данных
                                nodeText = text;
                                workbook.SetColor(cell.Node, null, color);
                                if (textIsNumber)
                                {
                                    cell.SetNumberType();
                                }
                            }
                            else
                            {
                                nodeText = emptyVal;
                            }
                        }
                        else
                        {
                            nodeText = "";
                        }
                    }
                }
            }

            if (nodeText != null)
            {
                cell.DataNode.InnerText = nodeText;
            }
        }
Пример #17
0
        /// <summary>
        /// Копировать текущие данные и признаки изменения тегов КП, 
        /// затем сбросить признаки изменения
        /// </summary>
        public void CopyCurData(SrezTableLight.CnlData[] destCurData, bool[] destCurDataModified)
        {
            if (destCurData == null)
                throw new ArgumentNullException("destCurData");
            if (destCurDataModified == null)
                throw new ArgumentNullException("destCurDataModified");

            try
            {
                lock (curData)
                {
                    int tagCnt = curData.Length;
                    Array.Copy(curData, destCurData, tagCnt);
                    Array.Copy(curDataModified, destCurDataModified, tagCnt);
                    Array.Clear(curDataModified, 0, tagCnt);
                }
            }
            catch (Exception ex)
            {
                WriteToLog((Localization.UseRussian ?
                    "Ошибка при копировании текущих данных тегов КП: " :
                    "Error copying current data of device tags: ") + ex.Message);
            }
        }
Пример #18
0
 /// <summary>
 /// Потокобезопасно установить текущие данные тега КП и признак их изменения
 /// </summary>
 protected void SetCurData(int tagIndex, SrezTableLight.CnlData newData)
 {
     lock (curData)
     {
         if (0 <= tagIndex && tagIndex < curData.Length)
         {
             SrezTableLight.CnlData curTagData = curData[tagIndex];
             curDataModified[tagIndex] |= curTagData.Val != newData.Val || curTagData.Stat != newData.Stat;
             curData[tagIndex] = newData;
         }
     }
 }
Пример #19
0
        /// <summary>
        /// Получить таблицу часовых данных за сутки из кэша или от сервера
        /// </summary>
        /// <remarks>Возвращаемая таблица после загрузки не изменяется экземпляром данного класса,
        /// таким образом, чтение её данных является потокобезопасным.
        /// Метод всегда возвращает объект, не равный null</remarks>
        public SrezTableLight GetHourTable(DateTime date)
        {
            try
            {
                // получение таблицы часовых срезов из кэша
                date = date.Date;
                DateTime utcNowDT = DateTime.UtcNow;
                Cache <DateTime, SrezTableLight> .CacheItem cacheItem = HourTableCache.GetOrCreateItem(date, utcNowDT);

                // блокировка доступа только к одной таблице часовых срезов
                lock (cacheItem)
                {
                    SrezTableLight table           = cacheItem.Value;                                  // таблица, которую необходимо получить
                    DateTime       tableAge        = cacheItem.ValueAge;                               // время изменения файла таблицы
                    bool           tableIsNotValid = utcNowDT - cacheItem.ValueRefrDT > DataValidSpan; // таблица могла устареть

                    // получение таблицы часовых срезов от сервера
                    if (table == null || tableIsNotValid)
                    {
                        string   tableName   = SrezAdapter.BuildHourTableName(date);
                        DateTime newTableAge = serverComm.ReceiveFileAge(ServerComm.Dirs.Hour, tableName);

                        if (newTableAge == DateTime.MinValue) // файл таблицы не существует или нет связи с сервером
                        {
                            table = null;
                            // не засорять лог

                            /*log.WriteError(string.Format(Localization.UseRussian ?
                             *  "Не удалось принять время изменения таблицы часовых данных {0}" :
                             *  "Unable to receive modification time of the hourly data table {0}", tableName));*/
                        }
                        else if (newTableAge != tableAge) // файл таблицы изменён
                        {
                            table = new SrezTableLight();
                            if (serverComm.ReceiveSrezTable(tableName, table))
                            {
                                table.FileModTime  = newTableAge;
                                table.LastFillTime = utcNowDT;
                            }
                            else
                            {
                                throw new ScadaException(Localization.UseRussian ?
                                                         "Не удалось принять таблицу часовых срезов." :
                                                         "Unable to receive hourly data table.");
                            }
                        }

                        if (table == null)
                        {
                            table = new SrezTableLight();
                        }

                        // обновление таблицы в кэше
                        HourTableCache.UpdateItem(cacheItem, table, newTableAge, utcNowDT);
                    }

                    return(table);
                }
            }
            catch (Exception ex)
            {
                log.WriteException(ex, Localization.UseRussian ?
                                   "Ошибка при получении таблицы часовых данных за {0} из кэша или от сервера" :
                                   "Error getting hourly data table for {0} from the cache or from the server",
                                   date.ToLocalizedDateString());
                return(new SrezTableLight());
            }
        }
Пример #20
0
 /// <summary>
 /// Добавить текущие данные в очередь экспорта
 /// </summary>
 public void EnqueueCurData(SrezTableLight.Srez curSrez)
 {
     lock (curSrezQueue)
     {
         if (curSrezQueue.Count < MaxQueueSize)
         {
             curSrezQueue.Enqueue(curSrez);
         }
         else
         {
             skipCurSrezCnt++;
             log.WriteAction(string.Format(Localization.UseRussian ?
                 "Невозможно добавить в очередь текущие данные. Максимальный размер очереди {0} превышен" :
                 "Unable to enqueue current data. The maximum size of the queue {0} is exceeded",
                 MaxQueueSize));
         }
     }
 }
Пример #21
0
        /// <summary>
        /// Генерировать событие в соответствии со свойствами и данными входного канала
        /// </summary>
        private void GenEvent(InCnl inCnl, SrezTableLight.CnlData oldCnlData, SrezTableLight.CnlData newCnlData)
        {
            if (inCnl.EvEnabled)
            {
                double oldVal = oldCnlData.Val;
                double newVal = newCnlData.Val;
                int oldStat = oldCnlData.Stat;
                int newStat = newCnlData.Stat;

                bool dataHasChanged =
                    oldStat > BaseValues.CnlStatuses.Undefined && newStat > BaseValues.CnlStatuses.Undefined &&
                    (oldVal != newVal || oldStat != newStat);

                if (// события по изменению
                    inCnl.EvOnChange && dataHasChanged ||
                    // события по неопределённому состоянию и выходу из него
                    inCnl.EvOnUndef &&
                    (oldStat > BaseValues.CnlStatuses.Undefined && newStat == BaseValues.CnlStatuses.Undefined ||
                    oldStat == BaseValues.CnlStatuses.Undefined && newStat > BaseValues.CnlStatuses.Undefined) ||
                    // события нормализации, занижения и завышения
                    (newStat == BaseValues.CnlStatuses.Normal || newStat == BaseValues.CnlStatuses.LowCrash ||
                    newStat == BaseValues.CnlStatuses.Low || newStat == BaseValues.CnlStatuses.High ||
                    newStat == BaseValues.CnlStatuses.HighCrash) && oldStat != newStat)
                {
                    // создание события
                    EventTableLight.Event ev = new EventTableLight.Event();
                    ev.DateTime = DateTime.Now;
                    ev.ObjNum = inCnl.ObjNum;
                    ev.KPNum = inCnl.KPNum;
                    ev.ParamID = inCnl.ParamID;
                    ev.CnlNum = inCnl.CnlNum;
                    ev.OldCnlVal = oldCnlData.Val;
                    ev.OldCnlStat = oldStat;
                    ev.NewCnlVal = newCnlData.Val;
                    ev.NewCnlStat = dataHasChanged && oldStat == BaseValues.CnlStatuses.Defined &&
                        newStat == BaseValues.CnlStatuses.Defined ? BaseValues.CnlStatuses.Changed : newStat;

                    // запись события и выполнение действий модулей
                    WriteEvent(ev);
                }
            }
        }
Пример #22
0
 /// <summary>
 /// Вызвать событие OnCurDataCalculated для модулей
 /// </summary>
 private void RaiseOnCurDataCalculated(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
     lock (modules)
     {
         foreach (ModLogic modLogic in modules)
         {
             try
             {
                 modLogic.OnCurDataCalculated(cnlNums, curSrez);
             }
             catch (Exception ex)
             {
                 AppLog.WriteAction(string.Format(Localization.UseRussian ? "Ошибка при выполнении действий " +
                     "после вычисления дорасчётных каналов текущего среза в модуле {0}: {1}" :
                     "Error executing actions on current data calculated in module {0}: {1}",
                     modLogic.Name, ex.Message), Log.ActTypes.Exception);
             }
         }
     }
 }
Пример #23
0
 /// <summary>
 /// Выполнить действия после вычисления дорасчётных каналов текущего среза
 /// </summary>
 /// <remarks>Номера каналов упорядочены по возрастанию</remarks>
 public virtual void OnCurDataCalculated(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
 }
Пример #24
0
        /// <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();
            }
        }
Пример #25
0
        /// <summary>
        /// Преобразовать данные тега КП в строку
        /// </summary>
        protected override string ConvertTagDataToStr(int signal, SrezTableLight.CnlData tagData)
        {
            if (tagData.Stat > 0)
            {
                if (signal == 1)
                    return tagData.Val.ToString("N0");
            }

            return base.ConvertTagDataToStr(signal, tagData);
        }
Пример #26
0
        private Trend trend; // ��������� ���������� �������� �����

        #endregion Fields

        #region Constructors

        /// <summary>
        /// �����������
        /// </summary>
        public MainData()
        {
            serverComm = null;
            settFileName = "";
            settModTime = DateTime.MinValue;

            tblCur = new SrezTableLight();
            hourTableCache = new SrezTableLight[HourCacheSize];
            eventTableCache = new EventTableLight[EventCacheSize];
            for (int i = 0; i < HourCacheSize; i++)
                hourTableCache[i] = null;
            for (int i = 0; i < EventCacheSize; i++)
                eventTableCache[i] = null;
            hourTableIndex = 0;
            eventTableIndex = 0;
            trend = null;
            nfi = new NumberFormatInfo();
            defDecSep = Localization.Culture.NumberFormat.NumberDecimalSeparator;
            defGrSep = Localization.Culture.NumberFormat.NumberGroupSeparator;

            baseModTime = DateTime.MinValue;
            baseFillTime = DateTime.MinValue;
            tblInCnl = new DataTable("InCnl");
            tblCtrlCnl = new DataTable("CtrlCnl");
            tblObj = new DataTable("Obj");
            tblKP = new DataTable("KP");
            tblRole = new DataTable("Role");
            tblUser = new DataTable("User");
            tblInterface = new DataTable("Interface");
            tblRight = new DataTable("Right");
            tblEvType = new DataTable("EvType");
            tblParam = new DataTable("Param");
            tblUnit = new DataTable("Unit");
            tblCmdVal = new DataTable("CmdVal");
            tblFormat = new DataTable("Format");

            baseTblArr = new DataTable[13];
            baseTblArr[0] = tblInCnl;
            baseTblArr[1] = tblCtrlCnl;
            baseTblArr[2] = tblObj;
            baseTblArr[3] = tblKP;
            baseTblArr[4] = tblRole;
            baseTblArr[5] = tblUser;
            baseTblArr[6] = tblInterface;
            baseTblArr[7] = tblRight;
            baseTblArr[8] = tblEvType;
            baseTblArr[9] = tblParam;
            baseTblArr[10] = tblUnit;
            baseTblArr[11] = tblCmdVal;
            baseTblArr[12] = tblFormat;

            cnlPropsArr = null;
            maxCnlCnt = 0;

            refrLock = new Object();
            baseLock = new Object();
            cnlPropLock = new Object();
            cnlDataLock = new Object();
            eventLock = new Object();
        }
Пример #27
0
        /// <summary>
        /// �������� (�����������) ������ ��� ������ ������� �� SCADA-��������
        /// ��� ��������� ����� �������� ���������� �� SCADA-��������
        /// </summary>
        private void RefrServerComm()
        {
            if (settFileName != "")
            {
                DateTime dateTime = GetLastWriteTime(settFileName);
                if (dateTime > DateTime.MinValue && dateTime != settModTime)
                {
                    settModTime = dateTime;
                    CommSettings commSettings = new CommSettings();
                    commSettings.LoadFromFile(settFileName, AppData.Log);
                    if (serverComm == null || !serverComm.CommSettings.Equals(commSettings))
                    {
                        if (serverComm != null)
                        {
                            serverComm.Close();

                            tblCur = new SrezTableLight();
                            for (int i = 0; i < HourCacheSize; i++)
                                hourTableCache[i] = null;
                            for (int i = 0; i < EventCacheSize; i++)
                                eventTableCache[i] = null;
                            hourTableIndex = 0;
                            eventTableIndex = 0;
                            trend = null;

                            baseModTime = DateTime.MinValue;
                            baseFillTime = DateTime.MinValue;
                        }
                        serverComm = new ServerComm(commSettings);
                    }
                }
            }
        }
Пример #28
0
 /// <summary>
 /// Установить данные тега среза
 /// </summary>
 protected void SetTagData(int tagIndex, SrezTableLight.CnlData newData)
 {
     if (0 <= tagIndex && tagIndex < TagData.Length)
         TagData[tagIndex] = newData;
 }
Пример #29
0
 /// <summary>
 /// Вызвать событие OnCurDataProcessed для модулей
 /// </summary>
 private void RaiseOnCurDataProcessed(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
     lock (modules)
     {
         foreach (ModLogic modLogic in modules)
         {
             try
             {
                 modLogic.OnCurDataProcessed(cnlNums, curSrez);
             }
             catch (Exception ex)
             {
                 AppLog.WriteAction(string.Format(Localization.UseRussian ?
                     "Ошибка при выполнении действий после обработки новых текущих данных в модуле {0}: {1}" :
                     "Error executing actions on current data processed in module {0}: {1}",
                     modLogic.Name, ex.Message), Log.ActTypes.Exception);
             }
         }
     }
 }
Пример #30
0
        /// <summary>
        /// Отправить архивный срез SCADA-Серверу
        /// </summary>
        public bool SendArchive(SrezTableLight.Srez arcSrez, out bool result)
        {
            Monitor.Enter(tcpLock);
            bool complete = false;
            result = false;
            errMsg = "";

            try
            {
                if (RestoreConnection())
                {
                    commState = CommStates.WaitResponse;
                    tcpClient.ReceiveTimeout = commSettings.ServerTimeout;

                    // отправка команды записи архивного среза
                    int cnlCnt = arcSrez.CnlNums.Length;
                    int cmdLen = cnlCnt * 14 + 13;

                    byte[] buf = new byte[cmdLen];
                    buf[0] = (byte)(cmdLen % 256);
                    buf[1] = (byte)(cmdLen / 256);
                    buf[2] = 0x04;

                    double arcDT = Arithmetic.EncodeDateTime(arcSrez.DateTime);
                    byte[] bytes = BitConverter.GetBytes(arcDT);
                    Array.Copy(bytes, 0, buf, 3, 8);

                    buf[11] = (byte)(cnlCnt % 256);
                    buf[12] = (byte)(cnlCnt / 256);

                    for (int i = 0; i < cnlCnt; i++)
                    {
                        bytes = BitConverter.GetBytes((UInt32)arcSrez.CnlNums[i]);
                        Array.Copy(bytes, 0, buf, i * 14 + 13, 4);

                        SrezTableLight.CnlData data = arcSrez.CnlData[i];
                        bytes = BitConverter.GetBytes(data.Val);
                        Array.Copy(bytes, 0, buf, i * 14 + 17, 8);

                        bytes = BitConverter.GetBytes((UInt16)data.Stat);
                        Array.Copy(bytes, 0, buf, i * 14 + 25, 2);
                    }

                    netStream.Write(buf, 0, cmdLen);

                    // приём результата
                    buf = new byte[4];
                    int bytesRead = netStream.Read(buf, 0, 4);

                    // обработка полученных данных
                    if (bytesRead == buf.Length && CheckDataFormat(buf, 0x04))
                    {
                        result = buf[3] > 0;
                        commState = result ? CommStates.Authorized : CommStates.NotReady;
                        complete = true;
                    }
                    else
                    {
                        errMsg = Localization.UseRussian ?
                            "Неверный формат ответа SCADA-Сервера на команду отправки архивного среза" :
                            "Incorrect SCADA-Server response to sending archive data command";
                        WriteAction(errMsg, Log.ActTypes.Exception);
                        commState = CommStates.Error;
                    }
                }
            }
            catch (Exception ex)
            {
                errMsg = (Localization.UseRussian ? "Ошибка при отправке архивного среза SCADA-Серверу: " : 
                    "Error sending archive data to SCADA-Server: ") + ex.Message;
                WriteAction(errMsg, Log.ActTypes.Exception);
                Disconnect();
            }
            finally
            {
                RestoreReceiveTimeout();
                Monitor.Exit(tcpLock);
            }

            return complete;
        }
Пример #31
0
        /// <summary>
        /// �������� ������� ���� ������������, �������� � ������� ������, ���� ��� ����������
        /// </summary>
        /// <param name="reqDate">���� ������������� ������� ������</param>
        /// <param name="hourTable">������� ������� ������</param>
        public void RefreshData(DateTime reqDate, out SrezTableLight hourTable)
        {
            RefreshBase();
            Monitor.Enter(refrLock);

            try
            {
                // ���������� �������� �����
                DateTime now = DateTime.Now;

                if ((now - tblCur.LastFillTime).TotalSeconds > CurSrezValidTime) // ������ ��������
                {
                    DateTime curModTime = serverComm.ReceiveFileAge(ServerComm.Dirs.Cur, "current.dat");
                    if (curModTime != tblCur.FileModTime) // ���� ����� ������
                        tblCur.FileModTime = serverComm.ReceiveSrezTable("current.dat", tblCur) ?
                            curModTime : DateTime.MinValue;
                }

                // ���������� ������� ������� ������
                hourTable = null;

                if (reqDate > DateTime.MinValue)
                {
                    string hourTableName = "h" + reqDate.ToString("yyMMdd") + ".dat";

                    // ����� ������� ������� ������� ������ � ����
                    int tableIndex = -1;
                    for (int i = 0; i < HourCacheSize; i++)
                    {
                        hourTable = hourTableCache[i];
                        if (hourTable != null && hourTable.TableName == hourTableName)
                        {
                            tableIndex = i;
                            break;
                        }
                    }

                    if (tableIndex < 0 || (now - hourTable.LastFillTime).TotalSeconds > HourSrezValidTime /*������ ��������*/)
                    {
                        DateTime fileModTime = serverComm.ReceiveFileAge(ServerComm.Dirs.Hour, hourTableName);

                        if (tableIndex < 0)
                        {
                            hourTable = null;

                            // ����������� ����� � ���� ��� ����� ������� ������� ������
                            tableIndex = hourTableIndex;
                            if (++hourTableIndex == HourCacheSize)
                                hourTableIndex = 0;
                        }

                        if (hourTable == null || fileModTime != hourTable.FileModTime /*���� ������ ������*/)
                        {
                            // �������� ����� ������� ������� ������
                            hourTable = new SrezTableLight();
                            hourTableCache[tableIndex] = hourTable;

                            // �������� ������� ������� ������
                            if (serverComm.ReceiveSrezTable(hourTableName, hourTable))
                                hourTable.FileModTime = fileModTime;
                        }
                    }
                }
            }
            finally
            {
                Monitor.Exit(refrLock);
            }
        }
Пример #32
0
        /// <summary>
        /// Экспортировать срез
        /// </summary>
        private void ExportSrez(DbCommand cmd, SrezTableLight.Srez srez)
        {
            DataSource.SetCmdParam(cmd, "dateTime", srez.DateTime);

            foreach (int cnlNum in srez.CnlNums)
            {
                SrezTableLight.CnlData cnlData;
                if (srez.GetCnlData(cnlNum, out cnlData))
                {
                    DataSource.SetCmdParam(cmd, "cnlNum", cnlNum);
                    DataSource.SetCmdParam(cmd, "val", cnlData.Val);
                    DataSource.SetCmdParam(cmd, "stat", cnlData.Stat);
                    cmd.ExecuteNonQuery();
                }
            }
        }
Пример #33
0
        /// <summary>
        /// Получить таблицу срезов, содержащую данные заданных каналов
        /// </summary>
        public SrezTableLight GetSrezTable(DateTime date, SrezTypes srezType, int[] cnlNums)
        {
            try
            {
                SrezTableLight destSrezTable;
                int cnlNumsLen = cnlNums == null ? 0 : cnlNums.Length;

                if (serverIsReady && cnlNumsLen > 0)
                {
                    // получение кэша таблицы срезов
                    SrezTableCache srezTableCache = GetSrezTableCache(date.Date, srezType);

                    lock (srezTableCache)
                    {
                        // заполнение таблицы срезов в кэше
                        srezTableCache.FillSrezTable();

                        // создание новой таблицы срезов и копирование в неё данных заданных каналов
                        SrezTable srcSrezTable = srezTableCache.SrezTable;
                        SrezTable.SrezDescr prevSrezDescr = null;
                        int[] cnlNumIndexes = new int[cnlNumsLen];
                        destSrezTable = new SrezTableLight();

                        foreach (SrezTable.Srez srcSrez in srcSrezTable.SrezList.Values)
                        {
                            // определение индексов каналов
                            if (!srcSrez.SrezDescr.Equals(prevSrezDescr))
                            {
                                for (int i = 0; i < cnlNumsLen; i++)
                                    cnlNumIndexes[i] = Array.BinarySearch<int>(srcSrez.CnlNums, cnlNums[i]);
                            }

                            // создание и заполнение среза, содержащего заданные каналы
                            SrezTableLight.Srez destSrez = new SrezTableLight.Srez(srcSrez.DateTime, cnlNumsLen);

                            for (int i = 0; i < cnlNumsLen; i++)
                            {
                                destSrez.CnlNums[i] = cnlNums[i];
                                int cnlNumInd = cnlNumIndexes[i];
                                destSrez.CnlData[i] = cnlNumInd < 0 ?
                                    SrezTableLight.CnlData.Empty : srcSrez.CnlData[cnlNumInd];
                            }

                            destSrezTable.SrezList.Add(destSrez.DateTime, destSrez);
                            prevSrezDescr = srcSrez.SrezDescr;
                        }
                    }
                }
                else
                {
                    destSrezTable = null;
                }

                return destSrezTable;
            }
            catch (Exception ex)
            {
                AppLog.WriteAction((Localization.UseRussian ?
                    "Ошибка при получении таблицы срезов: " :
                    "Error getting snapshot table: ") + ex.Message, Log.ActTypes.Exception);
                return null;
            }
        }
Пример #34
0
 /// <summary>
 /// Добавить архивные данные в очередь экспорта
 /// </summary>
 public void EnqueueArcData(SrezTableLight.Srez arcSrez)
 {
     lock (arcSrezQueue)
     {
         if (arcSrezQueue.Count < MaxQueueSize)
         {
             arcSrezQueue.Enqueue(arcSrez);
         }
         else
         {
             skipArcSrezCnt++;
             log.WriteAction(string.Format(Localization.UseRussian ?
                 "Невозможно добавить в очередь архивные данные. Максимальный размер очереди {0} превышен" :
                 "Unable to enqueue archive data. The maximum size of the queue {0} is exceeded",
                 MaxQueueSize));
         }
     }
 }
Пример #35
0
 public override void OnArcDataProcessed(int[] cnlNums, SrezTableLight.Srez arcSrez)
 {
     // the method executes when new archive data have been processed by the server
     // метод выполняется после обработки новых архивных данных сервером
     WriteToLog("Process archive data by the module " + Name, Log.ActTypes.Action);
 }
Пример #36
0
 /// <summary>
 /// Преобразовать данные тега КП в строку
 /// </summary>
 protected virtual string ConvertTagDataToStr(int signal, SrezTableLight.CnlData tagData)
 {
     return tagData.Stat > 0 ? tagData.Val.ToString("N3", Localization.Culture) : "---";
 }
Пример #37
0
 public override void OnCurDataCalculated(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
     // the method executes after current data calculation (approximately every 100 ms)
     // метод выполняется после вычисления дорасчётных каналов текущего среза (примерно каждые 100 мс)
 }
Пример #38
0
        /// <summary>
        /// Получить часовые данные входных каналов
        /// </summary>
        private HourCnlData[] GetHourCnlDataArr(int year, int month, int day,
                                                int startHour, int endHour, IList <int> cnlList, bool existing, ref long[] dataAgeArr)
        {
            if (startHour > endHour)
            {
                throw new ArgumentException("Start hour must be less or equal than end hour.");
            }

            DataAccess dataAccess = AppData.DataAccess;
            DataCache  dataCache  = dataAccess.DataCache;

            DateTime date      = new DateTime(year, month, day);
            DateTime startDT   = date.AddHours(startHour);
            DateTime startDate = startDT.Date;
            DateTime endDT     = date.AddHours(endHour);
            DateTime endDate   = endDT.Date;
            int      hourCnt   = endHour - startHour + 1;
            int      dayCnt    = (int)(endDate - startDate).TotalDays + 1;

            List <HourCnlData> hourCnlDataList = new List <HourCnlData>(hourCnt);

            long[]   newDataAgeArr = new long[dayCnt];
            DateTime nowDT         = DateTime.Now;
            DateTime curDate       = startDate;

            for (int dayInd = 0; dayInd < dayCnt; dayInd++)
            {
                SrezTableLight tblHour     = dataCache.GetHourTable(curDate);
                long           newDataAge  = WebUtils.DateTimeToJs(tblHour.FileModTime);
                long           prevDataAge = dayInd < dataAgeArr.Length ? dataAgeArr[dayInd] : 0;
                bool           modified    = prevDataAge <= 0 || prevDataAge < newDataAge;
                newDataAgeArr[dayInd] = newDataAge;
                DateTime nextDate = curDate.AddDays(1.0);

                if (existing)
                {
                    // получение всех существующих часовых срезов
                    DateTime dayStartDT = curDate > startDate ? curDate : startDT;
                    DateTime dayEndDT   = curDate < endDate ? nextDate : endDT;

                    foreach (SrezTableLight.Srez snapshot in tblHour.SrezList.Values)
                    {
                        DateTime snapshotDT = snapshot.DateTime;
                        if (dayStartDT <= snapshotDT && snapshotDT <= dayEndDT)
                        {
                            double hour = (snapshotDT - date).TotalHours;
                            if (modified)
                            {
                                AppendHourCnlData(hourCnlDataList, hour, cnlList, snapshot, snapshotDT, nowDT);
                            }
                            else
                            {
                                AppendEmptyHourCnlData(hourCnlDataList, hour);
                            }
                        }
                    }
                }
                else
                {
                    // заполнение данных по целым часам
                    int dayStartHour = curDate > startDate ? 0 : startDT.Hour;
                    int dayEndHour   = curDate < endDate ? 23 : endDT.Hour;

                    for (int dayHour = dayStartHour; dayHour <= dayEndHour; dayHour++)
                    {
                        DateTime            snapshotDT = curDate.AddHours(dayHour);
                        SrezTableLight.Srez snapshot;
                        tblHour.SrezList.TryGetValue(snapshotDT, out snapshot);
                        double hour = (snapshotDT - date).TotalHours;
                        if (modified)
                        {
                            AppendHourCnlData(hourCnlDataList, hour, cnlList, snapshot, snapshotDT, nowDT);
                        }
                        else
                        {
                            AppendEmptyHourCnlData(hourCnlDataList, hour);
                        }
                    }
                }

                curDate = nextDate;
            }

            dataAgeArr = newDataAgeArr;
            return(hourCnlDataList.ToArray());
        }
Пример #39
0
        /// <summary>
        /// �������� ����������������� �������� ������ �� �������� ��� �������� ����� �� ��������� �����
        /// </summary>
        /// <remarks>��� �������� �������� hourTable ����� null ��� dataDT ����� DateTime.MinValue</remarks>
        public string GetCnlVal(SrezTableLight hourTable, int cnlNum, DateTime dateTime, bool showUnit, 
            out string color)
        {
            // ��������� �������� � ������� ������
            double val;
            int stat;

            if (dateTime == DateTime.MinValue || hourTable == null)
                GetCurData(cnlNum, out val, out stat);
            else
                GetHourData(hourTable, cnlNum, dateTime, out val, out stat);

            // �������������� �������� ������
            bool isNumber;
            return FormatCnlVal(val, stat, GetCnlProps(cnlNum), showUnit, true, dateTime, DateTime.Now,
                out isNumber, out color);
        }
Пример #40
0
 /// <summary>
 /// Выполнить действия после обработки новых архивных данных
 /// </summary>
 /// <remarks>Номера каналов упорядочены по возрастанию.
 /// Вычисление дорасчётных каналов архивного среза в момент вызова метода завершено</remarks>
 public virtual void OnArcDataProcessed(int[] cnlNums, SrezTableLight.Srez arcSrez)
 {
 }
Пример #41
0
        /// <summary>
        /// Вычислить дорасчётные каналы
        /// </summary>
        private void CalcDRCnls(List<InCnl> inCnls, SrezTableLight.Srez srez, bool genEvents)
        {
            lock (calculator)
            {
                try
                {
                    procSrez = srez;

                    foreach (InCnl inCnl in inCnls)
                    {
                        int cnlInd = srez.GetCnlIndex(inCnl.CnlNum);

                        if (cnlInd >= 0)
                        {
                            // вычисление новых данных входного канала
                            SrezTableLight.CnlData oldCnlData = srez.CnlData[cnlInd];
                            SrezTableLight.CnlData newCnlData =
                                new SrezTableLight.CnlData(oldCnlData.Val, BaseValues.CnlStatuses.Defined);
                            CalcCnlData(inCnl, oldCnlData, ref newCnlData);

                            // запись новых данных в срез
                            srez.CnlData[cnlInd] = newCnlData;

                            // генерация события
                            if (genEvents)
                                GenEvent(inCnl, oldCnlData, newCnlData);
                        }
                    }
                }
                catch (Exception ex)
                {
                    AppLog.WriteAction((Localization.UseRussian ?
                        "Ошибка при вычислении дорасчётных каналов: " :
                        "Error calculating channels: ") + ex.Message, Log.ActTypes.Exception);
                }
                finally
                {
                    procSrez = null;
                }
            }
        }
Пример #42
0
        /// <summary>
        /// Обработать новые архивные данные
        /// </summary>
        public bool ProcArcData(SrezTableLight.Srez receivedSrez)
        {
            try
            {
                if (serverIsReady)
                {
                    bool result = true;
                    int cnlCnt = receivedSrez == null ? 0 : receivedSrez.CnlNums.Length;

                    if (cnlCnt > 0)
                    {
                        // определение времени, на которое записывются архивные данные
                        DateTime paramSrezDT = receivedSrez.DateTime;
                        DateTime paramSrezDate = paramSrezDT.Date;
                        DateTime nearestMinDT = CalcNearestTime(paramSrezDT, Settings.WriteMinPer);
                        DateTime nearestHrDT = CalcNearestTime(paramSrezDT, Settings.WriteHrPer);

                        // получение кэша таблиц срезов
                        SrezTableCache minCache = Settings.WriteMin || Settings.WriteMinCopy ?
                            GetSrezTableCache(paramSrezDate, SrezTypes.Min) : null;
                        SrezTableCache hrCache =
                            nearestHrDT == paramSrezDT && (Settings.WriteHr || Settings.WriteHrCopy) ?
                                GetSrezTableCache(paramSrezDate, SrezTypes.Hour) : null;
                        SrezTableLight.Srez arcSrez = null;

                        // запись минутных данных
                        if (minCache != null)
                        {
                            lock (minCache)
                            {
                                if (Settings.WriteMin && !WriteReceivedSrez(minCache.SrezTable,
                                    minCache.SrezAdapter, receivedSrez, nearestMinDT, ref arcSrez))
                                    result = false;

                                if (Settings.WriteMinCopy && !WriteReceivedSrez(minCache.SrezTableCopy,
                                    minCache.SrezCopyAdapter, receivedSrez, nearestMinDT, ref arcSrez))
                                    result = false;
                            }
                        }

                        // запись часовых данных
                        if (hrCache != null)
                        {
                            lock (hrCache)
                            {
                                if (Settings.WriteHr && !WriteReceivedSrez(hrCache.SrezTable,
                                    hrCache.SrezAdapter, receivedSrez, nearestHrDT, ref arcSrez))
                                    result = false;

                                if (Settings.WriteHrCopy && !WriteReceivedSrez(hrCache.SrezTableCopy,
                                    hrCache.SrezCopyAdapter, receivedSrez, nearestHrDT, ref arcSrez))
                                    result = false;
                            }
                        }

                        // выполнение действий модулей
                        RaiseOnArcDataProcessed(receivedSrez.CnlNums, arcSrez);
                    }

                    return result;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                AppLog.WriteAction((Localization.UseRussian ?
                    "Ошибка при обработке новых архивных данных: " :
                    "Error processing the new archive data: ") + ex.Message, Log.ActTypes.Exception);
                return false;
            }
        }
Пример #43
0
		public override TaskStatus Run ()
		{
			Info("Start RSSendValues task");


			bool IsIndata = false;

			try {

				if(indata=="file")
				{
					foreach(FileInf fi in SelectFiles())
					{
						SrezTableLight stl = new SrezTableLight ();
						sa.FileName = fi.Path;
						sa.Fill(stl);
						int id = int.Parse (fi.FileName.Split (new char[]{'.'},StringSplitOptions.RemoveEmptyEntries)[1]);
						stls.AddSrez(id,stl.SrezList.Values[0]);
					}
					IsIndata  = true;
				}

				if (indata == "mem")
				{

					foreach(RSServer srv in srvs.GetRSServers())
					{
						stls.AddSrez(srv.Id,srv.GetCurrSrez());
					}
					IsIndata = true;

				}


				if(IsIndata)
				{
					foreach(Cnl cnl in Cnls)
					{
						Argument cArg = new Argument(cnl.ToString(),stls.GetCnlData(cnl.ID,cnl.Num));
						CalcArgs.Add(cArg);
					}
					CalcArgs.AddRange(xArgs);

					List<Cnl> cnls = new List<Cnl>();

					foreach(Argument arg in SendVals)
					{
						PrimitiveElement[] pes = CalcArgs.ToArray();
						arg.addDefinitions(pes);
						Cnl cnl = new Cnl(arg.getArgumentName(),arg.getArgumentValue(),1);
						cnls.Add(cnl);
						arg.removeDefinitions(CalcArgs.ToArray());
					}
					srvs.SendCurrSrez(cnls);
				}
				else{
					Info("No set parametr indata");
				}

				CalcArgs.Clear();
				stls.ClearSrez();
			} catch (ThreadAbortException) {
				throw;
			} catch (Exception ex) {
				InfoFormat ("An error RSSendValues: {0}", ex.Message);
			}
			Info("Task RSSendValues finished");
			return new TaskStatus (Status.Success, false);
		}
Пример #44
0
        /// <summary>
        /// Обработать новые текущие данные
        /// </summary>
        public bool ProcCurData(SrezTableLight.Srez receivedSrez)
        {
            lock (curSrez) lock (calculator)
            {
                try
                {
                    if (serverIsReady)
                    {
                        procSrez = curSrez;
                        int cnlCnt = receivedSrez == null ? 0 : receivedSrez.CnlNums.Length;

                        for (int i = 0; i < cnlCnt; i++)
                        {
                            int cnlNum = receivedSrez.CnlNums[i];
                            int cnlInd = curSrez.GetCnlIndex(cnlNum);
                            InCnl inCnl;

                            if (inCnls.TryGetValue(cnlNum, out inCnl) && cnlInd >= 0) // входной канал существует
                            {
                                if (inCnl.CnlTypeID == BaseValues.CnlTypes.TS ||
                                    inCnl.CnlTypeID == BaseValues.CnlTypes.TI)
                                {
                                    // вычисление новых данных входного канала
                                    SrezTableLight.CnlData oldCnlData = curSrez.CnlData[cnlInd];
                                    SrezTableLight.CnlData newCnlData = receivedSrez.CnlData[i];
                                    CalcCnlData(inCnl, oldCnlData, ref newCnlData);

                                    // расчёт данных для усреднения
                                    if (inCnl.Averaging && newCnlData.Stat > BaseValues.CnlStatuses.Undefined &&
                                        newCnlData.Stat != BaseValues.CnlStatuses.FormulaError &&
                                        newCnlData.Stat != BaseValues.CnlStatuses.Unreliable)
                                    {
                                        minAvgData[cnlInd].Sum += newCnlData.Val;
                                        minAvgData[cnlInd].Cnt++;
                                        hrAvgData[cnlInd].Sum += newCnlData.Val;
                                        hrAvgData[cnlInd].Cnt++;
                                    }

                                    // запись новых данных в текущий срез
                                    curSrez.CnlData[cnlInd] = newCnlData;

                                    // генерация события
                                    GenEvent(inCnl, oldCnlData, newCnlData);

                                    // обновление информации об активности канала
                                    activeDTs[cnlInd] = DateTime.Now;
                                }
                                else if (inCnl.CnlTypeID != BaseValues.CnlTypes.TSDR &&
                                    inCnl.CnlTypeID != BaseValues.CnlTypes.TIDR)
                                {
                                    // запись новых данных минутных и часовых каналов, а также
                                    // количества переключений в текущий срез без вычислений
                                    curSrez.CnlData[cnlInd] = receivedSrez.CnlData[i];
                                }
                            }
                        }

                        // выполнение действий модулей
                        if (cnlCnt > 0)
                            RaiseOnCurDataProcessed(receivedSrez.CnlNums, curSrez);

                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    AppLog.WriteAction((Localization.UseRussian ?
                        "Ошибка при обработке новых текущих данных: " :
                        "Error processing the new current data: ") + ex.Message, Log.ActTypes.Exception);
                    return false;
                }
                finally
                {
                    procSrez = null;
                    curSrezMod = true;
                }
            }
        }
Пример #45
0
        /// <summary>
        /// Вычислить данные входного канала
        /// </summary>
        private void CalcCnlData(InCnl inCnl, SrezTableLight.CnlData oldCnlData, ref SrezTableLight.CnlData newCnlData)
        {
            if (inCnl != null)
            {
                try
                {
                    // вычисление новых данных
                    if (inCnl.CalcCnlData != null)
                        inCnl.CalcCnlData(ref newCnlData);

                    // увеличение счётчика количества переключений
                    if (inCnl.CnlTypeID == BaseValues.CnlTypes.SWCNT &&
                        newCnlData.Stat > BaseValues.CnlStatuses.Undefined)
                    {
                        bool even = (int)oldCnlData.Val % 2 == 0; // старое значение чётное
                        newCnlData.Val = newCnlData.Val < 0 && even || newCnlData.Val >= 0 && !even ?
                            Math.Truncate(oldCnlData.Val) + 1 : Math.Truncate(oldCnlData.Val);
                    }

                    // корректировка нового статуса, если задана проверка границ значения
                    if (newCnlData.Stat == BaseValues.CnlStatuses.Defined &&
                        (inCnl.LimLow < inCnl.LimHigh || inCnl.LimLowCrash < inCnl.LimHighCrash))
                    {
                        newCnlData.Stat = BaseValues.CnlStatuses.Normal;

                        if (inCnl.LimLow < inCnl.LimHigh)
                        {
                            if (newCnlData.Val < inCnl.LimLow)
                                newCnlData.Stat = BaseValues.CnlStatuses.Low;
                            else if (newCnlData.Val > inCnl.LimHigh)
                                newCnlData.Stat = BaseValues.CnlStatuses.High;
                        }

                        if (inCnl.LimLowCrash < inCnl.LimHighCrash)
                        {
                            if (newCnlData.Val < inCnl.LimLowCrash)
                                newCnlData.Stat = BaseValues.CnlStatuses.LowCrash;
                            else if (newCnlData.Val > inCnl.LimHighCrash)
                                newCnlData.Stat = BaseValues.CnlStatuses.HighCrash;
                        }
                    }
                }
                catch
                {
                    newCnlData.Stat = BaseValues.CnlStatuses.FormulaError;
                }
            }
        }
Пример #46
0
        /// <summary>
        /// Записать принятый срез в таблицу архивных срезов
        /// </summary>
        private bool WriteReceivedSrez(SrezTable srezTable, SrezAdapter srezAdapter,
            SrezTableLight.Srez receivedSrez, DateTime srezDT, ref SrezTableLight.Srez arcSrez)
        {
            string fileName = "";

            try
            {
                // получение существующего или создание нового архивного среза
                fileName = srezAdapter.FileName;
                SrezTableCache.FillSrezTable(srezTable, srezAdapter);
                SrezTable.Srez srez = srezTable.GetSrez(srezDT);
                bool addSrez;

                if (srez == null)
                {
                    srez = new SrezTable.Srez(srezDT, srezDescr, receivedSrez);
                    addSrez = true;
                }
                else
                {
                    addSrez = false;
                }

                if (arcSrez == null)
                    arcSrez = srez;

                // изменение архивного среза
                lock (calculator)
                {
                    try
                    {
                        procSrez = srez;
                        int cntCnt = receivedSrez.CnlNums.Length;

                        for (int i = 0; i < cntCnt; i++)
                        {
                            int cnlNum = receivedSrez.CnlNums[i];
                            int cnlInd = srez.GetCnlIndex(cnlNum);
                            InCnl inCnl;

                            if (inCnls.TryGetValue(cnlNum, out inCnl) && cnlInd >= 0 &&
                                (inCnl.CnlTypeID == BaseValues.CnlTypes.TS || inCnl.CnlTypeID == BaseValues.CnlTypes.TI))
                            {
                                // вычисление новых данных входного канала
                                SrezTableLight.CnlData oldCnlData = srez.CnlData[cnlInd];
                                SrezTableLight.CnlData newCnlData = receivedSrez.CnlData[i];
                                if (newCnlData.Stat == BaseValues.CnlStatuses.Defined)
                                    newCnlData.Stat = BaseValues.CnlStatuses.Archival;
                                CalcCnlData(inCnl, oldCnlData, ref newCnlData);

                                // запись новых данных в архивный срез
                                srez.CnlData[cnlInd] = newCnlData;
                            }
                        }
                    }
                    finally
                    {
                        procSrez = null;
                    }
                }

                // вычисление дорасчётных каналов
                CalcDRCnls(drCnls, srez, false);

                if (addSrez)
                    srezTable.AddSrez(srez);
                else
                    srezTable.MarkSrezAsModified(srez);

                // запись изменений таблицы срезов
                srezAdapter.Update(srezTable);
                srezTable.FileModTime = File.GetLastWriteTime(fileName);
                return true;
            }
            catch (Exception ex)
            {
                string fileNameStr = string.IsNullOrEmpty(fileName) ? "" :
                    Environment.NewLine + (Localization.UseRussian ? "Имя файла: " : "Filename: ") + fileName;
                AppLog.WriteAction(string.Format(Localization.UseRussian ?
                    "Ошибка при записи принятого среза в таблицу архивных срезов: {0}{1}" :
                    "Error writing received snapshot in the archive data table: {0}{1}",
                    ex.Message, fileNameStr), Log.ActTypes.Exception);
                return false;
            }
        }
Пример #47
0
        /// <summary>
        /// �������� ������ ������ �������� ����� �� ��������� ������� ������
        /// </summary>
        public void GetHourData(SrezTableLight hourTable, int cnlNum, DateTime dateTime, 
            out double val, out int stat)
        {
            Monitor.Enter(cnlDataLock);
            val = 0.0;
            stat = 0;

            try
            {
                SrezTableLight.Srez srez;
                if (hourTable != null && hourTable.SrezList.TryGetValue(dateTime, out srez))
                {
                    SrezTableLight.CnlData cnlData;
                    bool found = srez.GetCnlData(cnlNum, out cnlData);
                    if (found)
                    {
                        val = cnlData.Val;
                        stat = cnlData.Stat;
                    }
                }
            }
            catch (Exception ex)
            {
                AppData.Log.WriteAction(string.Format(Localization.UseRussian ?
                    "������ ��� ��������� ������ ������ {0} �������� �����: {1}" :
                    "Error getting channel {0} hour data: {1}", cnlNum, ex.Message), Log.ActTypes.Exception);
            }
            finally
            {
                Monitor.Exit(cnlDataLock);
            }
        }