/// <summary> /// Gets a user interface object for the device. /// </summary> private bool GetDeviceView(Settings.KP kp, bool common, out KPView kpView) { try { string dllPath = Path.Combine(Environment.AppDirs.KPDir, kp.Dll); KPView commonKpView = Environment.GetKPView(dllPath); if (common) { kpView = commonKpView; } else { kpView = KPFactory.GetKPView(commonKpView.GetType(), kp.Number); kpView.KPProps = new KPView.KPProperties(CustomParams, kp.CmdLine); kpView.AppDirs = Environment.AppDirs; } return(true); } catch (Exception ex) { ScadaUiUtils.ShowError(ex.Message); Environment.ErrLog.WriteException(ex); kpView = null; return(false); } }
/// <summary> /// Gets the user interface of the particular device. /// </summary> public KPView GetKPView(string dllPath, int kpNum, KPView.KPProperties kpProps) { KPView commonKpView = GetKPView(dllPath); KPView kpView = KPFactory.GetKPView(commonKpView.GetType(), kpNum); kpView.KPProps = kpProps ?? throw new ArgumentNullException("kpProps"); kpView.AppDirs = AppDirs; return(kpView); }
/// <summary> /// Gets the user interface of the driver. /// </summary> public KPView GetKPView(string dllPath) { if (!KPViews.TryGetValue(dllPath, out KPView kpView)) { kpView = KPFactory.GetKPView(dllPath); kpView.AppDirs = AppDirs; KPViews[dllPath] = kpView; } return(kpView); }
private void cbDevice_SelectedIndexChanged(object sender, EventArgs e) { // create a user interface of the selected device CnlPrototypes = null; if (cbDevice.SelectedItem is KP kp) { if (deviceItems.TryGetValue(kp.KPNum, out DeviceItem deviceItem) && deviceItem.Instance != null) { try { if (deviceItem.KPView == null) { CommDirs commDirs = new CommDirs( appData.AppSettings.PathOptions.CommDir, deviceItem.Instance); deviceItem.KPView = KPFactory.GetKPView( Path.Combine(commDirs.KPDir, deviceItem.KPSettings.Dll), kp.KPNum); deviceItem.KPView.KPProps = new KPView.KPProperties( deviceItem.CommLineSettings.CustomParams, deviceItem.KPSettings.CmdLine); deviceItem.KPView.AppDirs = commDirs; } CnlPrototypes = deviceItem.KPView.DefaultCnls; int inCnlCnt = CnlPrototypes == null ? 0 : CnlPrototypes.InCnls.Count; int ctrlCnlCnt = CnlPrototypes == null ? 0 : CnlPrototypes.CtrlCnls.Count; txtInfo.Text = string.Format(AppPhrases.DeviceInfo, deviceItem.KPSettings.Dll, deviceItem.Instance.Name, inCnlCnt, ctrlCnlCnt); pbStatus.Image = inCnlCnt > 0 || ctrlCnlCnt > 0 ? Properties.Resources.success : Properties.Resources.warning; } catch (Exception ex) { txtInfo.Text = ex.Message; pbStatus.Image = Properties.Resources.error; } } else { txtInfo.Text = AppPhrases.DeviceNotFound; pbStatus.Image = Properties.Resources.warning; } } else { txtInfo.Text = AppPhrases.NoDeviceSelected; pbStatus.Image = Properties.Resources.warning; } OnSelectedDeviceChanged(); }
/// <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> /// 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); }