Compare commits

..
Author SHA1 Message Date
michal 20f76ca515 iPerl Reader - NOT FINISHED
Add initial implementation for `iPerlReaderUNI` with `Factory`, `ProcParams`, and `IPerlReader` classes.
2025-09-18 15:24:42 +02:00
michal 9863b54bc8 Enhance ScopedLoggerFactory to support log file compression with rolling, include LogZipService for managing zipped archives, and update CliRunner configuration accordingly. 2025-09-17 13:00:17 +02:00
michal e57c6a6a02 Add ShowDialog and SaveCommunication fields to EntryFormCfg, implement related functionalities in PoseidonReader and EntryForm, and improve logging with ScopedLoggerFactory integration. 2025-09-17 10:45:40 +02:00
michal afa215534c Version increment to 3.9.2146.4 2025-09-09 20:48:19 +02:00
michal 780d44166e Refactor PoseidonReader to use lazy initialization for CliRunner, introduce SafetyTimeOut, enhance JSON deserialization with fallback logic, and improve error logging using log4net. 2025-09-09 20:47:53 +02:00
michal 35e4078dda Merge branch 'master-3' into PoseidonCmd 2025-09-09 15:13:29 +02:00
michal 47e09584f2 Frequency pulse meter 2025-09-09 12:51:26 +02:00
michal fc8e82c0e8 Merge branch 'master-3' into feature/processLogging
# Conflicts:
#	TBF/Rig/Sequences/ProcessData.cs
#	TBF/Rig/TestMethods/PMaxTest/PMaxTestSeq.cs
2025-09-09 12:24:20 +02:00
michal a20b0761fd Fix nested string formatting in DoubleBox's return statement
Revised the return statement to correctly handle nested string formatting by ensuring the format string is constructed properly. This resolves potential formatting issues with dynamic values.
2025-03-26 10:22:50 +01:00
michal 3b9e8d754d fix valve Debug Simulate mode 2025-01-10 08:48:52 +01:00
michal fed3281525 log for processData in LeakTestSeq.cs set 2025-01-08 07:43:58 +01:00
michal c1d966d86a final add process data to PMaxTestSeq.cs 2025-01-07 16:23:01 +01:00
michal b2d2f8c13b Solved problem with Null Exeprion in ProcessData.cs 2025-01-07 16:22:18 +01:00
michal 4e5e3d63e1 Fixed problem with F2 formating of decimal num 2025-01-07 16:21:28 +01:00
michal 25602fb914 Bug fix - Refactor flow meter handling and add validation checks.
Simplified flow meter logic by introducing a reusable variable for `LtrPerPulse` and handling potential null values. Added batch components correlation validation to ensure water meter counts align with configuration, preventing mismatches. Additionally, improved code formatting for consistency and readability.
2024-12-19 14:16:25 +01:00
michal 602d0d5308 Add logging for process start and measurement steps
Updated `PMaxTestSeq` to include logging of process data at key steps: process start and measurement. Added TODO comments to review logging positions for alignment with expected workflow.
2024-12-17 09:59:31 +01:00
54 changed files with 14839 additions and 319 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ namespace TBF.Boxes
}
else
{
return string.Format(Format, Val * Factor);
return string.Format(string.Format("{{0:{0}}}", Format), Val * Factor);
}
}
+2 -2
View File
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.9.2146.3")]
[assembly: AssemblyFileVersion("3.9.2146.3")]
[assembly: AssemblyVersion("3.9.2146.4")]
[assembly: AssemblyFileVersion("3.9.2146.4")]
+18
View File
@@ -5153,6 +5153,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Save Communication.
/// </summary>
internal static string SaveCommunication {
get {
return ResourceManager.GetString("SaveCommunication", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Saving all results.
/// </summary>
@@ -5549,6 +5558,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Show Dialog.
/// </summary>
internal static string ShowDialog {
get {
return ResourceManager.GetString("ShowDialog", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shut down computer after exiting Test Bench Framework.
/// </summary>
+3
View File
@@ -1755,4 +1755,7 @@
<data name="Project_number" xml:space="preserve">
<value>Projtové číslo</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Zobraz Okno</value>
</data>
</root>
+3
View File
@@ -2220,4 +2220,7 @@
<data name="Project_number" xml:space="preserve">
<value>Projektnummer</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Dialog anzeigen</value>
</data>
</root>
+3
View File
@@ -123,4 +123,7 @@
<data name="Project_number" xml:space="preserve">
<value>Número de proyecto</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Mostrar diálogo</value>
</data>
</root>
+3
View File
@@ -2019,4 +2019,7 @@
<data name="Project_number" xml:space="preserve">
<value>Numéro de projet</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Afficher la boîte de dialogue</value>
</data>
</root>
+3
View File
@@ -1788,4 +1788,7 @@
<data name="Project_number" xml:space="preserve">
<value>Numero del progetto</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Mostra dialogo</value>
</data>
</root>
+7
View File
@@ -2467,4 +2467,11 @@
<data name="Voltage" xml:space="preserve">
<value>Voltage</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Show Dialog</value>
</data>
<data name="SaveCommunication" xml:space="preserve">
<value>Save Communication</value>
</data>
</root>
+3
View File
@@ -840,4 +840,7 @@
<data name="Project_number" xml:space="preserve">
<value>Numărul proiectului</value>
</data>
<data name="SaveCommunication" xml:space="preserve">
<value>Save Communication</value>
</data>
</root>
+6
View File
@@ -244,4 +244,10 @@
<data name="Project_number" xml:space="preserve">
<value>Číslo projektu</value>
</data>
<data name="ShowDialog" xml:space="preserve">
<value>Zobraz dialóg</value>
</data>
<data name="SaveCommunication" xml:space="preserve">
<value>Ulož komunikáciu</value>
</data>
</root>
+17 -1
View File
@@ -3,6 +3,7 @@
///
using System;
using System.Collections.Generic;
using Common;
using log4net;
using Dirichlet.Numerics;
using TBF.Boxes;
@@ -273,6 +274,11 @@ namespace TBF.Rig.BuiltIn
/// <summary>Start this operation</summary>
public void Start()
{
if (cb.DebugLevel == DebugMode.Simulate)
{
return ;
}
UInt128 changed = cb.SetValves(switchPoints[0].MasksOpen, switchPoints[0].MasksClose, StateMachine.LogicalFnValves);
if (timeStamp != null && switchPoints[0].TimeSec == timeShift)
@@ -291,7 +297,12 @@ namespace TBF.Rig.BuiltIn
/// </returns>
public Event Run()
{
if (nextIx >= switchPoints.Count)
if (cb.DebugLevel == DebugMode.Simulate)
{
return Event.ValvesSet;
}
if (nextIx >= switchPoints.Count)
{
return (StateMachine.Time >= swStartTime + maxDelayTime + waitOnCBDelay) ? Event.ValvesSet : Event.ValvesBusy;
}
@@ -320,6 +331,11 @@ namespace TBF.Rig.BuiltIn
/// <summary>Start this operation</summary>
public void Stop()
{
if (cb.DebugLevel == DebugMode.Simulate)
{
return;
}
if (switchTime != null && startStopValveBitNr >= 16 && startStopValveBitNr <= 23 && cb is ControlBoard.Uni.UniCB)
{
switchTime.Val = (cb as ControlBoard.Uni.UniCB).Data.ValveSwitchTime[startStopValveBitNr - 16];
+15 -2
View File
@@ -292,7 +292,17 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
currentOp = CurrentOp.None;
}
public bool ShowForm { get; set; }
public bool ShowForm
{
get { return entryFormCfg == null ? false : entryFormCfg.ShowDialog; }
set {} // only for read - svia dilalog
}
public bool CliLogging
{
get { return entryFormCfg == null ? false : entryFormCfg.SaveCommunication;}
}
public bool ReadAndSetDataToMeters()
{
bool bOperationSuccess = false;
@@ -307,6 +317,8 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
if (iRegReader is PoseidonReader)
{
PoseidonReader poseidonReader = (iRegReader as PoseidonReader);
poseidonReader.SetCliLogging(CliLogging);
if (poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.SendStartDataStream_Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.SendStartDataStream_Runing)
{
@@ -346,8 +358,9 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
if (iRegReader is PoseidonReader)
{
PoseidonReader poseidonReader = (iRegReader as PoseidonReader);
if(poseidonReader != null)
if(poseidonReader == null)
continue;
poseidonReader.SetCliLogging(CliLogging);
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Running))
{
+41 -1
View File
@@ -68,6 +68,8 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
///
public Direction Direction;
public Orders Orders;
public bool ShowDialog;
public bool SaveCommunication;
/// Private parameterless constructor invoked by all other (public) constructors
EntryFormCfg() { }
@@ -87,12 +89,16 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
{
Direction = Direction.Forward_RL;
Orders = Orders.Arbitrary;
ShowDialog = false;
SaveCommunication = false;
}
string[] paramNames = new string[]
{
Strings.Direction,
Strings.Orders,
Strings.ShowDialog,
Strings.SaveCommunication,
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
@@ -108,6 +114,14 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
case 1:
for (Orders o = 0; o < Orders.Count; o++) list.Add(o.ToDescription());
return list;
case 2:
list.Add("True");
list.Add("False");
return list;
case 3:
list.Add("True");
list.Add("False");
return list;
default:
return null;
}
@@ -120,8 +134,10 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
{
case 0: return Direction.ToDescription();
case 1: return Orders.ToDescription();
case 2: return ShowDialog.ToString();
case 3: return SaveCommunication.ToString();
default:
return string.Format("Name={0}, Direction={1}, Orders={2}", Name, Direction, Orders);
return string.Format("Name={0}, Direction={1}, Orders={2}, ShowDialog={3}, StoreCommunication={4}", Name, Direction, Orders, ShowDialog, SaveCommunication);
}
}
@@ -146,6 +162,24 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
return CfgUpdateFlags.RestartRqrd;
}
break;
case 2:
{
bool lastSetting = ShowDialog;
if (str == "True") ShowDialog = true;
else ShowDialog = false;
if (lastSetting != ShowDialog)
return CfgUpdateFlags.RestartRqrd;
}
break;
case 3:
{
bool lastSetting = SaveCommunication;
if (str == "True") SaveCommunication = true;
else SaveCommunication = false;
if (lastSetting != SaveCommunication)
return CfgUpdateFlags.RestartRqrd;
}
break;
}
return CfgUpdateFlags.None;
@@ -161,6 +195,10 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
case 1:
if (ParamValues(i).Contains(str)) return true;
break;
case 2:
case 3:
if (str == "True" || str == "False") return true;
break;
default:
message = "Invalid index";
return false;
@@ -174,6 +212,8 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
{
prms.Direction = this.Direction;
prms.Orders = this.Orders;
prms.ShowDialog = this.ShowDialog;
prms.SaveCommunication = this.SaveCommunication;
}
public IParamsProvider Clone()
@@ -0,0 +1,24 @@
using System.Collections.Generic;
using Config.Entities;
using TBF.Rig.Generic;
namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB
{
public class Factory : IComponentFactory
{
public string ClassName { get { return GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new FrequencyRegisterReader(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new FrequencyRegisterReader(cfg, components); }
public IComponentCfg DefaultConfig() { return new RRCfg("Frequency", this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Component component)
{
return ComponentCfgBase.CreateFromDbEntity(RRCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Common;
using log4net;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB
{
public class FrequencyRegisterReader : ComponentBase, GenericDevices.IRegReader
{
private static readonly ILog log = LogManager.GetLogger(typeof(FrequencyRegisterReader));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly RRCfg rrCfg;
readonly TBF.Rig.ControlBoard.IControlBoard cb;
public int Position { get{ return rrCfg.Position; } }
public Common.RegisterReaderType RegisterReaderType { get { return Common.RegisterReaderType.Pulses; } }
public double PulsesPerLtr { get { return rrCfg.ProcParams.PulsesPerLtr; } }
public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); ; } }
public int Filter { get { return rrCfg.ProcParams.Filter; } }
public int WMPulses { get { return cb.PulsesWM(Position); } }
public int WMRefPulses { get { return cb.RefPulsesWM(Position); } }
public double WMVolume { get { return LtrsPerPulse * Convert.ToDouble(WMPulses); } }
public double BeginWMState { get { return 0; } } /// Always 0
public double EndWMState { get { return WMVolume; } } /// Derived from WMVolume
public FrequencyRegisterReader() { }
public FrequencyRegisterReader(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
rrCfg = cfg as RRCfg;
cb = TbfComponents.FindComponent(cfg.ParentName, components) as TBF.Rig.ControlBoard.IControlBoard;
if (cb == null) throw new Exception("Cannot find " + Name + " parent");
log.Warn(this.ToString());
}
public override void Initialize() { }
}
}
@@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB
{
public class RRCfg : ComponentCfgBase, Generic.IChildComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RRCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
IComponentCfgCtrl IComponentCfg.GetControl(IList<Component> cmpntEntities) { return new RRCfgCtrl(); }
///
/// Serialized parameters
///
public int Position; /// 1..nrWaterMeters
/// <summary> Procedure parameters </summary>
[XmlIgnore]
public RRProcParams ProcParams;
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
public override IParamsProvider CreateProcParamsProvider() { return new RRProcParams(true); }
/// Private parameterless constructor invoked by all other (public) constructors
RRCfg()
{
ProcParams = new RRProcParams(true);
}
public RRCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = "UniCB";
Position = 1;
}
string IComponentCfg.ToString(int i)
{
return string.Format("Name={0}, Parent={1}, Position={2}",
Name,
(string.IsNullOrEmpty(ParentName) ? "-" : ParentName),
Position);
}
}
}
@@ -0,0 +1,106 @@
///
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using System;
using System.Windows.Forms;
using Common;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB
{
public partial class RRCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
bool IComponentCfgCtrl.ShowMore { get { return false; } }
RRCfg config;
IComponentCfg IComponentCfgCtrl.Config
{
get { return config as IComponentCfg; }
set
{
config = value as RRCfg;
Redraw();
}
}
public RRCfgCtrl()
{
InitializeComponent();
}
private void RegisterReaderCfgCtrl_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 ControlBoard.Uni.Factory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
void IComponentCfgCtrl.Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
componentNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
positionTextBox.Text = config.Position.ToString();
}
void IComponentCfgCtrl.Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
positionTextBox.Enabled = true;
}
CfgUpdateFlags IComponentCfgCtrl.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 (!int.TryParse(positionTextBox.Text, out dummy) || (dummy < 1))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Position' should be >= 1";
}
return flags;
}
CfgUpdateFlags IComponentCfgCtrl.UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
config.Position = int.Parse(positionTextBox.Text);
return flags;
}
}
}
@@ -0,0 +1,133 @@
///
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB
{
partial class RRCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.positionTextBox = new System.Windows.Forms.TextBox();
this.positionLabel = new System.Windows.Forms.Label();
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.componentNameLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// positionTextBox
//
this.positionTextBox.Enabled = false;
this.positionTextBox.Location = new System.Drawing.Point(136, 119);
this.positionTextBox.Name = "positionTextBox";
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
this.positionTextBox.TabIndex = 6;
//
// positionLabel
//
this.positionLabel.AutoSize = true;
this.positionLabel.Location = new System.Drawing.Point(26, 122);
this.positionLabel.Name = "positionLabel";
this.positionLabel.Size = new System.Drawing.Size(44, 13);
this.positionLabel.TabIndex = 5;
this.positionLabel.Text = "Position";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(26, 96);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent Name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(136, 67);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(26, 70);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// componentNameLabel
//
this.componentNameLabel.AutoSize = true;
this.componentNameLabel.Location = new System.Drawing.Point(133, 43);
this.componentNameLabel.Name = "componentNameLabel";
this.componentNameLabel.Size = new System.Drawing.Size(83, 13);
this.componentNameLabel.TabIndex = 0;
this.componentNameLabel.Text = "ComonentName";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(136, 93);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// RegisterReaderCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.positionTextBox);
this.Controls.Add(this.positionLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.componentNameLabel);
this.Name = "RegisterReaderCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.RegisterReaderCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox positionTextBox;
private System.Windows.Forms.Label positionLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label componentNameLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,132 @@
///
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Resources;
namespace TBF.Rig.RegisterReaders.FrequencyMeterFromUniCB
{
public class RRProcParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RRProcParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public double PulsesPerLtr; /// [l^-1]
public int Filter;
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
Filter = 0;
}
string[] paramNames = new string[]
{
Strings.PulsesPerLtr,
Strings.Filter,
};
public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; }
public override string ToString(int i)
{
switch (i)
{
case 0: return PulsesPerLtr.ToString();
case 1: return Filter.ToString();
default: return string.Empty;
}
}
/// Retrieves parameters from UI controls
CfgUpdateFlags IParamsProvider.UpdateParam(int i, string strValue)
{
switch (i)
{
case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 1: Filter = int.Parse(strValue); return CfgUpdateFlags.None;
default: return CfgUpdateFlags.None;
}
}
/// Verifies whether strings in UI controls represent valid parameters
bool IParamsProvider.ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
double dummy;
int idummy;
switch (i)
{
case 0:
if (Utils.TryParseUDouble(strValue, out dummy)) return true;
break;
case 1:
if (int.TryParse(strValue, out idummy) && (idummy >= 0)) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(RRProcParams prms)
{
prms.PulsesPerLtr = this.PulsesPerLtr;
prms.Filter = this.Filter;
}
IParamsProvider IParamsProvider.Clone()
{
RRProcParams pars = new RRProcParams();
CopyContentTo(pars);
return pars;
}
public override void UpdateFromDbEntity(ComponentProcedure dbEntity)
{
if (dbEntity == null) return;
try
{
RRProcParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as RRProcParams;
procedureParamsEntity = dbEntity;
componentName = dbEntity.CmpntName;
procedure = dbEntity.Procedure;
if (tmp != null) tmp.CopyContentTo(this);
}
catch
{
}
}
public RRProcParams()
{
}
public RRProcParams(bool initialize)
{
if (initialize) InitializeAll();
}
public RRProcParams(ComponentProcedure procedureParamsEntity, string componentName, Procedure procedure)
{
this.procedureParamsEntity = procedureParamsEntity;
this.componentName = componentName;
this.procedure = procedure;
}
}
}
@@ -1,15 +1,23 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using log4net;
using log4net.Config;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SharedDatabase;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public class CliRunner
{
//static readonly ILog log = LogManager.GetLogger(typeof(CliRunner));
private readonly ILog log;
private List<Task> taskPool = new List<Task>();
private long startTime;
@@ -39,9 +47,22 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
return (DateTime.Now.Ticks - startTime) > timeout;
}
public CliRunner()
public CliRunner(bool isCliLogging)
{
startTime = DateTime.Now.Ticks;
if (isCliLogging)
{
log = new ScopedLoggerFactory().CreateLogger<CliRunner>(
@"C:\TBF\Logs\CliRunner.txt",
10, // maxFileSizeMB
7, // maxBackups
log4net.Core.Level.Debug,
true, // zipRolledFiles
true, // singleZipPerDay
TimeSpan.FromMinutes(2) // zipScanInterval
);
}
}
/// <summary>
@@ -91,18 +112,18 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
// Now all outputs are available
string allOutput = sb.ToString();
log?.Debug(allOutput);
return allOutput;
}
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
{
var task = RunAndCaptureJsonAsync<T>(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
taskPool.Add(task);
}
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args)
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args) where T : new()
{
var psi = new ProcessStartInfo
{
@@ -130,18 +151,65 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
// Now sb contains all output text
string allOutput = sb.ToString();
log?.Debug(allOutput);
// Extract JSON part
string json = ExtractJson(allOutput);
if (json != null)
{
return JsonConvert.DeserializeObject<T>(json);
try
{
return JsonConvert.DeserializeObject<T>(json);
}
catch (Exception ex)
{
log.Debug(ex.Message);
return TryConvert<T>(json);
}
}
return default;
}
private static T TryConvert<T>(string json) where T : new()
{
T obj = new T();
try
{
JObject jObject = JObject.Parse(json);
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!prop.CanWrite) continue;
JToken token;
if (jObject.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out token))
{
try
{
object value = token.ToObject(prop.PropertyType);
prop.SetValue(obj, value);
}
catch
{
// leave default if conversion fails
}
}
// else → keep default value
}
}
catch (Exception ex)
{
Console.WriteLine($"TryConvert failed: {ex.Message}");
}
return obj;
}
private string ExtractJson(string text)
{
int start = text.IndexOf('{');
@@ -31,7 +31,17 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
private bool activeHandlerSessioEnabled = false;
private CliRunner _cliRunner;
private CliRunner CliRunner
{
get
{
return (_cliRunner != null ?
_cliRunner :
(_cliRunner = new CliRunner(GetCliLogging())));
}
}
public enum CurrentPoseidonOp
{
None,
@@ -48,6 +58,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
CurrentPoseidonOp _currentOp;
private bool _isReadingStart = true;
private bool? _isCliLogging;
public CurrentPoseidonOp CurrentOp
{
@@ -58,6 +69,16 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
_currentOp = operation ;
}
public bool GetCliLogging()
{
return _isCliLogging.HasValue ? _isCliLogging.Value : true;
}
public void SetCliLogging(bool isCliLogging)
{
_isCliLogging = isCliLogging;
}
public int Position
{
@@ -300,23 +321,27 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
/// <summary>Start this operation</summary>
public void Start()
{
//TODO BUMI start CLI serial port
_cliRunner = new CliRunner();
}
/// <summary>
/// for debug purposes what time will consume answer
/// </summary>
private long startTimeInMilis, fullTimeInMilis;
private static long SafetyTimeOut = 30 * 1000; /// 30 seconds
/// <summary>Run this operation</summary>
/// <returns>eventDone</returns>
public Event Run()
{
if (_currentOp == CurrentPoseidonOp.SendStartDataStream)
{
_cliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
return Event.Busy;
}
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Runing)
{
if (_cliRunner.AreTasksDone()
|| _cliRunner.TimeOutReceived(5000))
if (CliRunner.AreTasksDone()
|| CliRunner.TimeOutReceived(SafetyTimeOut))
{
_currentOp = CurrentPoseidonOp.SendStartDataStream_Done;
}
@@ -330,14 +355,15 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
else if (_currentOp == CurrentPoseidonOp.ReadDataStream_Start
|| _currentOp == CurrentPoseidonOp.ReadDataStream_End)
{
startTimeInMilis = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
_isReadingStart = (_currentOp == CurrentPoseidonOp.ReadDataStream_Start);
_cliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
_currentOp = CurrentPoseidonOp.ReadDatastream_Running;
return Event.Busy;
}else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Running)
{
if (_cliRunner.AreTasksDone()
|| _cliRunner.TimeOutReceived(5000))
if (CliRunner.AreTasksDone()
|| CliRunner.TimeOutReceived(SafetyTimeOut))
{
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
}
@@ -345,8 +371,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
}
else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Done)
{
fullTimeInMilis = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - startTimeInMilis;
log.Debug($"PoseidonReader.Run() Name= {Cfg.Name} fullTimeInMilis = {fullTimeInMilis} ");
JsonDataFromPoseidon data = null;
var first = _cliRunner.TaskPool.FindLast(t => t is Task<JsonDataFromPoseidon>);
var first = CliRunner.TaskPool.FindLast(t => t is Task<JsonDataFromPoseidon>);
if (first != null && first is Task<JsonDataFromPoseidon>)
{
data = (first as Task<JsonDataFromPoseidon>).Result;
@@ -438,10 +466,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
else
{
//TODO BUMI start session - CMD send data to Poseidon
_cliRunner = new CliRunner();
_cliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
_cliRunner.WaitAll();
foreach (Task task in _cliRunner.TaskPool)
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
CliRunner.WaitAll();
foreach (Task task in CliRunner.TaskPool)
{
if (task is Task<string>)
{
@@ -453,7 +481,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
}
}
_cliRunner.Clear();
CliRunner.Clear();
}
}
@@ -482,7 +510,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
if (_cliRunner != null)
{
_cliRunner.Clear();
}
activeHandlerSessioEnabled = false;
}
@@ -0,0 +1,172 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using log4net;
using log4net.Appender;
using log4net.Core;
using log4net.Layout;
using log4net.Repository.Hierarchy;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public sealed class ScopedLoggerFactory
{
private static readonly LogZipService ZipService = new LogZipService();
public ILog CreateLogger<T>(
string logFile,
int maxFileSizeMB,
int maxBackups,
Level level,
bool zipRolledFiles,
bool singleZipPerDay,
TimeSpan zipScanInterval)
{
var layout = new PatternLayout("%date %-5level %logger - %message%newline");
layout.ActivateOptions();
var appender = new RollingFileAppender
{
Name = typeof(T).Name + "Appender",
File = logFile,
AppendToFile = true,
RollingStyle = RollingFileAppender.RollingMode.Composite,
DatePattern = "'.'yyyyMMdd",
StaticLogFileName = true,
PreserveLogFileNameExtension = true,
MaxSizeRollBackups = maxBackups,
MaximumFileSize = maxFileSizeMB + "MB",
CountDirection = 1,
LockingModel = new FileAppender.MinimalLock(),
ImmediateFlush = true,
Layout = layout
};
appender.ActivateOptions();
var hierarchy = (Hierarchy)LogManager.GetRepository();
var logger = (log4net.Repository.Hierarchy.Logger)hierarchy.GetLogger(typeof(T).FullName);
logger.RemoveAllAppenders();
logger.AddAppender(appender);
logger.Level = level ?? Level.Debug;
logger.Additivity = false;
hierarchy.Configured = true;
if (zipRolledFiles)
{
ZipService.StartFor(logFile, singleZipPerDay, zipScanInterval);
}
return LogManager.GetLogger(typeof(T));
}
}
internal sealed class LogZipService : IDisposable
{
private readonly ConcurrentDictionary<string, Timer> _timers =
new ConcurrentDictionary<string, Timer>();
public void StartFor(string baseLogFile, bool singleZipPerDay, TimeSpan interval)
{
_timers.GetOrAdd(baseLogFile, delegate (string key)
{
// .NET Framework Timer ctor: Timer(Callback, state, dueTimeMs, periodMs)
return new Timer(
new TimerCallback(delegate (object state) { CompressRolledFiles(key, singleZipPerDay); }),
null,
(int)TimeSpan.FromSeconds(20).TotalMilliseconds,
(int)interval.TotalMilliseconds
);
});
}
private static void CompressRolledFiles(string baseLogFile, bool singleZipPerDay)
{
try
{
var dir = Path.GetDirectoryName(baseLogFile);
var fileName = Path.GetFileName(baseLogFile);
var nameNoExt = Path.GetFileNameWithoutExtension(fileName);
var ext = Path.GetExtension(fileName);
var candidates = Directory.EnumerateFiles(dir)
.Where(f =>
!f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) &&
!StringComparer.OrdinalIgnoreCase.Equals(f, baseLogFile) &&
Regex.IsMatch(Path.GetFileName(f),
"^" + Regex.Escape(nameNoExt) + "\\.\\d{8}(\\.\\d+)?" + Regex.Escape(ext) + "$"));
foreach (var f in candidates)
{
if ((DateTime.UtcNow - File.GetLastWriteTimeUtc(f)).TotalSeconds < 15)
continue;
if (!CanOpenExclusive(f)) continue;
string zipPath = singleZipPerDay
? Path.Combine(dir, nameNoExt + "-" + ExtractDatePart(f) + ".zip")
: f + ".zip";
AddFileToZip(zipPath, f);
File.Delete(f);
}
}
catch
{
// ignore errors
}
}
private static void AddFileToZip(string zipPath, string fileToAdd)
{
var entryName = Path.GetFileName(fileToAdd);
if (!File.Exists(zipPath))
{
using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(fileToAdd, entryName, CompressionLevel.Optimal);
}
}
else
{
using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Update))
{
var existing = archive.GetEntry(entryName);
if (existing != null) existing.Delete();
archive.CreateEntryFromFile(fileToAdd, entryName, CompressionLevel.Optimal);
}
}
}
private static bool CanOpenExclusive(string path)
{
try
{
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
{
return true;
}
}
catch { return false; }
}
private static string ExtractDatePart(string rolledFilePath)
{
var name = Path.GetFileName(rolledFilePath);
var m = Regex.Match(name, @"\.(\d{8})(?:\.\d+)?(\.[^.]+)$");
if (m.Success) return m.Groups[1].Value;
return DateTime.UtcNow.ToString("yyyyMMdd");
}
public void Dispose()
{
foreach (var t in _timers.Values) t.Dispose();
_timers.Clear();
}
}
}
@@ -0,0 +1,23 @@
using TBF.Rig.Generic;
using System.Collections.Generic;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
public class Factory: IComponentFactory
{
public string ClassName { get { return this.GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new IPerlReader(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new IPerlReader(cfg); }
public IComponentCfg DefaultConfig() { return new IPerlCfg(this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(IPerlCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
public class IPerlCfg : ComponentCfgBase, Generic.IComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(IPerlCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
{
return new IPerlCfgCtrl();
}
///
/// Serialized parameters
///
public bool UseTcpIP;
public string OptoIPAddress;
public ushort OptoTcpipPortNr;
public int HeadCommunicationComPortNr;
public int OptoComPortNr;
public int RfidComPortNr; /// 0 = use MuxBoardNr
public int MuxBoardNr; /// 0 = use RfidComPort(Nr), otherwise mux. board nr. 1 .. 4
public int Group; /// Number written to QuidoRS to connct the watermeter to RfidComPort, 1 .. 10
public CommunicationInterface CommunicationInterface; /// Communication Interface: RFID or NFC
/// <summary> Procedure parameters </summary>
[XmlIgnore]
public ProcParams ProcParams;
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
public override IParamsProvider CreateProcParamsProvider() { return new ProcParams(true); }
[XmlIgnore]
public MeterType MeterType { get { return (ProcParams != null) ? ProcParams.MeterType : MeterType.AutoDetect; } }
/// Private parameterless constructor invoked by all other (public) constructors
IPerlCfg()
{
Name = "iPerl";
ParentName = string.Empty;
OptoComPortNr = 10;
RfidComPortNr = 0; /// = use mux. board
MuxBoardNr = 1;
ProcParams = CreateProcParamsProvider() as ProcParams;
CommunicationInterface = CommunicationInterface.RFID;
HeadCommunicationComPortNr = 0;
}
public IPerlCfg(IComponentFactory factory)
: this()
{
this.Factory = factory;
}
public string ToString(int i)
{
return $"{Name} Group1 (mux#)={MuxBoardNr}, Group2={Group}, Opto=Com{OptoComPortNr}, {CommunicationInterface}=Com{RfidComPortNr}";
}
}
}
@@ -0,0 +1,163 @@
///
/// Copyright (c) 2015-2017 Sensus Metering Systems
///
using System;
using System.Net;
using System.Windows.Forms;
using Common;
using TBF.Rig.Generic;
using TBF.Resources;
using TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
public partial class IPerlCfgCtrl : UserControl, IComponentCfgCtrl
{
public bool ShowMore { get { return false; } }
IPerlCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as IPerlCfg;
Redraw();
}
}
public IPerlCfgCtrl()
{
InitializeComponent();
}
private void WaterMeterCfgCtrl_Load(object sender, EventArgs e)
{
nameLabel.Text = Strings.Name;
classNameLabel.Text = config.Factory.ClassName;
Redraw();
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
nameTextBox.Text = config.Name;
radioButton1.Checked = config.UseTcpIP;
radioButton2.Checked = !config.UseTcpIP;
ipAddressTextBox.Text = (config.OptoIPAddress != null) ? config.OptoIPAddress : "0.0.0.0";
tcpipPortTextBox.Text = config.OptoTcpipPortNr.ToString();
headPortNrTextBox.Text = config.HeadCommunicationComPortNr.ToString();
optoSerialPortTextBox.Text = config.OptoComPortNr.ToString();
rfidPortNrTextBox.Text = config.RfidComPortNr.ToString();
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
groupTextBox.Text = config.Group.ToString();
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
tabPage2.Controls.Add(new IperlHeadTestCtrl(config));
}
public void Unlock()
{
nameTextBox.Enabled = true;
radioButton1.Enabled = true;
radioButton2.Enabled = true;
ipAddressTextBox.Enabled = true;
tcpipPortTextBox.Enabled = true;
optoSerialPortTextBox.Enabled = true;
rfidPortNrTextBox.Enabled = true;
headPortNrTextBox.Enabled = true;
muxBoardNrTextBox.Enabled = true;
groupTextBox.Enabled = true;
comboBoxCommunicationInterface.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
int dummy;
if (radioButton1.Checked)
{
IPAddress dummyIPAddress;
if (!IPAddress.TryParse(ipAddressTextBox.Text, out dummyIPAddress))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'IP address' is not valid";
}
ushort sdummy;
if (!ushort.TryParse(tcpipPortTextBox.Text, out sdummy))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'TCP/IP port nr.' is not valid";
}
}
else
{
if (!int.TryParse(optoSerialPortTextBox.Text, out dummy) || dummy < 1 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Opto serial port nr.' is not valid";
}
}
if (!int.TryParse(rfidPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'RFID serial port nr.' is not valid";
}
if (!int.TryParse(headPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Head communication serial port nr.' is not valid";
}
if (!int.TryParse(muxBoardNrTextBox.Text, out dummy) || dummy < 1 || dummy > 4)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, muxBoardNrLabel.Text);
}
if (!int.TryParse(groupTextBox.Text, out dummy) || dummy < 1 || dummy > 10)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, groupLabel.Text);
}
return flags;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
if (radioButton1.Checked)
{
config.UseTcpIP = true;
config.OptoIPAddress = ipAddressTextBox.Text;
config.OptoTcpipPortNr = ushort.Parse(tcpipPortTextBox.Text);
}
else
{
config.UseTcpIP = false;
config.OptoComPortNr = int.Parse(optoSerialPortTextBox.Text);
}
config.RfidComPortNr = int.Parse(rfidPortNrTextBox.Text);
config.MuxBoardNr = int.Parse(muxBoardNrTextBox.Text);
config.Group = int.Parse(groupTextBox.Text);
config.CommunicationInterface = (CommunicationInterface)comboBoxCommunicationInterface.SelectedIndex;
config.HeadCommunicationComPortNr = int.Parse(headPortNrTextBox.Text);
return flags;
}
}
}
@@ -0,0 +1,441 @@
///
/// Copyright (c) 2015-2017 Sensus Metering Systems
///
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
partial class IPerlCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.comboBoxCommunicationInterface = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.rfidPortNrTextBox = new System.Windows.Forms.TextBox();
this.rfidSerialPortNrLabel = new System.Windows.Forms.Label();
this.optoDataGroupBox = new System.Windows.Forms.GroupBox();
this.tcpipPortLabel = new System.Windows.Forms.Label();
this.tcpipPortTextBox = new System.Windows.Forms.TextBox();
this.ipAddressLabel = new System.Windows.Forms.Label();
this.ipAddressTextBox = new System.Windows.Forms.TextBox();
this.radioButton1 = new System.Windows.Forms.RadioButton();
this.radioButton2 = new System.Windows.Forms.RadioButton();
this.optoSerialPortLabel = new System.Windows.Forms.Label();
this.optoSerialPortTextBox = new System.Windows.Forms.TextBox();
this.groupTextBox = new System.Windows.Forms.TextBox();
this.groupLabel = new System.Windows.Forms.Label();
this.muxBoardNrTextBox = new System.Windows.Forms.TextBox();
this.muxBoardNrLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.headPortNrTextBox = new System.Windows.Forms.TextBox();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.groupBox1.SuspendLayout();
this.optoDataGroupBox.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(3, 3);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(611, 432);
this.tabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.groupBox2);
this.tabPage1.Controls.Add(this.label4);
this.tabPage1.Controls.Add(this.label3);
this.tabPage1.Controls.Add(this.groupBox1);
this.tabPage1.Controls.Add(this.optoDataGroupBox);
this.tabPage1.Controls.Add(this.groupTextBox);
this.tabPage1.Controls.Add(this.groupLabel);
this.tabPage1.Controls.Add(this.muxBoardNrTextBox);
this.tabPage1.Controls.Add(this.muxBoardNrLabel);
this.tabPage1.Controls.Add(this.nameTextBox);
this.tabPage1.Controls.Add(this.nameLabel);
this.tabPage1.Controls.Add(this.classNameLabel);
this.tabPage1.Location = new System.Drawing.Point(4, 25);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(603, 403);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Config";
this.tabPage1.UseVisualStyleBackColor = true;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(208, 101);
this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(40, 16);
this.label4.TabIndex = 25;
this.label4.Text = "1 .. 10";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(208, 72);
this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(33, 16);
this.label3.TabIndex = 24;
this.label3.Text = "1 .. 4";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.comboBoxCommunicationInterface);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.rfidPortNrTextBox);
this.groupBox1.Controls.Add(this.rfidSerialPortNrLabel);
this.groupBox1.Location = new System.Drawing.Point(10, 259);
this.groupBox1.Margin = new System.Windows.Forms.Padding(4);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(4);
this.groupBox1.Size = new System.Drawing.Size(552, 68);
this.groupBox1.TabIndex = 23;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "RFID / NFC communication (in case mux. board is not used)";
//
// comboBoxCommunicationInterface
//
this.comboBoxCommunicationInterface.Enabled = false;
this.comboBoxCommunicationInterface.FormattingEnabled = true;
this.comboBoxCommunicationInterface.Items.AddRange(new object[] {
"RFID",
"NFC"});
this.comboBoxCommunicationInterface.Location = new System.Drawing.Point(201, 27);
this.comboBoxCommunicationInterface.Name = "comboBoxCommunicationInterface";
this.comboBoxCommunicationInterface.Size = new System.Drawing.Size(71, 24);
this.comboBoxCommunicationInterface.TabIndex = 9;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(41, 30);
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(153, 16);
this.label1.TabIndex = 8;
this.label1.Text = "Communication Interface";
//
// rfidPortNrTextBox
//
this.rfidPortNrTextBox.Enabled = false;
this.rfidPortNrTextBox.Location = new System.Drawing.Point(439, 26);
this.rfidPortNrTextBox.Margin = new System.Windows.Forms.Padding(4);
this.rfidPortNrTextBox.Name = "rfidPortNrTextBox";
this.rfidPortNrTextBox.Size = new System.Drawing.Size(44, 22);
this.rfidPortNrTextBox.TabIndex = 7;
//
// rfidSerialPortNrLabel
//
this.rfidSerialPortNrLabel.AutoSize = true;
this.rfidSerialPortNrLabel.Location = new System.Drawing.Point(321, 30);
this.rfidSerialPortNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.rfidSerialPortNrLabel.Name = "rfidSerialPortNrLabel";
this.rfidSerialPortNrLabel.Size = new System.Drawing.Size(88, 16);
this.rfidSerialPortNrLabel.TabIndex = 6;
this.rfidSerialPortNrLabel.Text = "Serial port nr.:";
//
// optoDataGroupBox
//
this.optoDataGroupBox.Controls.Add(this.tcpipPortLabel);
this.optoDataGroupBox.Controls.Add(this.tcpipPortTextBox);
this.optoDataGroupBox.Controls.Add(this.ipAddressLabel);
this.optoDataGroupBox.Controls.Add(this.ipAddressTextBox);
this.optoDataGroupBox.Controls.Add(this.radioButton1);
this.optoDataGroupBox.Controls.Add(this.radioButton2);
this.optoDataGroupBox.Controls.Add(this.optoSerialPortLabel);
this.optoDataGroupBox.Controls.Add(this.optoSerialPortTextBox);
this.optoDataGroupBox.Location = new System.Drawing.Point(10, 131);
this.optoDataGroupBox.Margin = new System.Windows.Forms.Padding(4);
this.optoDataGroupBox.Name = "optoDataGroupBox";
this.optoDataGroupBox.Padding = new System.Windows.Forms.Padding(4);
this.optoDataGroupBox.Size = new System.Drawing.Size(552, 119);
this.optoDataGroupBox.TabIndex = 18;
this.optoDataGroupBox.TabStop = false;
this.optoDataGroupBox.Text = "Opto-data";
//
// tcpipPortLabel
//
this.tcpipPortLabel.AutoSize = true;
this.tcpipPortLabel.Location = new System.Drawing.Point(41, 87);
this.tcpipPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.tcpipPortLabel.Name = "tcpipPortLabel";
this.tcpipPortLabel.Size = new System.Drawing.Size(54, 16);
this.tcpipPortLabel.TabIndex = 4;
this.tcpipPortLabel.Text = "Port nr..:";
//
// tcpipPortTextBox
//
this.tcpipPortTextBox.Enabled = false;
this.tcpipPortTextBox.Location = new System.Drawing.Point(143, 84);
this.tcpipPortTextBox.Margin = new System.Windows.Forms.Padding(4);
this.tcpipPortTextBox.Name = "tcpipPortTextBox";
this.tcpipPortTextBox.Size = new System.Drawing.Size(51, 22);
this.tcpipPortTextBox.TabIndex = 5;
//
// ipAddressLabel
//
this.ipAddressLabel.AutoSize = true;
this.ipAddressLabel.Location = new System.Drawing.Point(41, 59);
this.ipAddressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.ipAddressLabel.Name = "ipAddressLabel";
this.ipAddressLabel.Size = new System.Drawing.Size(78, 16);
this.ipAddressLabel.TabIndex = 2;
this.ipAddressLabel.Text = "IP address.:";
//
// ipAddressTextBox
//
this.ipAddressTextBox.Enabled = false;
this.ipAddressTextBox.Location = new System.Drawing.Point(143, 55);
this.ipAddressTextBox.Margin = new System.Windows.Forms.Padding(4);
this.ipAddressTextBox.Name = "ipAddressTextBox";
this.ipAddressTextBox.Size = new System.Drawing.Size(129, 22);
this.ipAddressTextBox.TabIndex = 3;
//
// radioButton1
//
this.radioButton1.AutoSize = true;
this.radioButton1.Checked = true;
this.radioButton1.Enabled = false;
this.radioButton1.Location = new System.Drawing.Point(29, 23);
this.radioButton1.Margin = new System.Windows.Forms.Padding(4);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(99, 20);
this.radioButton1.TabIndex = 0;
this.radioButton1.TabStop = true;
this.radioButton1.Text = "Use TCP/IP";
this.radioButton1.UseVisualStyleBackColor = true;
//
// radioButton2
//
this.radioButton2.AutoSize = true;
this.radioButton2.Enabled = false;
this.radioButton2.Location = new System.Drawing.Point(312, 23);
this.radioButton2.Margin = new System.Windows.Forms.Padding(4);
this.radioButton2.Name = "radioButton2";
this.radioButton2.Size = new System.Drawing.Size(115, 20);
this.radioButton2.TabIndex = 1;
this.radioButton2.Text = "Use serial port";
this.radioButton2.UseVisualStyleBackColor = true;
//
// optoSerialPortLabel
//
this.optoSerialPortLabel.AutoSize = true;
this.optoSerialPortLabel.Location = new System.Drawing.Point(321, 55);
this.optoSerialPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.optoSerialPortLabel.Name = "optoSerialPortLabel";
this.optoSerialPortLabel.Size = new System.Drawing.Size(88, 16);
this.optoSerialPortLabel.TabIndex = 6;
this.optoSerialPortLabel.Text = "Serial port nr.:";
//
// optoSerialPortTextBox
//
this.optoSerialPortTextBox.Enabled = false;
this.optoSerialPortTextBox.Location = new System.Drawing.Point(439, 52);
this.optoSerialPortTextBox.Margin = new System.Windows.Forms.Padding(4);
this.optoSerialPortTextBox.Name = "optoSerialPortTextBox";
this.optoSerialPortTextBox.Size = new System.Drawing.Size(44, 22);
this.optoSerialPortTextBox.TabIndex = 7;
//
// groupTextBox
//
this.groupTextBox.Enabled = false;
this.groupTextBox.Location = new System.Drawing.Point(153, 97);
this.groupTextBox.Margin = new System.Windows.Forms.Padding(4);
this.groupTextBox.Name = "groupTextBox";
this.groupTextBox.Size = new System.Drawing.Size(44, 22);
this.groupTextBox.TabIndex = 22;
//
// groupLabel
//
this.groupLabel.AutoSize = true;
this.groupLabel.Location = new System.Drawing.Point(6, 101);
this.groupLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.groupLabel.Name = "groupLabel";
this.groupLabel.Size = new System.Drawing.Size(54, 16);
this.groupLabel.TabIndex = 21;
this.groupLabel.Text = "Group 2";
//
// muxBoardNrTextBox
//
this.muxBoardNrTextBox.Enabled = false;
this.muxBoardNrTextBox.Location = new System.Drawing.Point(153, 69);
this.muxBoardNrTextBox.Margin = new System.Windows.Forms.Padding(4);
this.muxBoardNrTextBox.Name = "muxBoardNrTextBox";
this.muxBoardNrTextBox.Size = new System.Drawing.Size(44, 22);
this.muxBoardNrTextBox.TabIndex = 20;
//
// muxBoardNrLabel
//
this.muxBoardNrLabel.AutoSize = true;
this.muxBoardNrLabel.Location = new System.Drawing.Point(6, 72);
this.muxBoardNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.muxBoardNrLabel.Name = "muxBoardNrLabel";
this.muxBoardNrLabel.Size = new System.Drawing.Size(131, 16);
this.muxBoardNrLabel.TabIndex = 19;
this.muxBoardNrLabel.Text = "Group 1 (mux. board)";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(153, 40);
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(160, 22);
this.nameTextBox.TabIndex = 17;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(6, 44);
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(44, 16);
this.nameLabel.TabIndex = 16;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(149, 11);
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(78, 16);
this.classNameLabel.TabIndex = 15;
this.classNameLabel.Text = "ClassName";
//
// tabPage2
//
this.tabPage2.Location = new System.Drawing.Point(4, 25);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(603, 403);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Test";
this.tabPage2.UseVisualStyleBackColor = true;
//
// groupBox2
//
this.groupBox2.Controls.Add(this.headPortNrTextBox);
this.groupBox2.Controls.Add(this.label2);
this.groupBox2.Location = new System.Drawing.Point(10, 335);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(552, 50);
this.groupBox2.TabIndex = 26;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Head Communication";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(321, 18);
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(88, 16);
this.label2.TabIndex = 7;
this.label2.Text = "Serial port nr.:";
//
// headPortNrTextBox
//
this.headPortNrTextBox.Enabled = false;
this.headPortNrTextBox.Location = new System.Drawing.Point(439, 15);
this.headPortNrTextBox.Margin = new System.Windows.Forms.Padding(4);
this.headPortNrTextBox.Name = "headPortNrTextBox";
this.headPortNrTextBox.Size = new System.Drawing.Size(44, 22);
this.headPortNrTextBox.TabIndex = 8;
//
// IperlHeadCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabControl1);
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "IPerlCfgCtrl";
this.Size = new System.Drawing.Size(617, 438);
this.Load += new System.EventHandler(this.WaterMeterCfgCtrl_Load);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.optoDataGroupBox.ResumeLayout(false);
this.optoDataGroupBox.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox comboBoxCommunicationInterface;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox rfidPortNrTextBox;
private System.Windows.Forms.Label rfidSerialPortNrLabel;
private System.Windows.Forms.GroupBox optoDataGroupBox;
private System.Windows.Forms.Label tcpipPortLabel;
private System.Windows.Forms.TextBox tcpipPortTextBox;
private System.Windows.Forms.Label ipAddressLabel;
private System.Windows.Forms.TextBox ipAddressTextBox;
private System.Windows.Forms.RadioButton radioButton1;
private System.Windows.Forms.RadioButton radioButton2;
private System.Windows.Forms.Label optoSerialPortLabel;
private System.Windows.Forms.TextBox optoSerialPortTextBox;
private System.Windows.Forms.TextBox groupTextBox;
private System.Windows.Forms.Label groupLabel;
private System.Windows.Forms.TextBox muxBoardNrTextBox;
private System.Windows.Forms.Label muxBoardNrLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.TextBox headPortNrTextBox;
private System.Windows.Forms.Label label2;
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,137 @@
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
partial class IperlHeadTestCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.optoTestGroupBox = new System.Windows.Forms.GroupBox();
this.optoListBox = new System.Windows.Forms.ListBox();
this.rfidOutputListBox = new System.Windows.Forms.ListBox();
this.RfidTestGroupBox = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.rfidCommandComboBox = new System.Windows.Forms.ComboBox();
this.commandTestButton = new System.Windows.Forms.Button();
this.optoTestGroupBox.SuspendLayout();
this.RfidTestGroupBox.SuspendLayout();
this.SuspendLayout();
//
// optoTestGroupBox
//
this.optoTestGroupBox.Controls.Add(this.optoListBox);
this.optoTestGroupBox.Location = new System.Drawing.Point(5, 4);
this.optoTestGroupBox.Name = "optoTestGroupBox";
this.optoTestGroupBox.Size = new System.Drawing.Size(591, 161);
this.optoTestGroupBox.TabIndex = 2;
this.optoTestGroupBox.TabStop = false;
this.optoTestGroupBox.Text = "Opto-data";
//
// optoListBox
//
this.optoListBox.FormattingEnabled = true;
this.optoListBox.ItemHeight = 16;
this.optoListBox.Location = new System.Drawing.Point(7, 22);
this.optoListBox.Name = "optoListBox";
this.optoListBox.Size = new System.Drawing.Size(573, 132);
this.optoListBox.TabIndex = 0;
//
// rfidOutputListBox
//
this.rfidOutputListBox.FormattingEnabled = true;
this.rfidOutputListBox.ItemHeight = 16;
this.rfidOutputListBox.Location = new System.Drawing.Point(5, 54);
this.rfidOutputListBox.Name = "rfidOutputListBox";
this.rfidOutputListBox.SelectionMode = System.Windows.Forms.SelectionMode.None;
this.rfidOutputListBox.Size = new System.Drawing.Size(575, 164);
this.rfidOutputListBox.TabIndex = 3;
//
// RfidTestGroupBox
//
this.RfidTestGroupBox.Controls.Add(this.rfidOutputListBox);
this.RfidTestGroupBox.Controls.Add(this.label2);
this.RfidTestGroupBox.Controls.Add(this.rfidCommandComboBox);
this.RfidTestGroupBox.Controls.Add(this.commandTestButton);
this.RfidTestGroupBox.Location = new System.Drawing.Point(5, 171);
this.RfidTestGroupBox.Name = "RfidTestGroupBox";
this.RfidTestGroupBox.Size = new System.Drawing.Size(591, 224);
this.RfidTestGroupBox.TabIndex = 3;
this.RfidTestGroupBox.TabStop = false;
this.RfidTestGroupBox.Text = "RFID / NFC data";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(2, 25);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(69, 16);
this.label2.TabIndex = 2;
this.label2.Text = "Command";
//
// rfidCommandComboBox
//
this.rfidCommandComboBox.FormattingEnabled = true;
this.rfidCommandComboBox.Location = new System.Drawing.Point(86, 19);
this.rfidCommandComboBox.Name = "rfidCommandComboBox";
this.rfidCommandComboBox.Size = new System.Drawing.Size(341, 24);
this.rfidCommandComboBox.TabIndex = 1;
//
// commandTestButton
//
this.commandTestButton.Location = new System.Drawing.Point(449, 19);
this.commandTestButton.Name = "commandTestButton";
this.commandTestButton.Size = new System.Drawing.Size(126, 24);
this.commandTestButton.TabIndex = 0;
this.commandTestButton.Text = "Send command";
this.commandTestButton.UseVisualStyleBackColor = true;
this.commandTestButton.MouseClick += new System.Windows.Forms.MouseEventHandler(this.CommandTestButtonClick);
//
// IperlHeadTestCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.optoTestGroupBox);
this.Controls.Add(this.RfidTestGroupBox);
this.Name = "IperlHeadTestCtrl";
this.Size = new System.Drawing.Size(611, 432);
this.Load += new System.EventHandler(this.UserControl_Load);
this.optoTestGroupBox.ResumeLayout(false);
this.RfidTestGroupBox.ResumeLayout(false);
this.RfidTestGroupBox.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox optoTestGroupBox;
private System.Windows.Forms.ListBox rfidOutputListBox;
private System.Windows.Forms.GroupBox RfidTestGroupBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox rfidCommandComboBox;
private System.Windows.Forms.Button commandTestButton;
private System.Windows.Forms.ListBox optoListBox;
}
}
@@ -0,0 +1,192 @@
using System;
using System.Threading;
using System.Web.UI.WebControls;
using System.Windows.Forms;
using TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication;
using TBF.Rig.Sequences;
using TBF.Rig.TestMethods.iPerlCommunication;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
public partial class IperlHeadTestCtrl : UserControl
{
IPerlCfg config;
IPerlReader _iPerlReader;
Thread optoThread;
private bool stopWorkerThread;
public event EventHandler<OptoReceivedEventArgs> OptoReceivedHandler;
public IperlHeadTestCtrl(IPerlCfg config)
{
this.config = config;
InitializeComponent();
if (config == null) return;
//TODO fix possibility set test method in config
//iPerlCommunicationForm.cfg = new TestMethodCfg(null); // default values for iPerlCommunication
foreach(var head in ProcessData.IperlHeads)
{
if (head != null && head.Name == config.Name) { _iPerlReader = head; }
}
rfidCommandComboBox.DisplayMember = "Name";
rfidCommandComboBox.ValueMember = "Value";
var items = new[]
{
new {Name = "Read PCB", Value = "ReadPCB" },
new {Name = "Set Test Mode", Value = "SetTestMode" },
new {Name = "Set Active Mode", Value = "SetActiveMode" },
#if DEBUG
new {Name = "Start Read Opto Data", Value = "ReadOptoData" },
new {Name = "Stop Read Opto Data", Value = "StopReadOptoData" },
#endif
new {Name = " ", Value = "" },
new {Name = "Reset NFC Head", Value = "ResetNfcHead" },
new {Name = "Set NFC Head Interface", Value = "SetNfcHead" },
new {Name = "Set RFID Head interface", Value = "SetRfidHead" }
};
/*
// CTRL+ALT+double click - hidden poweruser menu
if (((Keyboard.ModifierKeys & Keys.Control) == Keys.Control) && ((Keyboard.ModifierKeys & Keys.Alt) == Keys.Alt) && Users.CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser)
{
Array.Resize(ref items, items.Length + 1);
items[items.Length - 1] = new { Name = "Kluc", Value = "Kluc" };
}
*/
rfidCommandComboBox.DataSource = items;
stopWorkerThread = false;
OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
{
if (this.InvokeRequired)
this.Invoke((Delegate)new EventHandler<OptoReceivedEventArgs>(this.OnOptoReceived2), sndr, (object)args);
else
this.OnOptoReceived2(sndr, args);
});
}
public void OnOptoReceived2(object sender, OptoReceivedEventArgs args)
{
optoListBox.Items.Insert(0,args.Data);
}
private void CommandTestButtonClick(object sender, MouseEventArgs e)
{
rfidOutputListBox.Items.Clear();
using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
{
ListItem rfidListItem = new ListItem();
rfidListItem.Attributes.Add("style", "font-weight:bold");
switch (rfidCommandComboBox.SelectedValue)
{
case "ReadPCB":
rfidListItem.Text = $"PCB: {OpticalHeadTest.ReadRequest_PCB(_iPerlReader)}";
break;
case "SetTestMode":
rfidListItem.Text = OpticalHeadTest.SetTestMode(_iPerlReader);
optoListBox.Items.Clear();
stopWorkerThread = false;
optoThread = new Thread(OptoWorker);
if (!optoThread.IsAlive)
{
_iPerlReader.StartDataStreamProcessing(); // open opto port
optoThread.Start();
}
break;
case "SetActiveMode":
rfidListItem.Text = OpticalHeadTest.SetActiveMode(_iPerlReader);
stopWorkerThread = true;
_iPerlReader.StopDataStreamProcessing(); // close opto port
break;
case "ResetNfcHead":
_iPerlReader.ResetNfcInterface();
break;
case "SetNfcHead":
_iPerlReader.SetNfcInterface();
break;
case "SetRfidHead":
_iPerlReader.SetRfidInterface();
break;
case "ReadOptoData":
optoListBox.Items.Clear();
stopWorkerThread = false;
optoThread = new Thread(OptoWorker);
if (optoThread.IsAlive)
{
stopWorkerThread = true;
_iPerlReader.StopDataStreamProcessing(); // close opto port
}
if (!optoThread.IsAlive)
{
_iPerlReader.StartDataStreamProcessing(); // open opto port
optoThread.Start();
}
break;
case "StopReadOptoData":
stopWorkerThread = true;
_iPerlReader.StopDataStreamProcessing(); // close opto port
break;
}
rfidOutputListBox.Items.Add(rfidListItem);
rfidOutputListBox.Items.AddRange(logChecker.Messages.ToArray());
}
}
private void OptoWorker()
{
while (!this.stopWorkerThread)
{
Thread.Sleep(250);
if (this.stopWorkerThread)
break;
try
{
string buffer = _iPerlReader.ReadOptoData();
if (string.IsNullOrEmpty(buffer))
{
this.OnOptoReceived((object)this, new OptoReceivedEventArgs("."));
}
else
OnOptoReceived((object)this, new OptoReceivedEventArgs(buffer));
}
catch (Exception ex)
{
this.OnOptoReceived((object)this, new OptoReceivedEventArgs(ex.Message));
}
}
}
public void OnOptoReceived(object sender, OptoReceivedEventArgs args)
{
if (this.OptoReceivedHandler == null)
return;
try
{
this.OptoReceivedHandler(sender, args);
}
catch (Exception ex)
{
}
}
private void UserControl_Load(object sender, EventArgs e)
{
this.ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
}
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
{
//OnHandleDestroyed(new EventArgs());
stopWorkerThread = true;
if (optoThread != null)
{
optoThread.Abort();
}
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,184 @@
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
{
public class ProcParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public int WMType_ID;
public MeterType MeterType;
public float CalibTarget; /// Target error after calibration in [%]
public int FactorLimitLo; /// Lower limit for the calibration factor
public int FactorLimitHi; /// Upper limit for the calibration factor
public Counting Counting; /// Initial iPerl counting (Artbitrary, Positive or Negative)
public override void InitializeAll()
{
MeterType = MeterType.AutoDetect;
CalibTarget = 0;
FactorLimitLo = 1000;
FactorLimitHi = 8000;
Counting = Counting.Arbitrary;
}
string[] paramNames = new string[]
{
"iPerl type",
"Calib. target [%]",
"Calib. factor Lo",
"Calib. factor Hi",
"Counting",
};
public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; }
public override ICollection<string> ParamValues(int i)
{
if (i == 0)
{
var retVal = new List<string>();
for (MeterType mt = 0; mt < MeterType.Count; mt++) retVal.Add(mt.ToString());
return retVal;
}
else if (i == 5)
{
var retVal = new List<string>();
for (Counting c = 0; c < Counting.Count; c++) retVal.Add(c.ToString());
return retVal;
}
return null;
}
public override string ToString(int i)
{
switch (i)
{
case 0: return MeterType.ToString();
case 1: return CalibTarget.ToString();
case 2: return FactorLimitLo.ToString();
case 3: return FactorLimitHi.ToString();
case 4: return Counting.ToString();
default: return string.Empty;
}
}
//implement IParamsProvider
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
int iDummy;
float fDummy;
switch (i)
{
case 0:
for (MeterType mt = 0; mt < MeterType.Count; mt++) if (mt.ToString().Equals(strValue)) return true;
break;
case 1:
if (Utils.TryParseSFloat(strValue, out fDummy) && fDummy >= -10.0f && fDummy <= 10.0f) return true;
break;
case 2:
case 3:
if (int.TryParse(strValue, out iDummy) && iDummy >= 1000 && iDummy <= 8000) return true;
break;
case 4:
for (Counting c = 0; c < Counting.Count; c++) if (c.ToString().Equals(strValue)) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
public CfgUpdateFlags UpdateParam(int i, string strValue)
{
switch (i)
{
case 0:
for (MeterType mt = 0; mt < MeterType.Count; mt++)
{
if (mt.ToString().Equals(strValue)) { MeterType = mt; return CfgUpdateFlags.None; }
}
break;
case 1: CalibTarget = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
case 2: FactorLimitLo = int.Parse(strValue); return CfgUpdateFlags.None;
case 3: FactorLimitHi = int.Parse(strValue); return CfgUpdateFlags.None;
case 4:
for (Counting c = 0; c < Counting.Count; c++)
{
if (c.ToString().Equals(strValue)) { Counting = c; return CfgUpdateFlags.None; }
}
break;
default: return CfgUpdateFlags.None;
}
return CfgUpdateFlags.None;
}
void CopyContentTo(ProcParams prms)
{
prms.MeterType = this.MeterType;
prms.CalibTarget = this.CalibTarget;
prms.FactorLimitLo = this.FactorLimitLo;
prms.FactorLimitHi = this.FactorLimitHi;
prms.Counting = this.Counting;
}
public IParamsProvider Clone()
{
ProcParams pars = new ProcParams();
CopyContentTo(pars);
return pars;
}
public override void UpdateFromDbEntity(ComponentProcedure dbEntity)
{
if (dbEntity == null) return;
try
{
ProcParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as ProcParams;
procedureParamsEntity = dbEntity;
componentName = dbEntity.CmpntName;
procedure = dbEntity.Procedure;
if (tmp != null) tmp.CopyContentTo(this);
}
catch
{
}
}
public ProcParams()
{
}
public ProcParams(bool initialize)
{
if (initialize) InitializeAll();
}
public ProcParams(ComponentProcedure procParamsEntity, string componentName, Procedure procedure)
{
this.procedureParamsEntity = procParamsEntity;
this.componentName = componentName;
this.procedure = procedure;
}
}
}
@@ -0,0 +1,242 @@
///
/// Copyright (c) 2015-2020 Sensus Metering Systems
///
using System;
using System.IO;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
{
public class CalibrationStruct
{
public const int Length = 35;
public Byte Version;
public MeterType MeterType;
public UInt16 Calibration;
public VolumeUnits VolumeUnits;
public FlowArrow FlowArrow;
public UInt16 FWVersion;
public UInt16[] TargetField;
public UInt16 RecipMeanCurrent;
public UInt16 ThresholdVolume;
public UInt16 ThresholdTime;
public UInt16 FlowActivationThr;
public UInt16 VolumeArrowThr;
public UInt32 CalibrationTime;
public ulong SerialNumber;
public MeterSealed MeterSealed;
public byte CheckSum;
public CalibrationStruct()
{
TargetField = new UInt16[3];
}
public byte[] ToByteArray()
{
byte[] result = new byte[Length];
result[0] = Version;
result[1] = (byte)MeterType;
result[2] = (byte)(Calibration & 0x00FF);
result[3] = (byte)((Calibration >> 8) & 0x00FF);
result[4] = (byte)VolumeUnits;
result[5] = (byte)FlowArrow;
result[6] = (byte)(FWVersion & 0x00FF);
result[7] = (byte)((FWVersion >> 8) & 0x00FF);
result[8] = (byte)( TargetField[0] & 0x00FF);
result[9] = (byte)((TargetField[0] >> 8) & 0x00FF);
result[10] = (byte)( TargetField[1] & 0x00FF);
result[11] = (byte)((TargetField[1] >> 8) & 0x00FF);
result[12] = (byte)( TargetField[2] & 0x00FF);
result[13] = (byte)((TargetField[2] >> 8) & 0x00FF);
result[14] = (byte)(RecipMeanCurrent & 0x00FF);
result[15] = (byte)((RecipMeanCurrent >> 8) & 0x00FF);
result[16] = (byte)(ThresholdVolume & 0x00FF);
result[17] = (byte)((ThresholdVolume >> 8) & 0x00FF);
result[18] = (byte)(ThresholdTime & 0x00FF);
result[19] = (byte)((ThresholdTime >> 8) & 0x00FF);
result[20] = (byte)(FlowActivationThr & 0x00FF);
result[21] = (byte)((FlowActivationThr >> 8) & 0x00FF);
result[22] = (byte)(VolumeArrowThr & 0x00FF);
result[23] = (byte)((VolumeArrowThr >> 8) & 0x00FF);
result[24] = (byte)(CalibrationTime & 0x000000FF);
result[25] = (byte)((CalibrationTime >> 8) & 0x000000FF);
result[26] = (byte)((CalibrationTime >> 16) & 0x000000FF);
result[27] = (byte)((CalibrationTime >> 24) & 0x000000FF);
result[28] = (byte)(SerialNumber & 0x00000000000000FF);
result[29] = (byte)((SerialNumber >> 8) & 0x00000000000000FF);
result[30] = (byte)((SerialNumber >> 16) & 0x00000000000000FF);
result[31] = (byte)((SerialNumber >> 24) & 0x00000000000000FF);
result[32] = (byte)((SerialNumber >> 32) & 0x00000000000000FF);
result[33] = (byte)MeterSealed;
result[34] = CheckSum;
return result;
}
/// <summary>
/// Create a calibration structure from a complete byte array
/// </summary>
/// <param name="data">A complete byte array data</param>
/// <returns>CalibrationStruct or null when byte array was not complete</returns>
public static CalibrationStruct FromByteArray(byte[] data)
{
if (data.Length != Length) return null;
CalibrationStruct result = new CalibrationStruct();
result.Version = data[0];
result.MeterType = (MeterType)data[1];
result.Calibration = (UInt16)(data[2] + 256 * data[3]);
result.VolumeUnits = (VolumeUnits)data[4];
result.FlowArrow = (FlowArrow)data[5];
result.FWVersion = (UInt16)(data[6] + 256 * data[7]);
result.TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
result.TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
result.TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
result.RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
result.ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
result.ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
result.FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
result.VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
result.CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
result.SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
result.MeterSealed = (MeterSealed)data[33];
result.CheckSum = data[34];
return result;
}
/// <summary>
/// Update the calibration structure from an incomplete byte array
/// </summary>
/// <param name="data">Byte array data</param>
/// <param name="offset">Offset of byte array data in CalibrationStruct</param>
/// <returns>true when successful, false when data are not appropriate</returns>
public bool Update(byte[] data, int offset)
{
if ((data.Length == 2) && (offset == 2))
{
/// Data containing iPerl calibration factor
Calibration = (UInt16)(data[0] + 256 * data[1]);
return true;
}
else if ((data.Length == Length) && (offset == 0))
{
/// Data containing a complete CalibrationStruct
Version = data[0];
MeterType = (MeterType)data[1];
Calibration = (UInt16)(data[2] + 256 * data[3]);
VolumeUnits = (VolumeUnits)data[4];
FlowArrow = (FlowArrow)data[5];
FWVersion = (UInt16)(data[6] + 256 * data[7]);
TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
MeterSealed = (MeterSealed)data[33];
CheckSum = data[34];
return true;
}
else
return false;
}
public string FWVersionStr()
{
int d1 = (FWVersion >> 8) & 0x000F;
int d2 = (FWVersion >> 12) & 0x000F;
int d3 = (FWVersion >> 4) & 0x000F;
int d4 = FWVersion & 0x000F;
return string.Format("{0}.{1}{2}{3}", d1, d2, d3, d4);
}
public override string ToString()
{
return string.Format("Calibration: V{0} Type={1} Cal={2} Units={3} FlowArrow.{4} FW={5} Hi={6} Norm={7} Low={8} RMC={9} ThrVol={10} ThrTime={11} FlActThr={12} VolArrThr={13} CalTm={14} SN={15} MeterSealed={16} Chksum={17}",
Version,
MeterType,
Calibration,
VolumeUnits,
FlowArrow,
FWVersion,
TargetField[0],
TargetField[1],
TargetField[2],
RecipMeanCurrent,
ThresholdVolume,
ThresholdTime,
FlowActivationThr,
VolumeArrowThr,
CalibrationTime,
SerialNumber,
MeterSealed,
CheckSum.ToString("X2"));
}
public virtual void WriteBinary(BinaryWriter writer)
{
writer.Write(Version);
writer.Write((byte)MeterType);
writer.Write(Calibration);
writer.Write((byte)VolumeUnits);
writer.Write((byte)FlowArrow);
writer.Write(FWVersion);
writer.Write(TargetField[0]);
writer.Write(TargetField[1]);
writer.Write(TargetField[2]);
writer.Write(RecipMeanCurrent);
writer.Write(ThresholdVolume);
writer.Write(ThresholdTime);
writer.Write(FlowActivationThr);
writer.Write(VolumeArrowThr);
writer.Write(CalibrationTime);
writer.Write(SerialNumber);
writer.Write((byte)MeterSealed);
writer.Write(CheckSum);
}
public virtual void ReadBinary(BinaryReader reader)
{
Version = reader.ReadByte();
MeterType = (MeterType)reader.ReadByte();
Calibration = reader.ReadUInt16();
VolumeUnits = (VolumeUnits)reader.ReadByte();
FlowArrow = (FlowArrow)reader.ReadByte();
FWVersion = reader.ReadUInt16();
TargetField[0] = reader.ReadUInt16();
TargetField[1] = reader.ReadUInt16();
TargetField[2] = reader.ReadUInt16();
RecipMeanCurrent = reader.ReadUInt16();
ThresholdVolume = reader.ReadUInt16();
ThresholdTime = reader.ReadUInt16();
FlowActivationThr = reader.ReadUInt16();
VolumeArrowThr = reader.ReadUInt16();
CalibrationTime = reader.ReadUInt32();
SerialNumber = reader.ReadUInt64();
MeterSealed = (MeterSealed)reader.ReadByte();
CheckSum = reader.ReadByte();
}
}
}
@@ -0,0 +1,258 @@
///
/// Copyright (c) 2018-2020 Sensus Slovensko a.s.
///
using System;
using System.IO;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
{
public class CalibrationStructV4
{
public const int Length = 37;
public Byte Version;
public MeterType MeterType;
public UInt16 Calibration;
public VolumeUnits VolumeUnits;
public FlowArrow FlowArrow;
public UInt16 FWVersion;
public UInt16[] TargetField;
public UInt16 RecipMeanCurrent;
public UInt16 ThresholdVolume;
public UInt16 ThresholdTime;
public UInt16 FlowActivationThr;
public UInt16 VolumeArrowThr;
public UInt32 CalibrationTime;
public ulong SerialNumber;
public MeterSealed MeterSealed;
public UInt16 CalibrationLNA;
public byte CheckSum;
public CalibrationStructV4()
{
TargetField = new UInt16[3];
}
public byte[] ToByteArray()
{
byte[] result = new byte[Length];
result[0] = Version;
result[1] = (byte)MeterType;
result[2] = (byte)(Calibration & 0x00FF);
result[3] = (byte)((Calibration >> 8) & 0x00FF);
result[4] = (byte)VolumeUnits;
result[5] = (byte)FlowArrow;
result[6] = (byte)(FWVersion & 0x00FF);
result[7] = (byte)((FWVersion >> 8) & 0x00FF);
result[8] = (byte)( TargetField[0] & 0x00FF);
result[9] = (byte)((TargetField[0] >> 8) & 0x00FF);
result[10] = (byte)( TargetField[1] & 0x00FF);
result[11] = (byte)((TargetField[1] >> 8) & 0x00FF);
result[12] = (byte)( TargetField[2] & 0x00FF);
result[13] = (byte)((TargetField[2] >> 8) & 0x00FF);
result[14] = (byte)(RecipMeanCurrent & 0x00FF);
result[15] = (byte)((RecipMeanCurrent >> 8) & 0x00FF);
result[16] = (byte)(ThresholdVolume & 0x00FF);
result[17] = (byte)((ThresholdVolume >> 8) & 0x00FF);
result[18] = (byte)(ThresholdTime & 0x00FF);
result[19] = (byte)((ThresholdTime >> 8) & 0x00FF);
result[20] = (byte)(FlowActivationThr & 0x00FF);
result[21] = (byte)((FlowActivationThr >> 8) & 0x00FF);
result[22] = (byte)(VolumeArrowThr & 0x00FF);
result[23] = (byte)((VolumeArrowThr >> 8) & 0x00FF);
result[24] = (byte)(CalibrationTime & 0x000000FF);
result[25] = (byte)((CalibrationTime >> 8) & 0x000000FF);
result[26] = (byte)((CalibrationTime >> 16) & 0x000000FF);
result[27] = (byte)((CalibrationTime >> 24) & 0x000000FF);
result[28] = (byte)(SerialNumber & 0x00000000000000FF);
result[29] = (byte)((SerialNumber >> 8) & 0x00000000000000FF);
result[30] = (byte)((SerialNumber >> 16) & 0x00000000000000FF);
result[31] = (byte)((SerialNumber >> 24) & 0x00000000000000FF);
result[32] = (byte)((SerialNumber >> 32) & 0x00000000000000FF);
result[33] = (byte)MeterSealed;
result[34] = (byte)(CalibrationLNA & 0x00FF);
result[35] = (byte)((CalibrationLNA >> 8) & 0x00FF);
result[36] = CheckSum;
return result;
}
/// <summary>
/// Create a calibration structure from a complete byte array
/// </summary>
/// <param name="data">A complete byte array data</param>
/// <returns>CalibrationStructV4 or null when byte array was not complete</returns>
public static CalibrationStructV4 FromByteArray(byte[] data)
{
if (data.Length != Length) return null;
CalibrationStructV4 result = new CalibrationStructV4();
result.Version = data[0];
result.MeterType = (MeterType)data[1];
result.Calibration = (UInt16)(data[2] + 256 * data[3]);
result.VolumeUnits = (VolumeUnits)data[4];
result.FlowArrow = (FlowArrow)data[5];
result.FWVersion = (UInt16)(data[6] + 256 * data[7]);
result.TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
result.TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
result.TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
result.RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
result.ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
result.ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
result.FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
result.VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
result.CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
result.SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
result.MeterSealed = (MeterSealed)data[33];
result.CalibrationLNA = (UInt16)(data[34] + 256 * data[35]);
result.CheckSum = data[36];
return result;
}
/// <summary>
/// Update the calibration structure from an incomplete byte array
/// </summary>
/// <param name="data">Byte array data</param>
/// <param name="offset">Offset of byte array data in CalibrationStructV2</param>
/// <returns>true when successful, false when data are not appropriate</returns>
public bool Update(byte[] data, int offset)
{
if ((data.Length == 2) && (offset == 2))
{
/// Data containing iPerl calibration factor
Calibration = (UInt16)(data[0] + 256 * data[1]);
return true;
}
else if ((data.Length == 2) && (offset == 34))
{
/// Data containing iPerl calibration factor
CalibrationLNA = (UInt16)(data[0] + 256 * data[1]);
return true;
}
else if ((data.Length == Length) && (offset == 0))
{
/// Data containing a complete CalibrationStruct
Version = data[0];
MeterType = (MeterType)data[1];
Calibration = (UInt16)(data[2] + 256 * data[3]);
VolumeUnits = (VolumeUnits)data[4];
FlowArrow = (FlowArrow)data[5];
FWVersion = (UInt16)(data[6] + 256 * data[7]);
TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
MeterSealed = (MeterSealed)data[33];
CalibrationLNA = (UInt16)(data[34] + 256 * data[35]);
CheckSum = data[36];
return true;
}
else
return false;
}
public string FWVersionStr()
{
int d1 = (FWVersion >> 8) & 0x000F;
int d2 = (FWVersion >> 12) & 0x000F;
int d3 = (FWVersion >> 4) & 0x000F;
int d4 = FWVersion & 0x000F;
return string.Format("{0}.{1}{2}{3}", d1, d2, d3, d4);
}
public override string ToString()
{
return string.Format("Calibration: V{0} Type={1} Cal={2} Units={3} FlowArrow.{4} FW={5} Hi={6} Norm={7} Low={8} RMC={9} ThrVol={10} ThrTime={11} FlActThr={12} VolArrThr={13} CalTm={14} SN={15} MeterSealed={16} CalLNA={17} Chksum={18}",
Version,
MeterType,
Calibration,
VolumeUnits,
FlowArrow,
FWVersion,
TargetField[0],
TargetField[1],
TargetField[2],
RecipMeanCurrent,
ThresholdVolume,
ThresholdTime,
FlowActivationThr,
VolumeArrowThr,
CalibrationTime,
SerialNumber,
MeterSealed,
CalibrationLNA,
CheckSum.ToString("X2"));
}
public virtual void WriteBinary(BinaryWriter writer)
{
writer.Write(Version);
writer.Write((byte)MeterType);
writer.Write(Calibration);
writer.Write((byte)VolumeUnits);
writer.Write((byte)FlowArrow);
writer.Write(FWVersion);
writer.Write(TargetField[0]);
writer.Write(TargetField[1]);
writer.Write(TargetField[2]);
writer.Write(RecipMeanCurrent);
writer.Write(ThresholdVolume);
writer.Write(ThresholdTime);
writer.Write(FlowActivationThr);
writer.Write(VolumeArrowThr);
writer.Write(CalibrationTime);
writer.Write(SerialNumber);
writer.Write((byte)MeterSealed);
writer.Write(CalibrationLNA);
writer.Write(CheckSum);
}
public virtual void ReadBinary(BinaryReader reader)
{
Version = reader.ReadByte();
MeterType = (MeterType)reader.ReadByte();
Calibration = reader.ReadUInt16();
VolumeUnits = (VolumeUnits)reader.ReadByte();
FlowArrow = (FlowArrow)reader.ReadByte();
FWVersion = reader.ReadUInt16();
TargetField[0] = reader.ReadUInt16();
TargetField[1] = reader.ReadUInt16();
TargetField[2] = reader.ReadUInt16();
RecipMeanCurrent = reader.ReadUInt16();
ThresholdVolume = reader.ReadUInt16();
ThresholdTime = reader.ReadUInt16();
FlowActivationThr = reader.ReadUInt16();
VolumeArrowThr = reader.ReadUInt16();
CalibrationTime = reader.ReadUInt32();
SerialNumber = reader.ReadUInt64();
MeterSealed = (MeterSealed)reader.ReadByte();
CalibrationLNA = reader.ReadUInt16();
CheckSum = reader.ReadByte();
}
}
}
@@ -0,0 +1,266 @@
///
/// Copyright (c) 2015-2020 Sensus Metering Systems
///
using System;
using System.IO;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
{
public class ConfigStruct
{
public const int Length = 32;
public Byte Version; /// 0: 1 byte
public MeterState MeterState; /// 1: 1 byte
public UInt32 TargetTimeVeryLowBatt; /// 2: 4 bytes in seconds
public UInt32 TargetTimeLowBatt; /// 6: 4 bytes, in seconds
public UInt32 TestModeTime; /// 10: 4 bytes, Max. test mode time in seconds
public UInt16 EmptyPipeThreshold; /// 14: 2 bytes
public byte[] PCBNumber; /// 16: 5 bytes
public byte TestModeConfig; /// 21: 1 byte
public UInt32 RadioAddress; /// 22: 4 bytes
public UInt16 TempCalibration; /// 26: 2 bytes
public UInt16 AlarmMask; /// 28: 2 bytes, Default 0xA3F7
public UInt16 ConfigCheckSum; /// 30: 2 bytes
public ConfigStruct()
{
PCBNumber = new byte[5];
}
public byte[] ToByteArray()
{
byte[] result = new byte[Length];
result[0] = Version;
result[1] = (byte)MeterState;
result[2] = (byte)(TargetTimeVeryLowBatt & 0x000000FF);
result[3] = (byte)((TargetTimeVeryLowBatt >> 8) & 0x000000FF);
result[4] = (byte)((TargetTimeVeryLowBatt >> 16) & 0x000000FF);
result[5] = (byte)((TargetTimeVeryLowBatt >> 24) & 0x000000FF);
result[6] = (byte)(TargetTimeLowBatt & 0x000000FF);
result[7] = (byte)((TargetTimeLowBatt >> 8) & 0x000000FF);
result[8] = (byte)((TargetTimeLowBatt >> 16) & 0x000000FF);
result[9] = (byte)((TargetTimeLowBatt >> 24) & 0x000000FF);
result[10] = (byte)(TestModeTime & 0x000000FF);
result[11] = (byte)((TestModeTime >> 8) & 0x000000FF);
result[12] = (byte)((TestModeTime >> 16) & 0x000000FF);
result[13] = (byte)((TestModeTime >> 24) & 0x000000FF);
result[14] = (byte)(EmptyPipeThreshold & 0x00FF);
result[15] = (byte)((EmptyPipeThreshold >> 8) & 0x00FF);
result[16] = PCBNumber[0];
result[17] = PCBNumber[1];
result[18] = PCBNumber[2];
result[19] = PCBNumber[3];
result[20] = PCBNumber[4];
result[21] = TestModeConfig;
result[22] = (byte)(RadioAddress & 0x000000FF);
result[23] = (byte)((RadioAddress >> 8) & 0x000000FF);
result[24] = (byte)((RadioAddress >> 16) & 0x000000FF);
result[25] = (byte)((RadioAddress >> 24) & 0x000000FF);
result[26] = (byte)(TempCalibration & 0x00FF);
result[27] = (byte)((TempCalibration >> 8) & 0x00FF);
result[28] = (byte)(AlarmMask & 0x00FF);
result[29] = (byte)((AlarmMask >> 8) & 0x00FF);
result[30] = (byte)(ConfigCheckSum & 0x00FF);
result[31] = (byte)((ConfigCheckSum >> 8) & 0x00FF);
return result;
}
/// <summary>
/// Create a configuration structure from a complete byte array
/// </summary>
/// <param name="data">A complete byte array data</param>
/// <returns>ConfigStruct or null when byte array was not complete</returns>
public static ConfigStruct FromByteArray(byte[] data)
{
if (data.Length != Length) return null;
ConfigStruct result = new ConfigStruct();
result.Version = data[0];
result.MeterState = (MeterState)data[1];
result.TargetTimeVeryLowBatt = (((UInt32)data[5] * 256 + data[4]) * 256 + data[3]) * 256 + data[2];
result.TargetTimeLowBatt = (((UInt32)data[9] * 256 + data[8]) * 256 + data[7]) * 256 + data[6];
result.TestModeTime = (((UInt32)data[13] * 256 + data[12]) * 256 + data[11]) * 256 + data[10];
result.EmptyPipeThreshold = (UInt16)(data[15] * 256 + data[14]);
result.PCBNumber[0] = data[16];
result.PCBNumber[1] = data[17];
result.PCBNumber[2] = data[18];
result.PCBNumber[3] = data[19];
result.PCBNumber[4] = data[20];
result.TestModeConfig = data[21];
result.RadioAddress = (((UInt32)data[25] * 256 + data[24]) * 256 + data[23]) * 256 + data[22];
result.TempCalibration = (UInt16)(data[27] * 256 + data[26]);
result.AlarmMask = (UInt16)(data[29] * 256 + data[28]);
result.ConfigCheckSum = (UInt16)(data[31] * 256 + data[30]);
return result;
}
/// <summary>
/// Update the configuration structure from an incomplete byte array
/// </summary>
/// <param name="offset">Offset of byte array data in ConfigStruct</param>
/// <param name="data">Byte array data</param>
/// <returns>true when successful, false when data are not appropriate</returns>
public bool Update(int offset, byte[] data)
{
if (offset == 0 && data.Length == 2)
{
/// iPerl mode of function
Version = data[0];
MeterState = (MeterState)data[1];
return true;
}
else if (offset == 0 && data.Length == 4)
{
/// iPerl mode of function and extra 2 bytes
Version = data[0];
MeterState = (MeterState)data[1];
return true;
}
else if (offset == 21 && data.Length == 1)
{
/// TestModeConfig value
TestModeConfig = data[21 - offset];
return true;
}
else if (offset == 0 && data.Length == Length)
{
/// Complete ConfigStruct
Version = data[0];
MeterState = (MeterState)data[1];
TargetTimeVeryLowBatt = (((UInt32)data[5] * 256 + data[4]) * 256 + data[3]) * 256 + data[2];
TargetTimeLowBatt = (((UInt32)data[9] * 256 + data[8]) * 256 + data[7]) * 256 + data[6];
TestModeTime = (((UInt32)data[13] * 256 + data[12]) * 256 + data[11]) * 256 + data[10];
EmptyPipeThreshold = (UInt16)(data[15] * 256 + data[14]);
PCBNumber[0] = data[16];
PCBNumber[1] = data[17];
PCBNumber[2] = data[18];
PCBNumber[3] = data[19];
PCBNumber[4] = data[20];
TestModeConfig = data[21];
RadioAddress = (((UInt32)data[25] * 256 + data[24]) * 256 + data[23]) * 256 + data[22];
TempCalibration = (UInt16)(data[27] * 256 + data[26]);
AlarmMask = (UInt16)(data[29] * 256 + data[28]);
ConfigCheckSum = (UInt16)(data[31] * 256 + data[30]);
return true;
}
else
return false;
}
/// <summary>
/// Returns PCB number string (12 characters, 12 decimal digits)
/// </summary>
/// <returns>PCB number STRING</returns>
public string GetPcbNrString()
{
return PCBNumber2String(this.PCBNumber);
}
/// <summary>
/// Converts PCBNumber to string (12 characters, 12 decimal digits)
/// </summary>
/// <param name="pcbNumber"></param>
/// <returns>PCB number string</returns>
public static string PCBNumber2String(byte[] pcbNumber)
{
if (pcbNumber.Length != 5) return string.Empty;
Int64 number = 0;
for (int i = 4; i >= 0; i--)
{
number = 256 * number + (Int64)pcbNumber[i];
}
return number.ToString();
}
public override string ToString()
{
return string.Format("Config: V{0} State={1} VLoBattT={2}s LoBattT={3}s TestModeT={4}s EPThld={5} PCB#={6} TMCfg={7} RadioAddr={8} TempCalib={9} AlarmMask={10} CfgCheckSum={11}",
Version,
MeterState,
TargetTimeVeryLowBatt,
TargetTimeLowBatt,
TestModeTime,
EmptyPipeThreshold,
GetPcbNrString(),
TestModeConfig.ToString("X2"),
RadioAddress,
TempCalibration,
AlarmMask.ToString("X4"),
ConfigCheckSum.ToString("X4"));
}
public string ToString(int sel)
{
return string.Format("{1} PCB#={6} TMCfg={7}",
Version,
MeterState,
TargetTimeVeryLowBatt,
TargetTimeLowBatt,
TestModeTime,
EmptyPipeThreshold,
GetPcbNrString(),
TestModeConfig.ToString("X2"),
RadioAddress,
TempCalibration,
AlarmMask.ToString("X4"),
ConfigCheckSum.ToString("X4"));
}
public virtual void WriteBinary(BinaryWriter writer)
{
writer.Write(Version);
writer.Write((byte)MeterState);
writer.Write(TargetTimeVeryLowBatt);
writer.Write(TargetTimeLowBatt);
writer.Write(TestModeTime);
writer.Write(EmptyPipeThreshold);
writer.Write(PCBNumber[0]);
writer.Write(PCBNumber[1]);
writer.Write(PCBNumber[2]);
writer.Write(PCBNumber[3]);
writer.Write(PCBNumber[4]);
writer.Write(TestModeConfig);
writer.Write(RadioAddress);
writer.Write(TempCalibration);
writer.Write(AlarmMask);
writer.Write(ConfigCheckSum);
}
public virtual void ReadBinary(BinaryReader reader)
{
Version = reader.ReadByte();
MeterState = (MeterState)reader.ReadByte();
TargetTimeVeryLowBatt = reader.ReadUInt32();
TargetTimeLowBatt = reader.ReadUInt32();
TestModeTime = reader.ReadUInt32();
EmptyPipeThreshold = reader.ReadUInt16();
PCBNumber[0] = reader.ReadByte();
PCBNumber[1] = reader.ReadByte();
PCBNumber[2] = reader.ReadByte();
PCBNumber[3] = reader.ReadByte();
PCBNumber[4] = reader.ReadByte();
TestModeConfig = reader.ReadByte();
RadioAddress = reader.ReadUInt32();
TempCalibration = reader.ReadUInt16();
AlarmMask = reader.ReadUInt16();
ConfigCheckSum = reader.ReadUInt16();
}
}
}
@@ -0,0 +1,113 @@
///
/// Copyright (c) 2015-2021 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
{
public enum MessageID
{
Calibration = 0x00, /// Access to stCalibration
Configuration = 0x01, /// Access to stConfig
Status = 0x02, /// Access to stStaus, read only
Power = 0x03, /// Access to stPower, containing power info from both processors
LCD = 0x04, /// Access to stLCD
EventData = 0x05, /// NOT USED
IntervalData = 0x06, /// NOT USED
Diagnostics = 0x07, /// Access tostMetroDiagArray, read onl
MetrologyMemory = 0x08, /// Memory block access, read only
Error_LongAck = 0x09, /// Error message
Command = 0x0A, /// Command to execute, with no arguments
Parameterizing = 0x0B, /// Parameterizing message is used in MCI-SPI interface only
Error_ShortAck = 0x0C, /// Short acknowledge message is used in MCI-SPI interface only
ChanelAlive = 0x0D, /// Channel alive message is used in MCI-SPI interface only
RadioPassthrough = 0x0E, /// RFID <-> Metrology <-> Radio passthrough message
ASICRegisterReadTest = 0x0F, /// ASIC Register read test
IMIDebugMessagesAccess = 0x10, /// IMI debug messages read test
ProductionChecksumsRead = 0x11, /// Production checksum read: Calibration (1 byte), Configuration (2 bytes), spare (4 bytes)
HardwareParametersTest = 0x12, /// Hardware Parameters Testing: User configurable fixed field drive time (1 byte)
/// <summary>
/// Notes:
/// 1. Short Ack message contains 1-byte error code and all the fields (Offset, Payload length, payload and password) will not be present.
/// 2. Channel Alive message does not contain the fields (Offset, Payload length, payload and password).
/// 3. Except the above two special messages, rest all the messages in the above table will follow the message format mentioned in sections 3.1 and 3.2.
/// </summary>
Count /// Number of MessageID-s
}
public enum MeterType : byte
{
DN15 = 0,
CoaxManifold = 1,
DN20 = 2,
DN25 = 3, /// DN25 Q3 = 6.3 m3/h
DN25_Q3_10 = 4, /// DN25 Q3 = 10 m3/h
DN32 = 5,
DN40 = 6,
AutoDetect,
Count /// Number of meter types
}
public enum VolumeUnits : byte
{
m3 = 0,
UK_gallon = 1,
US_gallon = 2,
Count /// Number of volume units
}
public enum FlowArrow : byte
{
No = 0,
Right = 1,
Left = 2,
Count /// Number of flow arrows
}
public enum MeterSealed : byte
{
InProduction = 0x00,
OutOfProduction = 0xA5,
Sealed = 0x5A,
}
public enum MeterState : byte
{
None = 0,
Idle = 1,
Active = 2,
Test = 3,
EndOfLife = 4,
Count /// Number of meter states
}
public enum Command : byte
{
SetActiveMode = 6,
SetTestMode = 7,
}
public enum FlowState : byte
{
No = 0,
Reverse = 1,
Forward = 2,
EmptyPipe = 3,
Count /// Number of flow states
}
public enum DataStreamState
{
Flush = 0,
ProcessAndSave,
}
public enum CommunicationInterface
{
RFID,
NFC
}
}
@@ -0,0 +1,20 @@
///
/// Copyright (c) 2015-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
{
public class OptoReceivedEventArgs : EventArgs
{
public string Data;
public OptoReceivedEventArgs(string data)
{
this.Data = data;
}
}
}
@@ -0,0 +1,131 @@
using Config.Resources;
using log4net;
using Sensus.iPerl.RfidCom.Helper;
using Sensus.iPerl.RfidCom.Services;
using Sensus.iPerl.RfidCom.Structures;
using System;
using System.Threading;
using TBF.Rig.Hart.Common;
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
using static Sensus.iPerl.NfcHandler.MCI_Protocol;
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.test
{
internal class OpticalHeadTest
{
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
internal static string OpenSealing(IperlHead iHead)
{
if (RfidCommands.OpenSealing($"COM{iHead.RfidComPortNr}")) return "OK";
return "Error Open Sealing";
}
internal static string ReadRequest_PCB(IperlHead iHead)
{
try
{
byte[] pcb = null;
int readRetVal = iPerlCommunicationForm.ReadRequestPort(iHead, MessageID.Configuration, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.Configuration, 16, 5, out pcb);
if (readRetVal == 0)
{
return RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(BitConverter.ToString(pcb).Replace("-", string.Empty))).ToString();
}
rfidDataLogger.Error($"COM{iHead.RfidComPortNr}: ReadRequest_PCB ({MessageID.Configuration},16,5...) <- Error: {readRetVal}");
return "Error";
}
catch (Exception ex)
{
return (ex.Message.ToString());
}
}
internal static string SetActiveMode(IperlHead iHead)
{
byte[] cmd = new byte[1] { (byte)Command.SetActiveMode };
if (0 == iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.Command, StructName.Command, 0, 1, cmd))
{
return "OK";
}
else
{
return "Error Set Active Mode";
}
}
internal static string SetTestMode(IperlHead iHead)
{
byte[] cmd = new byte[1] { (byte)Command.SetTestMode };
if (0 == iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.Command, StructName.Command, 0, 1, cmd))
{
return "OK";
}
else
{
return "Error Set Test Mode";
}
}
#if IPERL
internal static string TurnOffRadio(IperlHead iHead)
{
try
{
int retValue = iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.RadioPassthrough, StructName.RadioParams, 0x1898, 1, new byte[] { (byte)3 }); // WakeUpInterval
return 0 == retValue ? "OK" : "Error";
}
catch (Exception ex)
{
return (ex.Message.ToString());
}
}
internal static string SetProductionMode(IperlHead iHead)
{
try
{
int retValue = iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.RadioPassthrough, StructName.RadioInfo, 0x1804, 1, new byte[] { (byte)1 }); // System Status
return 0 == retValue ? "OK" : "Error";
}
catch (Exception ex)
{
return (ex.Message.ToString());
}
}
internal static string WriteRequestPort_u8_Customer_Text(IperlHead iHead)
{
string custText = "FF0123456789ABCDEF"; // Sample text to test write function
/*try
{
byte[] cmd = RfidHelper.HexStringToByteArray(custText);
if (0 == iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.RadioPassthrough, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.RadioParams, 0x1899, 9, cmd))
{
RfidCommunicationService rfidCommunicationService = new RfidCommunicationService { ComPort = $"COM{iHead.RfidComPortNr}", WaitTimeAfterFailure = 2200, PassThroughWaitTime = 1500, MaxRetries = 3, TimeOut = 5000 };
//rfidCommunicationService.RfidWrite(Params.u8_Customer_Text, custText);
return rfidCommunicationService.RfidRead<string>(Params.u8_Customer_Text).ToString();
}
}
catch (Exception ex)
{
return (ex.Message.ToString());
}*/
return $"Error COM{iHead.RfidComPortNr}";
}
internal static string SetRfidMode(IperlHead iHead)
{
iHead.SetRfidInterface();
iHead.SetCommunicationInterface(CommunicationInterface.RFID);
return ($"OK - {Strings.Program_restart_is_required_to_apply_some_settings}");
}
internal static string SetNfcMode(IperlHead iHead)
{
iHead.SetNfcInterface();
iHead.SetCommunicationInterface(CommunicationInterface.NFC);
return ($"OK - {Strings.Program_restart_is_required_to_apply_some_settings}");
}
#endif /// IPERL
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4 -6
View File
@@ -539,12 +539,10 @@ namespace TBF.Rig.Sequences
//---endnew2
(outPath.Scale is IScale) ? (outPath.Scale as IScale).Mass : 0, /// collected water mass in kg
"VolMM",
//---new2
AmbTemp.ToString(), /// ambient temperature in degree C
AmbHumi.ToString(), /// ambient humidity in R%
AmbPress.ToString(), /// ambient pressure in mbar (= 1 hPa)
//---endnew2
outPath.RegValve.Position.ToString("F1")); /// regulation valve position in % (0=closed / 100=open)
AmbTemp, /// ambient temperature in degree C
AmbHumi, /// ambient humidity in R%
AmbPress, /// ambient pressure in mbar (= 1 hPa)
outPath.RegValve?.Position.ToString("F1")); /// regulation valve position in % (0=closed / 100=open)
}
public void LogProcessDataHeaderHeatMeters(ILog logger, string sectionName)
+8 -6
View File
@@ -1505,23 +1505,25 @@ namespace TBF.Rig.Sequences
tstRslt.DensityLine = Formulas.RealDensity();
tstRslt.DensityDiv = Formulas.RealDensity();
double flowMeterLtrPerPulse = outPath.FlowMeter?.LtrPerPulse ?? 1;
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
tstRslt.StartTime = DateTime.Now;
tstRslt.EndTime = DateTime.Now + new TimeSpan(0, 0, 1);
tstRslt.FlowSetTime = 10;
tstRslt.TestTime = tstRslt.TargetTime();
tstRslt.PulsesMaster = (outPath.FlowMeter.LtrPerPulse > 1E-6) ? (1.0075 * tstRslt.TargetVolume() / outPath.FlowMeter.LtrPerPulse) : 1;
tstRslt.PulsesMaster = (flowMeterLtrPerPulse > 1E-6) ? (1.0075 * tstRslt.TargetVolume() / flowMeterLtrPerPulse) : 1;
tstRslt.MassStartRaw = 0;
tstRslt.MassStart = MeasurementCorrection.CorrectedValue(tstRslt.MassStartRaw, outPath.Scale.Corrections);
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Formulas.RealDensity() / 1000.0f;
tstRslt.MassEnd = MeasurementCorrection.CorrectedValue(tstRslt.MassEndRaw, outPath.Scale.Corrections);
tstRslt.Flow = 3.6 * outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster / tstRslt.TestTime;
tstRslt.Flow = 3.6 * flowMeterLtrPerPulse * tstRslt.PulsesMaster / tstRslt.TestTime;
tstRslt.MassOfEvapWater = 0;
tstRslt.VolumeCTV = 1000 * tstRslt.Batch.Buoyancy * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.DensityLine; /// [l] commercially true volume
tstRslt.VolumeMaster = outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
tstRslt.ConstMasterRaw = outPath.FlowMeter.LtrPerPulse; /// Uncorrected master flowmeter coefficient
tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean); /// Corrected master pulses per liter
tstRslt.ConstMaster = (tstRslt.VolumeMaster == 0) ? tstRslt.ConstMasterCorr : (outPath.FlowMeter.LtrPerPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster);
tstRslt.VolumeMaster = flowMeterLtrPerPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
tstRslt.ConstMasterRaw = flowMeterLtrPerPulse; /// Uncorrected master flowmeter coefficient
tstRslt.ConstMasterCorr = outPath.FlowMeter?.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean) ?? 1; /// Corrected master pulses per liter
tstRslt.ConstMaster = (tstRslt.VolumeMaster == 0) ? tstRslt.ConstMasterCorr : (flowMeterLtrPerPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster);
tstRslt.ErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV);
+1
View File
@@ -125,6 +125,7 @@ namespace TBF.Rig
new BuiltIn.PumpTandem.PumpFactory(),
new RegisterReaders.DataStream.MefImport.Factory(), /// 'Interface for data stream stream via MEF'
new RegisterReaders.DataStream.Reader.Factory(), /// 'RegisterReader for data stream stream via MEF'
new RegisterReaders.FrequencyMeterFromUniCB.Factory(), ///
new RegisterReaders.PulsesFromUniCB.Factory(), /// 'RegisterReader'
new RegisterReaders.StandingStartStop.Factory(), /// 'RegisterReader for standing start/stop'
new TestMethods.iPerlCommunication.iPerlHead.Factory(), /// 'RegisterReader for iPerl'
@@ -123,6 +123,11 @@ namespace TBF.Rig.TestMethods.LeakTest
Bridge.OnActivity(this, Strings.Setting_the_water_pressure);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
//------------------------------------------------
//TODO BUMI - check this possition for sstart logging - when finish remove this comment
//--- log start process in this section
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
float pumpPower = test.PumpPower;
int startTime = StateMachine.Time;
@@ -214,10 +219,14 @@ namespace TBF.Rig.TestMethods.LeakTest
Bridge.OnActivity(this, Strings.Test_in_progress);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
//------------------------------------------------
LogProcessDataHeader(processDataLogger, "Maximum water pressure set");
State.Create(string.Format("{0}({1}) : Maximum water pressure set", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(testParams.DurationPMax))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@@ -246,10 +255,14 @@ namespace TBF.Rig.TestMethods.LeakTest
//-----------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//-----------------------------------------------------
LogProcessDataHeader(processDataLogger, "Measuring the start mass");
State.Create(string.Format("{0}({1}) : Measuring the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@@ -275,10 +288,14 @@ namespace TBF.Rig.TestMethods.LeakTest
///------------------------------------------------
Bridge.OnActivity(this, Strings.Test_in_progress);
///------------------------------------------------
LogProcessDataHeader(processDataLogger, "Starting the test");
State.Create(string.Format("{0}({1}) : Starting the test", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(testParams.DurationLeak))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@@ -305,10 +322,14 @@ namespace TBF.Rig.TestMethods.LeakTest
//-----------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//-----------------------------------------------------
LogProcessDataHeader(processDataLogger, " Measuring the end mass");
State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
+15 -6
View File
@@ -111,7 +111,7 @@ namespace TBF.Rig.TestMethods.PMaxTest
Bridge.OnActivity(this, Strings.Setting_the_water_pressure);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
//------------------------------------------------
float pumpPower = test.PumpPower;
while (true)
{
@@ -175,11 +175,21 @@ namespace TBF.Rig.TestMethods.PMaxTest
int startTime = StateMachine.Time;
int endTime = startTime + testParams.DurationPMax;
//TODO BUMI - check this possition for sstart logging - when finish remove this comment
//--- log start process in this section
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_in_progress);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
//------------------------------------------------
//TODO BUMI - check if is ok possition to start logging - at last remove comment
//--- log start process in this section
LogProcessDataHeader(processDataLogger, "Starting the test");
/*//---new1
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
@@ -194,10 +204,8 @@ namespace TBF.Rig.TestMethods.PMaxTest
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(testParams.DurationPMax))
//---new1
.AddOperation(processDataLoggingOp)
//---endNew1
.EnterState();
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@@ -213,7 +221,8 @@ namespace TBF.Rig.TestMethods.PMaxTest
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
}
while (e.Contains(Event.TimerBusy));
///
/// PMaxTest completed
///
@@ -469,7 +469,8 @@ namespace TBF.Rig.TestMethods.StandingStart
(dataEntryCmpnt as GenericDevices.IDataEntryForCamera).StartImages = startImages;
}
long readStartTime = StateMachine.Time;
Bridge.OnActivity(this, Strings.Enter_water_meter_data);
State.Create(string.Format("{0}({1}) : Entering begin-state", test.Method, test.Name))
.AddOperation(checkUiOp)
@@ -482,6 +483,11 @@ namespace TBF.Rig.TestMethods.StandingStart
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.ModelessFormClosed));
long readEndTime = StateMachine.Time;
var elapsed = TimeSpan.FromTicks((readEndTime - readStartTime));
log.Debug($"Read poseidon Begin operation (with dialog) - took:{elapsed.TotalSeconds} => {elapsed:mm\\:ss}");
if (heatMetersTestParams != null)
{
@@ -703,7 +709,8 @@ namespace TBF.Rig.TestMethods.StandingStart
(dataEntryCmpnt as GenericDevices.IDataEntryForCamera).EndImages = endImages;
}
long readStartTime = DateTime.Now.Ticks;
Bridge.OnActivity(this, Strings.Enter_water_meter_data);
State state = State.Create(string.Format("{0}({1}) : Entering the end-state", test.Method, test.Name));
if (heatMetersTestParams != null && dataEntryCmpnt is GenericDevices.IHasHeatMtrStatesForm)
@@ -726,6 +733,9 @@ namespace TBF.Rig.TestMethods.StandingStart
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.ModelessFormClosed));
long readEndTime = DateTime.Now.Ticks;
var elapsed = TimeSpan.FromTicks((readEndTime - readStartTime));
log.Debug($"Read poseidon End operation (with dialog) - took:{elapsed.TotalSeconds} => {elapsed:mm\\:ss}");
if (heatMetersTestParams != null)
@@ -555,6 +555,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
Bridge.OnActivity(this, Strings.Enter_water_meter_data);
long readStartTime = StateMachine.Time;
State.Create(string.Format("{0}({1}) : Enter start states of water meters", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
@@ -568,6 +569,9 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.ModelessFormClosed));
long readEndTime = StateMachine.Time;
log.Debug("Read poseidon - took:" + (readEndTime - readStartTime));
if (heatMetersTestParams != null)
{
+53 -1
View File
@@ -139,6 +139,8 @@
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Management" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Numerics" />
@@ -1152,6 +1154,16 @@
<Compile Include="Rig\Output\FileWriters\Basic\WriterCfgCtrl.designer.cs">
<DependentUpon>WriterCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\FrequencyRegisterReader.cs" />
<Compile Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\Factory.cs" />
<Compile Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\RRCfg.cs" />
<Compile Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\RRCfgCtrl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\RRCfgCtrl.designer.cs">
<DependentUpon>RRCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\RRProcParams.cs" />
<Compile Include="Rig\RegisterReaders\DataStream\MefImport\Factory.cs" />
<Compile Include="Rig\RegisterReaders\DataStream\MefImport\MefImport.cs" />
<Compile Include="Rig\RegisterReaders\DataStream\MefImport\MefImportCfg.cs" />
@@ -1159,6 +1171,34 @@
<Compile Include="Rig\RegisterReaders\DataStream\Reader\ProcParams.cs" />
<Compile Include="Rig\RegisterReaders\DataStream\Reader\Reader.cs" />
<Compile Include="Rig\RegisterReaders\DataStream\Reader\ReaderCfg.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\comminication\CalibrationStruct.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\comminication\CalibrationStructV4.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\comminication\ConfigStruct.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\comminication\Enums.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\comminication\OptoReceivedEventArgs.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\Factory.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\IPerlCfgCtrl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\IPerlCfgCtrl.designer.cs">
<DependentUpon>IPerlCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\IperlHeadTestCtrl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\IperlHeadTestCtrl.Designer.cs">
<DependentUpon>IperlHeadTestCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\IPerlReader.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\IPerlCfg.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\ProcParams.cs" />
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\test\iPerlCommunicationForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\test\iPerlCommunicationForm.designer.cs">
<DependentUpon>iPerlCommunicationForm.cs</DependentUpon>
</Compile>
<Compile Include="Rig\RegisterReaders\iPerlReaderUNI\test\OpticalHeadTest.cs" />
<Compile Include="Rig\RegisterReaders\KPackE\DataEntryForRadio\CycleBeginningForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -1199,6 +1239,7 @@
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonCfg.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonProcParams.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonReader.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\ScopedLoggerFactory.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\SerialPortData.cs" />
<Compile Include="Rig\RegisterReaders\PulsesFromUniCB\Factory.cs" />
<Compile Include="Rig\RegisterReaders\PulsesFromUniCB\RegisterReader.cs" />
@@ -3041,6 +3082,18 @@
<EmbeddedResource Include="Rig\Output\FileWriters\Basic\WriterCfgCtrl.resx">
<DependentUpon>WriterCfgCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\RegisterReaders\FrequencyMeterFromUniCB\RRCfgCtrl.resx">
<DependentUpon>RRCfgCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\RegisterReaders\iPerlReaderUNI\IPerlCfgCtrl.resx">
<DependentUpon>IPerlCfgCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\RegisterReaders\iPerlReaderUNI\IperlHeadTestCtrl.resx">
<DependentUpon>IperlHeadTestCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\RegisterReaders\iPerlReaderUNI\test\iPerlCommunicationForm.resx">
<DependentUpon>iPerlCommunicationForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\RegisterReaders\KPackE\DataEntryForRadio\CycleBeginningForm.resx">
<DependentUpon>CycleBeginningForm.cs</DependentUpon>
</EmbeddedResource>
@@ -3741,7 +3794,6 @@
<Name>Results</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
+356 -270
View File
@@ -1,9 +1,11 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Web.UI;
using System.Windows.Forms;
using log4net;
using NHibernate;
@@ -13,27 +15,31 @@ using Config.Entities;
using TBF.Rig;
using TBF.Rig.Generic;
using TBF.Resources;
using TBF.Rig.GenericDevices;
using TBF.Rig.WaterMeters.WaterMeter;
using TBF.UI.Shared;
namespace TBF.UI.Bench.Components
{
public partial class ComponentsManagerDlg : Form, IParentOfListViewEx
{
static readonly ILog log = LogManager.GetLogger(typeof(ComponentsManagerDlg));
public partial class ComponentsManagerDlg : Form, IParentOfListViewEx
{
static readonly ILog log = LogManager.GetLogger(typeof(ComponentsManagerDlg));
/// <summary>
/// List of components (=component configuration instances)
/// </summary>
IList<Component> cmpntEntities;
/// <summary>
/// List of components (=component configuration instances)
/// </summary>
IList<Component> cmpntEntities;
IList<Component> toBeDeletedEntities;
IList<Component> toBeDeletedEntities;
ISession session;
ISession session;
SelectComponentClassDlg selectComponentTypeDlg; /// Constructed once, the selection is kept between dialog usages
SelectComponentClassDlg selectComponentTypeDlg;
CfgUpdateFlags flags; /// Or-ed from particular Flags from ComponentParametersDlg
/// Constructed once, the selection is kept between dialog usages
CfgUpdateFlags flags;
/// Or-ed from particular Flags from ComponentParametersDlg
/// <summary>
/// ListViewEx columns
/// </summary>
@@ -50,27 +56,29 @@ namespace TBF.UI.Bench.Components
}
MySortOrder sortOrder = MySortOrder.Ascending;
int sortColumn = -1; /// 0-based index of column to be used for sorting
int sortColumn = -1;
/// Editors used by listViewEx
/// 0-based index of column to be used for sorting
/// Editors used by listViewEx
ComboBox debugCB;
ComboBox logCB;
bool unlocked;
bool unlocked;
public ComponentsManagerDlg()
{
toBeDeletedEntities = new List<Component>();
public ComponentsManagerDlg()
{
toBeDeletedEntities = new List<Component>();
InitializeComponent();
InitializeComponent();
flags = CfgUpdateFlags.None;
flags = CfgUpdateFlags.None;
selectComponentTypeDlg = new SelectComponentClassDlg();
selectComponentTypeDlg = new SelectComponentClassDlg();
/// SharedDlgButtons configuration
/// SharedDlgButtons configuration
sharedButtons.ParentForm = this;
sharedButtons.RequiredGroupMembership = new GID[] { GID.Metrologists };
sharedButtons.RequiredGroupMembership = new GID[] { GID.Metrologists };
sharedButtons.OptionalButtons = SharedButtons.Buttons.Add |
SharedButtons.Buttons.Remove |
@@ -81,34 +89,35 @@ namespace TBF.UI.Bench.Components
SharedButtons.Buttons.Export |
SharedButtons.Buttons.Import;
sharedButtons.Unlocked += Unlocked;
sharedButtons.OKClicked += okButton_Click;
sharedButtons.CancelClicked += cancelButton_Click;
sharedButtons.AddClicked += addButton_Click;
sharedButtons.RemoveClicked += removeButton_Click;
sharedButtons.UpClicked += upButton_Click;
sharedButtons.DownClicked += downButton_Click;
sharedButtons.EditClicked += editButton_Click;
sharedButtons.OKClicked += okButton_Click;
sharedButtons.CancelClicked += cancelButton_Click;
sharedButtons.AddClicked += addButton_Click;
sharedButtons.RemoveClicked += removeButton_Click;
sharedButtons.UpClicked += upButton_Click;
sharedButtons.DownClicked += downButton_Click;
sharedButtons.EditClicked += editButton_Click;
sharedButtons.CopyClicked += copyButton_Click;
sharedButtons.ExportClicked += exportButton_Click;
sharedButtons.ImportClicked += importButton_Click;
}
private void ComponentsManagerDlg_Load(object sender, EventArgs e)
{
private void ComponentsManagerDlg_Load(object sender, EventArgs e)
{
LoadFormPosition();
Text = Strings.Test_Bench_Components_Configuration;
LocalSettings ls = Program.LocalSettings;
listViewEx.Columns.Add(Strings.Nr, (ls.ComponentsColumnCount > 0) ? ls.ComponentsColumnWidths[0] : 40);
listViewEx.Columns.Add(Strings.Name, (ls.ComponentsColumnCount > 1) ? ls.ComponentsColumnWidths[1] : 80);
listViewEx.Columns.Add(Strings.Type, (ls.ComponentsColumnCount > 2) ? ls.ComponentsColumnWidths[2] : 120);
listViewEx.Columns.Add(Strings.Parent, (ls.ComponentsColumnCount > 3) ? ls.ComponentsColumnWidths[3] : 55);
listViewEx.Columns.Add(Strings.Mode, (ls.ComponentsColumnCount > 4) ? ls.ComponentsColumnWidths[4] : 55);
listViewEx.Columns.Add(Strings.Logging, (ls.ComponentsColumnCount > 5) ? ls.ComponentsColumnWidths[5] : 55);
listViewEx.Columns.Add(Strings.Parameters, (ls.ComponentsColumnCount > 6) ? ls.ComponentsColumnWidths[6] : 600);
listViewEx.Columns.Add(Strings.Nr, (ls.ComponentsColumnCount > 0) ? ls.ComponentsColumnWidths[0] : 40);
listViewEx.Columns.Add(Strings.Name, (ls.ComponentsColumnCount > 1) ? ls.ComponentsColumnWidths[1] : 80);
listViewEx.Columns.Add(Strings.Type, (ls.ComponentsColumnCount > 2) ? ls.ComponentsColumnWidths[2] : 120);
listViewEx.Columns.Add(Strings.Parent, (ls.ComponentsColumnCount > 3) ? ls.ComponentsColumnWidths[3] : 55);
listViewEx.Columns.Add(Strings.Mode, (ls.ComponentsColumnCount > 4) ? ls.ComponentsColumnWidths[4] : 55);
listViewEx.Columns.Add(Strings.Logging, (ls.ComponentsColumnCount > 5) ? ls.ComponentsColumnWidths[5] : 55);
listViewEx.Columns.Add(Strings.Parameters,
(ls.ComponentsColumnCount > 6) ? ls.ComponentsColumnWidths[6] : 600);
listViewEx.HeaderStyle = ColumnHeaderStyle.Clickable;
debugCB = new ComboBox();
debugCB = new ComboBox();
for (DebugMode level = 0; level < DebugMode.Count; level++) debugCB.Items.Add(level.ToDescription());
splitContainer.Panel1.Controls.Add(debugCB);
@@ -119,23 +128,23 @@ namespace TBF.UI.Bench.Components
listViewEx.SubItemClicked += new SubItemEventHandler(listViewEx_SubItemClicked);
listViewEx.SubItemEndEditing += new SubItemEndEditingEventHandler(listViewEx_SubItemEndEditing);
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
session = TBF.DB.CreateSession(DBKind.Config);
cmpntEntities = session.QueryOver<Component>()
.OrderBy(x => x.ItemNr).Asc
.List<Component>();
session = TBF.DB.CreateSession(DBKind.Config);
cmpntEntities = session.QueryOver<Component>()
.OrderBy(x => x.ItemNr).Asc
.List<Component>();
RedrawAll();
}
RedrawAll();
}
void listViewEx_SubItemClicked(object sender, SubItemEventArgs e)
{
if (unlocked && e.SubItem == (int)Column.DebugMode)
if (unlocked && e.SubItem == (int)Column.DebugMode)
{
listViewEx.StartEditing(debugCB, e.Item, e.SubItem);
}
else if (unlocked && e.SubItem == (int)Column.Logging)
else if (unlocked && e.SubItem == (int)Column.Logging)
{
listViewEx.StartEditing(logCB, e.Item, e.SubItem);
}
@@ -146,7 +155,7 @@ namespace TBF.UI.Bench.Components
if (!unlocked || ((e.SubItem != (int)Column.DebugMode) && (e.SubItem != (int)Column.Logging))) return;
if (DialogResult.Yes == MessageBox.Show(Strings.Do_you_want_to_copy_this_value_to_all_cells_below_this_cell,
Strings.Confirmation, MessageBoxButtons.YesNo, MessageBoxIcon.Question))
Strings.Confirmation, MessageBoxButtons.YesNo, MessageBoxIcon.Question))
{
int columnNr = e.SubItem;
string value = null;
@@ -204,10 +213,11 @@ namespace TBF.UI.Bench.Components
if (debugCB.Text.Equals(level.ToDescription()))
{
cmpnt.DebugMode = level;
flags |= CfgUpdateFlags.RestartRqrd;
flags |= CfgUpdateFlags.RestartRqrd;
return;
}
}
e.DisplayText = cmpnt.DebugMode.ToString();
}
else if (e.SubItem == (int)Column.Logging)
@@ -217,35 +227,36 @@ namespace TBF.UI.Bench.Components
if (logCB.Text.Equals(level.ToDescription()))
{
cmpnt.LogLevel = level;
flags |= CfgUpdateFlags.RestartRqrd;
return;
flags |= CfgUpdateFlags.RestartRqrd;
return;
}
}
e.DisplayText = cmpnt.LogLevel.ToString();
}
}
private void Unlocked(object sender, EventArgs e)
{
unlocked = true;
private void Unlocked(object sender, EventArgs e)
{
unlocked = true;
if (listViewEx.SelectedItems.Count == 1)
{
int ix = listViewEx.SelectedIndices[0];
Focus();
listViewEx.Items[ix].Selected = true;
listViewEx.Items[ix].EnsureVisible();
}
}
if (listViewEx.SelectedItems.Count == 1)
{
int ix = listViewEx.SelectedIndices[0];
Focus();
listViewEx.Items[ix].Selected = true;
listViewEx.Items[ix].EnsureVisible();
}
}
void RedrawAll()
{
listViewEx.Items.Clear();
foreach (var cmpnt in cmpntEntities) DrawOne(cmpnt);
}
void RedrawAll()
{
listViewEx.Items.Clear();
foreach (var cmpnt in cmpntEntities) DrawOne(cmpnt);
}
void DrawOne(Component cmpnt)
{
void DrawOne(Component cmpnt)
{
ListViewItem lvi = new ListViewItem(cmpnt.ItemNr.ToString());
lvi.Tag = cmpnt;
lvi.SubItems.Add(cmpnt.Name);
@@ -254,18 +265,17 @@ namespace TBF.UI.Bench.Components
IComponentCfg cmpCfg = TbfComponents.CmpntCfgFromCmpntEntity(cmpnt);
if (cmpCfg != null)
{
{
lvi.SubItems.Add(cmpCfg.DebugLevel.ToDescription());
lvi.SubItems.Add(cmpCfg.LogLevel.ToDescription());
lvi.SubItems.Add(cmpCfg.ToString(-1));
}
else
{
lvi.SubItems.Add("---");
lvi.SubItems.Add("---");
lvi.SubItems.Add("Not a component");
}
lvi.SubItems.Add(cmpCfg.LogLevel.ToDescription());
lvi.SubItems.Add(cmpCfg.ToString(-1));
}
else
{
lvi.SubItems.Add("---");
lvi.SubItems.Add("---");
lvi.SubItems.Add("Not a component");
}
listViewEx.Items.Add(lvi);
}
@@ -304,10 +314,10 @@ namespace TBF.UI.Bench.Components
private void LoadFormPosition()
{
LocalSettings ls = Program.LocalSettings;
Width = (ls.ComponentsDlgWidth > 0) ? ls.ComponentsDlgWidth : 850;
Width = (ls.ComponentsDlgWidth > 0) ? ls.ComponentsDlgWidth : 850;
Height = (ls.ComponentsDlgHeight > 0) ? ls.ComponentsDlgHeight : 500;
Left = (ls.ComponentsDlgLeft != 0) ? ls.ComponentsDlgLeft : 200;
Top = (ls.ComponentsDlgTop != 0) ? ls.ComponentsDlgTop : 100;
Left = (ls.ComponentsDlgLeft != 0) ? ls.ComponentsDlgLeft : 200;
Top = (ls.ComponentsDlgTop != 0) ? ls.ComponentsDlgTop : 100;
}
/// <summary>
@@ -334,7 +344,11 @@ namespace TBF.UI.Bench.Components
{
for (int i = 0; i < (int)Column.ColumnsCount; i++)
{
if (listViewEx.Columns[i].Width != ls.ComponentsColumnWidths[i]) { anyColumnDiffers = true; break; }
if (listViewEx.Columns[i].Width != ls.ComponentsColumnWidths[i])
{
anyColumnDiffers = true;
break;
}
}
}
@@ -366,84 +380,149 @@ namespace TBF.UI.Bench.Components
}
///
/// OK
/// OK
///
private void okButton_Click(object sender, EventArgs e)
{
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
{
{
ValidateComponents();
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
{
SaveDBChanges(session);
flags = CfgUpdateFlags.None; /// Changes saved
flags = CfgUpdateFlags.None; /// Changes saved
}
SaveUISettings();
DialogResult = DialogResult.OK;
Close();
return;
}
Close();
return;
}
/// Cancel
private void cancelButton_Click(object sender, EventArgs e)
{
private void ValidateComponents()
{
Boolean invalid = false;
string validationMessage = "";
//validation cycle
invalid = !ValidateMetersBatchCount(out validationMessage);
if (invalid)
{
MessageBox.Show(validationMessage, Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private Boolean ValidateMetersBatchCount(out string message)
{
bool invalid = false;
TBF.Rig.DataContainer.BenchInfo.ComponentCfg benchInfo = null;
int waterMetersCount = 0;
int iWaterMeterComponentCount = 0;
foreach (Component component in cmpntEntities)
{
if (component == null)
{
continue;
}
string className = (string.IsNullOrEmpty(component.ClassName) ? string.Empty : component.ClassName);
if (className == "DataContainer.BenchInfo")
{
try
{
var cfg = new TBF.Rig.DataContainer.BenchInfo.Factory().CmpntCfgFromCmpntEntity(component)
as TBF.Rig.DataContainer.BenchInfo.ComponentCfg;
waterMetersCount = cfg.WaterMetersCount;
}
catch (Exception e)
{
log.Error("Finding of DataContainer.BenchInfo data unsuccessfully!");
}
}
if (className == "WaterMeter")
{
iWaterMeterComponentCount++;
}
}
invalid = (waterMetersCount != iWaterMeterComponentCount);
if (invalid)
{
message = "The count of water meters on the bench does not match the count of their components!";
return false;
}
message = "";
return true;
}
/// Cancel
private void cancelButton_Click(object sender, EventArgs e)
{
SaveUISettings();
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
{
DialogResult dr = MessageBox.Show(Strings.Changes_will_be_lost_Do_you_want_to_proceed,
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (dr != DialogResult.Yes) return;
}
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
{
DialogResult dr = MessageBox.Show(Strings.Changes_will_be_lost_Do_you_want_to_proceed,
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (dr != DialogResult.Yes) return;
}
flags = CfgUpdateFlags.None; /// Abandoning changes confirmed
flags = CfgUpdateFlags.None; /// Abandoning changes confirmed
DialogResult = DialogResult.Cancel;
Close();
return;
}
Close();
return;
}
/// Add a new component
private void addButton_Click(object sender, EventArgs e)
{
selectComponentTypeDlg.SelectedScriptName = null;
DialogResult dialogRslt = selectComponentTypeDlg.ShowDialog();
if (dialogRslt != DialogResult.OK) return;
/// Add a new component
private void addButton_Click(object sender, EventArgs e)
{
selectComponentTypeDlg.SelectedScriptName = null;
DialogResult dialogRslt = selectComponentTypeDlg.ShowDialog();
if (dialogRslt != DialogResult.OK) return;
IComponentFactory factory = selectComponentTypeDlg.SlctdCmpntFactory;
IComponentFactory factory = selectComponentTypeDlg.SlctdCmpntFactory;
IComponentCfg cfg = factory.DefaultConfig();
if (selectComponentTypeDlg.SelectedScriptName == null)
{
{
///
/// Create a single component of the selected type
///
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
cfgControl.Config = cfg;
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
cfgControl.Config = cfg;
cfgControl.Config.ItemNr =
(cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
cfgForm.CmpntEntities = cmpntEntities;
cfgForm.ComponentCfgCtrl = cfgControl;
cfgForm.UnlockAfterStart = true;
dialogRslt = cfgForm.ShowDialog();
if (dialogRslt != DialogResult.OK) return;
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
cfgForm.CmpntEntities = cmpntEntities;
cfgForm.ComponentCfgCtrl = cfgControl;
cfgForm.UnlockAfterStart = true;
dialogRslt = cfgForm.ShowDialog();
if (dialogRslt != DialogResult.OK) return;
flags |= CfgUpdateFlags.RestartRqrd;
AddOne(cfgForm.Config.CreateDbEntity());
}
else
{
flags |= CfgUpdateFlags.RestartRqrd;
AddOne(cfgForm.Config.CreateDbEntity());
}
else
{
///
/// Create more components, read their names and other properties from a file
///
using (TextReader reader = new StreamReader(selectComponentTypeDlg.SelectedScriptName))
{
int zeroBasedIdx = 0;
string line = reader.ReadLine();
while (line != null)
{
line.Trim();
{
int zeroBasedIdx = 0;
string line = reader.ReadLine();
while (line != null)
{
line.Trim();
if (line.Length > 0)
{
string[] words = line.Split(new char[] { ' ', '\t' });
@@ -451,83 +530,85 @@ namespace TBF.UI.Bench.Components
if (UpdateCfg(ref cfg, words, ref zeroBasedIdx))
{
flags |= CfgUpdateFlags.RestartRqrd;
cfg.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
cfg.ItemNr = (cmpntEntities.Count > 0)
? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1)
: 1;
AddOne(cfg.CreateDbEntity());
}
zeroBasedIdx++;
}
line = reader.ReadLine();
}
}
}
}
line = reader.ReadLine();
}
}
}
}
void AddOne(Component cmpnt)
{
cmpntEntities.Add(cmpnt);
DrawOne(cmpnt);
}
void AddOne(Component cmpnt)
{
cmpntEntities.Add(cmpnt);
DrawOne(cmpnt);
}
/// Delete the component
private void removeButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
int ix = listViewEx.SelectedIndices[0];
if (ix < 0) return;
Component selectedCmpnt = (Component)listViewEx.Items[ix].Tag;
/// Delete the component
private void removeButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
int ix = listViewEx.SelectedIndices[0];
if (ix < 0) return;
Component selectedCmpnt = (Component)listViewEx.Items[ix].Tag;
if (selectedCmpnt.Id != 0) toBeDeletedEntities.Add(selectedCmpnt);
cmpntEntities.Remove(selectedCmpnt);
flags |= CfgUpdateFlags.AnyChange;
RedrawAll();
}
RedrawAll();
}
/// DoubleClick -> Edit the component
private void listViewEx_MouseDoubleClick(object sender, MouseEventArgs e)
{
editButton_Click(sender, e);
}
/// DoubleClick -> Edit the component
private void listViewEx_MouseDoubleClick(object sender, MouseEventArgs e)
{
editButton_Click(sender, e);
}
/// Edit a component
private void editButton_Click(object sender, EventArgs e)
{
/// Edit a component
private void editButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
ListViewItem lvi = listViewEx.SelectedItems[0];
Component component = lvi.Tag as Component;
if (component == null) return;
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity(component);
if (cfg != null)
{
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity(component);
if (cfg != null)
{
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this, component.Id);
cfgForm.CmpntEntities = cmpntEntities;
cfgForm.CmpntEntities = cmpntEntities;
cfgForm.ComponentCfgCtrl = cfg.GetControl(cmpntEntities);
cfgForm.ComponentCfgCtrl.Config = cfg;
DialogResult dr = cfgForm.ShowDialog();
if (dr != DialogResult.OK) return;
cfgForm.ComponentCfgCtrl.Config = cfg;
DialogResult dr = cfgForm.ShowDialog();
if (dr != DialogResult.OK) return;
flags |= cfgForm.Flags;
flags |= cfgForm.Flags;
sharedButtons.UnlockButtons(); /// Unlock this dialog buttons as changes were enabled
unlocked = true; /// in the ComponentParametersDlg.
sharedButtons.UnlockButtons(); /// Unlock this dialog buttons as changes were enabled
unlocked = true; /// in the ComponentParametersDlg.
Component modified = cfgForm.Config.CreateDbEntity();
Component original = (Component)lvi.Tag;
Component modified = cfgForm.Config.CreateDbEntity();
Component original = (Component)lvi.Tag;
original.Name = modified.Name;
original.ClassName = modified.ClassName;
original.Parent = modified.Parent;
original.DebugMode = modified.DebugMode;
original.LogLevel = modified.LogLevel;
original.Parameters = modified.Parameters;
original.Name = modified.Name;
original.ClassName = modified.ClassName;
original.Parent = modified.Parent;
original.DebugMode = modified.DebugMode;
original.LogLevel = modified.LogLevel;
original.Parameters = modified.Parameters;
RedrawAll();
}
}
RedrawAll();
}
}
/// Copy a component
private void copyButton_Click(object sender, EventArgs e)
@@ -535,7 +616,7 @@ namespace TBF.UI.Bench.Components
if (listViewEx.SelectedIndices.Count != 1) return;
ListViewItem lvi = listViewEx.SelectedItems[0];
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity((Component)lvi.Tag);
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity((Component)lvi.Tag);
if (cfg != null)
{
cfg.Name += Strings.New_name_copy;
@@ -543,7 +624,9 @@ namespace TBF.UI.Bench.Components
{
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
cfgControl.Config = cfg;
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0)
? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1)
: 1;
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
cfgForm.CmpntEntities = cmpntEntities;
@@ -588,7 +671,8 @@ namespace TBF.UI.Bench.Components
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
cfgControl.Config = cfg;
cfgControl.Config.Name = cfgControl.Config.Name + " imported";
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
cfgControl.Config.ItemNr =
(cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
cfgForm.CmpntEntities = cmpntEntities;
@@ -601,88 +685,90 @@ namespace TBF.UI.Bench.Components
}
}
private void upButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
int ix = listViewEx.SelectedIndices[0];
if (ix < 1) return;
private void upButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
int ix = listViewEx.SelectedIndices[0];
if (ix < 1) return;
Component item1 = (Component)(listViewEx.Items[ix - 1].Tag);
Component item2 = (Component)(listViewEx.Items[ix].Tag);
(item1 as IHasItemNr).ItemNr++;
(item2 as IHasItemNr).ItemNr--;
cmpntEntities.RemoveAt(ix);
cmpntEntities.Insert(ix - 1, item2);
Component item1 = (Component)(listViewEx.Items[ix - 1].Tag);
Component item2 = (Component)(listViewEx.Items[ix].Tag);
(item1 as IHasItemNr).ItemNr++;
(item2 as IHasItemNr).ItemNr--;
cmpntEntities.RemoveAt(ix);
cmpntEntities.Insert(ix - 1, item2);
flags |= CfgUpdateFlags.AnyChange;
flags |= CfgUpdateFlags.AnyChange;
RedrawAll();
RedrawAll();
Focus();
listViewEx.Items[ix - 1].Selected = true;
listViewEx.Items[ix - 1].EnsureVisible();
}
Focus();
listViewEx.Items[ix - 1].Selected = true;
listViewEx.Items[ix - 1].EnsureVisible();
}
private void downButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
int ix = listViewEx.SelectedIndices[0];
if (ix >= listViewEx.Items.Count - 1) return;
private void downButton_Click(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count != 1) return;
int ix = listViewEx.SelectedIndices[0];
if (ix >= listViewEx.Items.Count - 1) return;
Component item1 = (Component)(listViewEx.Items[ix].Tag);
Component item2 = (Component)(listViewEx.Items[ix + 1].Tag);
(item1 as IHasItemNr).ItemNr++;
(item2 as IHasItemNr).ItemNr--;
cmpntEntities.RemoveAt(ix + 1);
cmpntEntities.Insert(ix, item2);
Component item1 = (Component)(listViewEx.Items[ix].Tag);
Component item2 = (Component)(listViewEx.Items[ix + 1].Tag);
(item1 as IHasItemNr).ItemNr++;
(item2 as IHasItemNr).ItemNr--;
cmpntEntities.RemoveAt(ix + 1);
cmpntEntities.Insert(ix, item2);
flags |= CfgUpdateFlags.AnyChange;
flags |= CfgUpdateFlags.AnyChange;
RedrawAll();
RedrawAll();
Focus();
listViewEx.Items[ix + 1].Selected = true;
listViewEx.Items[ix + 1].EnsureVisible();
}
Focus();
listViewEx.Items[ix + 1].Selected = true;
listViewEx.Items[ix + 1].EnsureVisible();
}
private void componentsListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count == 1)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
}
else
{
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
}
}
private void componentsListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (listViewEx.SelectedIndices.Count == 1)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
}
else
{
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
}
}
public void UpdateButtonStates(SharedButtons.SelectedItemPos selectedItemPos)
{
if (selectedItemPos == SharedButtons.SelectedItemPos.None)
{
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
}
else if (selectedItemPos == SharedButtons.SelectedItemPos.First)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Down);
sharedButtons.DisableButtons(SharedButtons.Buttons.Up);
}
else if (selectedItemPos == SharedButtons.SelectedItemPos.Last)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up);
sharedButtons.DisableButtons(SharedButtons.Buttons.Down);
}
else if (selectedItemPos == SharedButtons.SelectedItemPos.FirstAndLast)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove);
sharedButtons.DisableButtons(SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
}
else
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
}
}
public void UpdateButtonStates(SharedButtons.SelectedItemPos selectedItemPos)
{
if (selectedItemPos == SharedButtons.SelectedItemPos.None)
{
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up |
SharedButtons.Buttons.Down);
}
else if (selectedItemPos == SharedButtons.SelectedItemPos.First)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Down);
sharedButtons.DisableButtons(SharedButtons.Buttons.Up);
}
else if (selectedItemPos == SharedButtons.SelectedItemPos.Last)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up);
sharedButtons.DisableButtons(SharedButtons.Buttons.Down);
}
else if (selectedItemPos == SharedButtons.SelectedItemPos.FirstAndLast)
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove);
sharedButtons.DisableButtons(SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
}
else
{
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up |
SharedButtons.Buttons.Down);
}
}
private void ComponentsManagerDlg_FormClosing(object sender, FormClosingEventArgs e)
{
@@ -691,9 +777,9 @@ namespace TBF.UI.Bench.Components
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
{
DialogResult dr = MessageBox.Show(Strings.Do_you_want_to_save_changes,
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (dr == DialogResult.Yes)
{
SaveDBChanges(session);
@@ -702,7 +788,7 @@ namespace TBF.UI.Bench.Components
if (CurrentUser.Restore(this)) Program.MainWnd.UpdateUser();
}
/// <summary>
/// Updates component configuration from a script file
@@ -713,7 +799,7 @@ namespace TBF.UI.Bench.Components
/// <returns>true = udated component configuration should be saved, new component should be created</returns>
bool UpdateCfg(ref IComponentCfg cfg, string[] words, ref int zeroBasedIdx)
{
string name = words[words.Length - 1]; /// The last word is the component name
string name = words[words.Length - 1]; /// The last word is the component name
cfg.Name = name.Replace("#", (zeroBasedIdx + 1).ToString());
if (cfg is Rig.BuiltIn.Valve.ValveCfg)
@@ -760,9 +846,9 @@ namespace TBF.UI.Bench.Components
}
else if (cfg is Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg)
{
(cfg as IChildComponentCfg).ParentName = "CB";
(cfg as Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg).ModbusAddress = (byte)(zeroBasedIdx + 1);
return true;
(cfg as IChildComponentCfg).ParentName = "CB";
(cfg as Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg).ModbusAddress = (byte)(zeroBasedIdx + 1);
return true;
}
else if (cfg is Rig.RegisterReaders.PulsesFromUniCB.RRCfg)
{
@@ -818,4 +904,4 @@ namespace TBF.UI.Bench.Components
listViewEx.Sort();
}
}
}
}
+4
View File
@@ -1181,6 +1181,10 @@ namespace TBF.UI.Process
if (args.TestRslt != null)
{
if (ProcessData.BatchRslts.Batch.WaterMeters.Count < wmsCount)
{
throw new Exception("Water Meter components cout is smaller as Bench Info water meter count!");
}
for (int i = 0; i < wmsCount; i++)
{
var wm = ProcessData.BatchRslts.Batch.WaterMeters[i];