From d84588650f92280eb32256f4d71bd730cce2a2f4 Mon Sep 17 00:00:00 2001 From: Milan Hanajik Date: Fri, 9 Apr 2021 11:26:52 +0200 Subject: [PATCH] ControlBoard.Papouch modified for 4 QuidoRS boards, ver. 3.1.1604 --- TBF/Properties/AssemblyInfo.cs | 4 +- .../Papouch/CBoardCfgCtrl.Designer.cs | 203 ----------- TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.cs | 143 -------- .../ControlBoard/Papouch/CBoardCfgCtrl.resx | 120 ------- TBF/Rig/ControlBoard/Papouch/PapouchCB.cs | 284 +++++++++------- TBF/Rig/ControlBoard/Papouch/PapouchCBCfg.cs | 317 ++++++++++++++++-- TBF/TBF.csproj | 9 - 7 files changed, 452 insertions(+), 628 deletions(-) delete mode 100644 TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.Designer.cs delete mode 100644 TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.cs delete mode 100644 TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.resx diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 9ace58492..37a3cfaae 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("3.1.1603.0")] -[assembly: AssemblyFileVersion("3.1.1603.0")] +[assembly: AssemblyVersion("3.1.1604.0")] +[assembly: AssemblyFileVersion("3.1.1604.0")] diff --git a/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.Designer.cs b/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.Designer.cs deleted file mode 100644 index 3fc1e39b6..000000000 --- a/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.Designer.cs +++ /dev/null @@ -1,203 +0,0 @@ -/// -/// Copyright (c) 2020 Sensus Slovensko a.s. -/// -namespace TBF.Rig.ControlBoard.Papouch -{ - partial class CBoardCfgCtrl - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.classNameLabel = new System.Windows.Forms.Label(); - this.nameLabel = new System.Windows.Forms.Label(); - this.nameTextBox = new System.Windows.Forms.TextBox(); - this.vValveRangeLoTextBox = new System.Windows.Forms.TextBox(); - this.vValveRangeLoLabel = new System.Windows.Forms.Label(); - this.vValveRangeHiTextBox = new System.Windows.Forms.TextBox(); - this.vValveRangeHiLabel = new System.Windows.Forms.Label(); - this.parentNameComboBox = new System.Windows.Forms.ComboBox(); - this.modbusAddressTextBox = new System.Windows.Forms.TextBox(); - this.modbusAddressLabel = new System.Windows.Forms.Label(); - this.parentNameLabel = new System.Windows.Forms.Label(); - this.variantComboBox = new System.Windows.Forms.ComboBox(); - this.variantLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // classNameLabel - // - this.classNameLabel.AutoSize = true; - this.classNameLabel.Location = new System.Drawing.Point(175, 26); - this.classNameLabel.Name = "classNameLabel"; - this.classNameLabel.Size = new System.Drawing.Size(83, 13); - this.classNameLabel.TabIndex = 2; - this.classNameLabel.Text = "ComonentName"; - // - // nameLabel - // - this.nameLabel.AutoSize = true; - this.nameLabel.Location = new System.Drawing.Point(42, 60); - this.nameLabel.Name = "nameLabel"; - this.nameLabel.Size = new System.Drawing.Size(35, 13); - this.nameLabel.TabIndex = 3; - this.nameLabel.Text = "Name"; - // - // nameTextBox - // - this.nameTextBox.Enabled = false; - this.nameTextBox.Location = new System.Drawing.Point(178, 57); - this.nameTextBox.Name = "nameTextBox"; - this.nameTextBox.Size = new System.Drawing.Size(130, 20); - this.nameTextBox.TabIndex = 4; - // - // vValveRangeLoTextBox - // - this.vValveRangeLoTextBox.Enabled = false; - this.vValveRangeLoTextBox.Location = new System.Drawing.Point(178, 161); - this.vValveRangeLoTextBox.Name = "vValveRangeLoTextBox"; - this.vValveRangeLoTextBox.Size = new System.Drawing.Size(46, 20); - this.vValveRangeLoTextBox.TabIndex = 6; - // - // vValveRangeLoLabel - // - this.vValveRangeLoLabel.AutoSize = true; - this.vValveRangeLoLabel.Location = new System.Drawing.Point(42, 164); - this.vValveRangeLoLabel.Name = "vValveRangeLoLabel"; - this.vValveRangeLoLabel.Size = new System.Drawing.Size(118, 13); - this.vValveRangeLoLabel.TabIndex = 5; - this.vValveRangeLoLabel.Text = "Virtual valves range Lo:"; - // - // vValveRangeHiTextBox - // - this.vValveRangeHiTextBox.Enabled = false; - this.vValveRangeHiTextBox.Location = new System.Drawing.Point(178, 186); - this.vValveRangeHiTextBox.Name = "vValveRangeHiTextBox"; - this.vValveRangeHiTextBox.Size = new System.Drawing.Size(46, 20); - this.vValveRangeHiTextBox.TabIndex = 8; - // - // vValveRangeHiLabel - // - this.vValveRangeHiLabel.AutoSize = true; - this.vValveRangeHiLabel.Location = new System.Drawing.Point(42, 189); - this.vValveRangeHiLabel.Name = "vValveRangeHiLabel"; - this.vValveRangeHiLabel.Size = new System.Drawing.Size(116, 13); - this.vValveRangeHiLabel.TabIndex = 7; - this.vValveRangeHiLabel.Text = "Virtual valves range Hi:"; - // - // parentNameComboBox - // - this.parentNameComboBox.Enabled = false; - this.parentNameComboBox.FormattingEnabled = true; - this.parentNameComboBox.Location = new System.Drawing.Point(178, 83); - this.parentNameComboBox.Name = "parentNameComboBox"; - this.parentNameComboBox.Size = new System.Drawing.Size(130, 21); - this.parentNameComboBox.TabIndex = 10; - // - // modbusAddressTextBox - // - this.modbusAddressTextBox.Enabled = false; - this.modbusAddressTextBox.Location = new System.Drawing.Point(178, 136); - this.modbusAddressTextBox.Name = "modbusAddressTextBox"; - this.modbusAddressTextBox.Size = new System.Drawing.Size(46, 20); - this.modbusAddressTextBox.TabIndex = 12; - // - // modbusAddressLabel - // - this.modbusAddressLabel.AutoSize = true; - this.modbusAddressLabel.Location = new System.Drawing.Point(42, 140); - this.modbusAddressLabel.Name = "modbusAddressLabel"; - this.modbusAddressLabel.Size = new System.Drawing.Size(86, 13); - this.modbusAddressLabel.TabIndex = 11; - this.modbusAddressLabel.Text = "Modbus Address"; - // - // parentNameLabel - // - this.parentNameLabel.AutoSize = true; - this.parentNameLabel.Location = new System.Drawing.Point(42, 86); - this.parentNameLabel.Name = "parentNameLabel"; - this.parentNameLabel.Size = new System.Drawing.Size(69, 13); - this.parentNameLabel.TabIndex = 9; - this.parentNameLabel.Text = "Parent Name"; - // - // variantComboBox - // - this.variantComboBox.Enabled = false; - this.variantComboBox.FormattingEnabled = true; - this.variantComboBox.Location = new System.Drawing.Point(178, 110); - this.variantComboBox.Name = "variantComboBox"; - this.variantComboBox.Size = new System.Drawing.Size(130, 21); - this.variantComboBox.TabIndex = 14; - // - // variantLabel - // - this.variantLabel.AutoSize = true; - this.variantLabel.Location = new System.Drawing.Point(42, 113); - this.variantLabel.Name = "variantLabel"; - this.variantLabel.Size = new System.Drawing.Size(40, 13); - this.variantLabel.TabIndex = 13; - this.variantLabel.Text = "Variant"; - // - // CBoardCfgCtrl - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.variantComboBox); - this.Controls.Add(this.variantLabel); - this.Controls.Add(this.parentNameComboBox); - this.Controls.Add(this.modbusAddressTextBox); - this.Controls.Add(this.modbusAddressLabel); - this.Controls.Add(this.parentNameLabel); - this.Controls.Add(this.vValveRangeHiTextBox); - this.Controls.Add(this.vValveRangeHiLabel); - this.Controls.Add(this.vValveRangeLoTextBox); - this.Controls.Add(this.vValveRangeLoLabel); - this.Controls.Add(this.nameTextBox); - this.Controls.Add(this.nameLabel); - this.Controls.Add(this.classNameLabel); - this.Name = "CBoardCfgCtrl"; - this.Size = new System.Drawing.Size(400, 300); - this.Load += new System.EventHandler(this.ControlBoardCfgCtrl_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label classNameLabel; - private System.Windows.Forms.Label nameLabel; - private System.Windows.Forms.TextBox nameTextBox; - private System.Windows.Forms.TextBox vValveRangeLoTextBox; - private System.Windows.Forms.Label vValveRangeLoLabel; - private System.Windows.Forms.TextBox vValveRangeHiTextBox; - private System.Windows.Forms.Label vValveRangeHiLabel; - private System.Windows.Forms.ComboBox parentNameComboBox; - private System.Windows.Forms.TextBox modbusAddressTextBox; - private System.Windows.Forms.Label modbusAddressLabel; - private System.Windows.Forms.Label parentNameLabel; - private System.Windows.Forms.ComboBox variantComboBox; - private System.Windows.Forms.Label variantLabel; - } -} diff --git a/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.cs b/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.cs deleted file mode 100644 index 97967f146..000000000 --- a/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.cs +++ /dev/null @@ -1,143 +0,0 @@ -/// -/// Copyright (c) 2020 Sensus Slovensko a.s. -/// -using System; -using System.Windows.Forms; -using Config.Entities; -using TBF.Rig.Generic; -using TBF.UI.Bench.Components; - -namespace TBF.Rig.ControlBoard.Papouch -{ - public partial class CBoardCfgCtrl : UserControl, IComponentCfgCtrl - { - ComponentParametersDlg parent; - - public bool ShowMore { get { return false; } } - - PapouchCBCfg config; - public IComponentCfg Config - { - get { return config as IComponentCfg; } - set - { - config = value as PapouchCBCfg; - Redraw(); - } - } - - public CBoardCfgCtrl() - { - InitializeComponent(); - } - - private void ControlBoardCfgCtrl_Load(object sender, EventArgs e) - { - parent = ParentForm as ComponentParametersDlg; - if (parent == null) return; - - if (parent.CmpntEntities != null) - { - foreach (var cmpnt in parent.CmpntEntities) - { - if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Modbus.Common.Factory) - { - parentNameComboBox.Items.Add(cmpnt.Name); - } - } - } - - for (QuidoVariant v = 0; v < QuidoVariant.Count; v++) variantComboBox.Items.Add(v.ToString()); - - Redraw(); - } - - public void Closing() - { - } - - void Redraw() - { - if (config == null) return; /// Control was not loaded, settings were not changed - - classNameLabel.Text = config.Factory.ClassName; - nameTextBox.Text = config.Name; - parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName; - variantComboBox.Text = config.Variant.ToString(); - modbusAddressTextBox.Text = config.ModbusAddress.ToString(); - vValveRangeLoTextBox.Text = config.VirtualValvesRangeLo.ToString(); - vValveRangeHiTextBox.Text = config.VirtualValvesRangeHi.ToString(); - } - - public void Unlock() - { - nameTextBox.Enabled = true; - parentNameComboBox.Enabled = true; - variantComboBox.Enabled = true; - modbusAddressTextBox.Enabled = true; - vValveRangeLoTextBox.Enabled = true; - vValveRangeHiTextBox.Enabled = true; - } - - /// - /// Verify current user controls for validity. - /// Called when user wants to close/save the configuration. - /// - /// See VerifyFlags - public CfgUpdateFlags VerifyCfg(ref string message) - { - CfgUpdateFlags flags = CfgUpdateFlags.None; - - int dummy; - if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text)) - { - flags |= CfgUpdateFlags.Error; - message += Environment.NewLine + "Invalid 'Parent Name'"; - } - if (!variantComboBox.Items.Contains(variantComboBox.Text)) - { - flags |= CfgUpdateFlags.Error; - message += Environment.NewLine + "Invalid 'Variant'"; - } - if (!int.TryParse(modbusAddressTextBox.Text, out dummy) || dummy < 0 || dummy > 255) - { - flags |= CfgUpdateFlags.Error; - message += Environment.NewLine + "'Modbus Address' should be between 0 and 255"; - } - if (!int.TryParse(vValveRangeLoTextBox.Text, out dummy) || dummy < 0 || dummy > 63) - { - message += "Virtual valves range Lo is invalid"; - flags |= CfgUpdateFlags.Error; - } - if (!int.TryParse(vValveRangeHiTextBox.Text, out dummy) || dummy < 0 || dummy > 63) - { - message += "Virtual valves range Hi is invalid"; - flags |= CfgUpdateFlags.Error; - } - - return flags; - } - - /// - /// Save settings to the configuration class. - /// - public CfgUpdateFlags UpdateCfg() - { - CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd; - - if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed - - this.Name = nameTextBox.Text; - config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text; - for (QuidoVariant v = 0; v < QuidoVariant.Count; v++) - { - if (variantComboBox.Text == v.ToString()) { config.Variant = v; break; } - } - config.ModbusAddress = (byte)int.Parse(modbusAddressTextBox.Text); - config.VirtualValvesRangeLo = int.Parse(vValveRangeLoTextBox.Text); - config.VirtualValvesRangeHi = int.Parse(vValveRangeHiTextBox.Text); - - return flags; - } - } -} diff --git a/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.resx b/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.resx deleted file mode 100644 index 1af7de150..000000000 --- a/TBF/Rig/ControlBoard/Papouch/CBoardCfgCtrl.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/TBF/Rig/ControlBoard/Papouch/PapouchCB.cs b/TBF/Rig/ControlBoard/Papouch/PapouchCB.cs index 23891b1b6..00ede71b9 100644 --- a/TBF/Rig/ControlBoard/Papouch/PapouchCB.cs +++ b/TBF/Rig/ControlBoard/Papouch/PapouchCB.cs @@ -22,17 +22,24 @@ namespace TBF.Rig.ControlBoard.Papouch public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); } readonly PapouchCBCfg cbCfg; - readonly GenericDevices.IModbus modbus; + + GenericDevices.IModbus modbus; - UInt32 currentOutputs; + const int quidosCount = 4; + QuidoVariant[] quidoVariants; + int[] modbusAddresses; + int[] offsetsOutputs; + int[] offsetsInputs; + UInt128[] routeOutputMasks; + UInt128[] routeInputMasks; + int[] lastStateMachineTimes; bool outputsInitialized; - DateTime lastOutputsChange; - int lastStateMachineTime = 0; /// + UInt128 currentOutputs; + UInt128 benchModelRoute; - UInt128 valvesToInvert; /// Route = valesToInvert ^ RequiredRouteWithoutInvertedVlaves - UInt128 routeMask; /// This mask masks out virtual valves, routeMask is set in the constructor - /// + UInt128 valvesToInvert; /// Route = valesToInvert ^ RequiredRouteWithoutInvertedVlaves + OutputPath devices; @@ -57,11 +64,6 @@ namespace TBF.Rig.ControlBoard.Papouch : base(cfg) { cbCfg = cfg as PapouchCBCfg; - - modbus = (GenericDevices.IModbus)TbfComponents.FindComponent(cfg.ParentName, components); - if (modbus == null) throw new Exception("Cannot find " + Name + " parent"); - - log.Warn(this.ToString()); } public void SpecifyInvertedValves(UInt128 valvesToInvert) @@ -70,73 +72,119 @@ namespace TBF.Rig.ControlBoard.Papouch this.benchModelRoute = valvesToInvert; } - /// - /// IDevice interface - /// public override void Initialize() { - outputsInitialized = false; - runningOp = SelectedOp.None; - routeMask = 0; + modbus = (GenericDevices.IModbus)TbfComponents.FindComponent(cbCfg.ParentName); + if (modbus == null) throw new Exception("Cannot find " + Name + " parent"); + + quidoVariants = new QuidoVariant[quidosCount] { cbCfg.Variant1, cbCfg.Variant2, cbCfg.Variant3, cbCfg.Variant4 }; + modbusAddresses = new int[quidosCount] { cbCfg.ModbusAddress1, cbCfg.ModbusAddress2, cbCfg.ModbusAddress3, cbCfg.ModbusAddress4 }; + offsetsOutputs = new int[quidosCount] { cbCfg.OffsetOutputs1, cbCfg.OffsetOutputs2, cbCfg.OffsetOutputs3, cbCfg.OffsetOutputs4 }; + offsetsInputs = new int[quidosCount] { cbCfg.OffsetInputs1, cbCfg.OffsetInputs2, cbCfg.OffsetInputs3, cbCfg.OffsetInputs4 }; + routeOutputMasks = new UInt128[quidosCount] { 0, 0, 0, 0 }; + routeInputMasks = new UInt128[quidosCount] { 0, 0, 0, 0 }; + lastStateMachineTimes = new int[quidosCount] { 0, 0, 0, 0 }; + for (int i = 0; i < 128; i++) { - if (i < cbCfg.VirtualValvesRangeLo || i > cbCfg.VirtualValvesRangeHi) + bool conflictAvoidanceFlag = false; + + for (int quidoIx = 0; quidoIx < quidosCount; quidoIx++) { - routeMask = routeMask | ((UInt128)1 << i); + if (i >= offsetsOutputs[quidoIx] && i < offsetsOutputs[quidoIx] + OutputsCount(quidoIx)) + { + if (conflictAvoidanceFlag) throw new Exception("Overlapping input/output bits"); + conflictAvoidanceFlag = true; + routeOutputMasks[quidoIx] = routeOutputMasks[quidoIx] | ((UInt128)1 << i); + } + + if (i >= offsetsInputs[quidoIx] && i < offsetsInputs[quidoIx] + InputsCount(quidoIx)) + { + if (conflictAvoidanceFlag) throw new Exception("Overlapping input/output bits"); + conflictAvoidanceFlag = true; + routeInputMasks[quidoIx] = routeInputMasks[quidoIx] | ((UInt128)1 << i); + } } } + outputsInitialized = false; + runningOp = SelectedOp.None; + TBF.UiBridge.Bridge.RouteChangeHandler += delegate(object sndr, TBF.UiBridge.RouteChangeArgs args) - { - UInt128 mask = ((UInt128)1) << args.BitNr; - if ((benchModelRoute & mask) == 0) { - benchModelRoute |= mask; - } - else - { - benchModelRoute &= (~mask); - } - }; + UInt128 mask = ((UInt128)1) << args.BitNr; + if ((benchModelRoute & mask) == 0) + { + benchModelRoute |= mask; + } + else + { + benchModelRoute &= (~mask); + } + }; + + if (cbCfg.DebugLevel == DebugMode.Normal) + log.FatalFormat("{0} initialized: {1}", cbCfg.Name, this); + else + log.FatalFormat("{0} simulated: {1}", cbCfg.Name, this); } + /// + /// IDevice interface + /// public void RunDeviceBefore() { - if (cbCfg.DebugLevel == Config.Entities.DebugMode.Simulate) return; - - if (modbus.ReceivedTelegrams[cbCfg.ModbusAddress].Count > 0) + for (int quidoIx = 0; quidoIx < quidosCount; quidoIx++ ) { - byte[] telegram = modbus.ReceivedTelegrams[cbCfg.ModbusAddress].Dequeue(); - - if ((telegram.Length >= 8) && (telegram[1] == 0x11) && (telegram[2] == telegram.Length - 5)) + if (modbus.ReceivedTelegrams[modbusAddresses[quidoIx]].Count > 0) { - int msgLen = telegram.Length - 7; - byte modbusAddress = telegram[3]; - string msg = Encoding.ASCII.GetString(telegram, 5, msgLen); - string s = string.Format("QuidoRS detected: Address={0}, Message={1}", modbusAddress, msg); - Debug.WriteLine(s); - log.Warn(s); - } + byte[] telegram = modbus.ReceivedTelegrams[modbusAddresses[quidoIx]].Dequeue(); - if ((telegram.Length == 6) && (telegram[1] == 0x02) && (telegram[2] == telegram.Length - 5)) - { - int inputData = telegram[3]; - string s = string.Format("QuidoRS inputs: {0}", inputData); - Debug.WriteLine(s); - log.Warn(s); + if ((telegram.Length >= 8) && (telegram[1] == 0x11) && (telegram[2] == telegram.Length - 5)) + { + int msgLen = telegram.Length - 7; + byte modbusAddress = telegram[3]; + string msg = Encoding.ASCII.GetString(telegram, 5, msgLen); + + string s = string.Format("Quido{0} detected: Address={1}, Message={2}", quidoIx + 1, modbusAddress, msg); + Debug.WriteLine(s); + log.Warn(s); + } + + if ((telegram.Length == 6) && (telegram[1] == 0x02) && (telegram[2] == telegram.Length - 5)) + { + UInt128 inputData = telegram[3]; + benchModelRoute = (benchModelRoute & ~routeInputMasks[quidoIx]) | ((inputData << offsetsInputs[quidoIx]) & routeInputMasks[quidoIx]); + + string s = string.Format("Quido{0} inputs: {1}", quidoIx + 1, telegram[3].ToString("X2")); + Debug.WriteLine(s); + log.Warn(s); + } } } } public void RunDeviceAfter() { - if (currentOutputs != (UInt32)(benchModelRoute & 0xFFFFFFFF) || !outputsInitialized || (StateMachine.Time - lastStateMachineTime) >= 3) + if (!outputsInitialized) { - SetOutputs((UInt32)(benchModelRoute & 0xFFFFFFFF)); + SendAllOutputs(benchModelRoute); + outputsInitialized = true; } else { - RequestInputs(); + for (int quidoIx = 0; quidoIx < quidosCount; quidoIx++) + { + if ((currentOutputs & routeOutputMasks[quidoIx]) != (benchModelRoute & routeOutputMasks[quidoIx]) || + (StateMachine.Time - lastStateMachineTimes[quidoIx]) >= 5) + { + SendOutputs(quidoIx, benchModelRoute, offsetsOutputs[quidoIx]); + } + else + { + RequestInputs(quidoIx); + } + } } ProcessData.UpdateMeasuredValuesAndSetpoints(); @@ -149,92 +197,94 @@ namespace TBF.Rig.ControlBoard.Papouch public void StopDevice() { - SendOutputs(0); + SendAllOutputs(0); } public void StopDevice2() { } - /// - /// Set outputs of QuidoRS board - /// - /// output value - public void SetOutputs(UInt32 outputs) + private void RequestAllInputs() { - lock (this) + for (int quidoIx = 0; quidoIx < quidosCount; quidoIx++) { - currentOutputs = outputs; + RequestInputs(quidoIx); } - SendOutputs(currentOutputs); } - /// - /// Set bit(s) specified by a bitMask. Leave other bits unaffeced. - /// - /// Specifies bit(s) to set - /// output value - public void SetBit(UInt32 bitMask) + private void RequestInputs(int quidoIx) { - lock (this) - { - currentOutputs = currentOutputs | bitMask; - } - SendOutputs(currentOutputs); - } - - /// - /// Reset bit(s) specified by a bitMask. Leave other bits unaffeced. - /// - /// Specifies bit(s) to reset - /// output value - public void ResetBit(UInt32 bitMask) - { - lock (this) - { - currentOutputs = currentOutputs & (~bitMask); - } - SendOutputs(currentOutputs); - } - - private void RequestInputs() - { - byte addr = cbCfg.ModbusAddress; + byte addr = (byte)modbusAddresses[quidoIx]; byte cmd = (byte)Function.ReadSingleInput; modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 2, 0, 0 }); } - private void SendOutputs(UInt32 outputs) + /// + /// Set outputs of QuidoRS board + /// + /// output value + private void SendAllOutputs(UInt128 route) { - byte addr = cbCfg.ModbusAddress; - byte cmd = (byte)Function.ForceMultipleCoils; - byte dataLo = (byte)(outputs & 0xFF); - byte data2 = (byte)(outputs >> 8); - byte data3 = (byte)(outputs >> 16); - byte dataHi = (byte)(outputs >> 24); - - if (cbCfg.Variant == QuidoVariant.QuidoRS_4_4) + for (int quidoIx = 0; quidoIx < quidosCount; quidoIx++) { - modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 4, 1, dataLo, 0, 0 }); + SendOutputs(quidoIx, route, offsetsOutputs[quidoIx]); } - else if (cbCfg.Variant == QuidoVariant.QuidoRS_8_8) - { - modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 8, 1, dataLo, 0, 0 }); - } - else if (cbCfg.Variant == QuidoVariant.QuidoRS_2_16) - { - modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 16, 2, dataLo, data2, 0, 0 }); - } - else if (cbCfg.Variant == QuidoVariant.QuidoRS_2_32) - { - modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 32, 4, dataLo, data2, data3, dataHi, 0, 0 }); - } - - outputsInitialized = true; - lastOutputsChange = DateTime.Now; - lastStateMachineTime = StateMachine.Time; } + private void SendOutputs(int quidoIx, UInt128 outputs, int offset) + { + if (cbCfg.DebugLevel == Config.Entities.DebugMode.Normal) + { + byte addr = (byte)modbusAddresses[quidoIx]; + byte cmd = (byte)Function.ForceMultipleCoils; + byte loByte = (byte)(outputs >> offset); + + switch (quidoVariants[quidoIx]) + { + case QuidoVariant.QuidoRS_4_4: + modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 4, 1, loByte, 0, 0 }); + break; + case QuidoVariant.QuidoRS_8_8: + modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 8, 1, loByte, 0, 0 }); + break; + case QuidoVariant.QuidoRS_2_16: + modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 16, 2, loByte, (byte)(outputs >> (offset + 8)), 0, 0 }); + break; + case QuidoVariant.QuidoRS_2_32: + modbus.SendMessage(new byte[] { addr, cmd, 0, 0, 0, 32, 4, loByte, (byte)(outputs >> (offset + 8)), + (byte)(outputs >> (offset + 16)), + (byte)(outputs >> (offset + 24)), 0, 0 }); + break; + } + } + + currentOutputs = (currentOutputs & ~routeOutputMasks[quidoIx]) | (outputs & routeOutputMasks[quidoIx]); + lastStateMachineTimes[quidoIx] = StateMachine.Time; + } + + int InputsCount(int quidoIx) + { + switch (quidoVariants[quidoIx]) + { + case QuidoVariant.QuidoRS_4_4: return 4; + case QuidoVariant.QuidoRS_8_8: return 8; + case QuidoVariant.QuidoRS_2_16: return 2; + case QuidoVariant.QuidoRS_2_32: return 2; + default: return 0; + } + } + + int OutputsCount(int quidoIx) + { + switch (quidoVariants[quidoIx]) + { + case QuidoVariant.QuidoRS_4_4: return 4; + case QuidoVariant.QuidoRS_8_8: return 8; + case QuidoVariant.QuidoRS_2_16: return 16; + case QuidoVariant.QuidoRS_2_32: return 32; + default: return 0; + } + } /// /// IControlBoard interface diff --git a/TBF/Rig/ControlBoard/Papouch/PapouchCBCfg.cs b/TBF/Rig/ControlBoard/Papouch/PapouchCBCfg.cs index 1fa11016d..fe3d3e624 100644 --- a/TBF/Rig/ControlBoard/Papouch/PapouchCBCfg.cs +++ b/TBF/Rig/ControlBoard/Papouch/PapouchCBCfg.cs @@ -1,7 +1,9 @@ -/// -/// Copyright (c) 2020 Sensus Slovensko a.s. +using Config.Entities; +/// +/// Copyright (c) 2020-2021 Sensus Slovensko a.s. /// using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; using TBF.Rig.Generic; @@ -9,6 +11,7 @@ namespace TBF.Rig.ControlBoard.Papouch { public enum QuidoVariant { + None, QuidoRS_4_4, QuidoRS_8_8, QuidoRS_2_16, @@ -16,47 +19,293 @@ namespace TBF.Rig.ControlBoard.Papouch Count } - public class PapouchCBCfg : ComponentCfgBase, Generic.IChildComponentCfg - { - public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PapouchCBCfg) })[0]; - public override XmlSerializer GetSerializer() { return Serializer; } + public class PapouchCBCfg : ComponentCfgBase, Generic.IChildComponentCfg, IParamsProvider + { + public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PapouchCBCfg) })[0]; + public override XmlSerializer GetSerializer() { return Serializer; } - public IComponentCfgCtrl GetControl(IList cmpntEntities) { return new CBoardCfgCtrl(); } + public IComponentCfgCtrl GetControl(IList cmpntEntities) + { + var parents = cmpntEntities.Where(x => x.ClassName == "Modbus.Common"); + return new Configs.ParamsProvider.ComponentCfgCtrl(this, parents); + } - /// - /// Serialized parameters - /// - public byte ModbusAddress; /// 1..254 - public QuidoVariant Variant; /// QuidoRS_2_16, QuidoRS_4_4 or QuidoRS_8_8 - public int VirtualValvesRangeLo; - public int VirtualValvesRangeHi; + /// + /// Serialized parameters + /// + public QuidoVariant Variant1; /// None, QuidoRS_4_4, QuidoRS_8_8, QuidoRS_2_16 or QuidoRS_2_32 + public int ModbusAddress1; /// 1 .. 254 + public int OffsetOutputs1; /// 0 .. (128 - output bits count) + public int OffsetInputs1; /// 0 .. (128 - input bits count) - /// Private parameterless constructor invoked by all other (public) constructors - PapouchCBCfg() - { - Name = "CB"; - ParentName = "Modbus"; - ModbusAddress = 1; - Variant = QuidoVariant.QuidoRS_2_32; - VirtualValvesRangeLo = 50; - VirtualValvesRangeHi = 59; - } + public QuidoVariant Variant2; /// None, QuidoRS_4_4, QuidoRS_8_8, QuidoRS_2_16 or QuidoRS_2_32 + public int ModbusAddress2; /// 1 .. 254 + public int OffsetOutputs2; /// 0 .. (128 - output bits count) + public int OffsetInputs2; /// 0 .. (128 - input bits count) + + public QuidoVariant Variant3; /// None, QuidoRS_4_4, QuidoRS_8_8, QuidoRS_2_16 or QuidoRS_2_32 + public int ModbusAddress3; /// 1 .. 254 + public int OffsetOutputs3; /// 0 .. (128 - output bits count) + public int OffsetInputs3; /// 0 .. (128 - input bits count) + + public QuidoVariant Variant4; /// None, QuidoRS_4_4, QuidoRS_8_8, QuidoRS_2_16 or QuidoRS_2_32 + public int ModbusAddress4; /// 1 .. 254 + public int OffsetOutputs4; /// 0 .. (128 - output bits count) + public int OffsetInputs4; /// 0 .. (128 - input bits count) + + /// Private parameterless constructor invoked by all other (public) constructors + PapouchCBCfg() { } public PapouchCBCfg(IComponentFactory factory) : this() { - this.Factory = factory; + Name = "CB"; + ParentName = "Modbus"; + InitializeAll(); + } + + public string ComponentName { get { return Name; } } + + public void InitializeAll() + { + Variant1 = QuidoVariant.QuidoRS_8_8; + ModbusAddress1 = 1; + OffsetOutputs1 = 0; + OffsetInputs1 = 64; + + Variant2 = QuidoVariant.None; + ModbusAddress2 = 0; + OffsetOutputs2 = 0; + OffsetInputs2 = 0; + + Variant3 = QuidoVariant.None; + ModbusAddress3 = 0; + OffsetOutputs3 = 0; + OffsetInputs3 = 0; + + Variant4 = QuidoVariant.None; + ModbusAddress4 = 0; + OffsetOutputs4 = 0; + OffsetInputs4 = 0; + } + + string[] paramNames = new string[] + { + "Board 1: Variant", /// 0 + "Board 1: Modbus address", /// 1 + "Board 1: Offset outputs", /// 2 + "Board 1: Offset inputs", /// 3 + "Board 2: Variant", /// 4 + "Board 2: Modbus address", /// 5 + "Board 2: Offset outputs", /// 6 + "Board 2: Offset inputs", /// 7 + "Board 3: Variant", /// 8 + "Board 3: Modbus address", /// 9 + "Board 3: Offset outputs", /// 10 + "Board 3: Offset inputs", /// 11 + "Board 4: Variant", /// 12 + "Board 4: Modbus address", /// 13 + "Board 4: Offset outputs", /// 14 + "Board 4: Offset inputs", /// 15 + }; + public string ParamName(int i) { return paramNames[i]; } + public int ParamsCount() { return paramNames.Length; } + + public ICollection ParamValues(int i) + { + switch (i) + { + case 0: + case 4: + case 8: + case 12: + return new string[] { QuidoVariant.None.ToString(), + QuidoVariant.QuidoRS_4_4.ToString(), + QuidoVariant.QuidoRS_8_8.ToString(), + QuidoVariant.QuidoRS_2_16.ToString(), + QuidoVariant.QuidoRS_2_32.ToString() }; + default: + return null; + } } public string ToString(int i) { - return string.Format("name={0}({1}) address={2} variant={3} vvLo={4} vvHi={5}", - Name, - (string.IsNullOrEmpty(ParentName) ? "-" : ParentName), - ModbusAddress, - Variant, - VirtualValvesRangeLo, - VirtualValvesRangeHi); - } - } + switch (i) + { + case 0: return Variant1.ToString(); + case 1: return ModbusAddress1.ToString(); + case 2: return OffsetOutputs1.ToString(); + case 3: return OffsetInputs1.ToString(); + + case 4: return Variant2.ToString(); + case 5: return ModbusAddress2.ToString(); + case 6: return OffsetOutputs2.ToString(); + case 7: return OffsetInputs2.ToString(); + + case 8: return Variant3.ToString(); + case 9: return ModbusAddress3.ToString(); + case 10: return OffsetOutputs3.ToString(); + case 11: return OffsetInputs3.ToString(); + + case 12: return Variant4.ToString(); + case 13: return ModbusAddress4.ToString(); + case 14: return OffsetOutputs4.ToString(); + case 15: return OffsetInputs4.ToString(); + + default: + return string.Format("name={0}({1}) {2}/a{3}/o{4}/i{5} {6}/a{7}/o{8}/i{9} {10}/a{11}/o{12}/i{13} {14}/a{15}/o{16}/i{17}", + Name, (string.IsNullOrEmpty(ParentName) ? "-" : ParentName), + Variant1, ModbusAddress1, OffsetOutputs1, OffsetInputs1, + Variant2, ModbusAddress2, OffsetOutputs2, OffsetInputs2, + Variant3, ModbusAddress3, OffsetOutputs3, OffsetInputs3, + Variant4, ModbusAddress4, OffsetOutputs4, OffsetInputs4); + } + } + + public CfgUpdateFlags UpdateParam(int i, string str) + { + switch (i) + { + case 0: + foreach (var v in new QuidoVariant[] { QuidoVariant.QuidoRS_4_4, QuidoVariant.QuidoRS_8_8, QuidoVariant.QuidoRS_2_16, QuidoVariant.QuidoRS_2_32 }) + { + if (str == v.ToString()) + { + Variant1 = v; + return CfgUpdateFlags.RestartRqrd; + } + } + Variant1 = QuidoVariant.None; + return CfgUpdateFlags.None; + + case 1: ModbusAddress1 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 2: OffsetOutputs1 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 3: OffsetInputs1 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + + case 4: + foreach (var v in new QuidoVariant[] { QuidoVariant.QuidoRS_4_4, QuidoVariant.QuidoRS_8_8, QuidoVariant.QuidoRS_2_16, QuidoVariant.QuidoRS_2_32 }) + { + if (str == v.ToString()) + { + Variant2 = v; + return CfgUpdateFlags.RestartRqrd; + } + } + Variant2 = QuidoVariant.None; + return CfgUpdateFlags.None; + + case 5: ModbusAddress2 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 6: OffsetOutputs2 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 7: OffsetInputs2 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + + case 8: + foreach (var v in new QuidoVariant[] { QuidoVariant.QuidoRS_4_4, QuidoVariant.QuidoRS_8_8, QuidoVariant.QuidoRS_2_16, QuidoVariant.QuidoRS_2_32 }) + { + if (str == v.ToString()) + { + Variant3 = v; + return CfgUpdateFlags.RestartRqrd; + } + } + Variant3 = QuidoVariant.None; + return CfgUpdateFlags.None; + + case 9: ModbusAddress3 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 10: OffsetOutputs3 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 11: OffsetInputs3 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + + case 12: + foreach (var v in new QuidoVariant[] { QuidoVariant.QuidoRS_4_4, QuidoVariant.QuidoRS_8_8, QuidoVariant.QuidoRS_2_16, QuidoVariant.QuidoRS_2_32 }) + { + if (str == v.ToString()) + { + Variant4 = v; + return CfgUpdateFlags.RestartRqrd; + } + } + Variant4 = QuidoVariant.None; + return CfgUpdateFlags.None; + + case 13: ModbusAddress4 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 14: OffsetOutputs4 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + case 15: OffsetInputs4 = (byte)int.Parse(str); return CfgUpdateFlags.RestartRqrd; + default: return CfgUpdateFlags.None; + } + } + + public bool ValidateParam(int i, string str, out string message) + { + message = string.Empty; + int idummy; + + switch (i) + { + case 0: + case 4: + case 8: + case 12: + if (ParamValues(i).Contains(str)) return true; + break; + + case 1: + case 5: + case 9: + case 13: + if (int.TryParse(str, out idummy) && idummy >= 1 && idummy <= 254) return true; + break; + + case 2: + case 3: + case 6: + case 7: + case 10: + case 11: + case 14: + case 15: + if (int.TryParse(str, out idummy) && idummy >= 0 && idummy <= 127) return true; + break; + + default: + message = "Invalid index"; + return false; + } + + message = ParamName(i) + " is invalid"; + return false; + } + + void CopyContentTo(PapouchCBCfg prms) + { + prms.ParentName = ParentName; + prms.Variant1 = Variant1; + prms.ModbusAddress1 = ModbusAddress1; + prms.OffsetOutputs1 = OffsetOutputs1; + prms.OffsetInputs1 = OffsetInputs1; + prms.Variant2 = Variant2; + prms.ModbusAddress2 = ModbusAddress2; + prms.OffsetOutputs2 = OffsetOutputs2; + prms.OffsetInputs2 = OffsetInputs2; + prms.Variant3 = Variant3; + prms.ModbusAddress3 = ModbusAddress3; + prms.OffsetOutputs3 = OffsetOutputs3; + prms.OffsetInputs3 = OffsetInputs3; + prms.Variant4 = Variant4; + prms.ModbusAddress4 = ModbusAddress4; + prms.OffsetOutputs4 = OffsetOutputs4; + prms.OffsetInputs4 = OffsetInputs4; + } + + public IParamsProvider Clone() + { + PapouchCBCfg pars = new PapouchCBCfg(); + CopyContentTo(pars); + return pars; + } + + public bool UpdateEmbeddedDbEntity() + { + return true; /// =OK, do nothing + } + } } diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj index 329e98217..8897ab4d0 100644 --- a/TBF/TBF.csproj +++ b/TBF/TBF.csproj @@ -220,12 +220,6 @@ - - UserControl - - - CBoardCfgCtrl.cs - @@ -2443,9 +2437,6 @@ ControlBoardCfgCtrl.cs - - CBoardCfgCtrl.cs - PumpCfgCtrl.cs