Example #1
0
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 public CnlTag(int index, int cnlNum, InCnl inCnl, Lim lim)
 {
     Index           = index;
     CnlNum          = cnlNum;
     InCnl           = inCnl ?? throw new ArgumentNullException(nameof(inCnl));
     Lim             = lim;
     LimCnlIndex     = null;
     CalcEngine      = null;
     CalcCnlDataFunc = null;
 }
Example #2
0
        /// <summary>
        /// Clones input channels.
        /// </summary>
        private bool CloneInCnls(int srcStartNum, int srcEndNum, int destStartNum,
                                 int replaceObjNum, int replaceKpNum, bool updateFormulas)
        {
            try
            {
                BaseTable <InCnl> inCnlTable = configBase.InCnlTable;
                int affectedRows             = 0;

                if (srcStartNum <= srcEndNum)
                {
                    // create new channels
                    int          shiftNum  = destStartNum - srcStartNum;
                    List <InCnl> cnlsToAdd = new List <InCnl>(srcEndNum - srcStartNum + 1);

                    foreach (InCnl inCnl in inCnlTable.Items.Values)
                    {
                        int cnlNum = inCnl.CnlNum;

                        if (srcStartNum <= cnlNum && cnlNum <= srcEndNum)
                        {
                            int newCnlNum = cnlNum + shiftNum;

                            if (newCnlNum <= AdminUtils.MaxCnlNum && !inCnlTable.PkExists(newCnlNum))
                            {
                                InCnl newInCnl = ScadaUtils.DeepClone(inCnl);
                                newInCnl.CnlNum = newCnlNum;

                                if (replaceObjNum >= 0)
                                {
                                    newInCnl.ObjNum = replaceObjNum > 0 ? replaceObjNum : (int?)null;
                                }

                                if (replaceKpNum >= 0)
                                {
                                    newInCnl.KPNum = replaceKpNum > 0 ? replaceKpNum : (int?)null;
                                }

                                if (updateFormulas)
                                {
                                    newInCnl.Formula = UpdateFormula(newInCnl.Formula, shiftNum);
                                }

                                cnlsToAdd.Add(newInCnl);
                            }
                        }
                        else if (cnlNum > srcEndNum)
                        {
                            break;
                        }
                    }

                    // add the created channels
                    foreach (InCnl inCnl in cnlsToAdd)
                    {
                        inCnlTable.AddItem(inCnl);
                    }

                    affectedRows = cnlsToAdd.Count;
                }

                if (affectedRows > 0)
                {
                    inCnlTable.Modified = true;
                }

                ScadaUiUtils.ShowInfo(string.Format(AppPhrases.CloneCnlsComplete, affectedRows));
                return(true);
            }
            catch (Exception ex)
            {
                appData.ProcError(ex, AppPhrases.CloneInCnlsError);
                return(false);
            }
        }
Example #3
0
        /// <summary>
        /// Вычислить данные входного канала
        /// </summary>
        private void CalcCnlData(InCnl inCnl, SrezTableLight.CnlData oldCnlData, ref SrezTableLight.CnlData newCnlData)
        {
            if (inCnl != null)
            {
                try
                {
                    // вычисление новых данных
                    if (inCnl.CalcCnlData != null)
                        inCnl.CalcCnlData(ref newCnlData);

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

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

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

                        if (inCnl.LimLowCrash < inCnl.LimHighCrash)
                        {
                            if (newCnlData.Val < inCnl.LimLowCrash)
                                newCnlData.Stat = BaseValues.CnlStatuses.LowCrash;
                            else if (newCnlData.Val > inCnl.LimHighCrash)
                                newCnlData.Stat = BaseValues.CnlStatuses.HighCrash;
                        }
                    }
                }
                catch
                {
                    newCnlData.Stat = BaseValues.CnlStatuses.FormulaError;
                }
            }
        }
Example #4
0
        /// <summary>
        /// Считать входные каналы из базы конфигурации
        /// </summary>
        private bool ReadInCnls()
        {
            try
            {
                lock (inCnls)
                {
                    // очистка информации о каналах
                    inCnls.Clear();
                    drCnls = new List<InCnl>();
                    drmCnls = new List<InCnl>();
                    drhCnls = new List<InCnl>();
                    drCnlNums = null;
                    drmCnlNums = null;
                    drhCnlNums = null;
                    avgCnlInds = new List<int>();

                    // заполнение информации о каналах
                    DataTable tblInCnl = new DataTable();
                    BaseAdapter adapter = new BaseAdapter();
                    adapter.FileName = Settings.BaseDATDir + "incnl.dat";
                    adapter.Fill(tblInCnl, false);

                    foreach (DataRow dataRow in tblInCnl.Rows)
                    {
                        if ((bool)dataRow["Active"])
                        {
                            // заполняются только свойства, используемые приложением
                            InCnl inCnl = new InCnl();
                            inCnl.CnlNum = (int)dataRow["CnlNum"];
                            inCnl.CnlTypeID = (int)dataRow["CnlTypeID"];
                            inCnl.ObjNum = (int)dataRow["ObjNum"];
                            inCnl.KPNum = (int)dataRow["KPNum"];
                            inCnl.FormulaUsed = (bool)dataRow["FormulaUsed"];
                            inCnl.Formula = (string)dataRow["Formula"];
                            inCnl.Averaging = (bool)dataRow["Averaging"];
                            inCnl.ParamID = (int)dataRow["ParamID"];
                            inCnl.EvEnabled = (bool)dataRow["EvEnabled"];
                            inCnl.EvOnChange = (bool)dataRow["EvOnChange"];
                            inCnl.EvOnUndef = (bool)dataRow["EvOnUndef"];
                            inCnl.LimLowCrash = (double)dataRow["LimLowCrash"];
                            inCnl.LimLow = (double)dataRow["LimLow"];
                            inCnl.LimHigh = (double)dataRow["LimHigh"];
                            inCnl.LimHighCrash = (double)dataRow["LimHighCrash"];

                            int cnlTypeID = inCnl.CnlTypeID;
                            if (BaseValues.CnlTypes.MinCnlTypeID <= cnlTypeID &&
                                cnlTypeID <= BaseValues.CnlTypes.MaxCnlTypeID)
                                inCnls.Add(inCnl.CnlNum, inCnl);

                            if (cnlTypeID == BaseValues.CnlTypes.TSDR || cnlTypeID == BaseValues.CnlTypes.TIDR ||
                                cnlTypeID == BaseValues.CnlTypes.SWCNT)
                                drCnls.Add(inCnl);
                            else if (cnlTypeID == BaseValues.CnlTypes.TSDRM || cnlTypeID == BaseValues.CnlTypes.TIDRM)
                                drmCnls.Add(inCnl);
                            else if (cnlTypeID == BaseValues.CnlTypes.TSDRH || cnlTypeID == BaseValues.CnlTypes.TIDRH)
                                drhCnls.Add(inCnl);

                            if (inCnl.Averaging && cnlTypeID == BaseValues.CnlTypes.TI)
                                avgCnlInds.Add(inCnls.Count - 1);
                        }
                    }

                    // заполнение номеров дорасчётных каналов
                    int cnt = drCnls.Count;
                    drCnlNums = new int[cnt];
                    for (int i = 0; i < cnt; i++)
                        drCnlNums[i] = drCnls[i].CnlNum;

                    cnt = drmCnls.Count;
                    drmCnlNums = new int[cnt];
                    for (int i = 0; i < cnt; i++)
                        drmCnlNums[i] = drmCnls[i].CnlNum;

                    cnt = drhCnls.Count;
                    drhCnlNums = new int[cnt];
                    for (int i = 0; i < cnt; i++)
                        drhCnlNums[i] = drhCnls[i].CnlNum;

                    // определение результата
                    if (inCnls.Count > 0)
                    {
                        AppLog.WriteAction(string.Format(Localization.UseRussian ?
                            "Входные каналы считаны из базы конфигурации. Количество активных каналов: {0}" :
                            "Input channels are read from the configuration database. Active channel count: {0}",
                            inCnls.Count), Log.ActTypes.Action);
                        return true;
                    }
                    else
                    {
                        AppLog.WriteAction(Localization.UseRussian ?
                            "В базе конфигурации отсутствуют активные входные каналы" :
                            "No active input channels in the configuration database", Log.ActTypes.Error);
                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                AppLog.WriteAction((Localization.UseRussian ?
                    "Ошибка при считывании входных каналов из базы конфигурации: " :
                    "Error reading input channels from the configuration database: ") +
                    ex.Message, Log.ActTypes.Exception);
                return false;
            }
        }
Example #5
0
        /// <summary>
        /// Генерировать событие в соответствии со свойствами и данными входного канала
        /// </summary>
        private void GenEvent(InCnl inCnl, SrezTableLight.CnlData oldCnlData, SrezTableLight.CnlData newCnlData)
        {
            if (inCnl.EvEnabled)
            {
                double oldVal = oldCnlData.Val;
                double newVal = newCnlData.Val;
                int oldStat = oldCnlData.Stat;
                int newStat = newCnlData.Stat;

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

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

                    // запись события и выполнение действий модулей
                    WriteEvent(ev);
                }
            }
        }
Example #6
0
        /// <summary>
        /// Creates channels based on the prototypes.
        /// </summary>
        private bool CreateChannels()
        {
            try
            {
                List <KPView.InCnlPrototype>   inCnlPrototypes   = ctrlCnlCreate1.CnlPrototypes.InCnls;
                List <KPView.CtrlCnlPrototype> ctrlCnlPrototypes = ctrlCnlCreate1.CnlPrototypes.CtrlCnls;
                int?                objNum        = ctrlCnlCreate2.ObjNum;
                int                 kpNum         = ctrlCnlCreate1.SelectedDevice.KPNum;
                string              cnlPrefix     = ctrlCnlCreate1.SelectedDevice.Name + " - ";
                int                 inCnlNum      = ctrlCnlCreate3.StartInCnl;
                int                 ctrlCnlNum    = ctrlCnlCreate3.StartOutCnl;
                int                 inCnlsAdded   = 0;
                int                 ctrlCnlsAdded = 0;
                BaseTable <InCnl>   inCnlTable    = project.ConfigBase.InCnlTable;
                BaseTable <CtrlCnl> ctrlCnlTable  = project.ConfigBase.CtrlCnlTable;
                BaseTable <Format>  formatTable   = project.ConfigBase.FormatTable;
                DictIndexes         dictIndexes   = new DictIndexes(project.ConfigBase);

                // create output channels
                foreach (KPView.CtrlCnlPrototype ctrlCnlPrototype in ctrlCnlPrototypes)
                {
                    ctrlCnlPrototype.CtrlCnlNum = ctrlCnlNum;

                    CtrlCnl ctrlCnl = new CtrlCnl
                    {
                        CtrlCnlNum  = ctrlCnlNum++,
                        Active      = ctrlCnlPrototype.Active,
                        Name        = cnlPrefix + ctrlCnlPrototype.CtrlCnlName,
                        CmdTypeID   = ctrlCnlPrototype.CmdTypeID,
                        ObjNum      = objNum,
                        KPNum       = kpNum,
                        CmdNum      = ctrlCnlPrototype.CmdNum > 0 ? (int?)ctrlCnlPrototype.CmdNum : null,
                        CmdValID    = dictIndexes.GetID(dictIndexes.CmdValByName, ctrlCnlPrototype.CmdVal),
                        FormulaUsed = ctrlCnlPrototype.FormulaUsed,
                        Formula     = ctrlCnlPrototype.Formula,
                        EvEnabled   = ctrlCnlPrototype.EvEnabled
                    };

                    if (ctrlCnl.Name.Length > ColumnLength.Name)
                    {
                        ctrlCnl.Name = ctrlCnl.Name.Substring(0, ColumnLength.Name);
                    }

                    ctrlCnlTable.AddItem(ctrlCnl);
                    ctrlCnlsAdded++;

                    if (ctrlCnlNum > ushort.MaxValue)
                    {
                        break;
                    }
                }

                if (ctrlCnlsAdded > 0)
                {
                    ctrlCnlTable.Modified = true;
                }

                // create input channels
                foreach (KPView.InCnlPrototype inCnlPrototype in inCnlPrototypes)
                {
                    int formatID = inCnlPrototype.ShowNumber ?
                                   Math.Min(inCnlPrototype.DecDigits, BaseValues.Formats.MaxFixedID) :
                                   BaseValues.Formats.EnumText;

                    InCnl inCnl = new InCnl
                    {
                        CnlNum      = inCnlNum++,
                        Active      = inCnlPrototype.Active,
                        Name        = cnlPrefix + inCnlPrototype.CnlName,
                        CnlTypeID   = inCnlPrototype.CnlTypeID,
                        ObjNum      = objNum,
                        KPNum       = kpNum,
                        Signal      = inCnlPrototype.Signal > 0 ? (int?)inCnlPrototype.Signal : null,
                        FormulaUsed = inCnlPrototype.FormulaUsed,
                        Formula     = inCnlPrototype.Formula,
                        Averaging   = inCnlPrototype.Averaging,
                        ParamID     = dictIndexes.GetID(dictIndexes.ParamByName, inCnlPrototype.ParamName),
                        FormatID    = formatTable.PkExists(formatID) ? (int?)formatID : null,
                        UnitID      = dictIndexes.GetID(dictIndexes.UnitByName, inCnlPrototype.UnitName),
                        CtrlCnlNum  = inCnlPrototype.CtrlCnlProps?.CtrlCnlNum,
                        EvEnabled   = inCnlPrototype.EvEnabled,
                        EvSound     = inCnlPrototype.EvSound,
                        EvOnChange  = inCnlPrototype.EvOnChange,
                        EvOnUndef   = inCnlPrototype.EvOnUndef,
                        LimLowCrash = double.IsNaN(inCnlPrototype.LimLowCrash) ?
                                      null : (double?)inCnlPrototype.LimLowCrash,
                        LimLow = double.IsNaN(inCnlPrototype.LimLow) ?
                                 null : (double?)inCnlPrototype.LimLow,
                        LimHigh = double.IsNaN(inCnlPrototype.LimHigh) ?
                                  null : (double?)inCnlPrototype.LimHigh,
                        LimHighCrash = double.IsNaN(inCnlPrototype.LimHighCrash) ?
                                       null : (double?)inCnlPrototype.LimHighCrash
                    };

                    if (inCnl.Name.Length > ColumnLength.Name)
                    {
                        inCnl.Name = inCnl.Name.Substring(0, ColumnLength.Name);
                    }

                    inCnlTable.AddItem(inCnl);
                    inCnlsAdded++;

                    if (inCnlNum > ushort.MaxValue)
                    {
                        break;
                    }
                }

                if (inCnlsAdded > 0)
                {
                    inCnlTable.Modified = true;
                }

                ScadaUiUtils.ShowInfo(string.Format(AppPhrases.CreateCnlsComplete, inCnlsAdded, ctrlCnlsAdded));
                return(true);
            }
            catch (Exception ex)
            {
                appData.ProcError(ex, AppPhrases.CreateCnlsError);
                return(false);
            }
        }
Example #7
0
 /// <summary>
 /// Performs the necessary actions after the calculation of the input channel data.
 /// </summary>
 public void EndCalcCnlData()
 {
     cnlNum         = 0;
     inCnl          = null;
     initialCnlData = CnlData.Empty;
 }
Example #8
0
 /// <summary>
 /// Performs the necessary actions before the calculation of the input channel data.
 /// </summary>
 public void BeginCalcCnlData(int cnlNum, InCnl inCnl, CnlData initialCnlData)
 {
     this.cnlNum         = cnlNum;
     this.inCnl          = inCnl;
     this.initialCnlData = initialCnlData;
 }