Exemple #1
0
        /// <summary>
        /// Принять команду от SCADA-Сервера
        /// </summary>
        public bool ReceiveCommand(out KPLogic.Command cmd)
        {
            int kpNum;
            int cmdNum;
            double cmdVal;
            byte[] cmdData;

            if (ReceiveCommand(out kpNum, out cmdNum, out cmdVal, out cmdData))
            {
                cmd = new KPLogic.Command();
                cmd.CmdType = cmdData == null ?
                    (double.IsNaN(cmdVal) ? KPLogic.CmdType.Request : KPLogic.CmdType.Standard) :
                    KPLogic.CmdType.Binary;
                cmd.KPNum = kpNum;
                cmd.CmdNum = cmdNum;
                if (cmd.CmdType == KPLogic.CmdType.Standard)
                    cmd.CmdVal = cmdVal;
                else if (cmd.CmdType == KPLogic.CmdType.Binary)
                    cmd.CmdData = cmdData;
                return true;
            }
            else
            {
                cmd = null;
                return false;
            }
        }
Exemple #2
0
        /// <summary>
        /// Инициализировать канал связи
        /// </summary>
        /// <remarks>В случае исключения дальнейшая работа линии связи невозможна</remarks>
        public virtual void Init(SortedList <string, string> commCnlParams, List <KPLogic> kpList)
        {
            // проверка аргументов метода
            if (commCnlParams == null)
            {
                throw new ArgumentNullException("commCnlParams");
            }
            if (kpList == null)
            {
                throw new ArgumentNullException("kpList");
            }

            // копирование ссылок на КП линии связи
            foreach (KPLogic kpLogic in kpList)
            {
                if (kpLogic == null)
                {
                    throw new ArgumentException("All the devices must not be null.");
                }

                this.kpList.Add(kpLogic);
            }

            kpListNotEmpty = kpList.Count > 0;
            firstKP        = kpListNotEmpty ? kpList[0] : null;
        }
        /// <summary>
        /// Цикл приёма данных по общему соединению в режиме ведомого (метод вызывается в отдельном потоке)
        /// </summary>
        protected void ListenSharedConn()
        {
            try
            {
                while (!terminated)
                {
                    if (sharedTcpConn.TcpClient.Available > 0)
                    {
                        KPLogic targetKP = null;
                        if (!ExecProcUnreadIncomingReq(firstKP, sharedTcpConn, ref targetKP))
                        {
                            sharedTcpConn.ClearNetStream(inBuf);
                        }
                    }

                    Thread.Sleep(SlaveThreadDelay);
                }
            }
            catch (Exception ex)
            {
                // данное исключение возникать не должно
                if (Localization.UseRussian)
                {
                    WriteToLog("Ошибка при приёме данных по общему соединению: " + ex.Message);
                    WriteToLog("Приём данных прекращён");
                }
                else
                {
                    WriteToLog("Error receiving data via shared connection: " + ex.Message);
                    WriteToLog("Data receiving is terminated");
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Обработать принятые по UDP данные
        /// </summary>
        protected void UdpReceiveCallback(IAsyncResult ar)
        {
            // приём данных
            byte[] buf;
            try
            {
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                buf = udpConn.UdpClient.EndReceive(ar, ref remoteEP);
                udpConn.RemoteAddress = remoteEP.Address.ToString();
                udpConn.RemotePort    = remoteEP.Port;
                WriteToLog("");
                WriteToLog(string.Format(Localization.UseRussian ?
                                         "{0} Получены данные от {1}:{2}" :
                                         "{0} Data received from {1}:{2}",
                                         CommUtils.GetNowDT(), udpConn.RemoteAddress, udpConn.RemotePort));

                if (buf == null)
                {
                    WriteToLog(Localization.UseRussian ?
                               "Данные пусты" :
                               "Data is empty");
                }
            }
            catch (Exception ex)
            {
                buf = null;
                WriteToLog(string.Format(Localization.UseRussian ?
                                         "Ошибка при приёме данных: {0}" :
                                         "Error receiving data: {0}", ex.Message));
            }

            if (buf != null && kpListNotEmpty)
            {
                if (settings.DevSelMode == DeviceSelectionModes.ByIPAddress)
                {
                    KPLogic kpLogic;
                    if (kpCallNumDict.TryGetValue(udpConn.RemoteAddress, out kpLogic))
                    {
                        // обработка входящего запроса для определённого КП
                        ExecProcIncomingReq(kpLogic, buf, 0, buf.Length, ref kpLogic);
                    }
                    else
                    {
                        WriteToLog(string.Format(Localization.UseRussian ?
                                                 "{0} Не удалось найти КП по IP-адресу {1}" :
                                                 "{0} Unable to find device by IP address {1}",
                                                 CommUtils.GetNowDT(), udpConn.RemoteAddress));
                    }
                }
                else // DeviceSelectionModes.ByDeviceLibrary
                {
                    // обработка входящего запроса для произвольного КП
                    KPLogic targetKP = null;
                    ExecProcIncomingReq(firstKP, buf, 0, buf.Length, ref targetKP);
                }
            }

            StartUdpReceive();
        }
Exemple #5
0
 /// <summary>
 /// Выполнить действия перед сеансом опроса КП или отправкой команды
 /// </summary>
 public override void BeforeSession(KPLogic kpLogic)
 {
     // открытие последовательного порта, если он закрыт
     if (serialConn != null && !serialConn.Connected)
     {
         OpenSerialPort();
     }
 }
Exemple #6
0
 /// <summary>
 /// Выполнить действия после сеанса опроса КП или отправки команды
 /// </summary>
 public override void AfterSession(KPLogic kpLogic)
 {
     // закрытие последовательного порта, если произошла ошибка записи в порт
     if (serialConn != null && serialConn.Connected && serialConn.WriteError)
     {
         CloseSerialPort();
     }
 }
Exemple #7
0
 /// <summary>
 /// Выполнить действия перед сеансом опроса КП или отправкой команды
 /// </summary>
 public override void BeforeSession(KPLogic kpLogic)
 {
     if (udpConn != null && Behavior == OperatingBehaviors.Master)
     {
         udpConn.RemoteAddress = string.IsNullOrEmpty(kpLogic.CallNum) ?
                                 settings.RemoteIpAddress : kpLogic.CallNum;
     }
 }
Exemple #8
0
        /// <summary>
        /// Обработать событие приёма данных по последовательному порту
        /// </summary>
        protected void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            KPLogic targetKP = null;

            if (!ExecProcUnreadIncomingReq(kpList[0], serialConn, ref targetKP))
            {
                serialConn.DiscardInBuffer();
            }
        }
Exemple #9
0
 /// <summary>
 /// Конструктор
 /// </summary>
 public CommChannelLogic()
 {
     writeToLog     = text => { }; // заглушка
     kpList         = new List <KPLogic>();
     kpListNotEmpty = false;
     firstKP        = null;
     thread         = null;
     terminated     = false;
 }
Exemple #10
0
 /// <summary>
 /// Выполнить действия после сеанса опроса КП или отправки команды
 /// </summary>
 public override void AfterSession(KPLogic kpLogic)
 {
     // очистка буфера неполностью считанной датаграммы, если сеанс опроса КП завершён с ошибкой
     if (kpLogic.WorkState == KPLogic.WorkStates.Error && Behavior == OperatingBehaviors.Master)
     {
         UdpConnection udpConn = kpLogic.Connection as UdpConnection;
         if (udpConn != null && udpConn.Connected)
         {
             udpConn.ClearDatagramBuffer();
         }
     }
 }
Exemple #11
0
 /// <summary>
 /// Выполнить действия после сеанса опроса КП или отправки команды
 /// </summary>
 public override void AfterSession(KPLogic kpLogic)
 {
     // очистка потока данных, если сеанс опроса КП завершён с ошибкой
     if (kpLogic.WorkState == KPLogic.WorkStates.Error && Behavior == OperatingBehaviors.Master)
     {
         TcpConnection tcpConn = kpLogic.Connection as TcpConnection;
         if (tcpConn != null && tcpConn.Connected)
         {
             tcpConn.ClearNetStream(inBuf);
         }
     }
 }
Exemple #12
0
 /// <summary>
 /// Обработать доступные данные в режиме соединения Shared
 /// </summary>
 protected void ProcAvailableDataShared(TcpConnection tcpConn)
 {
     // обработка входящего запроса в режиме ведомого для произвольного КП
     if (tcpConn == sharedTcpConn && slaveBehavior && firstKP != null)
     {
         KPLogic targetKP = null;
         if (!ExecProcUnreadIncomingReq(firstKP, tcpConn, ref targetKP))
         {
             tcpConn.ClearNetStream(inBuf);
         }
     }
 }
Exemple #13
0
        /// <summary>
        /// Установить соединение для КП
        /// </summary>
        protected void SetConnection(KPLogic kpLogic, TcpConnection tcpConn)
        {
            TcpConnection existingTcpConn = kpLogic.Connection as TcpConnection;

            if (existingTcpConn != null)
            {
                existingTcpConn.Broken = true;
                existingTcpConn.ClearRelatedKPs();
            }

            kpLogic.Connection = tcpConn;
            tcpConn.AddRelatedKP(kpLogic);
        }
Exemple #14
0
        /// <summary>
        /// Выполнить действия перед сеансом опроса КП или отправкой команды
        /// </summary>
        public override void BeforeSession(KPLogic kpLogic)
        {
            // установка соединения при необходимости
            TcpConnection tcpConn = kpLogic.Connection as TcpConnection;

            if (tcpConn != null && !tcpConn.Connected)
            {
                string reason;
                if (tcpConn.CanOpen(out reason))
                {
                    try
                    {
                        // определение IP-адреса и TCP-порта
                        string host;
                        int    port;

                        if (tcpConn == sharedTcpConn)
                        {
                            host = settings.Host;
                            port = settings.TcpPort;
                        }
                        else
                        {
                            CommUtils.ExtractHostAndPort(kpLogic.CallNum, settings.TcpPort, out host, out port);
                        }

                        // установка соединения
                        WriteToLog("");
                        WriteToLog(string.Format(Localization.UseRussian ?
                                                 "{0} Установка TCP-соединения с {1}:{2}" :
                                                 "{0} Establish a TCP connection with {1}:{2}", CommUtils.GetNowDT(), host, port));

                        if (tcpConn.NetStream != null) // соединение уже было открыто, но разорвано
                        {
                            tcpConn.Renew();
                        }

                        tcpConn.Open(host, port);
                    }
                    catch (Exception ex)
                    {
                        WriteToLog(ex.Message);
                    }
                }
                else
                {
                    WriteToLog("");
                    WriteToLog(string.Format("{0} {1}", CommUtils.GetNowDT(), reason));
                }
            }
        }
 /// <summary>
 /// Выполнить действия после сеанса опроса КП или отправки команды
 /// </summary>
 public override void AfterSession(KPLogic kpLogic)
 {
     // разрыв соединения согласно настройкам, а также если сеанс опроса КП завершён с ошибкой
     if (!settings.StayConnected || kpLogic.WorkState == KPLogic.WorkStates.Error)
     {
         if (kpLogic.Connection is TcpConnection tcpConn && tcpConn.Connected)
         {
             WriteToLog("");
             WriteToLog(string.Format(Localization.UseRussian ?
                                      "{0} Отключение от {1}" :
                                      "{0} Disconnect from {1}", CommUtils.GetNowDT(), tcpConn.RemoteAddress));
             tcpConn.Disconnect();
         }
     }
 }
Exemple #16
0
        /// <summary>
        /// Добавить КП, относящийся к данному соединению, в список
        /// </summary>
        public void AddRelatedKP(KPLogic kpLogic)
        {
            if (kpLogic == null)
            {
                throw new ArgumentNullException("kpLogic");
            }

            if (relatedKPList == null)
            {
                relatedKPList = new List <KPLogic>();
            }

            lock (relatedKPList)
                relatedKPList.Add(kpLogic);
        }
Exemple #17
0
 /// <summary>
 /// Выполнить метод ProcUnreadIncomingReq для заданного КП с обработкой исключений
 /// </summary>
 protected bool ExecProcUnreadIncomingReq(KPLogic kpLogic, Connection conn, ref KPLogic targetKP)
 {
     try
     {
         return(kpLogic.ProcUnreadIncomingReq(conn, ref targetKP));
     }
     catch (Exception ex)
     {
         WriteToLog((Localization.UseRussian ?
                     "Ошибка при обработке не считанного входящего запроса: " :
                     "Error processing unread incoming request: ") + ex.Message);
         targetKP = null;
         return(false);
     }
 }
Exemple #18
0
 /// <summary>
 /// Выполнить метод ProcIncomingReq для заданного КП с обработкой исключений
 /// </summary>
 protected bool ExecProcIncomingReq(KPLogic kpLogic, byte[] buffer, int offset, int count, ref KPLogic targetKP)
 {
     try
     {
         return(kpLogic.ProcIncomingReq(buffer, offset, count, ref targetKP));
     }
     catch (Exception ex)
     {
         WriteToLog((Localization.UseRussian ?
                     "Ошибка при обработке считанного входящего запроса: " :
                     "Error processing just read incoming request: ") + ex.Message);
         targetKP = null;
         return(false);
     }
 }
Exemple #19
0
 /// <summary>
 /// Выполнить действия после сеанса опроса КП или отправки команды
 /// </summary>
 public override void AfterSession(KPLogic kpLogic)
 {
     // разрыв соединения, если сеанс опроса КП завершён с ошибкой
     if (kpLogic.WorkState == KPLogic.WorkStates.Error && Behavior == OperatingBehaviors.Master)
     {
         TcpConnection tcpConn = kpLogic.Connection as TcpConnection;
         if (tcpConn != null && tcpConn.Connected)
         {
             WriteToLog("");
             WriteToLog(string.Format(Localization.UseRussian ?
                                      "{0} Отключение от {1}" :
                                      "{0} Disconnect from {1}", CommUtils.GetNowDT(), tcpConn.RemoteAddress));
             tcpConn.Disconnect();
         }
     }
 }
Exemple #20
0
        /// <summary>
        /// Обработать доступные данные в режиме соединения Individual
        /// </summary>
        protected void ProcAvailableDataIndiv(TcpConnection tcpConn)
        {
            if (tcpConn.RelatedKPExists)
            {
                // обработка входящего запроса в режиме ведомого для первого КП из группы с одинаковым позывным
                if (slaveBehavior)
                {
                    KPLogic targetKP = tcpConn.GetFirstRelatedKP();
                    if (!ExecProcUnreadIncomingReq(targetKP, tcpConn, ref targetKP))
                    {
                        tcpConn.ClearNetStream(inBuf);
                    }
                }
            }
            else
            {
                // привязка соединения к КП по первому пакету данных
                if (devSelByFirstPackage)
                {
                    if (tcpConn.JustConnected)
                    {
                        string firstPackage = ReceiveFirstPackage(tcpConn);
                        if (!BindConnByFirstPackage(tcpConn, firstPackage))
                        {
                            tcpConn.Broken = true;
                        }
                    }
                }
                else if (devSelByDeviceLibrary)
                {
                    // привязка соединения к КП, используя произвольную библиотеку КП
                    if (kpListNotEmpty)
                    {
                        KPLogic targetKP = null;
                        if (!ExecProcUnreadIncomingReq(firstKP, tcpConn, ref targetKP))
                        {
                            tcpConn.ClearNetStream(inBuf);
                        }
                        BindConnByDeviceLibrary(tcpConn, targetKP);
                    }
                }
            }

            tcpConn.JustConnected = false;
        }
Exemple #21
0
 /// <summary>
 /// Привязать соединение к КП, используя библиотеку КП
 /// </summary>
 protected void BindConnByDeviceLibrary(TcpConnection tcpConn, KPLogic kpLogic)
 {
     if (kpLogic != null)
     {
         WriteToLog(string.Format(Localization.UseRussian ?
                                  "{0} Клиент {1} привязан к {2}, используя библиотеку КП" :
                                  "{0} The client {1} is bound to the {2} using a device library",
                                  CommUtils.GetNowDT(), tcpConn.RemoteAddress, kpLogic.Caption));
         SetConnection(kpLogic, tcpConn);
     }
     else
     {
         WriteToLog(string.Format(Localization.UseRussian ?
                                  "{0} Не удалось привязать клиента {1} к КП, используя библиотеку КП" :
                                  "{0} Unable to bind the client {1} to a device using a device library",
                                  CommUtils.GetNowDT(), tcpConn.RemoteAddress));
     }
 }
        /// <summary>
        /// Цикл приёма данных по индивидуальным соединениям в режиме ведомого (метод вызывается в отдельном потоке)
        /// </summary>
        protected void ListenIndividualConn()
        {
            try
            {
                while (!terminated)
                {
                    foreach (KPLogic kpLogic in kpList)
                    {
                        TcpConnection tcpConn = kpLogic.Connection as TcpConnection;

                        if (tcpConn != null && tcpConn.TcpClient.Available > 0)
                        {
                            KPLogic targetKP = kpLogic;
                            if (!ExecProcUnreadIncomingReq(kpLogic, tcpConn, ref targetKP))
                            {
                                sharedTcpConn.ClearNetStream(inBuf);
                            }
                        }
                    }

                    Thread.Sleep(SlaveThreadDelay);
                }
            }
            catch (Exception ex)
            {
                // данное исключение возникать не должно
                if (Localization.UseRussian)
                {
                    WriteToLog("Ошибка при приёме данных по индивидуальным соединениям: " + ex.Message);
                    WriteToLog("Приём данных прекращён");
                }
                else
                {
                    WriteToLog("Error receiving data via individual connections: " + ex.Message);
                    WriteToLog("Data receiving is terminated");
                }
            }
        }
Exemple #23
0
        /// <summary>
        /// Listens to the serial port for incoming data.
        /// </summary>
        /// <remarks>This methods works in a separate thread. Is used in Mono.</remarks>
        protected void ListenSerialPort()
        {
            byte[] buffer      = new byte[SlaveInBufLen];
            int    readCnt     = 0;
            int    prevReadCnt = 0;

            while (!terminated)
            {
                try
                {
                    serialConn.SerialPort.ReadTimeout = 0;

                    try { readCnt += serialConn.SerialPort.Read(buffer, readCnt, SlaveInBufLen - readCnt); }
                    catch (TimeoutException) { }

                    Thread.Sleep(ReadIntervalTimeout);

                    if (prevReadCnt == readCnt && readCnt > 0 || readCnt == SlaveInBufLen)
                    {
                        KPLogic targetKP = null;
                        if (!ExecProcIncomingReq(firstKP, buffer, 0, readCnt, ref targetKP))
                        {
                            serialConn.DiscardInBuffer();
                        }
                        readCnt = 0;
                    }

                    prevReadCnt = readCnt;
                }
                catch (Exception ex)
                {
                    WriteToLog(string.Format(Localization.UseRussian ?
                                             "Ошибка при прослушивании последовательного порта: {0}" :
                                             "Error listening to the serial port: {0}", ex.Message));
                }
            }
        }
        /// <summary>
        /// Выполнить действия перед сеансом опроса КП или отправкой команды
        /// </summary>
        public override void BeforeSession(KPLogic kpLogic)
        {
            // установка соединения при необходимости
            TcpConnection tcpConn = kpLogic.Connection as TcpConnection;

            if (tcpConn != null && !tcpConn.Connected)
            {
                try
                {
                    // определение IP-адреса и TCP-порта
                    IPAddress addr;
                    int       port;

                    if (tcpConn == sharedTcpConn)
                    {
                        addr = IPAddress.Parse(settings.IpAddress);
                        port = settings.TcpPort;
                    }
                    else
                    {
                        CommUtils.ExtractAddrAndPort(kpLogic.CallNum, settings.TcpPort, out addr, out port);
                    }

                    // установка соединения
                    WriteToLog("");
                    WriteToLog(string.Format(Localization.UseRussian ?
                                             "{0} Установка TCP-соединения с {1}:{2}" :
                                             "{0} Establish a TCP connection with {1}:{2}", CommUtils.GetNowDT(), addr, port));
                    tcpConn.Open(addr, port);
                }
                catch (Exception ex)
                {
                    WriteToLog(ex.Message);
                }
            }
        }
Exemple #25
0
 /// <summary>
 /// Передать команду КП
 /// </summary>
 public void PassCmd(KPLogic.Command cmd)
 {
     if (cmd != null && linesStarted)
     {
         try
         {
             lock (lineLock)
             {
                 foreach (CommLine commLine in commLines)
                     commLine.AddCmd(cmd);
             }
         }
         catch (Exception ex)
         {
             Log.WriteAction((Localization.UseRussian ? "Ошибка при передаче команды менеджеру: " :
                 "Error passing command to the manager: ") + ex.Message, Log.ActTypes.Exception);
         }
     }
 }
Exemple #26
0
 /// <summary>
 /// Выполнить действия после сеанса опроса КП или отправки команды
 /// </summary>
 public virtual void AfterSession(KPLogic kpLogic)
 {
 }
Exemple #27
0
 /// <summary>
 /// Выполнить действия перед сеансом опроса КП или отправкой команды
 /// </summary>
 public virtual void BeforeSession(KPLogic kpLogic)
 {
 }
Exemple #28
0
 /// <summary>
 /// Отправить архивный срез SCADA-Серверу
 /// </summary>
 public bool SendArchive(KPLogic.ParamSrez arcSrez)
 {
     bool result;
     SrezTableLight.Srez srez = ConvertSrez(arcSrez);
     return srez == null || SendArchive(srez, out result) && result;
 }
Exemple #29
0
 /// <summary>
 /// Конструктор
 /// </summary>
 /// <param name="name">Наименование канала управления</param>
 /// <param name="cmdType">Тип команды</param>
 public CtrlCnlProps(string name, KPLogic.CmdType cmdType)
 {
     Name = name;
     CmdType = cmdType;
     CmdNum = 0;
     CmdValName = "";
     FormulaUsed = false;
     Formula = "";
     EvEnabled = false;
 }
Exemple #30
0
        /// <summary>
        /// Записать команду управления в файл
        /// </summary>
        /// <param name="cmdDir">Директория команд</param>
        /// <param name="sender">Имя приложения, отправившего команду</param>
        /// <param name="cmd">Команда КП</param>
        /// <param name="msg">Сообщение</param>
        /// <returns>Успешно ли произведена запись команды</returns>
        public static bool SaveCmd(string cmdDir, string sender, KPLogic.Command cmd, out string msg)
        {
            StringBuilder sbCmdData = new StringBuilder();
            if (cmd.CmdData != null)
            {
                int cmdDataLen = cmd.CmdData.Length;
                for (int i = 0; i < cmdDataLen; i++)
                    sbCmdData.Append(cmd.CmdData[i].ToString("X2"));
            }

            string[] cmdParams = new string[] {
                "KPNum=" + cmd.KPNum,
                "CmdNum=" + cmd.CmdNum,
                "CmdVal=" + cmd.CmdVal.ToString(),
                "CmdData=" + sbCmdData
            };

            return SaveCmd(cmdDir, sender, cmd.CmdType.ToString(), cmdParams, out msg);
        }
Exemple #31
0
        /// <summary>
        /// Отправить событие SCADA-Серверу
        /// </summary>
        public bool SendEvent(KPLogic.Event aEvent)
        {
            if (aEvent == null || aEvent.KPParam == null || aEvent.KPParam.CnlNum <= 0)
            {
                return true;
            }
            else
            {
                EventTableLight.Event ev = new EventTableLight.Event();
                ev.Number = aEvent.KPNum;
                ev.DateTime = aEvent.DateTime;
                ev.ObjNum = aEvent.KPParam.ObjNum;
                ev.KPNum = aEvent.KPNum;
                ev.ParamID = aEvent.KPParam.ParamID;
                ev.CnlNum = aEvent.KPParam.CnlNum;
                ev.OldCnlVal = aEvent.OldData.Val;
                ev.OldCnlStat = aEvent.OldData.Stat;
                ev.NewCnlVal = aEvent.NewData.Val;
                ev.NewCnlStat = aEvent.NewData.Stat;
                ev.Checked = aEvent.Checked;
                ev.UserID = aEvent.UserID;
                ev.Descr = aEvent.Descr;
                ev.Data = aEvent.Data;

                bool result;
                return SendEvent(ev, out result) && result;
            }
        }
Exemple #32
0
 /// <summary>
 /// Отправить текущий срез SCADA-Серверу
 /// </summary>
 public bool SendSrez(KPLogic.ParamSrez curSrez)
 {
     bool result;
     SrezTableLight.Srez srez = ConvertSrez(curSrez);
     return srez == null || SendSrez(srez, out result) && result;
 }
Exemple #33
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;
            }
        }