/// <summary> /// Updates the tag numbers starting from the specified element group node. /// </summary> private void UpdateTagNums(TreeNode startGroupNode) { // validate start node if (startGroupNode?.Tag is not ElemGroupConfig) { return; } // get start tag number TreeNode prevGroupNode = startGroupNode.PrevNode; int tagNum = prevGroupNode?.Tag is ElemGroupConfig prevElemGroup ? prevElemGroup.StartTagNum + prevElemGroup.Elems.Count : 1; // update element groups and elements for (int nodeIdx = startGroupNode.Index, nodeCnt = elemGroupsNode.Nodes.Count; nodeIdx < nodeCnt; nodeIdx++) { TreeNode groupNode = elemGroupsNode.Nodes[nodeIdx]; ElemGroupConfig elemGroup = (ElemGroupConfig)groupNode.Tag; elemGroup.StartTagNum = tagNum; int elemTagNum = tagNum; tagNum += elemGroup.Elems.Count; foreach (TreeNode elemNode in groupNode.Nodes) { ElemTag elem = (ElemTag)elemNode.Tag; elem.TagNum = elemTagNum++; } } }
/// <summary> /// Shows the element group configuration. /// </summary> private void ShowElemGroupConfig(ElemGroupConfig elemGroup) { numGrAddress.Minimum = AddrShift; numGrAddress.Maximum = ushort.MaxValue + AddrShift; numGrAddress.Value = 1; numGrAddress.Hexadecimal = !DecAddr; ShowFuncCode(elemGroup); if (elemGroup == null) { chkGrActive.Checked = false; txtGrName.Text = ""; cbGrDataBlock.SelectedIndex = 0; numGrAddress.SetValue(AddrShift); lblGrAddressHint.Text = ""; numGrElemCnt.Value = 1; gbElemGroup.Enabled = false; } else { chkGrActive.Checked = elemGroup.Active; txtGrName.Text = elemGroup.Name; cbGrDataBlock.SelectedIndex = (int)elemGroup.DataBlock; numGrAddress.SetValue(elemGroup.Address + AddrShift); lblGrAddressHint.Text = string.Format(ModbusDriverPhrases.AddressHint, AddrNotation, AddrShift); numGrElemCnt.Maximum = elemGroup.MaxElemCnt; numGrElemCnt.SetValue(elemGroup.Elems.Count); gbElemGroup.Enabled = true; } }
/// <summary> /// Initializes a new instance of the class. /// </summary> public ElemTag(DeviceTemplateOptions options, ElemGroupConfig elemGroupConfig, ElemConfig elemConfig) { TemplateOptions = options ?? throw new ArgumentNullException(nameof(options)); ElemGroup = elemGroupConfig ?? throw new ArgumentNullException(nameof(elemGroupConfig)); Elem = elemConfig ?? throw new ArgumentNullException(nameof(elemConfig)); Address = 0; TagNum = 0; }
/// <summary> /// Shows the element group configuration. /// </summary> private void ShowElemGroupConfig(ElemGroupConfig elemGroup) { ctrlElemGroup.Visible = true; ctrlElem.Visible = false; ctrlCmd.Visible = false; ctrlElemGroup.TemplateOptions = template.Options; ctrlElemGroup.ElemGroup = elemGroup; }
/// <summary> /// Shows the function code of the element group. /// </summary> private void ShowFuncCode(ElemGroupConfig elemGroup) { if (elemGroup == null) { txtGrFuncCode.Text = ""; } else { byte funcCode = ModbusUtils.GetReadFuncCode(elemGroup.DataBlock); txtGrFuncCode.Text = string.Format("{0} ({1}h)", funcCode, funcCode.ToString("X2")); } }
/// <summary> /// Creates a new Modbus command based on the element configuration. /// </summary> private ModbusCmd CreateModbusCmd(DeviceTemplateOptions options, ElemGroupConfig elemGroupConfig, ElemConfig elemConfig, int elemIndex) { ModbusCmd modbusCmd = deviceModel.CreateModbusCmd(elemGroupConfig.DataBlock, false); modbusCmd.Name = elemConfig.Name; modbusCmd.Address = (ushort)(elemGroupConfig.Address + elemIndex); modbusCmd.ElemType = elemConfig.ElemType; modbusCmd.ElemCnt = 1; modbusCmd.ByteOrder = ModbusUtils.ParseByteOrder(elemConfig.ByteOrder) ?? options.GetDefaultByteOrder(ModbusUtils.GetDataLength(elemConfig.ElemType)); modbusCmd.CmdNum = 0; modbusCmd.CmdCode = elemConfig.TagCode; modbusCmd.InitReqPDU(); modbusCmd.InitReqADU(deviceModel.Addr, transMode); return(modbusCmd); }
/// <summary> /// Initializes a new instance of the class. /// </summary> public FrmDeviceTemplate(AppDirs appDirs, CustomUi customUi) : this() { this.appDirs = appDirs ?? throw new ArgumentNullException(nameof(appDirs)); this.customUi = customUi ?? throw new ArgumentNullException(nameof(customUi)); elemGroupsNode = treeView.Nodes["elemGroupsNode"]; commandsNode = treeView.Nodes["commandsNode"]; template = null; modified = false; selectedNode = null; selectedElemGroup = null; selectedElemTag = null; selectedCmd = null; SaveOnly = false; FileName = ""; }
/// <summary> /// Creates a node that represents the specified element group. /// </summary> private TreeNode CreateElemGroupNode(ElemGroupConfig elemGroup) { TreeNode groupNode = new(GetElemGroupNodeText(elemGroup)) { Tag = elemGroup }; groupNode.SetImageKey(elemGroup.Active ? "group.png" : "group_inactive.png"); int elemAddr = elemGroup.Address; int elemTagNum = elemGroup.StartTagNum; foreach (ElemConfig elem in elemGroup.Elems) { groupNode.Nodes.Add(CreateElemNode(new ElemTag(template.Options, elemGroup, elem) { Address = elemAddr, TagNum = elemTagNum++ })); elemAddr += elem.Quantity; } return(groupNode); }
/// <summary> /// Fills the tree view according to the device template. /// </summary> private void FillTree() { // reset selected objects selectedNode = null; selectedElemGroup = null; selectedElemTag = null; selectedCmd = null; ShowElemGroupConfig(null); try { treeView.BeginUpdate(); elemGroupsNode.Nodes.Clear(); commandsNode.Nodes.Clear(); // fill element groups foreach (ElemGroupConfig elemGroup in template.ElemGroups) { elemGroupsNode.Nodes.Add(CreateElemGroupNode(elemGroup)); } // fill commands foreach (CmdConfig modbusCmd in template.Cmds) { commandsNode.Nodes.Add(CreateCmdNode(modbusCmd)); } elemGroupsNode.Expand(); commandsNode.Expand(); treeView.SelectedNode = elemGroupsNode; } finally { treeView.EndUpdate(); } }
private ElemGroupConfig elemGroup; // the element group configuration /// <summary> /// Initializes a new instance of the class. /// </summary> public CtrlElemGroup() { InitializeComponent(); elemGroup = null; TemplateOptions = null; }
/// <summary> /// Shows the element configuration. /// </summary> private void ShowElemConfig(ElemTag elemTag) { if (elemTag == null) { txtElemName.Text = ""; txtElemTagCode.Text = ""; pnlElemTagCodeWarn.Visible = false; txtElemTagNum.Text = ""; txtElemAddress.Text = ""; rbBool.Checked = true; txtElemByteOrder.Text = ""; chkElemReadOnly.Checked = false; chkElemIsBitMask.Checked = false; gbElem.Enabled = false; } else { ElemGroupConfig elemGroup = elemTag.ElemGroup; ElemConfig elem = elemTag.Elem; txtElemName.Text = elem.Name; txtElemTagCode.Text = elem.TagCode; pnlElemTagCodeWarn.Visible = string.IsNullOrEmpty(elem.TagCode); txtElemTagNum.Text = elemTag.TagNum.ToString(); txtElemAddress.Text = elemTag.AddressRange; if (elem.ElemType == ElemType.Bool) { rbUShort.Enabled = rbShort.Enabled = rbUInt.Enabled = rbInt.Enabled = rbULong.Enabled = rbLong.Enabled = rbFloat.Enabled = rbDouble.Enabled = false; rbBool.Enabled = true; } else { rbUShort.Enabled = rbShort.Enabled = rbUInt.Enabled = rbInt.Enabled = rbULong.Enabled = rbLong.Enabled = rbFloat.Enabled = rbDouble.Enabled = true; rbBool.Enabled = false; } switch (elem.ElemType) { case ElemType.UShort: rbUShort.Checked = true; break; case ElemType.Short: rbShort.Checked = true; break; case ElemType.UInt: rbUInt.Checked = true; break; case ElemType.Int: rbInt.Checked = true; break; case ElemType.ULong: rbULong.Checked = true; break; case ElemType.Long: rbLong.Checked = true; break; case ElemType.Float: rbFloat.Checked = true; break; case ElemType.Double: rbDouble.Checked = true; break; default: rbBool.Checked = true; break; } txtElemByteOrder.Text = elem.ByteOrder; txtElemByteOrder.Enabled = elemGroup.ByteOrderEnabled; chkElemReadOnly.Checked = elem.ReadOnly; chkElemReadOnly.Enabled = elemGroup.ReadOnlyEnabled; chkElemIsBitMask.Checked = elem.IsBitMask; chkElemIsBitMask.Enabled = elemGroup.BitMaskEnabled; gbElem.Enabled = true; } }
/// <summary> /// Gets the command node text. /// </summary> private static string GetElemGroupNodeText(ElemGroupConfig elemGroup) { return(string.Format("{0} ({1})", string.IsNullOrEmpty(elemGroup.Name) ? ModbusDriverPhrases.UnnamedElemGroup : elemGroup.Name, ModbusUtils.GetDataBlockName(elemGroup.DataBlock))); }