/// <summary> /// Calculate the channel numbers and write them to the list of information on KP /// </summary> public static bool CalcCnlNums(Dictionary <string, Type> kpViewTypes, List <KPInfo> kpInfoList, Scada.Comm.AppDirs commDirs, List <int> inCnlNums, CnlNumParams inCnlNumParams, List <int> ctrlCnlNums, CnlNumParams ctrlCnlNumParams, out string errMsg) { if (kpViewTypes == null) { throw new ArgumentNullException(nameof(kpViewTypes)); } if (kpInfoList == null) { throw new ArgumentNullException(nameof(kpInfoList)); } if (inCnlNums == null) { throw new ArgumentNullException(nameof(inCnlNums)); } if (inCnlNumParams == null) { throw new ArgumentNullException(nameof(inCnlNumParams)); } if (ctrlCnlNums == null) { throw new ArgumentNullException(nameof(ctrlCnlNums)); } if (ctrlCnlNumParams == null) { throw new ArgumentNullException(nameof(ctrlCnlNumParams)); } var hasChannels = false; var hasErrors = false; errMsg = ""; try { // loading SCADA-Communicator settings Scada.Comm.Settings commSett = new Scada.Comm.Settings(); if (!commSett.Load(commDirs.ConfigDir + Scada.Comm.Settings.DefFileName, out errMsg)) { throw new Exception(errMsg); } // filling the directory of KP properties Dictionary <int, KPView.KPProperties> kpPropsDict = new Dictionary <int, KPView.KPProperties>(); foreach (Scada.Comm.Settings.CommLine commLine in commSett.CommLines) { foreach (Scada.Comm.Settings.KP kp in commLine.ReqSequence) { if (!kpPropsDict.ContainsKey(kp.Number)) { kpPropsDict.Add(kp.Number, new KPView.KPProperties(commLine.CustomParams, kp.CmdLine)); } } } // determining the starting number of the input channel int inCnlsStart = inCnlNumParams.Start; int inCnlsMultiple = inCnlNumParams.Multiple; int inCnlsSpace = inCnlNumParams.Space; int remainder = inCnlsStart % inCnlsMultiple; int curInCnlNum = remainder > 0 ? inCnlsStart - remainder : inCnlsStart; curInCnlNum += inCnlNumParams.Shift; if (curInCnlNum < inCnlsStart) { curInCnlNum += inCnlsMultiple; } // determination of the control channel start number int ctrlCnlsStart = ctrlCnlNumParams.Start; int ctrlCnlsMultiple = ctrlCnlNumParams.Multiple; int ctrlCnlsSpace = ctrlCnlNumParams.Space; remainder = ctrlCnlsStart % ctrlCnlNumParams.Multiple; int curCtrlCnlNum = remainder > 0 ? ctrlCnlsStart - remainder : ctrlCnlsStart; curCtrlCnlNum += ctrlCnlNumParams.Shift; if (curCtrlCnlNum < ctrlCnlNumParams.Start) { curCtrlCnlNum += ctrlCnlNumParams.Multiple; } // calculation channel numbers KP var curInCnlInd = 0; int inCnlNumsCnt = inCnlNums.Count; var curCtrlCnlInd = 0; int ctrlCnlNumsCnt = ctrlCnlNums.Count; foreach (var kpInfo in kpInfoList) { if (kpInfo.Selected) { // getting interface type kp if (!kpViewTypes.TryGetValue(kpInfo.DllFileName, out Type kpViewType)) { continue; } // instantiating a KP interface class KPView kpView = null; try { kpView = KPFactory.GetKPView(kpViewType, kpInfo.KPNum); KPView.KPProperties kpProps; if (kpPropsDict.TryGetValue(kpInfo.KPNum, out kpProps)) { kpView.KPProps = kpProps; } kpView.AppDirs = commDirs; } catch { kpInfo.SetInCnlNums(true); kpInfo.SetCtrlCnlNums(true); continue; } // default prototype channel acquisition try { kpInfo.DefaultCnls = kpView.DefaultCnls; } catch { kpInfo.SetInCnlNums(true); kpInfo.SetCtrlCnlNums(true); continue; } // definition of numbers of input channels, taking into account the numbers occupied by existing channels if (kpInfo.DefaultCnls != null && kpInfo.DefaultCnls.InCnls.Count > 0) { hasChannels = true; int firstInCnlNum; // first input channel number int lastInCnlNum; // number of last input channel KP int newInCnlInd; // new index of the number of input channels CalcFirstAndLastNums(curInCnlNum, curInCnlInd, inCnlNums, inCnlNumsCnt, kpInfo.DefaultCnls.InCnls.Count, inCnlsSpace, inCnlsMultiple, out firstInCnlNum, out lastInCnlNum, out newInCnlInd); if (lastInCnlNum > ushort.MaxValue) { hasErrors = true; kpInfo.SetInCnlNums(true); } else { kpInfo.SetInCnlNums(false, firstInCnlNum, lastInCnlNum); curInCnlInd = newInCnlInd; curInCnlNum = firstInCnlNum; do { curInCnlNum += inCnlsMultiple; } while (curInCnlNum - lastInCnlNum <= inCnlsSpace); } } else { // channel numbers are not assigned because KP does not support input channel creation kpInfo.SetInCnlNums(false); } // identification of control channel numbers with regard to numbers occupied by existing channels if (kpInfo.DefaultCnls != null && kpInfo.DefaultCnls.CtrlCnls.Count > 0) { hasChannels = true; int firstCtrlCnlNum; // first control channel number int lastCtrlCnlNum; // control channel last control channel number int newCtrlCnlInd; // new index of the list of control channel numbers CalcFirstAndLastNums(curCtrlCnlNum, curCtrlCnlInd, ctrlCnlNums, ctrlCnlNumsCnt, kpInfo.DefaultCnls.CtrlCnls.Count, ctrlCnlsSpace, ctrlCnlsMultiple, out firstCtrlCnlNum, out lastCtrlCnlNum, out newCtrlCnlInd); if (lastCtrlCnlNum > ushort.MaxValue) { hasErrors = true; kpInfo.SetCtrlCnlNums(true); } else { kpInfo.SetCtrlCnlNums(false, firstCtrlCnlNum, lastCtrlCnlNum); curCtrlCnlInd = newCtrlCnlInd; curCtrlCnlNum = firstCtrlCnlNum; do { curCtrlCnlNum += ctrlCnlsMultiple; } while (curCtrlCnlNum - lastCtrlCnlNum <= ctrlCnlsSpace); } } else { // channel numbers are not assigned because KP does not support the creation of control channels kpInfo.SetCtrlCnlNums(false); } } else { // channel numbers are not assigned because KP is not selected kpInfo.SetInCnlNums(false, -1, -1); kpInfo.SetCtrlCnlNums(false, -1, -1); } } if (hasErrors) { errMsg = AppPhrases.CalcCnlNumsErrors; } else if (!hasChannels) { errMsg = AppPhrases.CreatedCnlsMissing; } } catch (Exception ex) { hasErrors = true; errMsg = AppPhrases.CalcCnlNumsError + ":\r\n" + ex.Message; } return(hasChannels && !hasErrors); }
/// <summary> /// Расчитать номера каналов и записать их в список информации о КП /// </summary> public static bool CalcCnlNums(Dictionary <string, Type> kpViewTypes, List <KPInfo> kpInfoList, Scada.Comm.AppDirs commDirs, List <int> inCnlNums, CnlNumParams inCnlNumParams, List <int> ctrlCnlNums, CnlNumParams ctrlCnlNumParams, out string errMsg) { if (kpViewTypes == null) { throw new ArgumentNullException("kpViewTypes"); } if (kpInfoList == null) { throw new ArgumentNullException("kpInfoList"); } if (inCnlNums == null) { throw new ArgumentNullException("inCnlNums"); } if (inCnlNumParams == null) { throw new ArgumentNullException("inCnlNumParams"); } if (ctrlCnlNums == null) { throw new ArgumentNullException("ctrlCnlNums"); } if (ctrlCnlNumParams == null) { throw new ArgumentNullException("ctrlCnlNumParams"); } bool hasChannels = false; bool hasErrors = false; errMsg = ""; try { // загрузка настроек SCADA-Коммуникатора Scada.Comm.Settings commSett = new Scada.Comm.Settings(); if (!commSett.Load(commDirs.ConfigDir + Scada.Comm.Settings.DefFileName, out errMsg)) { throw new Exception(errMsg); } // заполнение справочника свойств КП Dictionary <int, KPView.KPProperties> kpPropsDict = new Dictionary <int, KPView.KPProperties>(); foreach (Scada.Comm.Settings.CommLine commLine in commSett.CommLines) { foreach (Scada.Comm.Settings.KP kp in commLine.ReqSequence) { if (!kpPropsDict.ContainsKey(kp.Number)) { kpPropsDict.Add(kp.Number, new KPView.KPProperties(commLine.CustomParams, kp.CmdLine)); } } } // определение стартового номера входного канала int inCnlsStart = inCnlNumParams.Start; int inCnlsMultiple = inCnlNumParams.Multiple; int inCnlsSpace = inCnlNumParams.Space; int remainder = inCnlsStart % inCnlsMultiple; int curInCnlNum = remainder > 0 ? inCnlsStart - remainder : inCnlsStart; curInCnlNum += inCnlNumParams.Shift; if (curInCnlNum < inCnlsStart) { curInCnlNum += inCnlsMultiple; } // определение стартового номера канала управления int ctrlCnlsStart = ctrlCnlNumParams.Start; int ctrlCnlsMultiple = ctrlCnlNumParams.Multiple; int ctrlCnlsSpace = ctrlCnlNumParams.Space; remainder = ctrlCnlsStart % ctrlCnlNumParams.Multiple; int curCtrlCnlNum = remainder > 0 ? ctrlCnlsStart - remainder : ctrlCnlsStart; curCtrlCnlNum += ctrlCnlNumParams.Shift; if (curCtrlCnlNum < ctrlCnlNumParams.Start) { curCtrlCnlNum += ctrlCnlNumParams.Multiple; } // расчёт номеров каналов КП int curInCnlInd = 0; int inCnlNumsCnt = inCnlNums.Count; int curCtrlCnlInd = 0; int ctrlCnlNumsCnt = ctrlCnlNums.Count; foreach (KPInfo kpInfo in kpInfoList) { if (kpInfo.Selected) { // получение типа интерфейса КП Type kpViewType; if (!kpViewTypes.TryGetValue(kpInfo.DllFileName, out kpViewType)) { continue; } // создание экземпляра класса интерфейса КП KPView kpView = null; try { kpView = KPFactory.GetKPView(kpViewType, kpInfo.KPNum); KPView.KPProperties kpProps; if (kpPropsDict.TryGetValue(kpInfo.KPNum, out kpProps)) { kpView.KPProps = kpProps; } kpView.AppDirs = commDirs; } catch { kpInfo.SetInCnlNums(true); kpInfo.SetCtrlCnlNums(true); continue; } // получение прототипов каналов КП по умолчанию try { kpInfo.DefaultCnls = kpView.DefaultCnls; } catch { kpInfo.SetInCnlNums(true); kpInfo.SetCtrlCnlNums(true); continue; } // определение номеров входных каналов с учётом занятых существующими каналами номеров if (kpInfo.DefaultCnls != null && kpInfo.DefaultCnls.InCnls.Count > 0) { hasChannels = true; int firstInCnlNum; // номер первого входного канала КП int lastInCnlNum; // номер последнего входного канала КП int newInCnlInd; // новый индекс списка номеров входных каналов CalcFirstAndLastNums(curInCnlNum, curInCnlInd, inCnlNums, inCnlNumsCnt, kpInfo.DefaultCnls.InCnls.Count, inCnlsSpace, inCnlsMultiple, out firstInCnlNum, out lastInCnlNum, out newInCnlInd); if (lastInCnlNum > ushort.MaxValue) { hasErrors = true; kpInfo.SetInCnlNums(true); } else { kpInfo.SetInCnlNums(false, firstInCnlNum, lastInCnlNum); curInCnlInd = newInCnlInd; curInCnlNum = firstInCnlNum; do { curInCnlNum += inCnlsMultiple; }while (curInCnlNum - lastInCnlNum <= inCnlsSpace); } } else { // номера каналов не назначаются, т.к. КП не поддерживает создание входных каналов kpInfo.SetInCnlNums(false); } // определение номеров каналов управления с учётом занятых существующими каналами номеров if (kpInfo.DefaultCnls != null && kpInfo.DefaultCnls.CtrlCnls.Count > 0) { hasChannels = true; int firstCtrlCnlNum; // номер первого канала управления КП int lastCtrlCnlNum; // номер последнего канала управления КП int newCtrlCnlInd; // новый индекс списка номеров каналов управления CalcFirstAndLastNums(curCtrlCnlNum, curCtrlCnlInd, ctrlCnlNums, ctrlCnlNumsCnt, kpInfo.DefaultCnls.CtrlCnls.Count, ctrlCnlsSpace, ctrlCnlsMultiple, out firstCtrlCnlNum, out lastCtrlCnlNum, out newCtrlCnlInd); if (lastCtrlCnlNum > ushort.MaxValue) { hasErrors = true; kpInfo.SetCtrlCnlNums(true); } else { kpInfo.SetCtrlCnlNums(false, firstCtrlCnlNum, lastCtrlCnlNum); curCtrlCnlInd = newCtrlCnlInd; curCtrlCnlNum = firstCtrlCnlNum; do { curCtrlCnlNum += ctrlCnlsMultiple; }while (curCtrlCnlNum - lastCtrlCnlNum <= ctrlCnlsSpace); } } else { // номера каналов не назначаются, т.к. КП не поддерживает создание каналов управления kpInfo.SetCtrlCnlNums(false); } } else { // номера каналов не назначаются, т.к. КП не выбран kpInfo.SetInCnlNums(false, -1, -1); kpInfo.SetCtrlCnlNums(false, -1, -1); } } if (hasErrors) { errMsg = AppPhrases.CalcCnlNumsErrors; } else if (!hasChannels) { errMsg = AppPhrases.CreatedCnlsMissing; } } catch (Exception ex) { hasErrors = true; errMsg = AppPhrases.CalcCnlNumsError + ":\r\n" + ex.Message; } return(hasChannels && !hasErrors); }
/// <summary> /// Расчитать номера каналов и записать их в список информации о КП /// </summary> public static bool CalcCnlNums(Dictionary<string, Type> kpViewTypes, List<KPInfo> kpInfoList, Scada.Comm.AppDirs commDirs, List<int> inCnlNums, CnlNumParams inCnlNumParams, List<int> ctrlCnlNums, CnlNumParams ctrlCnlNumParams, out string errMsg) { if (kpViewTypes == null) throw new ArgumentNullException("kpViewTypes"); if (kpInfoList == null) throw new ArgumentNullException("kpInfoList"); if (inCnlNums == null) throw new ArgumentNullException("inCnlNums"); if (inCnlNumParams == null) throw new ArgumentNullException("inCnlNumParams"); if (ctrlCnlNums == null) throw new ArgumentNullException("ctrlCnlNums"); if (ctrlCnlNumParams == null) throw new ArgumentNullException("ctrlCnlNumParams"); bool hasChannels = false; bool hasErrors = false; errMsg = ""; try { // загрузка настроек SCADA-Коммуникатора Scada.Comm.Settings commSett = new Scada.Comm.Settings(); if (!commSett.Load(commDirs.ConfigDir + Scada.Comm.Settings.DefFileName, out errMsg)) throw new Exception(errMsg); // заполнение справочника свойств КП Dictionary<int, KPView.KPProperties> kpPropsDict = new Dictionary<int, KPView.KPProperties>(); foreach (Scada.Comm.Settings.CommLine commLine in commSett.CommLines) { foreach (Scada.Comm.Settings.KP kp in commLine.ReqSequence) { if (!kpPropsDict.ContainsKey(kp.Number)) kpPropsDict.Add(kp.Number, new KPView.KPProperties(commLine.CustomParams, kp.CmdLine)); } } // определение стартового номера входного канала int inCnlsStart = inCnlNumParams.Start; int inCnlsMultiple = inCnlNumParams.Multiple; int inCnlsSpace = inCnlNumParams.Space; int remainder = inCnlsStart % inCnlsMultiple; int curInCnlNum = remainder > 0 ? inCnlsStart - remainder : inCnlsStart; curInCnlNum += inCnlNumParams.Shift; if (curInCnlNum < inCnlsStart) curInCnlNum += inCnlsMultiple; // определение стартового номера канала управления int ctrlCnlsStart = ctrlCnlNumParams.Start; int ctrlCnlsMultiple = ctrlCnlNumParams.Multiple; int ctrlCnlsSpace = ctrlCnlNumParams.Space; remainder = ctrlCnlsStart % ctrlCnlNumParams.Multiple; int curCtrlCnlNum = remainder > 0 ? ctrlCnlsStart - remainder : ctrlCnlsStart; curCtrlCnlNum += ctrlCnlNumParams.Shift; if (curCtrlCnlNum < ctrlCnlNumParams.Start) curCtrlCnlNum += ctrlCnlNumParams.Multiple; // расчёт номеров каналов КП int curInCnlInd = 0; int inCnlNumsCnt = inCnlNums.Count; int curCtrlCnlInd = 0; int ctrlCnlNumsCnt = ctrlCnlNums.Count; foreach (KPInfo kpInfo in kpInfoList) { if (kpInfo.Selected) { // получение типа интерфейса КП Type kpViewType; if (!kpViewTypes.TryGetValue(kpInfo.DllFileName, out kpViewType)) continue; // создание экземпляра класса интерфейса КП KPView kpView = null; try { kpView = KPFactory.GetKPView(kpViewType, kpInfo.KPNum); KPView.KPProperties kpProps; if (kpPropsDict.TryGetValue(kpInfo.KPNum, out kpProps)) kpView.KPProps = kpProps; kpView.AppDirs = commDirs; } catch { kpInfo.SetInCnlNums(true); kpInfo.SetCtrlCnlNums(true); continue; } // получение прототипов каналов КП по умолчанию try { kpInfo.DefaultCnls = kpView.DefaultCnls; } catch { kpInfo.SetInCnlNums(true); kpInfo.SetCtrlCnlNums(true); continue; } // определение номеров входных каналов с учётом занятых существующими каналами номеров if (kpInfo.DefaultCnls != null && kpInfo.DefaultCnls.InCnls.Count > 0) { hasChannels = true; int firstInCnlNum; // номер первого входного канала КП int lastInCnlNum; // номер последнего входного канала КП int newInCnlInd; // новый индекс списка номеров входных каналов CalcFirstAndLastNums(curInCnlNum, curInCnlInd, inCnlNums, inCnlNumsCnt, kpInfo.DefaultCnls.InCnls.Count, inCnlsSpace, inCnlsMultiple, out firstInCnlNum, out lastInCnlNum, out newInCnlInd); if (lastInCnlNum > ushort.MaxValue) { hasErrors = true; kpInfo.SetInCnlNums(true); } else { kpInfo.SetInCnlNums(false, firstInCnlNum, lastInCnlNum); curInCnlInd = newInCnlInd; curInCnlNum = firstInCnlNum; do { curInCnlNum += inCnlsMultiple; } while (curInCnlNum - lastInCnlNum <= inCnlsSpace); } } else { // номера каналов не назначаются, т.к. КП не поддерживает создание входных каналов kpInfo.SetInCnlNums(false); } // определение номеров каналов управления с учётом занятых существующими каналами номеров if (kpInfo.DefaultCnls != null && kpInfo.DefaultCnls.CtrlCnls.Count > 0) { hasChannels = true; int firstCtrlCnlNum; // номер первого канала управления КП int lastCtrlCnlNum; // номер последнего канала управления КП int newCtrlCnlInd; // новый индекс списка номеров каналов управления CalcFirstAndLastNums(curCtrlCnlNum, curCtrlCnlInd, ctrlCnlNums, ctrlCnlNumsCnt, kpInfo.DefaultCnls.CtrlCnls.Count, ctrlCnlsSpace, ctrlCnlsMultiple, out firstCtrlCnlNum, out lastCtrlCnlNum, out newCtrlCnlInd); if (lastCtrlCnlNum > ushort.MaxValue) { hasErrors = true; kpInfo.SetCtrlCnlNums(true); } else { kpInfo.SetCtrlCnlNums(false, firstCtrlCnlNum, lastCtrlCnlNum); curCtrlCnlInd = newCtrlCnlInd; curCtrlCnlNum = firstCtrlCnlNum; do { curCtrlCnlNum += ctrlCnlsMultiple; } while (curCtrlCnlNum - lastCtrlCnlNum <= ctrlCnlsSpace); } } else { // номера каналов не назначаются, т.к. КП не поддерживает создание каналов управления kpInfo.SetCtrlCnlNums(false); } } else { // номера каналов не назначаются, т.к. КП не выбран kpInfo.SetInCnlNums(false, -1, -1); kpInfo.SetCtrlCnlNums(false, -1, -1); } } if (hasErrors) errMsg = AppPhrases.CalcCnlNumsErrors; else if (!hasChannels) errMsg = AppPhrases.CreatedCnlsMissing; } catch (Exception ex) { hasErrors = true; errMsg = AppPhrases.CalcCnlNumsError + ":\r\n" + ex.Message; } return hasChannels && !hasErrors; }