iPerl component updated + interface change: ulong DigitalInputs (it was uint), iPerlCommunication test method added, etc, version 1.5.75.
This commit is contained in:
parent
40a43e46b4
commit
e569a80ec2
@ -56,7 +56,7 @@ namespace TBF.BenchControl.Elde
|
||||
public float RValvePosition(int rvNr1) { return controlCom.RValvePosition(rvNr1); }
|
||||
public float DivSamples(int ms) { return controlCom.DivSamples(ms); }
|
||||
public int ScopeSamples(int i, int j, int k) { return controlCom.ScopeSamples(i, j, k); }
|
||||
public uint DigitalInputs { get { return controlCom.DigitalInputs; } }
|
||||
public ulong DigitalInputs { get { return controlCom.DigitalInputs; } }
|
||||
public float AnalogInput(int adcNr0) { return controlCom.AnalogInput(adcNr0); }
|
||||
public uint AnalogInputRaw(int adcNr0, int bank) { return controlCom.AnalogInputRaw(adcNr0, bank); } /// adcNr0: 0=RV1, 1=RV2,... bank: 0=RV, 1=Temp
|
||||
public float ReferenceVolume { get { return controlCom.ReferenceVolume; } }
|
||||
|
||||
@ -63,7 +63,7 @@ namespace TBF.BenchControl.Elde
|
||||
public float RValvePosition(int rvNr1) { return 0; }
|
||||
public float DivSamples(int ms) { return 0; }
|
||||
public int ScopeSamples(int i, int j, int k) { return 0; }
|
||||
public uint DigitalInputs { get { return 0; } }
|
||||
public ulong DigitalInputs { get { return 0; } }
|
||||
public float AnalogInput(int adcNr0) { return 0; }
|
||||
public uint AnalogInputRaw(int adcNr0, int bank) { return 0; } /// bank0=RV, bank1=Temp
|
||||
public float ReferenceVolume { get { return 0; } }
|
||||
|
||||
@ -51,7 +51,7 @@ namespace TBF.BenchControl.Elde
|
||||
}
|
||||
public float DivSamples(int ms) { return ctrlBrdComponent.DIVSamples[ms, 0]; }
|
||||
public int ScopeSamples(int i, int j, int k) { return ctrlBrdComponent.ScopeSamples[i, j, k]; }
|
||||
public uint DigitalInputs { get { return ctrlBrdComponent.Vstupy; } }
|
||||
public ulong DigitalInputs { get { return (ulong)ctrlBrdComponent.Vstupy; } }
|
||||
public float AnalogInput(int adcNr0) { return ctrlBrdComponent.Analogy[adcNr0]; }
|
||||
public uint AnalogInputRaw(int adcNr0, int bank) { return ctrlBrdComponent.AnalogyRaw[adcNr0, bank]; } /// bank0=RV, bank1=Temp
|
||||
public float ReferenceVolume { get { return ctrlBrdComponent.ReferenceVolume; } }
|
||||
|
||||
@ -25,7 +25,7 @@ namespace TBF.BenchControl.Elde
|
||||
float RValvePosition(int rvNr1);
|
||||
float DivSamples(int ms);
|
||||
int ScopeSamples(int i, int j, int k);
|
||||
uint DigitalInputs { get; }
|
||||
ulong DigitalInputs { get; }
|
||||
float AnalogInput(int adcNr0);
|
||||
uint AnalogInputRaw(int adcNr0, int bank);
|
||||
float ReferenceVolume { get; }
|
||||
|
||||
@ -42,7 +42,8 @@ namespace TBF.BenchControl
|
||||
Factories.Add(new Cameras.IdcCamera.IdcCameraFactory());
|
||||
Factories.Add(new WaterMeters.iPerl.WaterMeterFactory()); /// iPerl
|
||||
Factories.Add(new TestMethods.iPerlAdjustment.TestMethodFactory()); /// iPerlAdjustment
|
||||
Factories.Add(new TestMethods.LeakTest.TestMethodFactory());
|
||||
Factories.Add(new TestMethods.iPerlCommunication.TestMethodFactory()); /// iPerlCommunication
|
||||
Factories.Add(new TestMethods.LeakTest.TestMethodFactory());
|
||||
Factories.Add(new MettlerToledo.Standard.BalanceFactory()); /// MettlerToledo Balance
|
||||
Factories.Add(new MettlerToledo.Standard.BalanceNewFactory()); /// MettlerToledoBalanceSN
|
||||
Factories.Add(new MettlerToledo.Multi.BalanceFactory()); /// MettlerToledo-Multi
|
||||
|
||||
@ -13,9 +13,9 @@ using TBF.BenchControl.WaterMeters.iPerl;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
{
|
||||
public partial class iPerlCommunicationForm : Form, GenericDevices.IHasCompleted
|
||||
public partial class iPerlAdjustmentForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm));
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlAdjustmentForm));
|
||||
|
||||
|
||||
[DllImport("libRfid.dll", EntryPoint = "getDllVersion")]
|
||||
@ -92,7 +92,7 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
|
||||
|
||||
/// <summary> Parameterless constructor for 3 watermeters </summary>
|
||||
public iPerlCommunicationForm()
|
||||
public iPerlAdjustmentForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@ -151,7 +151,7 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
|
||||
public iPerlCommunicationForm(IList<GenericDevices.IWaterMeter> waterMeters)
|
||||
public iPerlAdjustmentForm(IList<GenericDevices.IWaterMeter> waterMeters)
|
||||
: this()
|
||||
{
|
||||
this.WaterMetersCount = waterMeters.Count;
|
||||
@ -322,8 +322,6 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
|
||||
private void readConfigBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
byte[] data;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (int group = 1; group <= 10; group++)
|
||||
@ -336,23 +334,35 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
|
||||
foreach (var wm in WaterMeters)
|
||||
{
|
||||
if (wm.DebugLevel == Entities.DebugMode.Normal && wm.Group == group)
|
||||
if (wm.Group == group)
|
||||
{
|
||||
int r1 = openPort((uint)wm.RfidComPortNr);
|
||||
int r2 = ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out data, 1000);
|
||||
int r3 = closePort();
|
||||
Text = string.Format("WM={0} Group={1}", wm.Name, group);
|
||||
if (wm.DebugLevel == Entities.DebugMode.Normal)
|
||||
{
|
||||
byte[] data = null;
|
||||
bool success = false;
|
||||
int r1 = openPort((uint)wm.RfidComPortNr);
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out data, 1000))
|
||||
{
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
closePort();
|
||||
|
||||
if (r1==0 && r2==0 && r3==0)
|
||||
{
|
||||
errors[i++].Text = ConfigStruct.FromByteArray(data).ToString();
|
||||
if (r1 == 0 && success && data != null)
|
||||
{
|
||||
errors[i].Text = ConfigStruct.FromByteArray(data).ToString(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
errors[i].Text = "Cannot read configuration";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors[i++].Text = "Cannot read configuration";
|
||||
}
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
///
|
||||
namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
{
|
||||
partial class iPerlCommunicationForm
|
||||
partial class iPerlAdjustmentForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@ -20,9 +20,9 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
///
|
||||
delegate void ErrorsFormDlgt(iPerlAdjustmentSeq myRef);
|
||||
///
|
||||
void OpenWMErrorsForm(iPerlAdjustmentSeq myRef)
|
||||
void OpenIPerlCommForm(iPerlAdjustmentSeq myRef)
|
||||
{
|
||||
myRef.modelessDlg = new iPerlCommunicationForm(WaterMeters);
|
||||
myRef.modelessDlg = new iPerlAdjustmentForm(WaterMeters);
|
||||
modelessDlg.Show();
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
|
||||
///
|
||||
/// Show the modeless dialog with error indication
|
||||
///
|
||||
Program.MainWnd.Invoke(new ErrorsFormDlgt(OpenWMErrorsForm), this);
|
||||
Program.MainWnd.Invoke(new ErrorsFormDlgt(OpenIPerlCommForm), this);
|
||||
|
||||
loop:
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class AllCompletedEventArgs : EventArgs
|
||||
{
|
||||
public string CommMessage;
|
||||
|
||||
public AllCompletedEventArgs(string commMessage)
|
||||
{
|
||||
this.CommMessage = commMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class CommCompletedEventArgs : EventArgs
|
||||
{
|
||||
public int ThreadId;
|
||||
public int WMNr;
|
||||
public string CommMessage;
|
||||
|
||||
public CommCompletedEventArgs(int threadId, int wmNr, string commMessage)
|
||||
{
|
||||
this.ThreadId = threadId;
|
||||
this.WMNr = wmNr;
|
||||
this.CommMessage = commMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using TBF.BenchControl;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class TestMethod : ComponentBase, GenericDevices.ITestMethod
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(TestMethod));
|
||||
public override string ToString() { return string.Format("TestMethods.Adjustment({0})", Cfg.ToString(1)); }
|
||||
|
||||
readonly TestMethodCfg testMethodCfg;
|
||||
|
||||
public bool Evaluate { get { return false; } }
|
||||
public bool Publish { get { return false; } }
|
||||
public bool CanTest(Entities.MetersKind meters) { return meters == Entities.MetersKind.Single; }
|
||||
|
||||
public TestMethod()
|
||||
{
|
||||
}
|
||||
|
||||
public TestMethod(TestMethodCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
testMethodCfg = cfg;
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
public IList<Event> Execute(Entities.Test test)
|
||||
{
|
||||
return (new iPerlCommunicationSeq()).Execute(test, testMethodCfg.TestParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class TestMethodCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public IComponent GetComponent(IList<IComponent> components) { return new TestMethod(this); }
|
||||
public IComponentCfgCtrl GetControl() { return new TestMethodCfgCtrl(); }
|
||||
|
||||
/// <summary> Test parameters </summary>
|
||||
[XmlIgnore]
|
||||
public iPerlCommunicationParams TestParams;
|
||||
public override IParamsProvider GetTestParams() { return TestParams; }
|
||||
public override IParamsProvider CreateTestParams(Entities.Test test)
|
||||
{
|
||||
iPerlCommunicationParams testParams = new iPerlCommunicationParams();
|
||||
testParams.UpdateTestParams(Name, test);
|
||||
return testParams;
|
||||
}
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TestMethodCfg()
|
||||
{
|
||||
Name = "iPerlCommunication";
|
||||
ParentName = string.Empty;
|
||||
TestParams = new iPerlCommunicationParams();
|
||||
}
|
||||
|
||||
public TestMethodCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public partial class TestMethodCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
static readonly ILog log = LogManager.GetLogger(typeof(TestMethodCfgCtrl));
|
||||
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
TestMethodCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as TestMethodCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public TestMethodCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void EntryFormCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
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;
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/TestMethodCfgCtrl.designer.cs
generated
Normal file
87
TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/TestMethodCfgCtrl.designer.cs
generated
Normal file
@ -0,0 +1,87 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
partial class TestMethodCfgCtrl
|
||||
{
|
||||
/// <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.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(137, 57);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
|
||||
this.nameTextBox.TabIndex = 5;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(27, 60);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 4;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(134, 33);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 3;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// BasicPrinterCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "BasicPrinterCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(300, 200);
|
||||
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
}
|
||||
}
|
||||
@ -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,24 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class TestMethodFactory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return "iPerlCommunication"; } }
|
||||
|
||||
public void ResetStaticProperties() { TestMethod.ResetStaticProperties(); }
|
||||
|
||||
public IComponent DummyComponent() { return new TestMethod(); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new TestMethodCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(typeof(TestMethodCfg), component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,546 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.Resources;
|
||||
using TBF.BenchControl.WaterMeters.iPerl;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public partial class iPerlCommunicationForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm));
|
||||
|
||||
#region DLL_Interface
|
||||
|
||||
[DllImport("libRfid.dll", EntryPoint = "getDllVersion")]
|
||||
public static extern unsafe int getDllVersion();
|
||||
|
||||
[DllImport("libRfid.dll", EntryPoint = "openPort")]
|
||||
static extern unsafe int openPort(int comPort);
|
||||
|
||||
[DllImport("libRfid.dll", EntryPoint = "closePort")]
|
||||
static extern unsafe int closePort();
|
||||
|
||||
[DllImport("libRfid.dll", EntryPoint = "readRequestPort")]
|
||||
static extern unsafe int readRequestPort(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms);
|
||||
|
||||
[DllImport("libRfid.dll", EntryPoint = "writeRequestPort")]
|
||||
static extern unsafe int writeRequestPort(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms);
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper function with safe interface adn unsafe body
|
||||
/// </summary>
|
||||
/// <returns>Value returned by readRequestPort(...)</returns>
|
||||
public static unsafe int ReadRequestPort(MessageID messageID, int offset, int lenght, out byte[] buffer, int timeout)
|
||||
{
|
||||
byte[] buf = new byte[1000];
|
||||
int retv;
|
||||
|
||||
fixed (byte* pBuf = buf)
|
||||
{
|
||||
retv = readRequestPort(messageID, offset, lenght, pBuf, timeout);
|
||||
|
||||
buffer = new byte[lenght];
|
||||
for (int i = 0; i < lenght; i++) buffer[i] = buf[i];
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper function with safe interface adn unsafe body
|
||||
/// </summary>
|
||||
/// <returns>Value returned by writeRequestPort(...)</returns>
|
||||
public static unsafe int WriteRequestPort(MessageID messageID, int offset, int lenght, byte[] buffer, int timeout)
|
||||
{
|
||||
int retv;
|
||||
fixed (byte* pBuf = buffer)
|
||||
{
|
||||
retv = writeRequestPort(messageID, offset, lenght, pBuf, timeout);
|
||||
}
|
||||
return retv;
|
||||
}
|
||||
|
||||
#endregion DLL_Interface
|
||||
|
||||
|
||||
const int CommTimeout = 500;
|
||||
const int MaxCommRetries = 3;
|
||||
|
||||
|
||||
// Set to 'true' when the form closes
|
||||
public bool Completed { get { return formCompleted; } }
|
||||
bool formCompleted;
|
||||
|
||||
/// <summary> Number of text boxes for serial numbers </summary>
|
||||
public readonly int WaterMetersCount;
|
||||
|
||||
readonly bool[] disabled;
|
||||
|
||||
Entities.TestResult tr;
|
||||
|
||||
int textBoxesCount;
|
||||
|
||||
Label[] labels;
|
||||
TextBox[] messages;
|
||||
|
||||
static IList<WaterMeters.iPerl.WaterMeter> waterMeters;
|
||||
|
||||
Modbus.QuidoRS.QuidoRS quido;
|
||||
|
||||
|
||||
///
|
||||
/// RFID multiplexer PCB / RFID serial port and worker thread related variables
|
||||
///
|
||||
static string activity;
|
||||
static int currentGroup; /// form -> worker thread (0 = none)
|
||||
static int lastGroup;
|
||||
|
||||
static IList<Thread> workerThreads;
|
||||
static IList<int> rfidPortNrs;
|
||||
static IList<bool> stopWorkerThreads; /// form -> worker thread
|
||||
|
||||
|
||||
/// <summary> Parameterless constructor for 3 watermeters </summary>
|
||||
public iPerlCommunicationForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
textBoxesCount = 48;
|
||||
|
||||
labels = new Label[48]
|
||||
{
|
||||
wmLabel1, wmLabel2, wmLabel3, wmLabel4, wmLabel5,
|
||||
wmLabel6, wmLabel7, wmLabel8, wmLabel9, wmLabel10,
|
||||
wmLabel11, wmLabel12, wmLabel13, wmLabel14, wmLabel15,
|
||||
wmLabel16, wmLabel17, wmLabel18, wmLabel19, wmLabel20,
|
||||
wmLabel21, wmLabel22, wmLabel23, wmLabel24, wmLabel25,
|
||||
wmLabel26, wmLabel27, wmLabel28, wmLabel29, wmLabel30,
|
||||
wmLabel31, wmLabel32, wmLabel33, wmLabel34, wmLabel35,
|
||||
wmLabel36, wmLabel37, wmLabel38, wmLabel39, wmLabel40,
|
||||
wmLabel41, wmLabel42, wmLabel43, wmLabel44, wmLabel45,
|
||||
wmLabel46, wmLabel47, wmLabel48,
|
||||
};
|
||||
messages = new TextBox[48]
|
||||
{
|
||||
wmTextBox1, wmTextBox2, wmTextBox3, wmTextBox4, wmTextBox5,
|
||||
wmTextBox6, wmTextBox7, wmTextBox8, wmTextBox9, wmTextBox10,
|
||||
wmTextBox11, wmTextBox12, wmTextBox13, wmTextBox14, wmTextBox15,
|
||||
wmTextBox16, wmTextBox17, wmTextBox18, wmTextBox19, wmTextBox20,
|
||||
wmTextBox21, wmTextBox22, wmTextBox23, wmTextBox24, wmTextBox25,
|
||||
wmTextBox26, wmTextBox27, wmTextBox28, wmTextBox29, wmTextBox30,
|
||||
wmTextBox31, wmTextBox32, wmTextBox33, wmTextBox34, wmTextBox35,
|
||||
wmTextBox36, wmTextBox37, wmTextBox38, wmTextBox39, wmTextBox40,
|
||||
wmTextBox41, wmTextBox42, wmTextBox43, wmTextBox44, wmTextBox45,
|
||||
wmTextBox46, wmTextBox47, wmTextBox48,
|
||||
};
|
||||
|
||||
currentGroup = 0;
|
||||
lastGroup = 0; /// group numbers are >=1, lastGroup == 0 means no group
|
||||
|
||||
workerThreads = new List<Thread>();
|
||||
rfidPortNrs = new List<int>();
|
||||
stopWorkerThreads = new List<bool>();
|
||||
|
||||
formCompleted = false;
|
||||
tr = null;
|
||||
|
||||
/// Find QuidoRS
|
||||
foreach (var comp in StateMachine.Components)
|
||||
{
|
||||
if (comp is Modbus.QuidoRS.QuidoRS)
|
||||
{
|
||||
quido = comp as Modbus.QuidoRS.QuidoRS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Attach to 'CommCompleted' handler
|
||||
CommCompletedHandler += delegate(object sender, CommCompletedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired)
|
||||
{
|
||||
Invoke(new EventHandler<CommCompletedEventArgs>(DoOnCommCompleted), sender, args);
|
||||
}
|
||||
else DoOnCommCompleted(sender, args);
|
||||
};
|
||||
|
||||
/// Attach to 'AllCompleted' handler
|
||||
AllCompletedHandler += delegate(object sender, AllCompletedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired)
|
||||
{
|
||||
Invoke(new EventHandler<AllCompletedEventArgs>(DoOnAllCompleted), sender, args);
|
||||
}
|
||||
else DoOnAllCompleted(sender, args);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
|
||||
public iPerlCommunicationForm(IList<GenericDevices.IWaterMeter> waterMeters, string activity)
|
||||
: this()
|
||||
{
|
||||
iPerlCommunicationForm.activity = activity;
|
||||
this.WaterMetersCount = waterMeters.Count;
|
||||
iPerlCommunicationForm.waterMeters = new List<WaterMeters.iPerl.WaterMeter>();
|
||||
foreach (var wm in waterMeters)
|
||||
{
|
||||
WaterMeters.iPerl.WaterMeter iPerlWM = wm as WaterMeters.iPerl.WaterMeter;
|
||||
iPerlCommunicationForm.waterMeters.Add(iPerlWM);
|
||||
if (iPerlWM.Group > lastGroup) lastGroup = iPerlWM.Group;
|
||||
if (!rfidPortNrs.Contains(iPerlWM.RfidComPortNr))
|
||||
{
|
||||
rfidPortNrs.Add(iPerlWM.RfidComPortNr);
|
||||
if (workerThreads.Count < 1)
|
||||
{
|
||||
Thread thread = new Thread(iPerlCommunicationForm.Worker);
|
||||
workerThreads.Add(thread);
|
||||
stopWorkerThreads.Add(false);
|
||||
thread.Start(); /// TODO: start with arguments: thread.Start(workerThreads.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activityLabel.Text = activity;
|
||||
|
||||
ShuffleTextBoxes(this.WaterMetersCount, Program.LineSize);
|
||||
|
||||
disabled = new bool[this.WaterMetersCount];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Make sure the layout of labels/text boxes on the screen
|
||||
/// corresponds to the layout of watermeters of the test bench.
|
||||
/// </summary>
|
||||
/// <param name="wmsCount">Number of watermeters</param>
|
||||
/// <param name="lineSize">Number of watermeters in one line</param>
|
||||
void ShuffleTextBoxes(int wmsCount, int lineSize)
|
||||
{
|
||||
if (wmsCount < textBoxesCount && lineSize > 0)
|
||||
{
|
||||
int nrLines = (wmsCount + lineSize - 1) / lineSize;
|
||||
int gap = (textBoxesCount - wmsCount) / nrLines;
|
||||
|
||||
int dest = 0;
|
||||
for (int l = 0; l < nrLines; l++)
|
||||
{
|
||||
for (int i = 0; i < lineSize; i++)
|
||||
{
|
||||
labels[dest] = labels[l * lineSize + l * gap + i];
|
||||
messages[dest] = messages[l * lineSize + l * gap + i];
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
textBoxesCount = wmsCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Localize()
|
||||
{
|
||||
Text = Strings.Water_Meter_States;
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
labels[i].Text = string.Format("iPerl{0}", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void iPerlCommunicationForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Localize();
|
||||
|
||||
//Height = 50 + 90 * WaterMetersCount;
|
||||
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
if (disabled != null && i < disabled.Length && disabled[i])
|
||||
{
|
||||
labels[i].Visible = messages[i].Visible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
labels[i].Visible = messages[i].Visible = true;
|
||||
messages[i].Text = "---";
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Set QuidoRS outputs and start the whole communication process
|
||||
/// by incrementing 'currentGroup'.
|
||||
///
|
||||
if (quido != null)
|
||||
{
|
||||
quido.SetOutputs((ushort)(16 - currentGroup - 1));
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
currentGroup++;
|
||||
}
|
||||
|
||||
private void NormalClose()
|
||||
{
|
||||
CommCompletedHandler = null;
|
||||
AllCompletedHandler = null;
|
||||
|
||||
formCompleted = true;
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
void OnAdjustmentInProgress(object sender, UiBridge.AdjustmentInProgressEventArgs args)
|
||||
{
|
||||
tr = args.TestResult;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (tr != null)
|
||||
{
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
messages[i].Text = tr.Meters[i].VolumeErrorPct.ToString("F1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WMErrorsForm_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
//if (tr != null)
|
||||
//{
|
||||
// System.Drawing.Graphics graphics = this.CreateGraphics();
|
||||
|
||||
// for (int i = 0; i < WaterMetersCount; i++)
|
||||
// {
|
||||
// PaintOne(graphics, rects[i], tr.Meters[i].VolumeErrorPct, tr.ErrLimLo, tr.ErrLimHi);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
#region Forced close handling
|
||||
|
||||
public void StartForceCloseHandler()
|
||||
{
|
||||
UiBridge.Bridge.CloseModelessFormHandler += delegate(object sender, EventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<EventArgs>(OnForceClose), sender, args); }
|
||||
else OnForceClose(sender, args);
|
||||
};
|
||||
}
|
||||
|
||||
void OnForceClose(object sender, EventArgs args)
|
||||
{
|
||||
CommCompletedHandler = null;
|
||||
AllCompletedHandler = null;
|
||||
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
static void Worker()
|
||||
{
|
||||
int threadId = 0;
|
||||
int rfidPortNr = rfidPortNrs[threadId];
|
||||
|
||||
for (int group = 1; group <= lastGroup; group++)
|
||||
{
|
||||
while (currentGroup != group && !stopWorkerThreads[threadId]) Thread.Sleep(50);
|
||||
|
||||
if (stopWorkerThreads[threadId]) break;
|
||||
|
||||
int wmNr = 0;
|
||||
foreach (var wm in waterMeters)
|
||||
{
|
||||
if ((wm.RfidComPortNr == rfidPortNr) && (wm.Group == group))
|
||||
{
|
||||
if (wm.DebugLevel == Entities.DebugMode.Normal)
|
||||
{
|
||||
if (activity.Equals("Read configuration")) ReadConfig(wm, threadId, wmNr);
|
||||
else if (activity.Equals("Set to test mode")) SetToTestMode(wm, threadId, wmNr);
|
||||
else if (activity.Equals("Set to active mode")) SetToActiveMode(wm, threadId, wmNr);
|
||||
else OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Invalid activity"));
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Simulation"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
wmNr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ReadConfig(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
|
||||
{
|
||||
bool success = (0 == openPort(wm.RfidComPortNr)); /// Open RFID port
|
||||
|
||||
byte[] cfg = null;
|
||||
if (success)
|
||||
{
|
||||
success = false;
|
||||
|
||||
/// Read configuration
|
||||
for (int j = 0; j < MaxCommRetries; j++)
|
||||
{
|
||||
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out cfg, CommTimeout)) { success = true; break; }
|
||||
}
|
||||
}
|
||||
|
||||
closePort(); /// Close RFID port
|
||||
|
||||
if (success)
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(cfg).ToString(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read configuration"));
|
||||
}
|
||||
}
|
||||
|
||||
static void SetToTestMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
|
||||
{
|
||||
bool success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = false;
|
||||
|
||||
/// Switch to test mode
|
||||
byte[] cmd = new byte[1] { (byte)7 };
|
||||
for (int j = 0; j < MaxCommRetries; j++)
|
||||
{
|
||||
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
|
||||
}
|
||||
}
|
||||
|
||||
byte[] cfg = null;
|
||||
if (success)
|
||||
{
|
||||
success = false;
|
||||
|
||||
/// Read configuration
|
||||
for (int j = 0; j < MaxCommRetries; j++)
|
||||
{
|
||||
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out cfg, CommTimeout)) { success = true; break; }
|
||||
}
|
||||
}
|
||||
|
||||
closePort(); /// Close RFID port
|
||||
|
||||
if (success)
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(cfg).ToString(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot switch to test mode"));
|
||||
}
|
||||
}
|
||||
|
||||
static void SetToActiveMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
|
||||
{
|
||||
bool success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = false;
|
||||
|
||||
/// Switch to active mode
|
||||
byte[] cmd = new byte[1] { (byte)6 };
|
||||
for (int j = 0; j < MaxCommRetries; j++)
|
||||
{
|
||||
if (0 == WriteRequestPort(MessageID.Command, 0, 1, cmd, CommTimeout)) { success = true; break; }
|
||||
}
|
||||
}
|
||||
|
||||
byte[] cfg = null;
|
||||
if (success)
|
||||
{
|
||||
success = false;
|
||||
|
||||
/// Read configuration
|
||||
for (int j = 0; j < MaxCommRetries; j++)
|
||||
{
|
||||
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out cfg, CommTimeout)) { success = true; break; }
|
||||
}
|
||||
}
|
||||
|
||||
closePort(); /// Close RFID port
|
||||
|
||||
if (success)
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(cfg).ToString(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot switch to active mode"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called when communication with one watermeter is completed
|
||||
/// </summary>
|
||||
public static void OnCommCompleted(object sender, CommCompletedEventArgs data)
|
||||
{
|
||||
if (CommCompletedHandler == null) return;
|
||||
try { CommCompletedHandler(sender, data); }
|
||||
catch (Exception e) { log.Error("CommCompletedHandler(...) failed", e); }
|
||||
}
|
||||
public static event EventHandler<CommCompletedEventArgs> CommCompletedHandler;
|
||||
|
||||
void DoOnCommCompleted(object sender, CommCompletedEventArgs data)
|
||||
{
|
||||
messages[data.WMNr].Text = data.CommMessage;
|
||||
|
||||
if (currentGroup < lastGroup)
|
||||
{
|
||||
if (quido != null)
|
||||
{
|
||||
quido.SetOutputs((ushort)(16 - currentGroup - 1));
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
currentGroup++;
|
||||
}
|
||||
else
|
||||
{
|
||||
workerThreads[data.ThreadId].Join(2000);
|
||||
NormalClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called when communication with all watermeters is completed
|
||||
/// </summary>
|
||||
public static void OnAllCompleted(object sender, AllCompletedEventArgs data)
|
||||
{
|
||||
if (AllCompletedHandler == null) return;
|
||||
try { AllCompletedHandler(sender, data); }
|
||||
catch (Exception e) { log.Error("AllCompletedHandler(...) failed", e); }
|
||||
}
|
||||
public static event EventHandler<AllCompletedEventArgs> AllCompletedHandler;
|
||||
|
||||
void DoOnAllCompleted(object sender, AllCompletedEventArgs data)
|
||||
{
|
||||
Text = data.CommMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
1320
TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.designer.cs
generated
Normal file
1320
TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -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,96 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class iPerlCommunicationParams : TestParamsBase, IParamsProvider, ITestParams
|
||||
{
|
||||
public string Activity; /// Communication activity
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
Activity = "Read Configuration";
|
||||
}
|
||||
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
Strings.Activity,
|
||||
};
|
||||
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 Activity;
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: Activity = strValue; return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return true;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateTestParams(Entities.ComponentTest dbEntity)
|
||||
{
|
||||
if (dbEntity == null) return;
|
||||
try
|
||||
{
|
||||
iPerlCommunicationParams tmp = (iPerlCommunicationParams)(new XmlSerializer(typeof(iPerlCommunicationParams)))
|
||||
.Deserialize(new StringReader(dbEntity.Parameters));
|
||||
|
||||
testParamsEntity = dbEntity;
|
||||
componentName = dbEntity.CmpntName;
|
||||
test = dbEntity.Test;
|
||||
|
||||
Activity = tmp.Activity;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameterless constructor initializes the parameters
|
||||
/// </summary>
|
||||
public iPerlCommunicationParams()
|
||||
{
|
||||
}
|
||||
|
||||
public iPerlCommunicationParams(Entities.ComponentTest testParamsEntity, string componentName, Entities.Test test)
|
||||
{
|
||||
this.testParamsEntity = testParamsEntity;
|
||||
this.componentName = componentName;
|
||||
this.test = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
///
|
||||
/// Copyright (c) 2015 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using TBF.BenchControl;
|
||||
using TBF.Boxes;
|
||||
using TBF.Resources;
|
||||
using TBF.UiBridge;
|
||||
|
||||
namespace TBF.BenchControl.TestMethods.iPerlCommunication
|
||||
{
|
||||
public class iPerlCommunicationSeq : Sequences.SequenceBase
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationSeq));
|
||||
|
||||
System.Windows.Forms.Form modelessDlg;
|
||||
///
|
||||
delegate void ICommFormFormDlgt(iPerlCommunicationSeq myRef, string activity);
|
||||
///
|
||||
void OpenIPerlCommForm(iPerlCommunicationSeq myRef, string activity)
|
||||
{
|
||||
myRef.modelessDlg = new iPerlCommunicationForm(WaterMeters, activity);
|
||||
modelessDlg.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flying start mass collection method sequence
|
||||
/// </summary>
|
||||
/// <param name="test">Test entity</param>
|
||||
/// <returns>
|
||||
/// Event.Done . . . . . . . OK
|
||||
/// Event.UiCmdStop . . . . Stopped by the user using the on-screen button STOP
|
||||
/// Event.OpArgumentError . Target flow is out of range
|
||||
/// Event.Error . . . . . . Unspecified error
|
||||
/// </returns>
|
||||
public IList<Event> Execute(Entities.Test test, iPerlCommunicationParams testParams)
|
||||
{
|
||||
IList<Event> e = new List<Event>(); /// Events from currently running operations
|
||||
Event retVal = Event.Done;
|
||||
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
|
||||
|
||||
processDataLoggingOp = new TBF.BenchControl.Operations.ProcessDataLoggingOp(processDataLogger, this);
|
||||
|
||||
//====================================
|
||||
// Transition or SetRoute - Start
|
||||
//====================================
|
||||
switch (Transition(transitionBefore, TransitionContext.BeforeTest))
|
||||
{
|
||||
case Event.Error: { retVal = Event.Error; goto stopTest; }
|
||||
case Event.UiCmdStop: { retVal = Event.UiCmdStop; goto stopTest; }
|
||||
}
|
||||
|
||||
if (testParams.Activity.Contains("Simulate"))
|
||||
{
|
||||
IList<Event> rList = new List<Event>(1);
|
||||
|
||||
Entities.TestResult tstRslt = new Entities.TestResult(test, 1, Entities.MetersKind.Single);
|
||||
|
||||
if (testParams.Activity.Contains("Q1"))
|
||||
{
|
||||
tstRslt.VolumeMaster = tstRslt.VolumeCTV = 5;
|
||||
for (int i = 0; i < WaterMeters.Count; i++)
|
||||
{
|
||||
tstRslt.Meters[i].VolumeMeter = 5;
|
||||
tstRslt.Meters[i].VolumeRef = tstRslt.VolumeCTV;
|
||||
}
|
||||
AddOrOverwriteResult(tstRslt);
|
||||
}
|
||||
else if (testParams.Activity.Contains("Q2"))
|
||||
{
|
||||
tstRslt.VolumeMaster = tstRslt.VolumeCTV = 5;
|
||||
for (int i = 0; i < WaterMeters.Count; i++)
|
||||
{
|
||||
tstRslt.Meters[i].VolumeMeter = 5;
|
||||
tstRslt.Meters[i].VolumeRef = tstRslt.VolumeCTV;
|
||||
}
|
||||
AddOrOverwriteResult(tstRslt);
|
||||
}
|
||||
else if (testParams.Activity.Contains("Q3"))
|
||||
{
|
||||
tstRslt.VolumeMaster = tstRslt.VolumeCTV = 5;
|
||||
for (int i = 0; i < WaterMeters.Count; i++)
|
||||
{
|
||||
tstRslt.Meters[i].VolumeMeter = 5;
|
||||
tstRslt.Meters[i].VolumeRef = tstRslt.VolumeCTV;
|
||||
}
|
||||
AddOrOverwriteResult(tstRslt);
|
||||
}
|
||||
|
||||
rList.Add(Event.Done);
|
||||
return rList;
|
||||
}
|
||||
else
|
||||
{
|
||||
///
|
||||
/// Show the modeless dialog with error indication
|
||||
///
|
||||
Program.MainWnd.Invoke(new ICommFormFormDlgt(OpenIPerlCommForm), new object[] { this, testParams.Activity });
|
||||
}
|
||||
|
||||
loop:
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.Test_in_progress);
|
||||
//------------------------------------------------
|
||||
|
||||
/// Make sure the CycleBeginForm is closed so that water meter data (s/n) can be copied into results
|
||||
if (UIFlowControl.Stop == WaitBeginFormClosed()) goto stopTest;
|
||||
|
||||
/// Test 'Quit'
|
||||
if ((modelessDlg is GenericDevices.IHasCompleted) && !(modelessDlg as GenericDevices.IHasCompleted).Completed)
|
||||
{
|
||||
goto loop; /// Modeless dilaog not closed, keep looping
|
||||
}
|
||||
modelessDlg = null; /// Modeless dialog is closed now
|
||||
|
||||
stopTest:
|
||||
|
||||
/// Transition sequence at the end of test
|
||||
/// Prevent overwriting 'retVal' in case it was set to non-default value earlier
|
||||
switch (Transition(transitionAfter, TransitionContext.AfterTest))
|
||||
{
|
||||
case Event.Error: { if (retVal == Event.Done) retVal = Event.Error; break; }
|
||||
case Event.UiCmdStop: { if (retVal == Event.Done) retVal = Event.UiCmdStop; break; }
|
||||
}
|
||||
|
||||
/// Create a list with one item 'retVal' (default is Event.Done) and return it
|
||||
IList<Event> retList = new List<Event>(1);
|
||||
retList.Add(retVal);
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -119,5 +119,22 @@ namespace TBF.BenchControl.WaterMeters.iPerl
|
||||
AlarmMask.ToString("X4"),
|
||||
ConfigCheckSum.ToString("X4"));
|
||||
}
|
||||
}
|
||||
|
||||
public string ToString(int sel)
|
||||
{
|
||||
return string.Format("{1} PCBNr={6} TestModeCfg={7}",
|
||||
Version,
|
||||
MeterState,
|
||||
TargetTimeVeryLowBatt,
|
||||
TargetTimeLowBatt,
|
||||
TestModeTime,
|
||||
EmptyPipeThreshold,
|
||||
PCBNumber[0].ToString("X2") + PCBNumber[1].ToString("X2") + PCBNumber[2].ToString("X2") + PCBNumber[3].ToString("X2") + PCBNumber[4].ToString("X2"),
|
||||
TestModeConfig.ToString("X2"),
|
||||
RadioAddress,
|
||||
TempCalibration,
|
||||
AlarmMask.ToString("X4"),
|
||||
ConfigCheckSum.ToString("X4"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,10 +120,13 @@ namespace TBF.BenchControl.WaterMeters.iPerl
|
||||
|
||||
public void StopDevice()
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
workerThread.Join(2000);
|
||||
optoSerialPort.Close();
|
||||
optoPortOpen = false;
|
||||
if (DebugLevel == Entities.DebugMode.Normal)
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
workerThread.Join(2000);
|
||||
optoSerialPort.Close();
|
||||
optoPortOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.5.74.1")]
|
||||
[assembly: AssemblyFileVersion("1.5.74.1")]
|
||||
[assembly: AssemblyVersion("1.5.75.1")]
|
||||
[assembly: AssemblyFileVersion("1.5.75.1")]
|
||||
|
||||
@ -329,12 +329,31 @@
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlAdjustment\TestMethodFactory.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlAdjustment\iPerlCommunicationForm.cs">
|
||||
<Compile Include="BenchControl\TestMethods\iPerlAdjustment\iPerlAdjustmentForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlAdjustment\iPerlCommunicationForm.designer.cs">
|
||||
<Compile Include="BenchControl\TestMethods\iPerlAdjustment\iPerlAdjustmentForm.designer.cs">
|
||||
<DependentUpon>iPerlAdjustmentForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\AllCompletedEventArgs.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\CommCompletedEventArgs.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\iPerlCommunicationParams.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\iPerlCommunicationSeq.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\iPerlCommunicationForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\iPerlCommunicationForm.designer.cs">
|
||||
<DependentUpon>iPerlCommunicationForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\TestMethod.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\TestMethodCfg.cs" />
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\TestMethodCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\TestMethodCfgCtrl.designer.cs">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\TestMethods\iPerlCommunication\TestMethodFactory.cs" />
|
||||
<Compile Include="BenchControl\WaterMeters\iPerl\CalibrationStruct.cs" />
|
||||
<Compile Include="BenchControl\WaterMeters\iPerl\ConfigStruct.cs" />
|
||||
<Compile Include="BenchControl\WaterMeters\iPerl\Enums.cs" />
|
||||
@ -1484,9 +1503,15 @@
|
||||
<EmbeddedResource Include="BenchControl\TestMethods\iPerlAdjustment\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BenchControl\TestMethods\iPerlAdjustment\iPerlCommunicationForm.resx">
|
||||
<EmbeddedResource Include="BenchControl\TestMethods\iPerlAdjustment\iPerlAdjustmentForm.resx">
|
||||
<DependentUpon>iPerlAdjustmentForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BenchControl\TestMethods\iPerlCommunication\iPerlCommunicationForm.resx">
|
||||
<DependentUpon>iPerlCommunicationForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BenchControl\TestMethods\iPerlCommunication\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BenchControl\TestMethods\LeakTest\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user