Add PoseidonCmd DataEntry module integration: EntryForm, EntryFormCfg, Factory, and TestStartEndForm

This commit is contained in:
Michal Buzik 2025-09-05 12:23:06 +02:00
parent f95198e40e
commit 62ffc94c49
20 changed files with 5901 additions and 1 deletions

View File

@ -0,0 +1,290 @@
///
/// Copyright (c) 2015-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using log4net;
using Common;
using TBF.Rig.Sequences;
using TBF.Rig.Output.DB.SensusOracle;
using TBF.Resources;
using System.Drawing;
using NHibernate;
namespace TBF.Rig.DataEntry.PoseidonCmd
{
public partial class CycleBeginningForm : Form, GenericDevices.IHasCompleted
{
private static readonly ILog log = LogManager.GetLogger(typeof(CycleBeginningForm));
/// <summary> Number of water meters </summary>
public readonly int WaterMetersCount;
readonly EntryFormCfg cfg;
/// Loaded from database beforethe form is open
IList<IOrderInfo> listOfOrders;
string preselectedOrder;
/// To be retrieved after the form is closed
public string PurchaseOrder;
public string[] SNText;
public bool[] Disabled;
/// Set to 'true' when the form closes
public bool Completed { get { return completed; } }
bool completed;
/// <summary> Parameterless constructor for common functionality </summary>
public CycleBeginningForm()
{
InitializeComponent();
ControlBox = false;
preselectedOrder = null;
completed = false;
StartForceCloseHandler();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public CycleBeginningForm(int waterMetersCount, EntryFormCfg cfg, string preselectedOrder = null)
: this()
{
this.WaterMetersCount = waterMetersCount;
this.cfg = cfg;
this.preselectedOrder = preselectedOrder;
SNText = null;
Disabled = null;
}
private void CycleBeginningForm_Load(object sender, EventArgs e)
{
Text = Strings.Data;
orderGroupBox.Text = Strings.Purchase_order;
okButton.Text = Strings.OkBtnText;
listOfOrders = new List<IOrderInfo>();
if ((cfg.Orders == Orders.FromOracle || cfg.Orders == Orders.CombinedAndFromOracle)
&& ProcessData.OracleDB != null)
{
foreach (var o in ProcessData.OracleDB.ReadOrders())
{
listOfOrders.Add(o);
}
}
if ((cfg.Orders == Orders.FromTracingDB || cfg.Orders == Orders.CombinedAndFromTracingDB)
&& ProcessData.TracingDB != null
&& ProcessData.TracingDB.DebugLevel == DebugMode.Normal)
{
foreach (var o in ProcessData.TracingDB.ReadOrders())
{
listOfOrders.Add(o);
}
}
string insertFirst = null;
if (!string.IsNullOrEmpty(preselectedOrder))
{
insertFirst = preselectedOrder;
}
else
{
if (Program.LocalSettings.PurchaseOrderHistoryCount > 0)
{
foreach (var o in listOfOrders)
{
if (o.POName == Program.LocalSettings.PurchaseOrderHistory[0])
{
insertFirst = o.POName;
break;
}
}
}
}
switch (cfg.Orders)
{
case Orders.Arbitrary:
PrepareOrderCombo(orderComboBox);
break;
case Orders.FromOracle:
case Orders.FromTracingDB:
if (insertFirst != null)
{
orderComboBox.Items.Add(insertFirst);
orderComboBox.Text = insertFirst;
}
foreach (var o in listOfOrders)
if (o.POName != insertFirst)
orderComboBox.Items.Add(o.POName);
break;
case Orders.CombinedAndFromOracle:
case Orders.CombinedAndFromTracingDB:
if (insertFirst != null)
{
orderComboBox.Items.Add(insertFirst);
orderComboBox.Text = insertFirst;
}
orderComboBox.Items.Add("BBAAMMXX");
orderComboBox.Items.Add("BBAAOMXX");
orderComboBox.Items.Add("BBAAQMXX");
orderComboBox.Items.Add("BBAATMFR");
orderComboBox.Items.Add("BBAATMXX");
orderComboBox.Items.Add("CCAAMMXX");
orderComboBox.Items.Add("CCAAOMXX");
orderComboBox.Items.Add("CCAAQMXX");
orderComboBox.Items.Add("CCAATMFR");
orderComboBox.Items.Add("CCAATMXX");
orderComboBox.Items.Add("DDAAMMXX");
orderComboBox.Items.Add("DDAAOMXX");
orderComboBox.Items.Add("DDAAQMXX");
orderComboBox.Items.Add("DDAATMXX");
orderComboBox.Items.Add("DEAAMMXX");
orderComboBox.Items.Add("DEAAOMXX");
orderComboBox.Items.Add("DEAAQMXX");
orderComboBox.Items.Add("DEAATMXX");
orderComboBox.Items.Add("EEAAMMXX");
orderComboBox.Items.Add("EEAAOMXX");
orderComboBox.Items.Add("EEAAQMXX");
orderComboBox.Items.Add("EEAATMFR");
orderComboBox.Items.Add("EEAATMXX");
orderComboBox.Items.Add("FFAAMMXX");
orderComboBox.Items.Add("FFAAOMXX");
orderComboBox.Items.Add("FFAAQMXX");
orderComboBox.Items.Add("FFAATMFR");
orderComboBox.Items.Add("FFAATMXX");
orderComboBox.Items.Add("GFAAMMXX");
orderComboBox.Items.Add("GFAAOMXX");
orderComboBox.Items.Add("GFAAQMXX");
orderComboBox.Items.Add("GFAATMXX");
foreach (var o in listOfOrders)
if (o.POName != insertFirst)
orderComboBox.Items.Add(o.POName);
break;
}
///
/// Draw an appropriate test bench picture
///
Side side = (TBF.Rig.Sequences.ProcessData.BenchInfo is DataContainer.iPerlBenchInfo.Component)
? (TBF.Rig.Sequences.ProcessData.BenchInfo as DataContainer.iPerlBenchInfo.Component).Side
: Side.Left;
if ((cfg.Direction == Direction.Reversed_LR) && (side == Side.Left))
{
/// direction L->R (reversed), left side
pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\reversed_dir_left.jpg", Program.ExecutableDir, true));
}
else if ((cfg.Direction == Direction.Reversed_LR) && (side == Side.Right))
{
/// direction L->R (reversed), right side
pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\reversed_dir_right.jpg", Program.ExecutableDir, true));
}
else if (side == Side.Right)
{
/// direction R->L (forward), right side
pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\forward_dir_right.jpg", Program.ExecutableDir, true));
}
else
{
/// direction R->L (forward), left side
pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\forward_dir_left.jpg", Program.ExecutableDir, true));
}
}
/// <summary>
/// Load Purchase order combo box items from the LocalSettings PurchaseOrderHistory array
/// </summary>
/// <param name="orderComboBox">Puchase order ComboBox</param>
void PrepareOrderCombo(ComboBox orderComboBox)
{
for (int i = 0; i < Program.LocalSettings.PurchaseOrderHistoryCount; i++)
{
orderComboBox.Items.Add(Program.LocalSettings.PurchaseOrderHistory[i]);
}
if (orderComboBox.Items.Count > 0)
{
orderComboBox.Text = orderComboBox.Items[0].ToString();
}
}
private void okButton_Click(object sender, EventArgs e)
{
if (orderComboBox.Text.Length > 8 ||
(cfg.Orders != Orders.Arbitrary && !orderComboBox.Items.Contains(orderComboBox.Text)))
{
MessageBox.Show(Strings.Invalid_order_number, Strings.Error, MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return;
}
IOrderInfo oInfo = (listOfOrders == null) ? null : listOfOrders.FirstOrDefault<IOrderInfo>(x => x.POName == orderComboBox.Text);
///
if (oInfo is Output.DB.SensusOracle.OrderDetails)
{
ProcessData.OrderInfo = oInfo;
}
else if (oInfo is SharedDatabase.Entities.OrderInfo && ProcessData.TracingDB != null)
{
try
{
using (var session = ProcessData.TracingDB.SessionFactory.OpenSession())
{
var list = session.QueryOver<SharedDatabase.Entities.OrderInfo>()
.Where(x => (x.POName == Program.MainWnd.SelectedProcedure.OrderInfo.POName))
.List();
ProcessData.OrderInfo = (list.Count == 1) ? list[0] : null;
string workflow = (list.Count == 1) ? list[0].Workflow : null;
ProcessData.WorkflowSummary = SharedDatabase.WorkflowSummary.ReadFromDB(workflow, "test", session);
session.Close();
}
}
catch (Exception ex)
{
log.ErrorFormat("Unable to load an order, workflow or workstep: {0}", ex);
ProcessData.OrderInfo = null;
ProcessData.WorkflowSummary = null;
}
}
PurchaseOrder = orderComboBox.Text;
Program.LocalSettings.UpdateHistory(orderComboBox.Text, ref Program.LocalSettings.PurchaseOrderHistory);
completed = true;
Close();
}
#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);
};
}
private void OnForceClose(object sender, EventArgs args)
{
DialogResult = DialogResult.Cancel;
Close();
}
#endregion
}
}

View File

@ -0,0 +1,97 @@
///
/// Copyright (c) 2015 Sensus Metering Systems
///
namespace TBF.Rig.DataEntry.PoseidonCmd
{
partial class CycleBeginningForm
{
/// <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 Windows Form 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()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CycleBeginningForm));
this.okButton = new System.Windows.Forms.Button();
this.orderGroupBox = new System.Windows.Forms.GroupBox();
this.orderComboBox = new System.Windows.Forms.ComboBox();
this.pictureBox = new System.Windows.Forms.PictureBox();
this.orderGroupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
this.SuspendLayout();
//
// okButton
//
resources.ApplyResources(this.okButton, "okButton");
this.okButton.ForeColor = System.Drawing.Color.Black;
this.okButton.Name = "okButton";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
//
// orderGroupBox
//
this.orderGroupBox.Controls.Add(this.orderComboBox);
resources.ApplyResources(this.orderGroupBox, "orderGroupBox");
this.orderGroupBox.ForeColor = System.Drawing.Color.Black;
this.orderGroupBox.Name = "orderGroupBox";
this.orderGroupBox.TabStop = false;
//
// orderComboBox
//
this.orderComboBox.FormattingEnabled = true;
resources.ApplyResources(this.orderComboBox, "orderComboBox");
this.orderComboBox.Name = "orderComboBox";
//
// pictureBox
//
resources.ApplyResources(this.pictureBox, "pictureBox");
this.pictureBox.Name = "pictureBox";
this.pictureBox.TabStop = false;
//
// CycleBeginningForm
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DarkGray;
this.Controls.Add(this.pictureBox);
this.Controls.Add(this.orderGroupBox);
this.Controls.Add(this.okButton);
this.ForeColor = System.Drawing.Color.Black;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "CycleBeginningForm";
this.TopMost = true;
this.Load += new System.EventHandler(this.CycleBeginningForm_Load);
this.orderGroupBox.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.GroupBox orderGroupBox;
private System.Windows.Forms.ComboBox orderComboBox;
private System.Windows.Forms.PictureBox pictureBox;
}
}

View File

@ -0,0 +1,239 @@
<?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>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="okButton.Font" type="System.Drawing.Font, System.Drawing">
<value>Verdana, 14.25pt</value>
</data>
<data name="okButton.Location" type="System.Drawing.Point, System.Drawing">
<value>627, 26</value>
</data>
<data name="okButton.Size" type="System.Drawing.Size, System.Drawing">
<value>112, 63</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="okButton.TabIndex" type="System.Int32, mscorlib">
<value>7</value>
</data>
<data name="okButton.Text" xml:space="preserve">
<value>OK</value>
</data>
<data name="&gt;&gt;okButton.Name" xml:space="preserve">
<value>okButton</value>
</data>
<data name="&gt;&gt;okButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;okButton.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;okButton.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="orderComboBox.Location" type="System.Drawing.Point, System.Drawing">
<value>90, 32</value>
</data>
<data name="orderComboBox.Size" type="System.Drawing.Size, System.Drawing">
<value>432, 31</value>
</data>
<data name="orderComboBox.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;orderComboBox.Name" xml:space="preserve">
<value>orderComboBox</value>
</data>
<data name="&gt;&gt;orderComboBox.Type" xml:space="preserve">
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;orderComboBox.Parent" xml:space="preserve">
<value>orderGroupBox</value>
</data>
<data name="&gt;&gt;orderComboBox.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="orderGroupBox.Font" type="System.Drawing.Font, System.Drawing">
<value>Verdana, 14.25pt</value>
</data>
<data name="orderGroupBox.Location" type="System.Drawing.Point, System.Drawing">
<value>28, 12</value>
</data>
<data name="orderGroupBox.Size" type="System.Drawing.Size, System.Drawing">
<value>565, 82</value>
</data>
<data name="orderGroupBox.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="orderGroupBox.Text" xml:space="preserve">
<value>Order</value>
</data>
<data name="&gt;&gt;orderGroupBox.Name" xml:space="preserve">
<value>orderGroupBox</value>
</data>
<data name="&gt;&gt;orderGroupBox.Type" xml:space="preserve">
<value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;orderGroupBox.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;orderGroupBox.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="pictureBox.Location" type="System.Drawing.Point, System.Drawing">
<value>28, 118</value>
</data>
<data name="pictureBox.Size" type="System.Drawing.Size, System.Drawing">
<value>711, 497</value>
</data>
<data name="pictureBox.TabIndex" type="System.Int32, mscorlib">
<value>8</value>
</data>
<data name="&gt;&gt;pictureBox.Name" xml:space="preserve">
<value>pictureBox</value>
</data>
<data name="&gt;&gt;pictureBox.Type" xml:space="preserve">
<value>System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;pictureBox.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;pictureBox.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>6, 13</value>
</data>
<data name="$this.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>769, 639</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>Batch data</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>CycleBeginningForm</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

View File

@ -0,0 +1,353 @@
///
/// Copyright (c) 2015-2021 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using log4net;
using Config.Entities;
using NHibernate.Util;
using TBF.Rig;
using TBF.Rig.GenericDevices;
using TBF.Rig.RegisterReaders.PoseidonCmdStartStop;
using TBF.Rig.Sequences;
namespace TBF.Rig.DataEntry.PoseidonCmd
{
public class EntryForm : ComponentBase, IOperation, IDataEntry, IHasCycleBeginForm, IHasWMStatesForm, IHasFromUNIDisablePossibility
{
private static readonly ILog log = LogManager.GetLogger(typeof(EntryForm));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
public bool UsesCameras() { return false; }
readonly EntryFormCfg entryFormCfg;
IRegReader[] regReaders;
/// <summary>
/// Properties set by the Begin, End and WMStates form
/// </summary>
bool[] disabled; /// This array is shared between forms
string[] wmCycleEndState;
public string WMCycleEndState(int wmNr) { return (wmNr >= 0 && wmNr < wmCycleEndState.Length) ? wmCycleEndState[wmNr] : string.Empty; }
double[] wmStartState;
public double WMStartState(int wmNr) { return (wmNr >= 0 && wmNr < wmStartState.Length) ? wmStartState[wmNr] : 0; }
double[] wmEndState;
public double WMEndState(int wmNr) { return (wmNr >= 0 && wmNr < wmEndState.Length) ? wmEndState[wmNr] : 0; }
string[] wmStartStateStr;
System.Windows.Forms.Form modelessDlg;
public bool Completed { get { return (modelessDlg is IHasCompleted) ? (modelessDlg as IHasCompleted).Completed : true; } }
double refVolume;
double errLimLo;
double errLimHi;
bool resultSaved; /// Set in Run() when results are saved
IList<Results.Entities.WaterMeter> waterMeters; /// Reference to ...ProcessData.BatchRslts.WaterMeters[]
public enum CurrentOp
{
None,
SendStartDataStream,
ReadDatastream_StartStates,
ReadDatastream_EndStates,
}
CurrentOp currentOp;
public EntryForm() { }
public EntryForm(Generic.IComponentCfg cfg)
: base(cfg)
{
entryFormCfg = cfg as EntryFormCfg;
}
public override void Initialize()
{
disabled = new bool[TBF.Data.WMsCount];
wmStartState = new double[TBF.Data.WMsCount];
wmStartStateStr = new string[TBF.Data.WMsCount];
wmEndState = new double[TBF.Data.WMsCount];
wmCycleEndState = new string[TBF.Data.WMsCount];
currentOp = CurrentOp.None;
log.FatalFormat("{0} initialized: {1}", Name, this);
}
/// <returns>Reference to the operation</returns>
public IOperation ShowCycleBeginFormOp()
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.SendStartDataStream;
this.waterMeters = ProcessData.BatchRslts.Batch.WaterMeters;
return this;
}
/// <returns>Reference to the operation</returns>
public IOperation ShowTestStartFormOp(IRegReader[] regReaders)
{
if (!(
currentOp == CurrentOp.None
|| currentOp == CurrentOp.SendStartDataStream)
) throw new Exception("Sequence error");
currentOp = CurrentOp.ReadDatastream_StartStates;
//TODO BUMI apply show data in dialog if config required
//entryFormCfg.Direction = Direction.S640;
//currentOp = CurrentOp.EnterTestStartStates;
this.regReaders = regReaders;
return this;
}
/// <returns>null (not implemented)</returns>
public IOperation ShowAdvancedTestStartFormOp(IRegReader[] regReaders, IList<Results.Entities.WaterMeter> waterMeters, bool isCondOp) { return null; }
public IOperation ShowTestCollectFormOp(IRegReader[] regReaders, double volumeRef, double errLimLo, double errLimHi) { return null; }
/// <returns>Reference to the operation</returns>
public IOperation ShowTestEndFormOp(IRegReader[] regReaders, double refVolume, double errLimLo, double errLimHi)
{
if (!(currentOp == CurrentOp.None) )
throw new Exception("Sequence error");
currentOp = CurrentOp.ReadDatastream_EndStates;
this.regReaders = regReaders;
this.refVolume = refVolume;
this.errLimLo = errLimLo;
this.errLimHi = errLimHi;
return this;
}
delegate void EntryFormDlgt(EntryForm myRef);
///
void OpenBeginningDlg(EntryForm myRef)
{
if (!ShowForm)
return;
myRef.modelessDlg = new CycleBeginningForm(TBF.Data.WMsCount, myRef.entryFormCfg,
ProcessData.SelectedProcedure.OrderInfo != null ? ProcessData.SelectedProcedure.OrderInfo.POName : string.Empty);
modelessDlg.Show();
}
///
void OpenTestStartStatesDlg(EntryForm myRef)
{
if (!ShowForm)
return;
myRef.modelessDlg = new TestStartEndForm(myRef.waterMeters.Count, myRef.regReaders, disabled);
modelessDlg.Show();
}
///
void OpenTestEndStatesDlg(EntryForm myRef)
{
if (!ShowForm)
return;
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, wmStartStateStr, disabled, refVolume, errLimLo, errLimHi);
modelessDlg.Show();
}
/// <summary>Start this operation</summary>
public void Start()
{
if (!ShowForm)
return ;
resultSaved = false;
switch (currentOp)
{
case CurrentOp.SendStartDataStream:
ReadAndSetDataToMeters();
if (ProcessData.SelectedProcedure.OrderInfo == null || entryFormCfg.Direction != Direction.S640)
{
Program.MainWnd.Invoke(new EntryFormDlgt(OpenBeginningDlg), this);
}
else
{
/// Only in case of 640 meters and an order information entered during the procedure selection
/// this DataEntry form at the beginning of the cycle is skipped
modelessDlg = null;
}
break;
case CurrentOp.ReadDatastream_StartStates:
Program.MainWnd.Invoke(new EntryFormDlgt(OpenTestStartStatesDlg), this);
break;
case CurrentOp.ReadDatastream_EndStates:
Program.MainWnd.Invoke(new EntryFormDlgt(OpenTestEndStatesDlg), this);
break;
}
}
/// <summary>Run this operation</summary>
/// <returns>Event.ResultsPrinted</returns>
public Event Run()
{
ReadAndSetDataToMeters();
if (!ShowForm)
return Event.ModelessFormClosed;
if (ProcessData.SelectedProcedure.OrderInfo != null && entryFormCfg.Direction == Direction.S640)
{
for (int i = 0; i < waterMeters.Count; i++)
{
if (waterMeters[i] != null)
waterMeters[i].PurchaseOrder = ProcessData.SelectedProcedure.OrderInfo.POName;
}
return Event.ModelessFormClosed;
}
if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed)
{
return Event.ModelessFormIsOpen;
}
if (!resultSaved) /// This is to save the result only once
{
if (currentOp == CurrentOp.SendStartDataStream)
{
CycleBeginningForm dlg = (modelessDlg as CycleBeginningForm);
if (dlg != null)
{
for (int i = 0; i < Math.Min(dlg.WaterMetersCount, waterMeters.Count); i++)
{
if (waterMeters[i] != null)
{
if (dlg.PurchaseOrder != null) waterMeters[i].PurchaseOrder = dlg.PurchaseOrder;
}
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.ReadDatastream_StartStates)
{
/// Fixed start test - start
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
if (dlg != null)
{
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.ReadDatastream_EndStates)
{
/// Fixed start test - end
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
if (dlg != null)
{
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmEndState[i] = dlg.WMEndState[i];
}
}
}
resultSaved = true;
modelessDlg = null;
}
return Event.ModelessFormClosed; /// Form closed
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (modelessDlg is IHasCompleted)
{
UiBridge.Bridge.OnCloseModelessForm(this, null);
modelessDlg = null;
}
currentOp = CurrentOp.None;
}
public bool ShowForm { get; set; }
public bool ReadAndSetDataToMeters()
{
bool bOperationSuccess = false;
if (currentOp == CurrentOp.SendStartDataStream)
{
bool finishedReading = regReaders == null; // we can work only with register readers
while (!finishedReading)
{
bool bAllReadersFinished = true;
foreach (var iRegReader in regReaders )
{
if (iRegReader is PoseidonReader)
{
PoseidonReader poseidonReader = (iRegReader as PoseidonReader);
if (poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.SendStartDataStream_Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.SendStartDataStream_Runing)
{
poseidonReader.SetCurrentOp(PoseidonReader.CurrentPoseidonOp.SendStartDataStream);
}
/// Send start data stream
poseidonReader.Run();
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error))
{
bAllReadersFinished = false;
}
}
}
/// Wait for all readers to finish
if (bAllReadersFinished)
{
finishedReading = true;
}
else
{
System.Threading.Thread.Sleep(100);
}
}
bOperationSuccess = true;
}
else if ((currentOp == CurrentOp.ReadDatastream_StartStates)
|| (currentOp == CurrentOp.ReadDatastream_EndStates))
{
bool finishedReading = regReaders == null; // we can work only with register readers
while (!finishedReading)
{
bool bAllReadersFinished = true;
foreach (var iRegReader in regReaders )
{
if (iRegReader is PoseidonReader)
{
PoseidonReader poseidonReader = (iRegReader as PoseidonReader);
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.ReadDatastream_Running))
{
poseidonReader.SetCurrentOp((currentOp == CurrentOp.ReadDatastream_StartStates)?
PoseidonReader.CurrentPoseidonOp.ReadDataStream_Start :
PoseidonReader.CurrentPoseidonOp.ReadDataStream_End);
}
/// Send start data stream
poseidonReader.Run();
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error))
{
bAllReadersFinished = false;
}
}
}
if (bAllReadersFinished)
{
finishedReading = true;
}
else
{
System.Threading.Thread.Sleep(100);
}
}
bOperationSuccess = true;
}
return bOperationSuccess;
}
}
}

View File

@ -0,0 +1,191 @@
///
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Resources;
using TBF.Rig.Generic;
namespace TBF.Rig.DataEntry.PoseidonCmd
{
public enum Direction
{
#if LANG_SK
[Description("iPERL normálne (R-L)")] Forward_RL,
[Description("iPERL opačne (L-R)")] Reversed_LR,
[Description("640")] S640,
#elif LANG_DE
[Description("iPERL Forward (R-L)")] Forward_RL,
[Description("iPERL Reversed (L-R)")] Reversed_LR,
[Description("640")] S640,
#else
[Description("iPERL Forward (R-L)")] Forward_RL,
[Description("iPERL Reversed (L-R)")] Reversed_LR,
[Description("640")] S640,
#endif
Count,
}
public enum Orders
{
#if LANG_SK
[Description("Ľubovolné")] Arbitrary,
[Description("Z Oracle databázy")] FromOracle,
[Description("Zo sledovacej databázy")] FromTracingDB,
[Description("Združené a z Oracle")] CombinedAndFromOracle,
[Description("Združené a zo sledovacej databázy")] CombinedAndFromTracingDB,
#elif LANG_CZ
[Description("Libovolné")] Arbitrary,
[Description("Z Oracle databáze")] FromOracle,
[Description("Ze sledovací databáze")] FromTracingDB,
[Description("Sdružené a z Oracle")] CombinedAndFromOracle,
[Description("Sdružené a ze sledovací databáze")] CombinedAndFromTracingDB,
#else
[Description("Arbitrary")] Arbitrary,
[Description("From Oracle")] FromOracle,
[Description("From Tracing DB")] FromTracingDB,
[Description("Combined and from Oracle")] CombinedAndFromOracle,
[Description("Combined and from Tracing DB")] CombinedAndFromTracingDB,
#endif
Count,
}
public class EntryFormCfg : ComponentCfgBase, IComponentCfg, IParamsProvider
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(EntryFormCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
{
return new Configs.ParamsProvider.ComponentCfgCtrl(this, null);
}
///
/// Serialized parameters
///
public Direction Direction;
public Orders Orders;
/// Private parameterless constructor invoked by all other (public) constructors
EntryFormCfg() { }
public EntryFormCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = string.Empty;
InitializeAll();
}
public string ComponentName { get { return Name; } }
public void InitializeAll()
{
Direction = Direction.Forward_RL;
Orders = Orders.Arbitrary;
}
string[] paramNames = new string[]
{
Strings.Direction,
Strings.Orders,
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int i)
{
var list = new List<string>();
switch (i)
{
case 0:
for (Direction d = 0; d < Direction.Count; d++) list.Add(d.ToDescription());
return list;
case 1:
for (Orders o = 0; o < Orders.Count; o++) list.Add(o.ToDescription());
return list;
default:
return null;
}
}
public string ToString(int i)
{
switch (i)
{
case 0: return Direction.ToDescription();
case 1: return Orders.ToDescription();
default:
return string.Format("Name={0}, Direction={1}, Orders={2}", Name, Direction, Orders);
}
}
public CfgUpdateFlags UpdateParam(int i, string str)
{
switch (i)
{
case 0:
for (Direction d = 0; d < Direction.Count; d++)
if (d.ToDescription() == str)
{
Direction = d;
return CfgUpdateFlags.RestartRqrd;
}
break;
case 1:
for (Orders o = 0; o < Orders.Count; o++)
if (o.ToDescription() == str)
{
Orders = o;
return CfgUpdateFlags.RestartRqrd;
}
break;
}
return CfgUpdateFlags.None;
}
public bool ValidateParam(int i, string str, out string message)
{
message = string.Empty;
switch (i)
{
case 0:
case 1:
if (ParamValues(i).Contains(str)) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(EntryFormCfg prms)
{
prms.Direction = this.Direction;
prms.Orders = this.Orders;
}
public IParamsProvider Clone()
{
EntryFormCfg pars = new EntryFormCfg();
CopyContentTo(pars);
return pars;
}
public bool UpdateEmbeddedDbEntity()
{
return true; /// =OK, do nothing
}
}
}

View File

@ -0,0 +1,25 @@
///
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.DataEntry.PoseidonCmd
{
public class Factory : IComponentFactory
{
public string ClassName { get { return GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new EntryForm(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new EntryForm(cfg); }
public IComponentCfg DefaultConfig() { return new EntryFormCfg("DataEntry-PoseidonCmd", this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(EntryFormCfg.Serializer, component, this);
}
}
}

View File

@ -0,0 +1,478 @@
///
/// Copyright (c) 2015-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using log4net;
using TBF.Rig.GenericDevices;
using TBF.Resources;
namespace TBF.Rig.DataEntry.PoseidonCmd
{
public partial class TestStartEndForm : Form, GenericDevices.IHasCompleted
{
private static readonly ILog log = LogManager.GetLogger(typeof(TestStartEndForm));
// Set to 'true' when the form closes
public bool Completed { get { return completed; } }
bool completed;
/// <summary> Number of text boxes for serial numbers </summary>
public readonly int WaterMetersCount;
readonly IRegReader[] regReaders;
readonly bool[] disabled;
// To be retrieved after the form closes
public double[] WMStartState;
// To be retrieved after the form closes
public readonly string[] WMStartStateStr;
// To be retrieved after the form closes
public double[] WMEndState;
bool endStates; /// false=start states, true=end states
double refVolume;
double warningLimLo; /// limit to display exclamation mark, typically 2x errLimLo
double warningLimHi; /// limit to display exclamation mark, typically 2x errLimHi
int TextBoxesCount;
///
Label[] labels;
TextBox[] startTextBoxes;
TextBox[] endTextBoxes;
IList<TextBox> enabledTextBoxes;
/// <summary>
/// Parameterless constructor initializing common part for start and endstate form
/// </summary>
public TestStartEndForm()
{
InitializeComponent();
ControlBox = false;
TextBoxesCount = 48;
labels = new Label[]
{
label1, label2, label3, label4, label5, label6, label7, label8, label9, label10,
label11, label12, label13, label14, label15, label16, label17, label18, label19, label20,
label21, label22, label23, label24, label25, label26, label27, label28, label29, label30,
label31, label32, label33, label34, label35, label36, label37, label38, label39, label40,
label41, label42, label43, label44, label45, label46, label47, label48,
};
startTextBoxes = new TextBox[]
{
startTextBox1, startTextBox2, startTextBox3, startTextBox4, startTextBox5, startTextBox6, startTextBox7, startTextBox8, startTextBox9, startTextBox10,
startTextBox11, startTextBox12, startTextBox13, startTextBox14, startTextBox15, startTextBox16, startTextBox17, startTextBox18, startTextBox19, startTextBox20,
startTextBox21, startTextBox22, startTextBox23, startTextBox24, startTextBox25, startTextBox26, startTextBox27, startTextBox28, startTextBox29, startTextBox30,
startTextBox31, startTextBox32, startTextBox33, startTextBox34, startTextBox35, startTextBox36, startTextBox37, startTextBox38, startTextBox39, startTextBox40,
startTextBox41, startTextBox42, startTextBox43, startTextBox44, startTextBox45, startTextBox46, startTextBox47, startTextBox48,
};
endTextBoxes = new TextBox[]
{
endTextBox1, endTextBox2, endTextBox3, endTextBox4, endTextBox5, endTextBox6, endTextBox7, endTextBox8, endTextBox9, endTextBox10,
endTextBox11, endTextBox12, endTextBox13, endTextBox14, endTextBox15, endTextBox16, endTextBox17, endTextBox18, endTextBox19, endTextBox20,
endTextBox21, endTextBox22, endTextBox23, endTextBox24, endTextBox25, endTextBox26, endTextBox27, endTextBox28, endTextBox29, endTextBox30,
endTextBox31, endTextBox32, endTextBox33, endTextBox34, endTextBox35, endTextBox36, endTextBox37, endTextBox38, endTextBox39, endTextBox40,
endTextBox41, endTextBox42, endTextBox43, endTextBox44, endTextBox45, endTextBox46, endTextBox47, endTextBox48,
};
enabledTextBoxes = new List<TextBox>();
completed = false;
StartForceCloseHandler();
}
/// <summary>
/// Constructor to fill in start states
/// </summary>
/// <param name="waterMetersCount">Number of water meters</param>
/// <param name="disabled">Information from CycleBeginningForm about availability of water meters</param>
public TestStartEndForm(int waterMetersCount, IRegReader[] regReaders, bool[] disabled)
: this()
{
endStates = false;
this.WaterMetersCount = waterMetersCount;
this.regReaders = regReaders;
this.disabled = disabled;
ShuffleTextBoxes();
WMStartState = new double[waterMetersCount];
WMStartStateStr = new string[waterMetersCount];
}
/// <summary>
/// Constructor to fill in end states
/// </summary>
/// <param name="waterMetersCount">Number of water meters</param>
/// <param name="wmStartStateStr">Information entered on test start</param>
/// <param name="disabled">Information from CycleBeginningForm about availability of water meters</param>
/// <param name="refVolume">Reference volume, it is used to verify the end state, show/hide exclamation if necessary</param>
/// <param name="errLimLo">Error limit low, it is used to verify the end state, show/hide exclamation if necessary</param>
/// <param name="errLimHi">Error limit high, it is used to verify the end state, show/hide exclamation if necessary</param>
public TestStartEndForm(int waterMetersCount, IRegReader[] regReaders, string[] wmStartStateStr, bool[] disabled,
double refVolume, double errLimLo, double errLimHi)
: this()
{
endStates = true;
this.WaterMetersCount = waterMetersCount;
this.regReaders = regReaders;
if (wmStartStateStr == null || wmStartStateStr.Length != waterMetersCount)
throw (new Exception("Invalid 'wmStartStateStr' argument"));
this.WMStartStateStr = wmStartStateStr;
this.disabled = disabled;
this.refVolume = refVolume;
this.warningLimLo = 2 * errLimLo;
this.warningLimHi = 2 * errLimHi;
ShuffleTextBoxes();
WMEndState = new double[waterMetersCount];
}
/// <summary>
/// Make sure the layout of labels/text boxes on the screen
/// corresponds to the layout of watermeters of the test bench.
/// </summary>
void ShuffleTextBoxes()
{
if (TBF.Data.WMsCount < TextBoxesCount)
{
int nrLines = TBF.Data.WMsCount / TBF.Data.LineSize;
int gap = (TextBoxesCount - TBF.Data.WMsCount) / nrLines;
int dest = 0;
for (int l = 0; l < nrLines; l++)
{
for (int i = 0; i < TBF.Data.LineSize; i++)
{
labels[dest] = labels[l * TBF.Data.LineSize + l * gap + i];
startTextBoxes[dest] = startTextBoxes[l * TBF.Data.LineSize + l * gap + i];
endTextBoxes[dest] = endTextBoxes[l * TBF.Data.LineSize + l * gap + i];
dest++;
}
}
TextBoxesCount = TBF.Data.WMsCount;
}
}
private void CycleEndForm_Load(object sender, EventArgs e)
{
Localize();
//Height = 115 + 90 * WaterMetersCount;
for (int i = 0; i < TextBoxesCount; i++)
{
if (i < WaterMetersCount)
{
labels[i].Visible = startTextBoxes[i].Visible = endTextBoxes[i].Visible = true;
}
}
if (endStates)
{
for (int i = 0; i < TextBoxesCount; i++)
{
if (WMStartStateStr != null && i < WMStartStateStr.Length)
{
startTextBoxes[i].Text = WMStartStateStr[i];
}
if (disabled != null && i < disabled.Length && disabled[i])
{
endTextBoxes[i].Enabled = false;
}
else
{
endTextBoxes[i].Enabled = true;
enabledTextBoxes.Add(endTextBoxes[i]);
}
}
}
else
{
for (int i = 0; i < TextBoxesCount; i++)
{
if (disabled != null && i < disabled.Length && disabled[i])
{
startTextBoxes[i].Enabled = false;
}
else
{
startTextBoxes[i].Enabled = true;
enabledTextBoxes.Add(startTextBoxes[i]);
}
}
}
}
void Localize()
{
Text = Strings.Water_Meter_States;
for (int i = 0; i < TextBoxesCount; i++)
{
labels[i].Text = string.Format("{0} {1}", Strings.Water_Meter, i + 1);
}
startLabel.Text = start2Label.Text = Strings.Start;
endLabel.Text = end2Label.Text = Strings.End;
okButton.Text = Strings.OkBtnText;
}
private void okButton_Click(object sender, EventArgs eArgs)
{
try
{
if (endStates)
{
for (int i = 0; i < Math.Min(WaterMetersCount, TextBoxesCount); i++)
{
if (endTextBoxes[i].Visible && endTextBoxes[i].Enabled)
{
WMEndState[i] = Utils.ParseUDouble(endTextBoxes[i].Text);
}
}
}
else
{
for (int i = 0; i < Math.Min(WaterMetersCount, TextBoxesCount); i++)
{
if (startTextBoxes[i].Visible && startTextBoxes[i].Enabled)
{
WMStartStateStr[i] = startTextBoxes[i].Text;
WMStartState[i] = Utils.ParseUDouble(startTextBoxes[i].Text);
}
}
}
}
catch(Exception e)
{
log.ErrorFormat("Exception: {0}", e.Message);
return;
}
completed = true;
Close();
}
#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)
{
DialogResult = DialogResult.Cancel;
Close();
}
#endregion
/// <summary>
/// Calculate the approximate error and verify whether it is within limits.
/// Make an exclamation mark visible if out of range.
/// Similar event handler is implemented for all endTextBoxes (1..24).
/// </summary>
private void ProcTextChanged(object sender, EventArgs e, TextBox endStateTB, TextBox startStateTB, Label exclamation)
{
double err = 0;
try
{
double endState = Utils.ParseUDouble(endStateTB.Text);
double startState = Utils.ParseUDouble(startStateTB.Text);
err = 100.0 * (endState - startState - refVolume) / refVolume;
}
catch { err = 1000.0f; };
exclamation.Visible = (err < warningLimLo) || (warningLimHi < err);
}
private void endTextBox1_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox1, startTextBox1, exclamation1); }
private void endTextBox2_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox2, startTextBox2, exclamation2); }
private void endTextBox3_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox3, startTextBox3, exclamation3); }
private void endTextBox4_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox4, startTextBox4, exclamation4); }
private void endTextBox5_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox5, startTextBox5, exclamation5); }
private void endTextBox6_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox6, startTextBox6, exclamation6); }
private void endTextBox7_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox7, startTextBox7, exclamation7); }
private void endTextBox8_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox8, startTextBox8, exclamation8); }
private void endTextBox9_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox9, startTextBox9, exclamation9); }
private void endTextBox10_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox10, startTextBox10, exclamation10); }
private void endTextBox11_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox11, startTextBox11, exclamation11); }
private void endTextBox12_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox12, startTextBox12, exclamation12); }
private void endTextBox13_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox13, startTextBox13, exclamation13); }
private void endTextBox14_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox14, startTextBox14, exclamation14); }
private void endTextBox15_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox15, startTextBox15, exclamation15); }
private void endTextBox16_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox16, startTextBox16, exclamation16); }
private void endTextBox17_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox17, startTextBox17, exclamation17); }
private void endTextBox18_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox18, startTextBox18, exclamation18); }
private void endTextBox19_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox19, startTextBox19, exclamation19); }
private void endTextBox20_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox20, startTextBox20, exclamation20); }
private void endTextBox21_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox21, startTextBox21, exclamation21); }
private void endTextBox22_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox22, startTextBox22, exclamation22); }
private void endTextBox23_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox23, startTextBox23, exclamation23); }
private void endTextBox24_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox24, startTextBox24, exclamation24); }
private void endTextBox25_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox25, startTextBox25, exclamation25); }
private void endTextBox26_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox26, startTextBox26, exclamation26); }
private void endTextBox27_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox27, startTextBox27, exclamation27); }
private void endTextBox28_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox28, startTextBox28, exclamation28); }
private void endTextBox29_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox29, startTextBox29, exclamation29); }
private void endTextBox30_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox30, startTextBox30, exclamation30); }
private void endTextBox31_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox31, startTextBox31, exclamation31); }
private void endTextBox32_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox32, startTextBox32, exclamation32); }
private void endTextBox33_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox33, startTextBox33, exclamation33); }
private void endTextBox34_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox34, startTextBox34, exclamation34); }
private void endTextBox35_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox35, startTextBox35, exclamation35); }
private void endTextBox36_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox36, startTextBox36, exclamation36); }
private void endTextBox37_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox37, startTextBox37, exclamation37); }
private void endTextBox38_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox38, startTextBox38, exclamation38); }
private void endTextBox39_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox39, startTextBox39, exclamation39); }
private void endTextBox40_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox40, startTextBox40, exclamation40); }
private void endTextBox41_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox41, startTextBox41, exclamation41); }
private void endTextBox42_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox42, startTextBox42, exclamation42); }
private void endTextBox43_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox43, startTextBox43, exclamation43); }
private void endTextBox44_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox44, startTextBox44, exclamation44); }
private void endTextBox45_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox45, startTextBox45, exclamation45); }
private void endTextBox46_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox46, startTextBox46, exclamation46); }
private void endTextBox47_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox47, startTextBox47, exclamation47); }
private void endTextBox48_TextChanged(object sndr, EventArgs e) { ProcTextChanged(sndr, e, endTextBox48, startTextBox48, exclamation48); }
/// <summary>
/// Process a key press within any enabled text boxe
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <param name="currentFocusOwner">TextBox control which received the event</param>
private void ProcKeyPress(object sender, KeyPressEventArgs e, TextBox currentFocusOwner)
{
if (e.KeyChar == '+')
{
/// Process '+' key ..... Form completed
okButton_Click(sender, e);
}
if (e.KeyChar == '\r')
{
/// Process <enter> key ..... Next text field
if (enabledTextBoxes.Count < 2) return; /// There is just one enabled textbox
for (int i = 0; i < enabledTextBoxes.Count; i++)
{
if (enabledTextBoxes[i] == currentFocusOwner)
{
/// Change focus to the next enabled text box
enabledTextBoxes[(i + 1) % enabledTextBoxes.Count].Focus();
return;
}
}
}
}
private void startTextBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox1); }
private void startTextBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox2); }
private void startTextBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox3); }
private void startTextBox4_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox4); }
private void startTextBox5_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox5); }
private void startTextBox6_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox6); }
private void startTextBox7_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox7); }
private void startTextBox8_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox8); }
private void startTextBox9_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox9); }
private void startTextBox10_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox10); }
private void startTextBox11_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox11); }
private void startTextBox12_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox12); }
private void startTextBox13_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox13); }
private void startTextBox14_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox14); }
private void startTextBox15_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox15); }
private void startTextBox16_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox16); }
private void startTextBox17_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox17); }
private void startTextBox18_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox18); }
private void startTextBox19_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox19); }
private void startTextBox20_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox20); }
private void startTextBox21_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox21); }
private void startTextBox22_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox22); }
private void startTextBox23_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox23); }
private void startTextBox24_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox24); }
private void startTextBox25_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox25); }
private void startTextBox26_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox26); }
private void startTextBox27_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox27); }
private void startTextBox28_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox28); }
private void startTextBox29_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox29); }
private void startTextBox30_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox30); }
private void startTextBox31_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox31); }
private void startTextBox32_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox32); }
private void startTextBox33_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox33); }
private void startTextBox34_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox34); }
private void startTextBox35_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox35); }
private void startTextBox36_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox36); }
private void startTextBox37_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox37); }
private void startTextBox38_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox38); }
private void startTextBox39_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox39); }
private void startTextBox40_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox40); }
private void startTextBox41_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox41); }
private void startTextBox42_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox42); }
private void startTextBox43_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox43); }
private void startTextBox44_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox44); }
private void startTextBox45_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox45); }
private void startTextBox46_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox46); }
private void startTextBox47_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox47); }
private void startTextBox48_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, startTextBox48); }
private void endTextBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox1); }
private void endTextBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox2); }
private void endTextBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox3); }
private void endTextBox4_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox4); }
private void endTextBox5_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox5); }
private void endTextBox6_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox6); }
private void endTextBox7_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox7); }
private void endTextBox8_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox8); }
private void endTextBox9_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox9); }
private void endTextBox10_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox10); }
private void endTextBox11_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox11); }
private void endTextBox12_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox12); }
private void endTextBox13_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox13); }
private void endTextBox14_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox14); }
private void endTextBox15_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox15); }
private void endTextBox16_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox16); }
private void endTextBox17_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox17); }
private void endTextBox18_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox18); }
private void endTextBox19_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox19); }
private void endTextBox20_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox20); }
private void endTextBox21_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox21); }
private void endTextBox22_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox22); }
private void endTextBox23_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox23); }
private void endTextBox24_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox24); }
private void endTextBox25_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox25); }
private void endTextBox26_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox26); }
private void endTextBox27_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox27); }
private void endTextBox28_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox28); }
private void endTextBox29_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox29); }
private void endTextBox30_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox30); }
private void endTextBox31_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox31); }
private void endTextBox32_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox32); }
private void endTextBox33_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox33); }
private void endTextBox34_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox34); }
private void endTextBox35_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox35); }
private void endTextBox36_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox36); }
private void endTextBox37_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox37); }
private void endTextBox38_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox38); }
private void endTextBox39_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox39); }
private void endTextBox40_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox40); }
private void endTextBox41_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox41); }
private void endTextBox42_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox42); }
private void endTextBox43_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox43); }
private void endTextBox44_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox44); }
private void endTextBox45_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox45); }
private void endTextBox46_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox46); }
private void endTextBox47_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox47); }
private void endTextBox48_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, endTextBox48); }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -0,0 +1,9 @@
namespace TBF.Rig.GenericDevices
{
public interface IHasFromUNIDisablePossibility
{
bool ShowForm { get; set; }
bool ReadAndSetDataToMeters();
}
}

View File

@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public class CliRunner
{
private List<Task> taskPool = new List<Task>();
private long startTime;
public List<Task> TaskPool { get { return taskPool; } }
public void AddTask(Task task) { taskPool.Add(task); }
public void WaitAll() { Task.WaitAll(taskPool.ToArray()); }
public void Clear() { taskPool.Clear(); }
public void CancelAll() { Task.WhenAll(taskPool).ContinueWith(t => { }); }
public void StartAll()
{
taskPool.ForEach(t => t.Start());
}
public bool AreTasksDone()
{
return taskPool.All(task => task.IsCompleted);
}
public long StartTime
{
get => startTime;
}
public bool TimeOutReceived(long timeout)
{
return (DateTime.Now.Ticks - startTime) > timeout;
}
public CliRunner()
{
startTime = DateTime.Now.Ticks;
}
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <param name="args"></param>
/// <typeparam name="T"></typeparam>
public void AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
{
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
taskPool.Add(task);
}
public void AddSendAsync(string fileName, string args)
{
var task = SendAsync(fileName, args);
taskPool.Add(task);
}
public async Task<string> SendAsync(string fileName, string args)
{
var psi = new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process { StartInfo = psi };
var sb = new StringBuilder();
process.OutputDataReceived += (sender, e) =>
{
if (e.Data != null)
sb.AppendLine(e.Data);
};
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
// Now all outputs are available
string allOutput = sb.ToString();
return allOutput;
}
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
{
var task = RunAndCaptureJsonAsync<T>(data.SerialPortCmdClientPath, data.DefaultArgSettings(eMeterArg));
taskPool.Add(task);
}
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args)
{
var psi = new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process { StartInfo = psi };
var sb = new StringBuilder();
process.OutputDataReceived += (sender, e) =>
{
if (e.Data != null)
sb.AppendLine(e.Data);
};
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
// Now sb contains all output text
string allOutput = sb.ToString();
// Extract JSON part
string json = ExtractJson(allOutput);
if (json != null)
{
return JsonConvert.DeserializeObject<T>(json);
}
return default;
}
private string ExtractJson(string text)
{
int start = text.IndexOf('{');
int end = text.LastIndexOf('}');
if (start >= 0 && end > start)
{
return text.Substring(start, end - start + 1);
}
return null;
}
}
}

View File

@ -0,0 +1,26 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using TBF.Rig.Generic;
using TBF.Rig.RegisterReaders.StandingStartStop;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
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 PoseidonReader(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new PoseidonReader(cfg, components); }
public IComponentCfg DefaultConfig() { return new PoseidonCfg("PoseidonCmdStartStop", this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(PoseidonCfg.Serializer, component, this);
}
}
}

View File

@ -0,0 +1,22 @@
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public class JsonDataFromPoseidon
{
public bool? NfcTagDetected { get; set; }
public int? ProductType { get; set; }
public string ProductTypeVersion { get; set; }
public string DeviceId { get; set; }
public string Reading { get; set; }
public string Reading_Totalizer { get; set; }
public string Reading_Digits { get; set; }
public string Reading_Shift { get; set; }
public string Reading_Resolution { get; set; }
public string Reading_Units { get; set; }
public string Reading_FlowDirection { get; set; }
public string Reading_FlowRate { get; set; }
public string CalibrationFactor { get; set; }
public bool? ReadingComplete { get; set; }
}
}

View File

@ -0,0 +1,156 @@
///
/// Copyright (c) 2013-2016 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Xml.Serialization;
using Common;
using TBF.Rig.Generic;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
/// PoseidonCSSCfg => Poseidon Cmd Start Stop Cfg
public class PoseidonCfg : ComponentCfgBase, IComponentCfg, IParamsProvider
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PoseidonCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public string ComponentName { get; }
///
/// Serialized parameters
///
public int ComPortNr;
public string CliFileName;
public int MeterType;
/// <summary> Procedure parameters </summary>
[XmlIgnore]
public PoseidonProcParams ProcParams;
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
public override IParamsProvider CreateProcParamsProvider() { return new PoseidonProcParams(true); }
string[] paramNames = new string[]
{
"Serial port number", /// 0
"CLI program name", /// 1
"Meter Type", /// 2
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int i)
{
switch (i)
{
case 0:
return new string[] { "3","4","5","6","7","8","9","10","11","12"};
case 1:
return new string[] { "HatCLI.exe"};
case 2:
return new string[] { "74" };
default:
return null;
}
}
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
public void InitializeAll()
{
ComPortNr = 3;
CliFileName = "HatCLI.exe";
MeterType = 74;
}
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
int idummy;
switch (i)
{
case 0:
if (int.TryParse(strValue, out idummy) && idummy > 0) return true;
break;
case 1:
if (ParamValues(i).Contains(strValue)) return true; //is in list
if(System.Text.RegularExpressions.Regex.IsMatch(strValue, @"^[a-zA-Z0-9_-]+\.exe$")) return true; //validate exe file name
break;
case 2:
if (int.TryParse(strValue, out idummy) && idummy > 0) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
public CfgUpdateFlags UpdateParam(int i, string str)
{
switch (i)
{
case 0: ComPortNr = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
case 1: CliFileName = str; return CfgUpdateFlags.RestartRqrd;
case 2: MeterType = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
default: return CfgUpdateFlags.None;
}
}
public bool UpdateEmbeddedDbEntity()
{
return true; /// =OK, do nothing
}
public IParamsProvider Clone()
{
PoseidonCfg pars = new PoseidonCfg();
CopyContentTo(pars);
return pars;
}
/// Private parameterless constructor invoked by all other (public) constructors
PoseidonCfg()
{
ProcParams = CreateProcParamsProvider() as PoseidonProcParams;
}
public PoseidonCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = "";
InitializeAll();
}
public string ToString(int i)
{
switch (i)
{
case 0: return ComPortNr.ToString();
case 1: return CliFileName;
case 2: return MeterType.ToString();
default:
return string.Format("{0}: Com{1}, CliName =`{2}`, MeterType = {3}",
Name, ComPortNr, CliFileName, MeterType);
}
}
void CopyContentTo(PoseidonCfg prms)
{
prms.ComPortNr = this.ComPortNr;
prms.CliFileName = this.CliFileName;
prms.MeterType = this.MeterType;
prms.ProcParams = this.ProcParams;
}
}
}

View File

@ -0,0 +1,288 @@
using System.IO;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Resources;
using TBF.Rig.Generic;
using TBF.Rig.RegisterReaders.SerialStream;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public class PoseidonProcParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PoseidonProcParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public StreamType StreamType; /// Enumerated stream type
public int FrameLength; /// Frame length in characters/bytes, 0 = unknown
public double FrameFrequency; /// Number of frames per second, 0 = unknown
public Common.Unit VolumeUnits;
public double VolumeScaleFactor; /// Volume =
public int VolumeFieldStart; /// Start of the volume field: 0-based index of the first character, -1 = no volume field in the frame
public int VolumeFieldEnd; /// End of the volume field: 0-based index of the last character
public FieldFormat VolumeFieldFormat; /// Hexadecimal or Decimal
public Common.Unit TimeUnits;
public double TimeScaleFactor; /// Time =
public int TimeFieldStart; /// Start of the time field: 0-based index of the first character, -1 = no time field in the frame
public int TimeFieldEnd; /// End of the time field: 0-based index of the last character
public FieldFormat TimeFieldFormat; /// Hexadecimal or Decimal
public override void InitializeAll()
{
/// Values are for iPerl DN15 in data stream mode at 8 Hz
StreamType = StreamType.Flexible;
FrameLength = 42;
FrameFrequency = 8;
VolumeUnits = Common.Unit.l;
VolumeScaleFactor = 16000;
VolumeFieldStart = 17;
VolumeFieldEnd = 22;
VolumeFieldFormat = FieldFormat.HexadecimalWindow;
TimeUnits = Common.Unit.s;
TimeScaleFactor = 8192;
TimeFieldStart = 29;
TimeFieldEnd = 36;
TimeFieldFormat = FieldFormat.HexadecimalWindow;
}
string[] paramNames = new string[]
{
"Stream type",
"Frame Length",
"Frame Frequency",
"Volume Units",
"Volume Scale Factor",
"Volume Field Start",
"Volume Field End",
"Volume Field Format",
"Time Units",
"Time Scale Factor",
"Time Field Start",
"Time Field End",
"Time Field Format",
};
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 StreamType.ToString();
case 1: return FrameLength.ToString();
case 2: return FrameFrequency.ToString();
case 3: return VolumeUnits.ToDescription();
case 4: return VolumeScaleFactor.ToString();
case 5: return VolumeFieldStart.ToString();
case 6: return VolumeFieldEnd.ToString();
case 7: return VolumeFieldFormat.ToString();
case 8: return TimeUnits.ToDescription();
case 9: return TimeScaleFactor.ToString();
case 10: return TimeFieldStart.ToString();
case 11: return TimeFieldEnd.ToString();
case 12: return TimeFieldFormat.ToString();
default: return string.Empty;
}
}
/// Retrieves parameters from UI controls
public CfgUpdateFlags UpdateParam(int i, string strValue)
{
switch (i)
{
case 0:
for (StreamType st = 0; st < StreamType.Count; st++)
{
if (st.ToString().Equals(strValue)) { StreamType = st; return CfgUpdateFlags.None; }
}
break;
case 1: FrameLength = int.Parse(strValue); return CfgUpdateFlags.None;
case 2: FrameFrequency = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 3:
for (Unit u = 0; u < Unit.Count; u++)
{
if (Units.IsQuantity(u, Quantity.Volume) && u.ToDescription().Equals(strValue))
{
VolumeUnits = u;
return CfgUpdateFlags.None;
}
}
break;
case 4: VolumeScaleFactor = Utils.ParseSDouble(strValue); return CfgUpdateFlags.None;
case 5: VolumeFieldStart = int.Parse(strValue); return CfgUpdateFlags.None;
case 6: VolumeFieldEnd = int.Parse(strValue); return CfgUpdateFlags.None;
case 7:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) { VolumeFieldFormat = ff; return CfgUpdateFlags.None; }
}
break;
case 8:
for (Unit u = 0; u < Unit.Count; u++)
{
if (Units.IsQuantity(u, Quantity.Time) && u.ToDescription().Equals(strValue))
{
TimeUnits = u;
return CfgUpdateFlags.None;
}
}
break;
case 9: TimeScaleFactor = Utils.ParseSDouble(strValue); return CfgUpdateFlags.None;
case 10: TimeFieldStart = int.Parse(strValue); return CfgUpdateFlags.None;
case 11: TimeFieldEnd = int.Parse(strValue); return CfgUpdateFlags.None;
case 12:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) { TimeFieldFormat = ff; return CfgUpdateFlags.None; }
}
break;
default: return CfgUpdateFlags.None;
}
return CfgUpdateFlags.None;
}
/// Verifies whether strings in UI controls represent valid parameters
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
int iDummy;
double fDummy;
switch (i)
{
case 0:
for (StreamType st = 0; st < StreamType.Count; st++)
{
if (st.ToString().Equals(strValue)) return true;
}
break;
case 1:
if (int.TryParse(strValue, out iDummy) && iDummy >= 0 && iDummy <= 8000) return true;
break;
case 2:
if (Utils.TryParseUDouble(strValue, out fDummy) && fDummy <= 1000.0f) return true;
break;
case 3:
for (Unit u = 0; u < Unit.Count; u++)
{
if (Units.IsQuantity(u, Quantity.Volume) && u.ToDescription().Equals(strValue))
{
return true;
}
}
break;
case 4: return Utils.TryParseSDouble(strValue, out fDummy);
case 5: return (int.TryParse(strValue, out iDummy) && (iDummy >= -1));
case 6: return (int.TryParse(strValue, out iDummy) && (iDummy >= 0));
case 7:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) return true;
}
break;
case 8:
for (Unit u = 0; u < Unit.Count; u++)
{
if (Units.IsQuantity(u, Quantity.Time) && u.ToDescription().Equals(strValue))
{
return true;
}
}
break;
case 9: return Utils.TryParseSDouble(strValue, out fDummy);
case 10: return (int.TryParse(strValue, out iDummy) && (iDummy >= -1));
case 11: return (int.TryParse(strValue, out iDummy) && (iDummy >= 0));
case 12:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) return true;
}
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(PoseidonProcParams prms)
{
prms.StreamType = this.StreamType;
prms.FrameLength = this.FrameLength;
prms.FrameFrequency = this.FrameFrequency;
prms.VolumeUnits = this.VolumeUnits;
prms.VolumeScaleFactor = this.VolumeScaleFactor;
prms.VolumeFieldStart = this.VolumeFieldStart;
prms.VolumeFieldEnd = this.VolumeFieldEnd;
prms.VolumeFieldFormat = this.VolumeFieldFormat;
prms.TimeUnits = this.TimeUnits;
prms.TimeScaleFactor = this.TimeScaleFactor;
prms.TimeFieldStart = this.TimeFieldStart;
prms.TimeFieldEnd = this.TimeFieldEnd;
prms.TimeFieldFormat = this.TimeFieldFormat;
}
public IParamsProvider Clone()
{
PoseidonProcParams pars = new PoseidonProcParams();
CopyContentTo(pars);
return pars;
}
public override void UpdateFromDbEntity(ComponentProcedure dbEntity)
{
if (dbEntity == null) return;
try
{
PoseidonProcParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as PoseidonProcParams;
procedureParamsEntity = dbEntity;
componentName = dbEntity.CmpntName;
procedure = dbEntity.Procedure;
if (tmp != null) tmp.CopyContentTo(this);
}
catch
{
}
}
public PoseidonProcParams()
{
}
public PoseidonProcParams(bool initialize)
{
if (initialize) InitializeAll();
}
public PoseidonProcParams(ComponentProcedure procedureParamsEntity, string componentName, Procedure procedure)
{
this.procedureParamsEntity = procedureParamsEntity;
this.componentName = componentName;
this.procedure = procedure;
}
}
}

View File

@ -0,0 +1,451 @@
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Windows.Forms;
using log4net;
using Common;
using NHibernate.Util;
using SharedDatabase.Entities;
using TBF.Boxes;
using TBF.Rig.Generic;
using TBF.Rig.GenericDevices;
using TBF.Rig.RegisterReaders.SerialStream;
using TBF.Rig.RegisterReaders.StandingStartStop;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(PoseidonReader));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly PoseidonCfg registerReaderCfg;
readonly ControlBoard.IControlBoard controlBoard;
private bool activeHandlerSessioEnabled = false;
private CliRunner _cliRunner;
public enum CurrentPoseidonOp
{
None,
SendStartDataStream,
SendStartDataStream_Runing,
SendStartDataStream_Done,
ReadDataStream_Start,
ReadDataStream_End,
ReadDatastream_Running,
ReadDatastream_Done,
Done,
Error,
}
CurrentPoseidonOp _currentOp;
private bool _isReadingStart = true;
public CurrentPoseidonOp CurrentOp
{
get { return _currentOp; }
}
public void SetCurrentOp(CurrentPoseidonOp operation = CurrentPoseidonOp.None)
{
_currentOp = operation ;
}
public int Position
{
get
{
int firstDigitPos = Name.IndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' });
int position;
return (firstDigitPos < 0) ? 0 : (int.TryParse(Name.Substring(firstDigitPos), out position) ? position : 0);
}
}
public RegisterReaderType RegisterReaderType { get { return RegisterReaderType.DataStream; } }
public double PulsesPerLtr { get { return 1000.0; } }
public double LtrsPerPulse { get { return 1 / PulsesPerLtr; } }
///
/// Wrappers for procedure parameters
///
public StreamType StreamType { get { return (registerReaderCfg.ProcParams != null) ?registerReaderCfg.ProcParams.StreamType : StreamType.None; } }
public int FrameLength { get { return (registerReaderCfg.ProcParams != null) ?registerReaderCfg.ProcParams.FrameLength : 0; } }
public double FrameFrequency { get { return (registerReaderCfg.ProcParams != null) ?registerReaderCfg.ProcParams.FrameFrequency : 0; } }
public Common.Unit VolumeUnits { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.VolumeUnits : Common.Unit.l; } }
public double VolumeScaleFactor { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.VolumeScaleFactor : 1; } }
public int VolumeFieldStart { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.VolumeFieldStart : 0; } }
public int VolumeFieldEnd { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.VolumeFieldEnd : 0; } }
public FieldFormat VolumeFieldFormat { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.VolumeFieldFormat : FieldFormat.None; } }
public Common.Unit TimeUnits { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.TimeUnits : Common.Unit.s; } }
public double TimeScaleFactor { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.TimeScaleFactor : 1; } }
public int TimeFieldStart { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.TimeFieldStart : 0; } }
public int TimeFieldEnd { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.TimeFieldEnd : 0; } }
public FieldFormat TimeFieldFormat { get { return (registerReaderCfg.ProcParams != null) ? registerReaderCfg.ProcParams.TimeFieldFormat : FieldFormat.None; } }
public bool CommFailed
{
get { return commFailed; }
set { commFailed = value; }
}
bool commFailed;
/// <summary>
/// Passed to OptoTelegramRaw.UpdateFromString(...)
/// </summary>
Int64 volumeRawExtLast;
Int64 timestampExtLast;
///
/// Required for IRegisterReader interface
///
public int WMPulses { get { return wmPulses; } }
public int WMRefPulses { get { return wmRefPulses; } }
public double WMVolume { get { return wmVolume; } }
public double BeginWMState { get { return beginWMState; } }
public double EndWMState { get { return endWMState; } }
public double WMTestTime { get { return wmTestTime; } }
double beginWMState;
double endWMState;
double wmVolume;
int wmPulses;
int wmRefPulses;
double wmTestTime;
public IOperation ReadDatastreamOp()
{
return this;
}
/// <summary>
/// Store/update values to be used as a part of the opto-data log file name.
/// Stop data stream processing and saving, if it is enabled.
/// </summary>
/// <param name="test">Currently executed test</param>
/// <param name="repetitionNr">Currently executed repetition number</param>
public void TestIsGoingToStartSoon(Config.Entities.Test test, int repetitionNr)
{
/// Store/update values to be used as a part of the opto-data log file name
testName = test.Name;
testRepeats = test.Repeats;
this.repetitionNr = repetitionNr;
}
///
string testName;
int testRepeats;
int repetitionNr;
///
/// Volume of water from the opto telegram
///
private Int64 lastVolumeRaw; /// Last read raw volume
private double volumeLtr; ///
private double volumeLtr0;
public double VolumeLtrStart { get { return volumeLtrStart; } } /// Test start volume for metrology
public double VolumeLtrEnd { get { return volumeLtrEnd; } } /// Test end volume for metrology
double volumeLtrStart; /// Test start volume for metrology
double volumeLtrEnd; /// Test end volume for metrology
double volumeLtrEnd1; /// auxiliary buffer1 to keep the end volume before test stops
double volumeLtrEnd2; /// auxiliary buffer2 to keep the end volume before test stops
double volumeLtrEnd3; /// auxiliary buffer3 to keep the end volume before test stops
///
/// Timestamp from the opto telegram
///
bool lastTimestampValid;
private Int64 lastTimestamp;
private double timestampSec;
private double timestampSec0;
public bool NoSamples { get { return (timestampSecEnd - timestampSecStart) < float.Epsilon; } }
public double TimestampSecStart { get { return timestampSecStart; } }
public double TimestampSecEnd { get { return timestampSecEnd; } }
double timestampSecStart;
double timestampSecEnd;
double timestampSecEnd1;
double timestampSecEnd2;
double timestampSecEnd3;
private int frameIx;
public int TestStartFrameIx;
public int TestEndFrameIx;
DatastreamFrame[] datastreamFrames;
const int MaxDatastreamFramesCount = 80000; /// almost 3h at 8 Hz
int datastreamFramesCount;
string datastreamLogFileName;
DatastreamFrame toBeFlushed;
int flushedFramesCount;
public int FlushedFramesCount
{
get { return flushedFramesCount; }
set { flushedFramesCount = lastFlushedFramesCount = lastFlushedFramesCount_1 = value; }
}
int lastFlushedFramesCount_1;
int lastFlushedFramesCount;
public int FlushedFramesDelta
{
get
{
int retval = Math.Max(flushedFramesCount - lastFlushedFramesCount, lastFlushedFramesCount - lastFlushedFramesCount_1);
lastFlushedFramesCount_1 = lastFlushedFramesCount;
lastFlushedFramesCount = flushedFramesCount;
return retval;
}
}
///
/// Opto serial port and worker thread related private variables
///
private SerialPortData serialPort; /// Used in DebugMode.Normal
private TextReader textReader; /// Used instead of serialPort in DebugMode.Simulate
public PoseidonReader() { }
public PoseidonReader(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
registerReaderCfg = cfg as PoseidonCfg;
/// Control board is used to read reference flowmeter pulses
// controlBoard = TbfComponents.FindComponent(cfg.ParentName, components) as ControlBoard.IControlBoard;
// if (controlBoard == null) throw new Exception("Cannot find " + Name + " parent");
//
// log.Warn(this.ToString());
}
public override void Initialize()
{
Clear();
//log.WarnFormat("Initialize() ... FrameFormat set to {0}");
/// Allocate memory for opto-data from iPerl
datastreamFrames = new DatastreamFrame[MaxDatastreamFramesCount];
for (int i = 0; i < MaxDatastreamFramesCount; i++) datastreamFrames[i] = new DatastreamFrame();
toBeFlushed = new DatastreamFrame();
flushedFramesCount = 0;
activeHandlerSessioEnabled = false;
if (DebugLevel == DebugMode.Normal)
{
/// Prepare serial port
serialPort = new SerialPortData(string.Format("COM{0}", registerReaderCfg.ComPortNr),
registerReaderCfg.CliFileName,
registerReaderCfg.MeterType);
//TODO BUMI prepare serial port - for us do nothing
//serialPort.Open();
//we can check file program if exists
if (!File.Exists(serialPort.SerialPortCmdClientPath))
{
log.FatalFormat("Serial port CLI {0} does not exist!", serialPort.SerialPortCmdClientPath);
return;
}
log.FatalFormat("{0} initialized: {1}", Name, this);
}
else if (DebugLevel == DebugMode.Simulate)
{
}
else
{
serialPort = null;
log.FatalFormat("{0} in other mode: {1}", Name, this);
}
}
public void Clear()
{
log.DebugFormat("{0}:Clear()", Name);
beginWMState = 0;
endWMState = 0;
wmRefPulses = 0;
}
private void ReadPulses()
{
wmRefPulses = controlBoard.RefPulses;
}
/// <summary>Start this operation</summary>
public void Start()
{
//TODO BUMI start CLI serial port
_cliRunner = new CliRunner();
}
/// <summary>Run this operation</summary>
/// <returns>eventDone</returns>
public Event Run()
{
if (_currentOp == CurrentPoseidonOp.SendStartDataStream)
{
_cliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
return Event.Busy;
}
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Runing)
{
if (_cliRunner.AreTasksDone()
|| _cliRunner.TimeOutReceived(5000))
{
_currentOp = CurrentPoseidonOp.SendStartDataStream_Done;
}
return Event.Busy;
}
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Done)
{
_currentOp = CurrentPoseidonOp.Done;
return Event.Done;
}
else if (_currentOp == CurrentPoseidonOp.ReadDataStream_Start
|| _currentOp == CurrentPoseidonOp.ReadDataStream_End)
{
_isReadingStart = (_currentOp == CurrentPoseidonOp.ReadDataStream_Start);
_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))
{
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
}
return Event.Busy;
}
else if (_currentOp == CurrentPoseidonOp.ReadDatastream_Done)
{
JsonDataFromPoseidon data = null;
var first = _cliRunner.TaskPool.FindLast(t => t is Task<JsonDataFromPoseidon>);
if (first != null && first is Task<JsonDataFromPoseidon>)
{
data = (first as Task<JsonDataFromPoseidon>).Result;
if (Double.TryParse(data.Reading, out double Volume))
{
double VolumeLi = Units.ConvertFrom(Unit.USgal, Volume);
double VolumeM3 = Units.ConvertTo(Unit.m3, VolumeLi);
if (_isReadingStart)
{
//volume
beginWMState = VolumeM3;
}
else
{
//volume
endWMState = VolumeM3;
}
}
}
_currentOp = CurrentPoseidonOp.Done;
return Event.Done;
}
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
//TODO BUMI stop CLI serial port
}
public void RunDeviceBefore()
{
//Start CLI communication and set CLI inputs and get CLI data
//ValidateCliFileExistence(true);
}
private void ValidateCliFileExistence(bool showErrorIfMissing)
{
if (DebugLevel == DebugMode.Normal && serialPort != null)
{
if (!serialPort.CliExists)
{
log.ErrorFormat("CLI file {0} does not exist!", serialPort.SerialPortCmdClientPath);
if (showErrorIfMissing)
MessageBox.Show($"CLI file {serialPort.SerialPortCmdClientPath} does not exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
log.DebugFormat("CLI file {0} found", serialPort.SerialPortCmdClientPath);
}
}
public void RunDeviceAfter()
{
}
public void StopDevice()
{
try
{
if (DebugLevel == DebugMode.Normal && serialPort != null)
{
}
}
catch
{
}
}
public void StopDevice2()
{
}
public void StartSession()
{
ValidateCliFileExistence(false);
//TODO BUMI start session - CMD send data to Poseidon
_cliRunner = new CliRunner();
_cliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
//_cliRunner.StartAll();
}
public void SaveMark(object mark)
{
throw new NotImplementedException();
}
public void EndSession()
{
if (_cliRunner != null)
{
}
activeHandlerSessioEnabled = false;
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.IO;
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
{
public class SerialPortData
{
private Boolean? _cliExists;
public bool CliExists { get {
if (_cliExists == null || !_cliExists.HasValue)
{
_cliExists = File.Exists(SerialPortCmdClientPath);
}
return _cliExists.Value;
} }
public string SerialPortCmdClientPath {
get { return Path.Combine("..","Cli", CmdClientName);}
}
public string CmdClientName { get; set; } = "HalCli.exe";
public string PortName { get; set; }
public int MeterType { get; set; }
public enum EMeterArg {
Calibration = 0,
AllParams = 2,
DeviceId = 3,
}
EMeterArg _eMeterArg = EMeterArg.AllParams;
public string DefaultArgSettings(EMeterArg eMeterArg)
{
switch (eMeterArg)
{
case EMeterArg.Calibration:
return $"-p {PortName} -m {MeterType} --operation write --parameter Calibration --value 1";
case EMeterArg.AllParams:
return $"-p {PortName} -m {MeterType} --operation readall";
case EMeterArg.DeviceId:
return $"-p {PortName} -m {MeterType} --operation read --parameter DeviceId";
default:
return "";
}
}
public SerialPortData(
string portName,
string cmdClientName,
int meterType)
{
PortName = portName;
CmdClientName = cmdClientName;
MeterType = meterType;
}
}
}

View File

@ -32,6 +32,7 @@ namespace TBF.Rig
new DataEntry.HeatMeters6.Factory(),
new DataEntry.HeatMeters12.Factory(),
new DataEntry.iPerl.Factory(),
new DataEntry.PoseidonCmd.Factory(),
new DataEntry.S620.Factory(),
new DataEntry.Single.Factory(),
new DataEntry.Single.FactoryNoStartEnd(),
@ -129,6 +130,7 @@ namespace TBF.Rig
new TestMethods.iPerlCommunication.iPerlHead.Factory(), /// 'RegisterReader for iPerl'
new RegisterReaders.S640Stream.Factory(), /// 'RegisterReader for S640'
new RegisterReaders.SerialStream.Factory(), /// 'RegisterReader for generic serial stream'
new RegisterReaders.PoseidonCmdStartStop.Factory(), /// 'RegisterReader for poseidon start/stop'
new RegisterReaders.KPackE.RegisterReader.Factory(), /// KPackE register reader
new RegisterReaders.KPackE.Radio.Factory(), /// Radio for KPackE register readers
new Uni.RegValve.Factory(),

View File

@ -615,7 +615,9 @@ namespace TBF.Rig.TestMethods.StandingStart
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
}
while (cBrd.RefPulses < initialPulsesCount + totalPulses && !e.Contains(Event.TestCompleted) && !e.Contains(Event.Next));
while ((cBrd.DebugLevel==DebugMode.Simulate && !e.Contains(Event.FlowReached)) ||
(cBrd.DebugLevel!=DebugMode.Simulate && cBrd.RefPulses < initialPulsesCount + totalPulses && !e.Contains(Event.TestCompleted) && !e.Contains(Event.Next)));
/// Measurement loop end
log.WarnFormat("Start valve switch time on test start = {0} ms", cBrd.ValveOpenCloseTime);

View File

@ -339,6 +339,21 @@
<DependentUpon>TestStartEndForm.cs</DependentUpon>
</Compile>
<Compile Include="Rig\DataEntry\OcrVidi.cs" />
<Compile Include="Rig\DataEntry\PoseidonCmd\CycleBeginningForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Rig\DataEntry\PoseidonCmd\CycleBeginningForm.designer.cs">
<DependentUpon>CycleBeginningForm.cs</DependentUpon>
</Compile>
<Compile Include="Rig\DataEntry\PoseidonCmd\EntryForm.cs" />
<Compile Include="Rig\DataEntry\PoseidonCmd\EntryFormCfg.cs" />
<Compile Include="Rig\DataEntry\PoseidonCmd\Factory.cs" />
<Compile Include="Rig\DataEntry\PoseidonCmd\TestStartEndForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Rig\DataEntry\PoseidonCmd\TestStartEndForm.designer.cs">
<DependentUpon>TestStartEndForm.cs</DependentUpon>
</Compile>
<Compile Include="Rig\DataEntry\S620\BarcodeReceivedEventArgs.cs" />
<Compile Include="Rig\DataEntry\S620\BodySerNrResult.cs" />
<Compile Include="Rig\DataEntry\S620\CheckItems\Barcode.cs">
@ -626,6 +641,7 @@
<Compile Include="Rig\GenericDevices\IFlowMeterSingle.cs" />
<Compile Include="Rig\GenericDevices\IFTPAdapter.cs" />
<Compile Include="Rig\GenericDevices\IHasCalendarEvents.cs" />
<Compile Include="Rig\GenericDevices\IHasFromUNIDisablePossibility.cs" />
<Compile Include="Rig\GenericDevices\IParallelOutput.cs" />
<Compile Include="Rig\GenericDevices\IReceivesDataFromRadio.cs" />
<Compile Include="Rig\GenericDevices\IRegReaderPulses.cs" />
@ -1176,6 +1192,13 @@
<Compile Include="Rig\RegisterReaders\KPackE\RegisterReader\RRCfgCtrl.designer.cs">
<DependentUpon>RRCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunner.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\Factory.cs" />
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\JsonDataFromPoseidon.cs" />
<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\SerialPortData.cs" />
<Compile Include="Rig\RegisterReaders\PulsesFromUniCB\Factory.cs" />
<Compile Include="Rig\RegisterReaders\PulsesFromUniCB\RegisterReader.cs" />
<Compile Include="Rig\RegisterReaders\PulsesFromUniCB\RRCfg.cs" />
@ -2717,6 +2740,12 @@
<EmbeddedResource Include="Rig\DataEntry\iPerl\TestStartEndForm.resx">
<DependentUpon>TestStartEndForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\DataEntry\PoseidonCmd\CycleBeginningForm.resx">
<DependentUpon>CycleBeginningForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\DataEntry\PoseidonCmd\TestStartEndForm.resx">
<DependentUpon>TestStartEndForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rig\DataEntry\S620\CheckItems\Barcode.resx">
<DependentUpon>Barcode.cs</DependentUpon>
</EmbeddedResource>