/// <summary> /// Обновить узлы элементов выбранной группы /// </summary> private void UpdateElemNodes(TreeNode grNode = null) { treeView.BeginUpdate(); if (grNode == null) { grNode = selNode; } if (grNode.Tag is Modbus.ElemGroup) { Modbus.ElemGroup elemGroup = (Modbus.ElemGroup)grNode.Tag; ushort elemAddr = elemGroup.Address; int elemSig = elemGroup.StartKPTagInd + 1; foreach (TreeNode elemNode in grNode.Nodes) { ElemInfo elemInfo = elemNode.Tag as ElemInfo; elemInfo.Address = elemAddr; elemInfo.Signal = elemSig++; elemNode.Text = elemInfo.Caption; elemAddr += (ushort)elemInfo.Elem.Length; } } treeView.EndUpdate(); }
private void btnDelete_Click(object sender, EventArgs e) { if (selElemGroup != null) { // удаление группы элементов devTemplate.ElemGroups.Remove(selElemGroup); grsNode.Nodes.Remove(selNode); } else if (selElemInfo != null) { // удаление элемента Modbus.ElemGroup elemGroup = selElemInfo.ElemGroup; elemGroup.Elems.Remove(selElemInfo.Elem); TreeNode grNode = selNode.Parent; grsNode.Nodes.Remove(selNode); UpdateElemNodes(grNode); UpdateSignals(grNode); ShowElemProps(selElemInfo); } else if (selCmd != null) { // удаление команды devTemplate.Cmds.Remove(selCmd); cmdsNode.Nodes.Remove(selNode); } // установка признака изменения Modified = true; }
/// <summary> /// Обновить сигналы КП элементов групп, начиная с заданного узла дерева /// </summary> private void UpdateSignals(TreeNode startGrNode) { // проверка корректности заданного узла дерева if (!(startGrNode.Tag is Modbus.ElemGroup)) { return; } // определение начального индекса тегов КП TreeNode prevGrNode = startGrNode.PrevNode; Modbus.ElemGroup prevElemGroup = prevGrNode == null ? null : prevGrNode.Tag as Modbus.ElemGroup; int tagInd = prevElemGroup == null ? 0 : prevElemGroup.StartKPTagInd + prevElemGroup.Elems.Count; // обновление групп и их элементов int grNodeCnt = grsNode.Nodes.Count; for (int i = startGrNode.Index; i < grNodeCnt; i++) { TreeNode grNode = grsNode.Nodes[i]; Modbus.ElemGroup elemGroup = grNode.Tag as Modbus.ElemGroup; int elemSig = tagInd + 1; elemGroup.StartKPTagInd = tagInd; tagInd += elemGroup.Elems.Count; foreach (TreeNode elemNode in grNode.Nodes) { ElemInfo elem = elemNode.Tag as ElemInfo; elem.Signal = elemSig++; } } }
/// <summary> /// Отобразить свойства группы элементов /// </summary> private void ShowElemGroupProps(Modbus.ElemGroup elemGroup) { procChangedEv = false; gbElemGroup.Visible = true; gbElem.Visible = false; gbCmd.Visible = false; if (elemGroup == null) { txtGrName.Text = ""; cbGrTableType.SelectedIndex = 0; numGrAddress.Value = 1; numGrElemCnt.Value = 1; gbElemGroup.Enabled = false; } else { txtGrName.Text = elemGroup.Name; cbGrTableType.SelectedIndex = (int)elemGroup.TableType; numGrAddress.Value = elemGroup.Address + 1; numGrElemCnt.Value = 1; numGrElemCnt.Maximum = Modbus.ElemGroup.GetMaxElemCnt(elemGroup.TableType); numGrElemCnt.Value = elemGroup.Elems.Count; gbElemGroup.Enabled = true; } procChangedEv = true; }
/// <summary> /// Создать узел группы элементов /// </summary> private TreeNode NewElemGroupNode(Modbus.ElemGroup elemGroup) { string name = elemGroup.Name == "" ? KpPhrases.DefGrName : elemGroup.Name; TreeNode grNode = new TreeNode(name + " (" + Modbus.GetTableTypeName(elemGroup.TableType) + ")"); grNode.ImageKey = grNode.SelectedImageKey = "group.png"; grNode.Tag = elemGroup; ushort elemAddr = elemGroup.Address; int elemSig = elemGroup.StartKPTagInd + 1; foreach (Modbus.Elem elem in elemGroup.Elems) { ElemInfo elemInfo = new ElemInfo(); elemInfo.Elem = elem; elemInfo.ElemGroup = elemGroup; elemInfo.Address = elemAddr; elemInfo.Signal = elemSig++; grNode.Nodes.Add(NewElemNode(elemInfo)); elemAddr += (ushort)elem.Length; } return(grNode); }
/// <summary> /// Установить значения тегов КП в соответствии со значениями элементов группы /// </summary> private void SetTagsData(Modbus.ElemGroup elemGroup) { int len = elemGroup.ElemVals.Length; for (int i = 0, j = elemGroup.StartKPTagInd + i; i < len; i++, j++) { SetCurData(j, elemGroup.GetElemVal(i), BaseValues.CnlStatuses.Defined); } }
/// <summary> /// Установить значения параметров КП в соответствии со значениями элементов группы /// </summary> private void SetParamsData(Modbus.ElemGroup elemGroup) { int len = elemGroup.ElemVals.Length; for (int i = 0, j = elemGroup.StartParamInd + i; i < len; i++, j++) { SetParamData(j, elemGroup.GetElemVal(i), BaseValues.ParamStat.Defined); } }
/// <summary> /// Выполнить сеанс опроса в режиме TCP /// </summary> private void TcpSession() { if (TcpConnect()) { int elemGroupInd = 0; while (elemGroupInd < elemGroupCnt && lastCommSucc) { Modbus.ElemGroup elemGroup = deviceModel.ElemGroups[elemGroupInd]; lastCommSucc = false; tryNum = 0; while (RequestNeeded() && netStream != null) { // выполнение запроса if (request(elemGroup)) { lastCommSucc = true; SetParamsData(elemGroup); // установка значений параметров } // разрыв соединения в случае ошибки работы TCP-сокета if (modbus.NetStream == null) { netStream = null; TcpDisconnect(); } // завершение запроса FinishRequest(); tryNum++; } if (lastCommSucc) { // переход к следующей группе элементов elemGroupInd++; } else if (tryNum > 0) { // установка неопределённого статуса параметров КП текущей и следующих групп, если запрос неудачный while (elemGroupInd < elemGroupCnt) { InvalParamsData(elemGroup); elemGroupInd++; } } } } else { InvalParamsData(null); // установка неопределённого статуса всех параметров КП Thread.Sleep(KPReqParams.Delay); lastCommSucc = false; } }
private void btnMoveDown_Click(object sender, EventArgs e) { // перемещение объекта вниз TreeNode nextNode = selNode.NextNode; int nextInd = nextNode.Index; if (selElemGroup != null) { // перемещение группы элементов вниз Modbus.ElemGroup nextElemGroup = nextNode.Tag as Modbus.ElemGroup; devTemplate.ElemGroups.RemoveAt(nextInd); devTemplate.ElemGroups.Insert(nextInd - 1, nextElemGroup); grsNode.Nodes.RemoveAt(nextInd); grsNode.Nodes.Insert(nextInd - 1, nextNode); UpdateSignals(nextNode); } else if (selElemInfo != null) { // перемещение элемента вниз ElemInfo nextElemInfo = nextNode.Tag as ElemInfo; selElemInfo.ElemGroup.Elems.RemoveAt(nextInd); selElemInfo.ElemGroup.Elems.Insert(nextInd - 1, nextElemInfo.Elem); TreeNode grNode = selNode.Parent; grNode.Nodes.RemoveAt(nextInd); grNode.Nodes.Insert(nextInd - 1, nextNode); UpdateElemNodes(grNode); ShowElemProps(selElemInfo); } else if (selCmd != null) { // перемещение команды вниз Modbus.Cmd nextCmd = nextNode.Tag as Modbus.Cmd; devTemplate.Cmds.RemoveAt(nextInd); devTemplate.Cmds.Insert(nextInd - 1, nextCmd); cmdsNode.Nodes.RemoveAt(nextInd); cmdsNode.Nodes.Insert(nextInd - 1, nextNode); } // установка доступности кнопок btnMoveUp.Enabled = selNode.PrevNode != null; btnMoveDown.Enabled = selNode.NextNode != null; // установка признака изменения Modified = true; }
private bool procChangedEv; // обрабатывать события на изменение данных /// <summary> /// Конструктор /// </summary> public FrmDevTemplate() { InitializeComponent(); devTemplate = new Modbus.DeviceModel(); modified = false; fileName = ""; selElemGroup = null; selElemInfo = null; selCmd = null; selNode = null; grsNode = treeView.Nodes["grsNode"]; cmdsNode = treeView.Nodes["cmdsNode"]; procChangedEv = false; ConfigDir = ""; LangDir = ""; }
private void treeView_AfterSelect(object sender, TreeViewEventArgs e) { // отображение выбранного объекта и его свойств selNode = e.Node; object tag = selNode.Tag; selElemGroup = tag as Modbus.ElemGroup; selElemInfo = tag as ElemInfo; selCmd = tag as Modbus.Cmd; if (selElemGroup != null) { ShowElemGroupProps(selElemGroup); } else if (selElemInfo != null) { ShowElemProps(selElemInfo); } else if (selCmd != null) { ShowCmdProps(selCmd); } else if (selNode == grsNode) { ShowElemGroupProps(null); } else if (selNode == cmdsNode) { ShowCmdProps(null); } else // не выполняется { DisableProps(); } // установка доступности кнопок btnAddElem.Enabled = selElemGroup != null || selElemInfo != null; bool nodeIsOk = selElemGroup != null || selCmd != null || selElemInfo != null && selElemInfo.ElemGroup.Elems.Count > 1 /*последний не удалять*/; btnMoveUp.Enabled = nodeIsOk && selNode.PrevNode != null; btnMoveDown.Enabled = nodeIsOk && selNode.NextNode != null; btnDelete.Enabled = nodeIsOk; }
/// <summary> /// Установка неопределённого статуса тегов КП, соотвующих элементам группы /// </summary> private void InvalTagsData(Modbus.ElemGroup elemGroup) { if (elemGroup == null) { int len = KPTags == null ? 0 : KPTags.Length; for (int i = 0; i < len; i++) { SetCurData(i, curData[i].Val, BaseValues.CnlStatuses.Undefined); } } else { int len = elemGroup.ElemVals.Length; for (int i = 0, j = elemGroup.StartKPTagInd + i; i < len; i++, j++) { SetCurData(j, curData[j].Val, BaseValues.CnlStatuses.Undefined); } } }
private bool procChangedEv; // обрабатывать события на изменение данных /// <summary> /// Конструктор, ограничивающий создание формы без параметров /// </summary> private FrmDevTemplate() { InitializeComponent(); appDirs = null; initialFileName = ""; fileName = ""; saveOnly = false; devTemplate = null; modified = false; selElemGroup = null; selElemInfo = null; selCmd = null; selNode = null; grsNode = treeView.Nodes["grsNode"]; cmdsNode = treeView.Nodes["cmdsNode"]; procChangedEv = false; }
/// <summary> /// Установка неопределённого статуса параметров КП, соотвующих элементам группы /// </summary> private void InvalParamsData(Modbus.ElemGroup elemGroup) { if (elemGroup == null) { int len = KPParams == null ? 0 : KPParams.Length; for (int i = 0; i < len; i++) { SetParamData(i, CurData[i].Val, BaseValues.ParamStat.Undefined); } } else { int len = elemGroup.ElemVals.Length; for (int i = 0, j = elemGroup.StartParamInd + i; i < len; i++, j++) { SetParamData(j, CurData[j].Val, BaseValues.ParamStat.Undefined); } } }
/// <summary> /// Выполнить сеанс опроса в режиме RTU или ASCII /// </summary> private void SerialSession() { int elemGroupInd = 0; while (elemGroupInd < elemGroupCnt && lastCommSucc) { Modbus.ElemGroup elemGroup = deviceModel.ElemGroups[elemGroupInd]; lastCommSucc = false; tryNum = 0; while (RequestNeeded()) { // выполнение запроса if (request(elemGroup)) { lastCommSucc = true; SetParamsData(elemGroup); // установка значений параметров } // завершение запроса FinishRequest(); tryNum++; } if (lastCommSucc) { // переход к следующей группе элементов elemGroupInd++; } else if (tryNum > 0) { // установка неопределённого статуса параметров КП текущей и следующих групп, если запрос неудачный while (elemGroupInd < elemGroupCnt) { InvalParamsData(elemGroup); elemGroupInd++; } } } }
private void btnAddElemGroup_Click(object sender, EventArgs e) { // создание группы элементов и добавление в шаблон устройства Modbus.ElemGroup elemGroup = new Modbus.ElemGroup(Modbus.TableTypes.DiscreteInputs); elemGroup.Elems.Add(new Modbus.Elem()); int ind = selNode != null && selNode.Tag is Modbus.ElemGroup ? selNode.Index + 1 : devTemplate.ElemGroups.Count; devTemplate.ElemGroups.Insert(ind, elemGroup); // создание узла дерева группы элементов TreeNode grNode = NewElemGroupNode(elemGroup); grsNode.Nodes.Insert(ind, grNode); UpdateSignals(grNode); grNode.Expand(); treeView.SelectedNode = grNode; txtGrName.Select(); // установка признака изменения Modified = true; }
/// <summary> /// Заполнить дерево в соответствии с шаблоном устройства /// </summary> private void FillTree() { // обнуление выбранных объектов и снятие признака изменения selElemGroup = null; selElemInfo = null; selCmd = null; selNode = null; ShowElemGroupProps(null); Modified = false; // приостановка отрисовки дерева treeView.BeginUpdate(); // очистка дерева grsNode.Nodes.Clear(); cmdsNode.Nodes.Clear(); treeView.SelectedNode = grsNode; // заполнение узла групп элементов foreach (Modbus.ElemGroup elemGroup in devTemplate.ElemGroups) { grsNode.Nodes.Add(NewElemGroupNode(elemGroup)); } // заполнение узла команд foreach (Modbus.Cmd cmd in devTemplate.Cmds) { cmdsNode.Nodes.Add(NewCmdNode(cmd)); } // раскрытие основных узлов дерева grsNode.Expand(); cmdsNode.Expand(); // возобновление отрисовки дерева treeView.EndUpdate(); }
private void btnAddElem_Click(object sender, EventArgs e) { // создание элемента и добавление в шаблон устройства Modbus.ElemGroup elemGroup = selElemGroup == null ? selElemInfo.ElemGroup : selElemGroup; int maxElemCnt = Modbus.ElemGroup.GetMaxElemCnt(elemGroup.TableType); if (elemGroup.Elems.Count >= maxElemCnt) { MessageBox.Show(string.Format(KpPhrases.ElemCntExceeded, maxElemCnt), CommonPhrases.WarningCaption, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } ElemInfo elemInfo = new ElemInfo(); elemInfo.Elem = new Modbus.Elem() { ElemType = elemGroup.DefElemType }; elemInfo.ElemGroup = elemGroup; int ind = selNode.Tag is ElemInfo ? selNode.Index + 1 : elemGroup.Elems.Count; elemGroup.Elems.Insert(ind, elemInfo.Elem); // создание узла дерева элемента TreeNode elemNode = NewElemNode(elemInfo); TreeNode grNode = selNode.Tag is ElemInfo ? selNode.Parent : selNode; grNode.Nodes.Insert(ind, elemNode); UpdateElemNodes(grNode); UpdateSignals(grNode); treeView.SelectedNode = elemNode; txtElemName.Select(); // установка признака изменения Modified = true; }
/// <summary> /// Выполнить сеанс опроса КП /// </summary> public override void Session() { base.Session(); if (deviceModel == null) { WriteToLog(Localization.UseRussian ? "Нормальное взаимодействие с КП невозможно, т.к. шаблон устройства не загружен" : "Normal device communication is impossible because device template has not been loaded"); Thread.Sleep(ReqParams.Delay); lastCommSucc = false; } else { if (deviceModel.ElemGroups.Count > 0) { // выполнение запросов по группам элементов int elemGroupInd = 0; while (elemGroupInd < elemGroupCnt && lastCommSucc) { Modbus.ElemGroup elemGroup = deviceModel.ElemGroups[elemGroupInd]; lastCommSucc = false; int tryNum = 0; while (RequestNeeded(ref tryNum)) { // выполнение запроса if (request(elemGroup)) { lastCommSucc = true; SetTagsData(elemGroup); // установка значений тегов КП } // завершение запроса FinishRequest(); tryNum++; } if (lastCommSucc) { // переход к следующей группе элементов elemGroupInd++; } else if (tryNum > 0) { // установка неопределённого статуса тегов КП текущей и следующих групп, если запрос неудачный while (elemGroupInd < elemGroupCnt) { InvalTagsData(elemGroup); elemGroupInd++; } } } } else { WriteToLog(Localization.UseRussian ? "Отсутствуют элементы для запроса" : "No elements for request"); Thread.Sleep(ReqParams.Delay); } } // расчёт статистики CalcSessStats(); }