Пример #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       = 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");
            }
        }
Пример #2
0
        /// <summary>
        /// Преобразовать среза параметров в срез входных каналов
        /// </summary>
        private SrezTableLight.Srez ConvertSrez(KPLogic.TagSrez tagSrez)
        {
            List<int> boundIndexes;
            int cnlCnt;

            if (tagSrez == null)
            {
                boundIndexes = null;
                cnlCnt = 0;
            }
            else
            {
                boundIndexes = tagSrez.GetBoundTagIndexes();
                cnlCnt = boundIndexes.Count;
            }

            if (cnlCnt == 0)
            {
                return null;
            }
            else
            {
                SrezTableLight.Srez srez = new SrezTableLight.Srez(tagSrez.DateTime, cnlCnt);

                for (int i = 0; i < cnlCnt; i++)
                {
                    int tagInd = boundIndexes[i];
                    srez.CnlNums[i] = tagSrez.KPTags[tagInd].CnlNum;
                    srez.CnlData[i] = tagSrez.TagData[tagInd];
                }

                return srez;
            }
        }
Пример #3
0
        /// <summary>
        /// Export archived data by downloading it from a file
        /// </summary>
        private void ExportArcDataFromFile(Exporter exporter, DateTime dateTime)
        {
            // loading the table of minute slices from a file
            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));
            }

            // search for a slice for a specified time
            SrezTableLight.Srez srez = srezTable.GetSrez(dateTime);

            // add slice to export queue
            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");
            }
        }
Пример #4
0
        /// <summary>
        /// Экспортировать архивные данные
        /// </summary>
        private void ExportArcData()
        {
            if (ExportParams.ExportArcData)
            {
                DbTransaction       trans = null;
                SrezTableLight.Srez srez  = null;

                try
                {
                    trans = DataSource.Connection.BeginTransaction();
                    DataSource.ExportArcDataCmd.Transaction = trans;

                    for (int i = 0; i < BundleSize; i++)
                    {
                        // извлечение среза из очереди
                        lock (arcSrezQueue)
                        {
                            if (arcSrezQueue.Count > 0)
                            {
                                srez = arcSrezQueue.Dequeue();
                            }
                            else
                            {
                                break;
                            }
                        }

                        // экспорт
                        ExportSrez(DataSource.ExportArcDataCmd, srez);

                        expArcSrezCnt++;
                        exportError = false;
                    }

                    trans.Commit();
                }
                catch (Exception ex)
                {
                    if (trans != null)
                    {
                        trans.Rollback();
                    }

                    // возврат среза в очередь
                    if (srez != null)
                    {
                        lock (arcSrezQueue)
                            arcSrezQueue.Enqueue(srez);
                    }

                    log.WriteAction(string.Format(Localization.UseRussian ?
                                                  "Ошибка при экспорте архивных данных в БД {0}: {1}" :
                                                  "Error export archive data to DB {0}: {1}", DataSource.Name, ex.Message));
                    exportError = true;
                    Thread.Sleep(ErrorDelay);
                }
            }
        }
Пример #5
0
        public bool SetCurrSrez(SrezTableLight.Srez srez)
        {
            bool rec;

            lock (rssrv)
            {
                rec = rssrv.SendSrez(srez, out rec);
            }
            return(rec);
        }
Пример #6
0
        /// <summary>
        /// Получить расширенные текущие данные входных каналов
        /// </summary>
        private CnlDataExt[] GetCurCnlDataExtArr(IList <int> cnlList)
        {
            DateTime dataAge;

            SrezTableLight.Srez snapshot = AppData.DataAccess.DataCache.GetCurSnapshot(out dataAge);

            string emptyVal;
            bool   dataVisible = DataFormatter.CurDataVisible(dataAge, DateTime.Now, out emptyVal);

            return(CreateCnlDataExtArr(cnlList, snapshot, dataVisible, emptyVal));
        }
Пример #7
0
        /// <summary>
        /// Export current data
        /// </summary>
        private void ExportCurData()
        {
            if (ExportParams.ExportCurData)
            {
                DbTransaction       trans = null;
                SrezTableLight.Srez srez  = null;

                try {
                    trans = DataSource.Connection.BeginTransaction();
                    DataSource.ExportCurDataCmd.Transaction = trans;

                    for (var i = 0; i < BundleSize; i++)
                    {
                        // extract slice from the queue
                        lock (curSrezQueue) {
                            if (curSrezQueue.Count > 0)
                            {
                                srez = curSrezQueue.Dequeue();
                            }
                            else
                            {
                                break;
                            }
                        }

                        // export
                        ExportSrez(DataSource.ExportCurDataCmd, srez);

                        expCurSrezCnt++;
                        exportError = false;
                    }

                    trans.Commit();
                } catch (Exception ex) {
                    SafeRollback(trans);

                    // return cut to the queue
                    if (srez != null)
                    {
                        lock (curSrezQueue)
                            curSrezQueue.Enqueue(srez);
                    }

                    log.WriteAction(string.Format(
                                        Localization.UseRussian
                            ? "Ошибка при экспорте текущих данных в БД {0}: {1}"
                            : "Error export current data to DB {0}: {1}", DataSource.Name, ex.Message));
                    exportError = true;
                    Thread.Sleep(ErrorDelay);
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Добавить часовые данные в список
        /// </summary>
        private void AppendHourCnlData(List <HourCnlData> hourCnlDataList, double hour, IList <int> cnlList,
                                       SrezTableLight.Srez snapshot, DateTime snapshotDT, DateTime nowDT)
        {
            HourCnlData hourCnlData = new HourCnlData(hour);

            hourCnlData.Modified = true;

            string emptyVal;
            bool   dataVisible = DataFormatter.HourDataVisible(snapshotDT, nowDT, snapshot != null, out emptyVal);

            hourCnlData.CnlDataExtArr = CreateCnlDataExtArr(cnlList, snapshot, dataVisible, emptyVal);
            hourCnlDataList.Add(hourCnlData);
        }
Пример #9
0
        /// <summary>
        /// Perform actions after processing new current data
        /// </summary>
        public override void OnCurDataProcessed(int[] cnlNums, SrezTableLight.Srez curSrez)
        {
            // export of current data to the database
            if (normalWork)
            {
                // creating an exported slice
                SrezTableLight.Srez srez = new SrezTableLight.Srez(DateTime.Now, cnlNums, curSrez);

                // add slice to export queue
                foreach (var exporter in exporters)
                {
                    exporter.EnqueueCurData(srez);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Выполнить действия после обработки новых текущих данных
        /// </summary>
        public override void OnCurDataProcessed(int[] cnlNums, SrezTableLight.Srez curSrez)
        {
            // экспорт текущих данных в БД
            if (normalWork)
            {
                // создание экпортируемого среза
                SrezTableLight.Srez srez = new SrezTableLight.Srez(DateTime.Now, cnlNums, curSrez);

                // добавление среза в очередь экспорта
                foreach (Exporter exporter in exporters)
                {
                    exporter.EnqueueCurData(srez);
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Выполнить действия после обработки новых архивных данных
        /// </summary>
        public override void OnArcDataProcessed(int[] cnlNums, SrezTableLight.Srez arcSrez)
        {
            // экспорт архивных данных в БД
            if (normalWork)
            {
                // создание экпортируемого среза
                SrezTableLight.Srez srez = new SrezTableLight.Srez(arcSrez.DateTime, cnlNums, arcSrez);

                // добавление среза в очередь экспорта
                foreach (Exporter exporter in exporters)
                {
                    exporter.EnqueueArcData(srez);
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Perform actions after processing new archived data
        /// </summary>
        public override void OnArcDataProcessed(int[] cnlNums, SrezTableLight.Srez arcSrez)
        {
            // export of archive data to the database
            if (normalWork)
            {
                // creating an exported slice
                SrezTableLight.Srez srez = new SrezTableLight.Srez(arcSrez.DateTime, cnlNums, arcSrez);

                // add slice to export queue
                foreach (var exporter in exporters)
                {
                    exporter.EnqueueArcData(srez);
                }
            }
        }
Пример #13
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();
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Экспортировать текущие данные
        /// </summary>
        private void ExportCurData()
        {
            if (ExportParams.ExportCurData)
            {
                SrezTableLight.Srez sres = null;
                try
                {
                    for (int i = 0; i < BundleSize; i++)
                    {
                        // извлечение среза из очереди
                        lock (curSrezQueue)
                        {
                            if (curSrezQueue.Count > 0)
                            {
                                sres = curSrezQueue.Dequeue();
                            }
                            else
                            {
                                break;
                            }
                        }

                        // экспорт
                        ExportSrez(DataSource.ExportCurDataCmd, sres);

                        expCurSrezCnt++;
                        exportError = false;
                    }
                }
                catch (Exception ex)
                {
                    // возврат среза в очередь
                    if (sres != null)
                    {
                        lock (curSrezQueue)
                            curSrezQueue.Enqueue(sres);
                    }

                    log.WriteAction(string.Format(Localization.UseRussian ?
                                                  "Ошибка при экспорте текущих данных в БД {0}: {1}" :
                                                  "Error export current data to DB {0}: {1}", DataSource.Name, ex.Message));
                    exportError = true;
                    Thread.Sleep(ErrorDelay);
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Получить расширенные текущие данные входных каналов
        /// </summary>
        private CnlDataExtDTO[] GetCnlDataExtDTOs(IList <int> cnlList)
        {
            int cnlCnt = cnlList.Count;

            CnlDataExtDTO[] cnlDataDTOs = new CnlDataExtDTO[cnlCnt];

            DataAccess dataAccess = AppData.DataAccess;
            DateTime   dataAge;

            SrezTableLight.Srez snapshot = dataAccess.DataCache.GetCurSnapshot(out dataAge);

            string emptyVal    = "";
            bool   dataVisible = snapshot != null &&
                                 DataFormatter.CurDataVisible(dataAge, DateTime.Now, out emptyVal);

            for (int i = 0; i < cnlCnt; i++)
            {
                int           cnlNum     = cnlList[i];
                CnlDataExtDTO cnlDataDTO = new CnlDataExtDTO(cnlNum);
                cnlDataDTOs[i] = cnlDataDTO;

                SrezTableLight.CnlData cnlData;
                snapshot.GetCnlData(cnlNum, out cnlData);
                cnlDataDTO.Val  = cnlData.Val;
                cnlDataDTO.Stat = cnlData.Stat;

                if (dataVisible)
                {
                    InCnlProps cnlProps = dataAccess.GetCnlProps(cnlNum);
                    string     text;
                    string     textWithUnit;
                    DataFormatter.FormatCnlVal(cnlData.Val, cnlData.Stat, cnlProps, out text, out textWithUnit);

                    cnlDataDTO.Text         = text;
                    cnlDataDTO.TextWithUnit = textWithUnit;
                    cnlDataDTO.Color        = DataFormatter.GetCnlValColor(cnlData.Val, cnlData.Stat, cnlProps,
                                                                           dataAccess.GetColorByStat);
                }
                else
                {
                    cnlDataDTO.Text = cnlDataDTO.TextWithUnit = emptyVal;
                }
            }

            return(cnlDataDTOs);
        }
Пример #16
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));
         }
     }
 }
Пример #17
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));
         }
     }
 }
Пример #18
0
        /// <summary>
        /// Создать срез с заданными номерами каналов, используя данные из исходного среза
        /// </summary>
        private SrezTableLight.Srez CreateSrez(DateTime srezDT, int[] cnlNums, SrezTableLight.Srez sourceSrez)
        {
            int cnlCnt = cnlNums.Length;

            SrezTableLight.Srez srez = new SrezTableLight.Srez(srezDT, cnlCnt);

            for (int i = 0; i < cnlCnt; i++)
            {
                int cnlNum = cnlNums[i];
                SrezTableLight.CnlData cnlData;
                sourceSrez.GetCnlData(cnlNum, out cnlData);

                srez.CnlNums[i] = cnlNum;
                srez.CnlData[i] = cnlData;
            }

            return(srez);
        }
Пример #19
0
        /// <summary>
        /// Создать и заполнить массив расширенных данных входных каналов
        /// </summary>
        private CnlDataExt[] CreateCnlDataExtArr(IList <int> cnlList, SrezTableLight.Srez snapshot,
                                                 bool dataVisible, string emptyVal)
        {
            DataAccess dataAccess = AppData.DataAccess;
            int        cnlCnt     = cnlList == null ? 0 : cnlList.Count;

            CnlDataExt[] cnlDataExtArr = new CnlDataExt[cnlCnt];

            for (int i = 0; i < cnlCnt; i++)
            {
                int        cnlNum     = cnlList[i];
                CnlDataExt cnlDataExt = new CnlDataExt(cnlNum);
                cnlDataExtArr[i] = cnlDataExt;

                if (dataVisible)
                {
                    double val;
                    int    stat;
                    snapshot.GetCnlData(cnlNum, out val, out stat);

                    if (!double.IsNaN(val))
                    {
                        cnlDataExt.Val  = val;
                        cnlDataExt.Stat = stat;
                    }

                    InCnlProps cnlProps = dataAccess.GetCnlProps(cnlNum);
                    string     text;
                    string     textWithUnit;
                    DataFormatter.FormatCnlVal(val, stat, cnlProps, out text, out textWithUnit);

                    cnlDataExt.Text         = text;
                    cnlDataExt.TextWithUnit = textWithUnit;
                    CnlStatProps cnlStatProps = dataAccess.GetCnlStatProps(stat);
                    cnlDataExt.Color = DataFormatter.GetCnlValColor(val, stat, cnlProps, cnlStatProps);
                }
                else
                {
                    cnlDataExt.Text = cnlDataExt.TextWithUnit = emptyVal;
                }
            }

            return(cnlDataExtArr);
        }
Пример #20
0
        /// <summary>
        /// Получить текущие данные входного канала.
        /// </summary>
        public SrezTableLight.CnlData GetCurCnlData(int cnlNum, out DateTime dataAge)
        {
            try
            {
                SrezTableLight.Srez    snapshot = dataCache.GetCurSnapshot(out dataAge);
                SrezTableLight.CnlData cnlData;
                return(snapshot != null && snapshot.GetCnlData(cnlNum, out cnlData) ?
                       cnlData : SrezTableLight.CnlData.Empty);
            }
            catch (Exception ex)
            {
                log.WriteException(ex, Localization.UseRussian ?
                                   "Ошибка при получении текущих данных входного канала {0}" :
                                   "Error getting current data of the input channel {0}", cnlNum);

                dataAge = DateTime.MinValue;
                return(SrezTableLight.CnlData.Empty);
            }
        }
Пример #21
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);
            }
        }
Пример #22
0
        private void btnSend_Click(object sender, EventArgs e)
        {
            // retrieve data to send
            if (!int.TryParse(cbCnlNum.Text, out int cnlNum))
            {
                ScadaUiUtils.ShowError(ServerShellPhrases.IncorrectCnlNum);
                return;
            }

            double cnlVal = ScadaUtils.StrToDouble(txtCnlVal.Text);

            if (double.IsNaN(cnlVal))
            {
                ScadaUiUtils.ShowError(ServerShellPhrases.IncorrectCnlVal);
                return;
            }

            DateTime srezDT = rbCurData.Checked ?
                              DateTime.MinValue :
                              dtpArcDate.Value.Date.Add(dtpArcTime.Value.TimeOfDay);

            SrezTableLight.Srez srez = new SrezTableLight.Srez(srezDT, 1);
            srez.CnlNums[0] = cnlNum;
            srez.CnlData[0] = new SrezTableLight.CnlData(cnlVal, decimal.ToInt32(numCnlStat.Value));

            // send data
            if (rbCurData.Checked ?
                serverComm.SendSrez(srez, out bool result) :
                serverComm.SendArchive(srez, out result))
            {
                cbCnlNum.Items.Remove(cnlNum);
                cbCnlNum.Items.Insert(0, cnlNum);
                DialogResult = DialogResult.OK;
            }
            else
            {
                errLog.WriteError(serverComm.ErrMsg);
                ScadaUiUtils.ShowError(serverComm.ErrMsg);
            }
        }
Пример #23
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;
                ServerCommands.PassCommand(cmd);
            }
        }
Пример #24
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.Value != cnlData.Val)
                 {
                     MqttPT.IsPub = true;
                 }
                 MqttPT.Value = cnlData.Val;
             }
         }
     }
     return(MqttPTs);
 }
Пример #25
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);
            }
        }
Пример #26
0
        /// <summary>
        /// Преобразовать среза параметров в срез входных каналов
        /// </summary>
        private SrezTableLight.Srez ConvertSrez(KPLogic.ParamSrez paramSrez)
        {
            List <int> bindedIndexes;
            int        cnlCnt;

            if (paramSrez == null)
            {
                bindedIndexes = null;
                cnlCnt        = 0;
            }
            else
            {
                bindedIndexes = paramSrez.GetBindedParamIndexes();
                cnlCnt        = bindedIndexes.Count;
            }

            if (cnlCnt == 0)
            {
                return(null);
            }
            else
            {
                SrezTableLight.Srez srez = new SrezTableLight.Srez(paramSrez.DateTime, cnlCnt);

                for (int i = 0; i < cnlCnt; i++)
                {
                    int paramInd = bindedIndexes[i];
                    srez.CnlNums[i] = paramSrez.KPParams[paramInd].CnlNum;
                    KPLogic.ParamData      paramData = paramSrez.Data[paramInd];
                    SrezTableLight.CnlData cnlData   = new SrezTableLight.CnlData(paramData.Val, paramData.Stat);
                    srez.CnlData[i] = cnlData;
                }

                return(srez);
            }
        }
Пример #27
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;
            }
        }
Пример #28
0
        private void btnSendSrez_Click(object sender, EventArgs e)
        {
            // отправка среза SCADA-Серверу
            int cnlNum;
            if (!int.TryParse(cbSrezCnlNum.Text, out cnlNum))
            {
                ScadaUtils.ShowError(AppPhrases.IncorrectCnlNum);
                return;
            }

            double cnlVal = ScadaUtils.StrToDouble(txtSrezCnlVal.Text);
            if (double.IsNaN(cnlVal))
            {
                ScadaUtils.ShowError(AppPhrases.IncorrectCnlVal);
                return;
            }

            DateTime srezDT = rbCurSrez.Checked ? DateTime.MinValue :
                dtpSrezDate.Value.Date.Add(dtpSrezTime.Value.TimeOfDay);
            SrezTableLight.Srez srez = new SrezTableLight.Srez(srezDT, 1);
            srez.CnlNums[0] = cnlNum;
            srez.CnlData[0] = new SrezTableLight.CnlData(cnlVal, decimal.ToInt32(numSrezCnlStat.Value));

            bool result;
            bool sendOk = rbCurSrez.Checked ? ServerComm.SendSrez(srez, out result) :
                ServerComm.SendArchive(srez, out result);

            if (sendOk)
            {
                string cnlNumStr = cbSrezCnlNum.Text.Trim();
                cbSrezCnlNum.Items.Remove(cnlNumStr);
                cbSrezCnlNum.Items.Insert(0, cnlNumStr);
                cbSrezCnlNum.Text = cnlNumStr;
                ScadaUtils.ShowInfo(AppPhrases.SendDataCompleted);
            }
            else
            {
                ScadaUtils.ShowError(ServerComm.ErrMsg);
            }
        }
Пример #29
0
Файл: Comm.cs Проект: iyus/scada
        /// <summary>
        /// Обработать полученную команду
        /// </summary>
        private void ProcCommand(ClientInfo client, byte cmd, int cmdLen)
        {
            bool sendResp = true;    // отправить ответ на команду
            int respDataLen = 0;     // длина данных ответа на команду
            byte[] extraData = null; // дополнительные данные ответа

            switch (cmd)
            {
                case 0x01: // проверка имени и пароля
                    int userNameLen = inBuf[3];
                    string userName = Encoding.Default.GetString(inBuf, 4, userNameLen);
                    string password = Encoding.Default.GetString(inBuf, 5 + userNameLen, inBuf[4 + userNameLen]);
                    bool pwdIsEmpty = string.IsNullOrEmpty(password);
                    int roleID;
                    bool checkOk = CheckUser(userName, password, out roleID);

                    if (client.Authenticated)
                    {
                        if (pwdIsEmpty)
                        {
                            string checkOkStr = checkOk ?
                                (Localization.UseRussian ? "успешно" : "success") :
                                (Localization.UseRussian ? "ошибка" : "error");
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Получение роли пользователя {0}. Результат: {1}" : "Get user {0} role. Result: {1}",
                                userName, checkOkStr), Log.ActTypes.Action);
                        }
                        else
                        {
                            string checkOkStr = checkOk ?
                                (Localization.UseRussian ? "верно" : "passed") :
                                (Localization.UseRussian ? "неверно" : "failed");
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Проверка имени и пароля пользователя {0}. Результат: {1}" :
                                "Check user {0} name and password. Result: {1}",
                                userName, checkOkStr), Log.ActTypes.Action);
                        }
                    }
                    else
                    {
                        if (checkOk && roleID != BaseValues.Roles.Disabled && !pwdIsEmpty)
                        {
                            client.Authenticated = true;
                            client.UserName = userName;
                            client.UserRoleID = roleID;
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Пользователь {0} успешно аутентифицирован" :
                                "The user {0} is successfully authenticated",
                                userName), Log.ActTypes.Action);
                        }
                        else
                        {
                            client.ActivityDT = DateTime.MinValue; // для отключения клиента после отправки ответа
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Неудачная попытка аутентификации пользователя {0}" :
                                "Unsuccessful attempt to authenticate the user {0}",
                                userName), Log.ActTypes.Action);
                        }
                    }

                    respDataLen = 1;
                    outBuf[3] = (byte)roleID;
                    break;
                case 0x02: // запрос состояния сервера (ping)
                    respDataLen = 1;
                    outBuf[3] = mainLogic.ServerIsReady ? (byte)1 : (byte)0;
                    break;
                case 0x03: // запись текущего среза
                    if (client.UserRoleID == BaseValues.Roles.App)
                    {
                        int cnlCnt = BitConverter.ToUInt16(inBuf, 3);
                        SrezTableLight.Srez srez = new SrezTableLight.Srez(DateTime.MinValue, cnlCnt);

                        for (int i = 0, j = 5; i < cnlCnt; i++, j += 14)
                        {
                            srez.CnlNums[i] = (int)BitConverter.ToUInt32(inBuf, j);
                            srez.CnlData[i] = new SrezTableLight.CnlData(
                                BitConverter.ToDouble(inBuf, j + 4),
                                BitConverter.ToUInt16(inBuf, j + 12));
                        }

                        outBuf[3] = mainLogic.ProcCurData(srez) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x04: // запись архивного среза
                    if (client.UserRoleID == BaseValues.Roles.App)
                    {
                        DateTime dateTime = Arithmetic.DecodeDateTime(BitConverter.ToDouble(inBuf, 3));
                        int cnlCnt = BitConverter.ToUInt16(inBuf, 11);
                        SrezTableLight.Srez srez = new SrezTableLight.Srez(dateTime, cnlCnt);

                        for (int i = 0, j = 13; i < cnlCnt; i++, j += 14)
                        {
                            srez.CnlNums[i] = (int)BitConverter.ToUInt32(inBuf, j);
                            srez.CnlData[i] = new SrezTableLight.CnlData(
                                BitConverter.ToDouble(inBuf, j + 4),
                                BitConverter.ToUInt16(inBuf, j + 12));
                        }

                        outBuf[3] = mainLogic.ProcArcData(srez) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x05: // запись события
                    if (client.UserRoleID == BaseValues.Roles.App)
                    {
                        EventTableLight.Event ev = new EventTableLight.Event();
                        ev.DateTime = Arithmetic.DecodeDateTime(BitConverter.ToDouble(inBuf, 3));
                        ev.ObjNum = BitConverter.ToUInt16(inBuf, 11);
                        ev.KPNum = BitConverter.ToUInt16(inBuf, 13);
                        ev.ParamID = BitConverter.ToUInt16(inBuf, 15);
                        ev.CnlNum = (int)BitConverter.ToUInt32(inBuf, 17);
                        ev.OldCnlVal = BitConverter.ToDouble(inBuf, 21);
                        ev.OldCnlStat = BitConverter.ToUInt16(inBuf, 29);
                        ev.NewCnlVal = BitConverter.ToDouble(inBuf, 31);
                        ev.NewCnlStat = BitConverter.ToUInt16(inBuf, 39);
                        ev.Checked = BitConverter.ToBoolean(inBuf, 41);
                        ev.UserID = BitConverter.ToUInt16(inBuf, 42);
                        int evDescrLen = inBuf[44];
                        int evDataLen = inBuf[45 + evDescrLen];
                        ev.Descr = Encoding.Default.GetString(inBuf, 45, evDescrLen);
                        ev.Data = Encoding.Default.GetString(inBuf, 46 + evDescrLen, evDataLen);

                        outBuf[3] = mainLogic.ProcEvent(ev) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x06: // команда ТУ
                    bool cmdProcOk = false; // команда обработана успешно

                    if (client.UserRoleID == BaseValues.Roles.Admin ||
                        client.UserRoleID == BaseValues.Roles.Dispatcher || client.UserRoleID == BaseValues.Roles.App)
                    {
                        int cmdUserID = BitConverter.ToUInt16(inBuf, 3);
                        byte cmdTypeID = inBuf[5];
                        int ctrlCnlNum = BitConverter.ToUInt16(inBuf, 6);
                        MainLogic.CtrlCnl ctrlCnl = mainLogic.GetCtrlCnl(ctrlCnlNum);

                        string notFoundStr = ctrlCnl == null ? Localization.UseRussian ?
                            " (не найден)" : " (not found)" : "";
                        appLog.WriteAction(string.Format(Localization.UseRussian ?
                            "Команда ТУ: канал упр. = {0}{1}, ид. польз. = {2}" :
                            "Command: out channel = {0}{1}, user ID = {2}",
                            ctrlCnlNum, notFoundStr, cmdUserID), Log.ActTypes.Action);

                        if (ctrlCnl != null)
                        {
                            // создание команды ТУ
                            ModLogic.Command ctrlCmd = new ModLogic.Command(cmdTypeID);
                            ctrlCmd.CmdData = new byte[BitConverter.ToUInt16(inBuf, 8)];
                            Array.Copy(inBuf, 10, ctrlCmd.CmdData, 0, ctrlCmd.CmdData.Length);

                            if (cmdTypeID == BaseValues.CmdTypes.Standard || cmdTypeID == BaseValues.CmdTypes.Binary)
                            {
                                ctrlCmd.KPNum = (ushort)ctrlCnl.KPNum;
                                ctrlCmd.CmdNum = (ushort)ctrlCnl.CmdNum;
                                if (cmdTypeID == BaseValues.CmdTypes.Standard && ctrlCmd.CmdData.Length == 8)
                                    ctrlCmd.CmdVal = BitConverter.ToDouble(ctrlCmd.CmdData, 0);
                            }
                            else if (cmdTypeID == BaseValues.CmdTypes.Request)
                            {
                                ctrlCmd.KPNum = BitConverter.ToUInt16(inBuf, 10);
                            }

                            // обработка команды ТУ
                            bool passToClients;
                            mainLogic.ProcCommand(ctrlCnl, ctrlCmd, cmdUserID, out passToClients);

                            // передача команды ТУ подключенным клиентам
                            if (passToClients)
                            {
                                foreach (ClientInfo cl in clients)
                                    if (cl.UserRoleID == BaseValues.Roles.App)
                                        cl.CmdList.Add(ctrlCmd);
                            }
                            else
                            {
                                appLog.WriteAction(Localization.UseRussian ?
                                    "Команда ТУ отменена" : "Command is canceled", Log.ActTypes.Action);
                            }

                            cmdProcOk = true;
                        }
                    }

                    respDataLen = 1;
                    outBuf[3] = cmdProcOk ? (byte)1 : (byte)0;
                    break;
                case 0x07: // запрос команды ТУ
                    if (client.UserRoleID == BaseValues.Roles.App && client.CmdList.Count > 0)
                    {
                        ModLogic.Command ctrlCmd = client.CmdList[0];
                        int cmdDataLen = ctrlCmd.CmdData == null ? 0 : ctrlCmd.CmdData.Length;
                        respDataLen = 7 + cmdDataLen;
                        outBuf[3] = (byte)(cmdDataLen % 256);
                        outBuf[4] = (byte)(cmdDataLen / 256);
                        outBuf[5] = (byte)ctrlCmd.CmdTypeID;
                        outBuf[6] = (byte)(ctrlCmd.KPNum % 256);
                        outBuf[7] = (byte)(ctrlCmd.KPNum / 256);
                        outBuf[8] = (byte)(ctrlCmd.CmdNum % 256);
                        outBuf[9] = (byte)(ctrlCmd.CmdNum / 256);
                        if (cmdDataLen > 0)
                            Array.Copy(ctrlCmd.CmdData, 0, outBuf, 10, cmdDataLen);

                        // удаление команды ТУ из списка команд клиента
                        client.CmdList.RemoveAt(0);
                    }
                    else
                    {
                        respDataLen = 2;
                        outBuf[3] = 0;
                        outBuf[4] = 0;
                    }
                    break;
                case 0x08: // открытие и чтение из файла
                    int readCnt = 0;
                    bool readOk = false;

                    if (client.Authenticated)
                    {
                        client.CloseFile();

                        try { client.Dir = (Dirs)inBuf[3]; }
                        catch { client.Dir = Dirs.Cur; }

                        int fileNameLen = inBuf[4];
                        client.FileName = Encoding.Default.GetString(inBuf, 5, fileNameLen);
                        string fullFileName = GetFullFileName(client.Dir, client.FileName);
                        int count = BitConverter.ToUInt16(inBuf, 5 + fileNameLen);

                        if (settings.DetailedLog)
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Открытие файла {0}" : "Opening file {0}", fullFileName), Log.ActTypes.Action);

                        try
                        {
                            if (File.Exists(fullFileName))
                            {
                                client.FileStream = new FileStream(fullFileName,
                                    FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                                readCnt = client.FileStream.Read(outBuf, 6, count);
                                readOk = true;
                            }
                            else
                            {
                                appLog.WriteAction(string.Format(Localization.UseRussian ?
                                    "Файл {0} не найден." : "File {0} not found.",
                                    client.FullFileNameInfo), Log.ActTypes.Error);
                            }
                        }
                        catch (Exception ex)
                        {
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при работе с файлом {0}: {1}" : "Error working with the file {0}: {1}",
                                client.FullFileNameInfo, ex.Message), Log.ActTypes.Exception);
                        }
                        finally
                        {
                            if (readCnt < count)
                                client.CloseFile();
                        }
                    }

                    respDataLen = 3 + readCnt;
                    outBuf[3] = readOk ? (byte)1 : (byte)0;
                    outBuf[4] = (byte)(readCnt % 256);
                    outBuf[5] = (byte)(readCnt / 256);
                    break;
                case 0x09: // перемещение позиции чтения из файла
                    long pos = 0;
                    bool seekOk = false;

                    if (client.Authenticated && client.FileStream != null)
                    {
                        SeekOrigin origin;
                        try { origin = (SeekOrigin)inBuf[3]; }
                        catch { origin = SeekOrigin.Begin; }
                        long offset = BitConverter.ToUInt32(inBuf, 4);

                        try
                        {
                            pos = client.FileStream.Seek(offset, origin);
                            seekOk = true;
                        }
                        catch (Exception ex)
                        {
                            appLog.WriteAction("Ошибка при работе с файлом " + client.FullFileNameInfo +
                                ": " + ex.Message, Log.ActTypes.Exception);
                        }
                    }

                    respDataLen = 5;
                    outBuf[3] = seekOk ? (byte)1 : (byte)0;
                    Array.Copy(BitConverter.GetBytes((uint)pos), 0, outBuf, 4, 4);
                    break;
                case 0x0A: // чтение из файла
                    readCnt = 0;

                    if (client.Authenticated && client.FileStream != null)
                    {
                        int count = BitConverter.ToUInt16(inBuf, 3);

                        try
                        {
                            readCnt = client.FileStream.Read(outBuf, 5, count);
                        }
                        catch (Exception ex)
                        {
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при работе с файлом {0}: {1}" : "Error working with the file {0}: {1}",
                                client.FullFileNameInfo, ex.Message), Log.ActTypes.Exception);
                        }
                        finally
                        {
                            if (readCnt < count)
                                client.CloseFile();
                        }
                    }

                    respDataLen = 2 + readCnt;
                    outBuf[3] = (byte)(readCnt % 256);
                    outBuf[4] = (byte)(readCnt / 256);
                    break;
                case 0x0B: // закрытие файла
                    if (client.Authenticated && client.FileStream != null)
                    {
                        client.CloseFile();
                        outBuf[3] = 1;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x0C: // запрос времени изменения файлов
                    int fileCnt = inBuf[3];
                    outBuf[3] = inBuf[3];

                    for (int i = 0, j = 4, k = 4; i < fileCnt; i++, k += 8)
                    {
                        Dirs dir;
                        try { dir = (Dirs)inBuf[j++]; }
                        catch { dir = Dirs.Cur; }

                        int fileNameLen = inBuf[j++];
                        string fileName = Encoding.Default.GetString(inBuf, j, fileNameLen);
                        string fullFileName = GetFullFileName(dir, fileName);
                        j += fileNameLen;

                        if (settings.DetailedLog)
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Получение времени изменения файла {0}" :
                                "Obtaining the modification time of the file {0}", fullFileName), Log.ActTypes.Action);

                        double fileModTime;
                        try
                        {
                            fileModTime = File.Exists(fullFileName) ?
                                Arithmetic.EncodeDateTime(File.GetLastWriteTime(fullFileName)) : 0;
                        }
                        catch { fileModTime = 0; }

                        Array.Copy(BitConverter.GetBytes(fileModTime), 0, outBuf, k, 8);
                    }

                    respDataLen = 1 + 8 * fileCnt;
                    break;
                case 0x0D: // запрос данных из таблицы среза
                    byte srezTypeNum = inBuf[3];
                    MainLogic.SrezTypes srezType;
                    DateTime srezDate;

                    if (srezTypeNum == 0x01)
                    {
                        srezType = MainLogic.SrezTypes.Cur;
                        srezDate = DateTime.MinValue;
                    }
                    else
                    {
                        srezType = srezTypeNum == 0x02 ? MainLogic.SrezTypes.Hour : MainLogic.SrezTypes.Min;
                        srezDate = new DateTime(inBuf[4] + 2000, inBuf[5], inBuf[6]);
                    }

                    int cnlNumCnt = BitConverter.ToUInt16(inBuf, 7);
                    int[] cnlNums = new int[cnlNumCnt];

                    for (int i = 0, j = 9; i < cnlNumCnt; i++, j += 4)
                        cnlNums[i] = (int)BitConverter.ToUInt32(inBuf, j);

                    if (settings.DetailedLog)
                    {
                        string srezTypeStr;
                        if (srezType == MainLogic.SrezTypes.Cur)
                            srezTypeStr = Localization.UseRussian ? "текущие" : "current";
                        else if (srezType == MainLogic.SrezTypes.Min)
                            srezTypeStr = Localization.UseRussian ? "минутные" : "minute";
                        else
                            srezTypeStr = Localization.UseRussian ? "часовые" : "hourly";

                        appLog.WriteAction(string.Format(Localization.UseRussian ?
                            "Запрос данных. Тип: {0}. Дата: {1}. Каналы: {2}" :
                            "Data request. Type: {0}. Date: {1}. Channels: {2}",
                            srezTypeStr, srezDate.ToString("d", Localization.Culture), string.Join(", ", cnlNums)),
                            Log.ActTypes.Action);
                    }

                    SrezTableLight srezTable = mainLogic.GetSrezTable(srezDate, srezType, cnlNums);
                    int srezCnt = srezTable == null ? 0 : srezTable.SrezList.Count;
                    outBuf[5] = (byte)(srezCnt % 256);
                    outBuf[6] = (byte)(srezCnt / 256);
                    extraData = new byte[srezCnt * (10 * cnlNumCnt + 8)];

                    for (int i = 0, j = 0; i < srezCnt; i++)
                    {
                        SrezTableLight.Srez srez = srezTable.SrezList.Values[i];
                        Array.Copy(BitConverter.GetBytes(Arithmetic.EncodeDateTime(srez.DateTime)), 0, extraData, j, 8);
                        j += 8;

                        for (int k = 0; k < cnlNumCnt; k++)
                        {
                            SrezTable.CnlData cnlData = srez.CnlData[k];
                            Array.Copy(BitConverter.GetBytes(cnlData.Val), 0, extraData, j, 8);
                            j += 8;
                            extraData[j++] = (byte)(cnlData.Stat % 256);
                            extraData[j++] = (byte)(cnlData.Stat / 256);
                        }
                    }

                    respDataLen = 2 + extraData.Length;
                    break;
                case 0x0E: // квитирование события
                    if (client.Authenticated)
                    {
                        int evUserID = BitConverter.ToUInt16(inBuf, 3);
                        DateTime evDate = new DateTime(inBuf[5] + 2000, inBuf[6], inBuf[7]);
                        int evNum = BitConverter.ToUInt16(inBuf, 8);
                        outBuf[3] = mainLogic.CheckEvent(evDate, evNum, evUserID) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
            }

            // передача ответа на команду
            if (sendResp)
            {
                if (cmd == 0x0D)
                {
                    int respLen = 5 + respDataLen;
                    Array.Copy(BitConverter.GetBytes((uint)respLen), 0, outBuf, 0, 4);
                    outBuf[4] = cmd;
                    client.NetStream.Write(outBuf, 0, 7);
                }
                else
                {
                    int respLen = 3 + respDataLen;
                    Array.Copy(BitConverter.GetBytes((ushort)respLen), 0, outBuf, 0, 2);
                    outBuf[2] = cmd;
                    client.NetStream.Write(outBuf, 0, respLen);
                }

                if (extraData != null && extraData.Length > 0)
                    client.NetStream.Write(extraData, 0, extraData.Length);
            }
        }
Пример #30
0
        /// <summary>
        /// Преобразовать среза параметров в срез входных каналов
        /// </summary>
        private SrezTableLight.Srez ConvertSrez(KPLogic.ParamSrez paramSrez)
        {
            List<int> bindedIndexes;
            int cnlCnt;

            if (paramSrez == null)
            {
                bindedIndexes = null;
                cnlCnt = 0;
            }
            else
            {
                bindedIndexes = paramSrez.GetBindedParamIndexes();
                cnlCnt = bindedIndexes.Count;
            }

            if (cnlCnt == 0)
            {
                return null;
            }
            else
            {
                SrezTableLight.Srez srez = new SrezTableLight.Srez(paramSrez.DateTime, cnlCnt);

                for (int i = 0; i < cnlCnt; i++)
                {
                    int paramInd = bindedIndexes[i];
                    srez.CnlNums[i] = paramSrez.KPParams[paramInd].CnlNum;
                    KPLogic.ParamData paramData = paramSrez.Data[paramInd];
                    SrezTableLight.CnlData cnlData = new SrezTableLight.CnlData(paramData.Val, paramData.Stat);
                    srez.CnlData[i] = cnlData;
                }

                return srez;
            }
        }
Пример #31
0
        /// <summary>
        /// Заполнить объект dest из файла срезов FileName
        /// </summary>
        protected void FillObj(object dest)
        {
            Stream stream = null;
            BinaryReader reader = null;
            DateTime fillTime = DateTime.Now;

            SrezTableLight srezTableLight = dest as SrezTableLight;
            DataTable dataTable = dest as DataTable;
            Trend trend = dest as Trend;

            SrezTable srezTable = srezTableLight as SrezTable;
            SrezTableLight.Srez lastStoredSrez = null;

            try
            {
                if (srezTableLight == null && dataTable == null && trend == null)
                    throw new Exception("Destination object is invalid.");

                // подготовка объекта для хранения данных
                if (srezTableLight != null)
                {
                    srezTableLight.Clear();
                    srezTableLight.TableName = tableName;

                    if (srezTable != null)
                        srezTable.BeginLoadData();
                }
                else if (dataTable != null)
                {
                    // формирование структуры таблицы
                    dataTable.BeginLoadData();
                    dataTable.DefaultView.Sort = "";

                    if (dataTable.Columns.Count == 0)
                    {
                        dataTable.Columns.Add("DateTime", typeof(DateTime));
                        dataTable.Columns.Add("CnlNum", typeof(int));
                        dataTable.Columns.Add("Val", typeof(double));
                        dataTable.Columns.Add("Stat", typeof(int));
                        dataTable.DefaultView.AllowNew = false;
                        dataTable.DefaultView.AllowEdit = false;
                        dataTable.DefaultView.AllowDelete = false;
                    }
                    else
                    {
                        dataTable.Rows.Clear();
                    }
                }
                else // trend != null
                {
                    trend.Clear();
                    trend.TableName = tableName;
                }

                // заполнение объекта данными
                stream = ioStream == null ?
                    new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) :
                    ioStream;
                reader = new BinaryReader(stream);

                DateTime date = Arithmetic.ExtractDate(tableName); // определение даты срезов
                SrezTable.SrezDescr srezDescr = null;              // описание среза
                int[] cnlNums = null; // ссылка на номера входных каналов из описания среза
                while (stream.Position < stream.Length)
                {
                    // считывание списка номеров каналов и КС
                    int cnlNumCnt = reader.ReadUInt16();
                    if (cnlNumCnt > 0)
                    {
                        // загрузка номеров каналов в буфер для увеличения скорости работы
                        int cnlNumSize = cnlNumCnt * 2;
                        byte[] buf = new byte[cnlNumSize];
                        int readSize = reader.Read(buf, 0, cnlNumSize);

                        // создание описания среза и заполнение номеров каналов из буфера
                        // с проверкой их уникальности и упорядоченности
                        if (readSize == cnlNumSize)
                        {
                            int prevCnlNum = -1;
                            srezDescr = new SrezTable.SrezDescr(cnlNumCnt);
                            cnlNums = srezDescr.CnlNums;
                            for (int i = 0; i < cnlNumCnt; i++)
                            {
                                int cnlNum = BitConverter.ToUInt16(buf, i * 2);
                                if (prevCnlNum >= cnlNum)
                                    throw new Exception("Table is incorrect.");
                                cnlNums[i] = prevCnlNum = cnlNum;
                            }
                            srezDescr.CalcCS();
                        }
                    }
                    else if (srezDescr == null)
                    {
                        throw new Exception("Table is incorrect.");
                    }

                    // считывание и проверка КС
                    ushort cs = reader.ReadUInt16();
                    bool csOk = cnlNumCnt > 0 ? srezDescr.CS == cs : cs == 1;

                    // считывание данных среза
                    int cnlCnt = cnlNums.Length;   // количество каналов в срезе
                    int srezDataSize = cnlCnt * 9; // размер данных среза
                    if (csOk)
                    {
                        long srezPos = stream.Position;
                        double time = reader.ReadDouble();
                        int hour, min, sec;
                        Arithmetic.DecodeTime(time, out hour, out min, out sec);
                        DateTime srezDT = new DateTime(date.Year, date.Month, date.Day, hour, min, sec);

                        // инициализация нового среза
                        SrezTableLight.Srez srez;
                        if (srezTable != null)
                        {
                            srez = new SrezTable.Srez(srezDT, srezDescr)
                            {
                                State = DataRowState.Unchanged,
                                Position = srezPos
                            };
                        }
                        else if (srezTableLight != null)
                        {
                            srez = new SrezTableLight.Srez(srezDT, cnlCnt);
                            cnlNums.CopyTo(srez.CnlNums, 0);
                        }
                        else // srezTableLight == null
                        {
                            srez = null;
                        }

                        // считывание данных входных каналов
                        int bufInd = 0;
                        double val;
                        byte stat;
                        if (trend != null)
                        {
                            // выбор данных требуемого канала для тренда
                            int index = Array.BinarySearch<int>(cnlNums, trend.CnlNum);
                            if (index >= 0)
                            {
                                stream.Seek(index * 9, SeekOrigin.Current);
                                byte[] buf = new byte[9];
                                int readSize = reader.Read(buf, 0, 9);
                                if (readSize == 9)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);
                                    Trend.Point point = new Trend.Point(srezDT, val, stat);
                                    trend.Points.Add(point);
                                    stream.Seek(srezDataSize - (index + 1) * 9, SeekOrigin.Current);
                                }
                            }
                            else
                            {
                                stream.Seek(srezDataSize, SeekOrigin.Current);
                            }
                        }
                        else
                        {
                            // загрузка данных среза в буфер для увеличения скорости работы
                            byte[] buf = new byte[srezDataSize];
                            int readSize = reader.Read(buf, 0, srezDataSize);

                            // заполение таблицы срезов из буфера
                            if (srezTableLight != null)
                            {
                                for (int i = 0; i < cnlCnt; i++)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);

                                    srez.CnlNums[i] = cnlNums[i];
                                    srez.CnlData[i].Val = val;
                                    srez.CnlData[i].Stat = stat;

                                    if (bufInd >= readSize)
                                        break;
                                }

                                srezTableLight.AddSrez(srez);
                                lastStoredSrez = srez;
                            }
                            else // dataTable != null
                            {
                                for (int i = 0; i < cnlCnt; i++)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);

                                    DataRow row = dataTable.NewRow();
                                    row["DateTime"] = srezDT;
                                    row["CnlNum"] = cnlNums[i];
                                    row["Val"] = val;
                                    row["Stat"] = stat;
                                    dataTable.Rows.Add(row);

                                    if (bufInd >= readSize)
                                        break;
                                }
                            }
                        }
                    }
                    else
                    {
                        // пропустить срез, считая его размер так, как при повторяющемся списке номеров каналов
                        stream.Seek(srezDataSize + 8, SeekOrigin.Current);
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // нормальная ситуация окончания файла
            }
            catch
            {
                fillTime = DateTime.MinValue;
                throw;
            }
            finally
            {
                if (fileMode)
                {
                    if (reader != null)
                        reader.Close();
                    if (stream != null)
                        stream.Close();
                }

                if (srezTableLight != null)
                {
                    srezTableLight.LastFillTime = fillTime;
                    if (srezTable != null)
                    {
                        srezTable.LastStoredSrez = (SrezTable.Srez)lastStoredSrez;
                        srezTable.EndLoadData();
                    }
                }
                else if (dataTable != null)
                {
                    dataTable.EndLoadData();
                    dataTable.AcceptChanges();
                    dataTable.DefaultView.Sort = "DateTime, CnlNum";
                }
                else if (trend != null)
                {
                    trend.LastFillTime = fillTime;
                    trend.Sort();
                }
            }
        }
Пример #32
0
 /// <summary>
 /// Выполнить действия после обработки новых архивных данных
 /// </summary>
 /// <remarks>
 /// Номера каналов упорядочены по возрастанию.
 /// Вычисление дорасчётных каналов архивного среза в момент вызова метода завершено.
 /// Параметр arcSrez равен null, если запись архивных срезов отключена
 /// </remarks>
 public virtual void OnArcDataProcessed(int[] cnlNums, SrezTableLight.Srez arcSrez)
 {
 }
Пример #33
0
 /// <summary>
 /// Выполнить действия после вычисления дорасчётных каналов текущего среза
 /// </summary>
 /// <remarks>Номера каналов упорядочены по возрастанию</remarks>
 public virtual void OnCurDataCalculated(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
 }
Пример #34
0
 /// <summary>
 /// Выполнить действия после обработки новых текущих данных
 /// </summary>
 /// <remarks>Номера каналов упорядочены по возрастанию.
 /// Вычисление дорасчётных каналов текущего среза в момент вызова метода не выполнено</remarks>
 public virtual void OnCurDataProcessed(int[] cnlNums, SrezTableLight.Srez curSrez)
 {
 }
Пример #35
0
        /// <summary>
        /// Exports the specified snapshot.
        /// </summary>
        private bool ExportSnapshot(SrezTableLight.Srez snapshot, DbTransaction trans,
                                    IEnumerable <DataTrigger> dataTriggers)
        {
            Trigger currentTrigger = null;

            try
            {
                int firstCnlNum = snapshot.CnlNums.Length > 0 ? snapshot.CnlNums[0] : 0;
                entityMap.DeviceByCnlNum.TryGetValue(firstCnlNum, out int deviceNum);

                foreach (DataTrigger trigger in dataTriggers)
                {
                    currentTrigger = trigger;

                    if ((trigger.CnlNums.Count == 0 || trigger.CnlNums.Overlaps(snapshot.CnlNums)) &&
                        (trigger.DeviceNums.Count == 0 || trigger.DeviceNums.Contains(deviceNum)))
                    {
                        DbCommand cmd = trigger.Command;
                        cmd.Transaction             = trans;
                        trigger.DateTimeParam.Value = snapshot.DateTime;
                        trigger.KpNumParam.Value    = deviceNum;

                        if (trigger.DataTriggerOptions.SingleQuery)
                        {
                            if (trigger.CnlNums.Count > 0)
                            {
                                foreach (int cnlNum in trigger.CnlNums)
                                {
                                    SrezTableLight.CnlData cnlData = snapshot.GetCnlData(cnlNum);
                                    trigger.SetValParam(cnlNum, cnlData.Val);
                                    trigger.SetStatParam(cnlNum, cnlData.Stat);
                                }

                                cmd.ExecuteNonQuery();
                            }
                        }
                        else
                        {
                            void ExportDataPoint(int cnlNum)
                            {
                                SrezTableLight.CnlData cnlData = snapshot.GetCnlData(cnlNum);
                                trigger.CnlNumParam.Value = cnlNum;
                                trigger.ValParam.Value    = cnlData.Val;
                                trigger.StatParam.Value   = cnlData.Stat;
                                cmd.ExecuteNonQuery();
                            }

                            if (trigger.CnlNums.Count > 0)
                            {
                                foreach (int cnlNum in snapshot.CnlNums)
                                {
                                    if (trigger.CnlNums.Contains(cnlNum))
                                    {
                                        ExportDataPoint(cnlNum);
                                    }
                                }
                            }
                            else
                            {
                                foreach (int cnlNum in snapshot.CnlNums)
                                {
                                    ExportDataPoint(cnlNum);
                                }
                            }
                        }
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                log.WriteException(ex, Localization.UseRussian ?
                                   "Ошибка при экспорте среза по триггеру \"{0}\"" :
                                   "Error export snapshot by the trigger \"{0}\"",
                                   currentTrigger?.Options?.Name ?? "");
                return(false);
            }
        }
Пример #36
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;
                }
            }
        }
Пример #37
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;
                }
            }
        }
Пример #38
0
        /// <summary>
        /// Обработать команду ТУ
        /// </summary>
        public void ProcCommand(CtrlCnl ctrlCnl, Command cmd, int userID, out bool passToClients)
        {
            passToClients = false;

            if (serverIsReady && ctrlCnl != null)
            {
                int ctrlCnlNum = ctrlCnl.CtrlCnlNum;

                // вычисление значения или данных команды по формуле канала управления
                if (ctrlCnl.CalcCmdVal != null)
                {
                    // вычисление значения стандартной команды
                    lock (curSrez) lock (calculator)
                    {
                        try
                        {
                            procSrez = curSrez; // необходимо для работы формул Val(n) и Stat(n)
                            double cmdVal = cmd.CmdVal;
                            ctrlCnl.CalcCmdVal(ref cmdVal);
                            cmd.CmdVal = cmdVal;
                            passToClients = !double.IsNaN(cmdVal);
                        }
                        catch (Exception ex)
                        {
                            AppLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при вычислении значения стандартной команды для канала управления {0}: {1}" :
                                "Error calculating standard command value for the output channel {0}: {1}",
                                ctrlCnlNum, ex.Message), Log.ActTypes.Error);
                            cmd.CmdVal = double.NaN;
                        }
                        finally
                        {
                            procSrez = null;
                        }
                    }
                }
                else if (ctrlCnl.CalcCmdData != null)
                {
                    // вычисление данных бинарной команды
                    lock (curSrez) lock (calculator)
                    {
                        try
                        {
                            procSrez = curSrez;
                            byte[] cmdData = cmd.CmdData;
                            ctrlCnl.CalcCmdData(ref cmdData);
                            cmd.CmdData = cmdData;
                            passToClients = cmdData != null;
                        }
                        catch (Exception ex)
                        {
                            AppLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при вычислении данных бинарной команды для канала управления {0}: {1}" :
                                "Error calculating binary command data for the output channel {0}: {1}",
                                ctrlCnlNum, ex.Message), Log.ActTypes.Error);
                            cmd.CmdVal = double.NaN;
                        }
                        finally
                        {
                            procSrez = null;
                        }
                    }
                }
                else
                {
                    passToClients = true;
                }

                // выполнение действий модулей после приёма команды
                RaiseOnCommandReceived(ctrlCnlNum, cmd, userID, ref passToClients);

                // создание события
                if (passToClients && ctrlCnl.EvEnabled)
                {
                    EventTableLight.Event ev = new EventTableLight.Event();
                    ev.DateTime = DateTime.Now;
                    ev.ObjNum = ctrlCnl.ObjNum;
                    ev.KPNum = ctrlCnl.KPNum;
                    ev.Descr = cmd.GetCmdDescr(ctrlCnlNum, userID);

                    // запись события и выполнение действий модулей
                    WriteEvent(ev);
                }
            }
        }
Пример #39
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);
 }
Пример #40
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;
            }
        }
Пример #41
0
        /// <summary>
        /// Создать срез с заданными номерами каналов, используя данные из исходного среза
        /// </summary>
        private SrezTableLight.Srez CreateSrez(DateTime srezDT, int[] cnlNums, SrezTableLight.Srez sourceSrez)
        {
            int cnlCnt = cnlNums.Length;
            SrezTableLight.Srez srez = new SrezTableLight.Srez(srezDT, cnlCnt);

            for (int i = 0; i < cnlCnt; i++)
            {
                int cnlNum = cnlNums[i];
                SrezTableLight.CnlData cnlData;
                sourceSrez.GetCnlData(cnlNum, out cnlData);

                srez.CnlNums[i] = cnlNum;
                srez.CnlData[i] = cnlData;
            }

            return srez;
        }