Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5936c8f19 | ||
|
|
2842425673 | ||
|
|
06a401a1ff | ||
|
|
3a2fc50fec | ||
|
|
38a58ed8b7 | ||
|
|
c7cba20de0 | ||
|
|
6311df49c3 | ||
|
|
f1d32a39ba | ||
|
|
224b53f774 | ||
|
|
1e2777c5e7 | ||
|
|
c3c21649fb |
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.9.2149.0")]
|
||||
[assembly: AssemblyFileVersion("3.9.2149.0")]
|
||||
[assembly: AssemblyVersion("3.9.2149.4")]
|
||||
[assembly: AssemblyFileVersion("3.9.2149.4")]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Rig.Sequences;
|
||||
|
||||
@@ -11,6 +12,10 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(FlyingStartStopTestOp));
|
||||
public override string ToString() { return string.Format("FlyingStartStopTestOp()"); }
|
||||
|
||||
private DateTime startTimeForSimulation;
|
||||
private bool simulationTimerStarted = false;
|
||||
|
||||
|
||||
/// Arguments of the constructor
|
||||
readonly UniCB uniCB;
|
||||
@@ -123,6 +128,28 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
{
|
||||
log.DebugFormat("Op.Run() opState={0}", opState);
|
||||
|
||||
//Simulation of processing time 25 seconds
|
||||
if (uniCB.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
if (opState == OpState.StartingTest)
|
||||
{
|
||||
startTimeForSimulation = DateTime.Now;
|
||||
simulationTimerStarted = false;
|
||||
}
|
||||
if (opState == OpState.TestInProgress)
|
||||
{
|
||||
if (!simulationTimerStarted)
|
||||
{
|
||||
startTimeForSimulation = DateTime.Now;
|
||||
simulationTimerStarted = true;
|
||||
}
|
||||
else if (DateTime.Now - startTimeForSimulation > TimeSpan.FromSeconds(25))
|
||||
{
|
||||
return Event.TestCompleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (opState)
|
||||
{
|
||||
case OpState.StartingTest:
|
||||
|
||||
@@ -8,10 +8,9 @@ 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;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
@@ -220,6 +219,25 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
orderComboBox.Text = orderComboBox.Items[0].ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public void AutoClickOkAfterDelay(int delayMs = 10000)
|
||||
{
|
||||
_ = AutoClickInternal(okButton, delayMs);
|
||||
}
|
||||
|
||||
private async Task AutoClickInternal(Button clickButton, int delayMs)
|
||||
{
|
||||
await Task.Delay(delayMs);
|
||||
|
||||
if (clickButton.IsHandleCreated && clickButton.Enabled && clickButton.Visible)
|
||||
{
|
||||
// Invoke on UI thread
|
||||
if (clickButton.InvokeRequired)
|
||||
clickButton.BeginInvoke(new Action(() => clickButton.PerformClick()));
|
||||
else
|
||||
clickButton.PerformClick();
|
||||
}
|
||||
}
|
||||
|
||||
private void okButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
|
||||
CurrentOp currentOp;
|
||||
|
||||
public enum ReadDataOp
|
||||
{
|
||||
None,
|
||||
Start,
|
||||
Busy,
|
||||
Done,
|
||||
}
|
||||
ReadDataOp readDataOp;
|
||||
|
||||
|
||||
public EntryForm() { }
|
||||
|
||||
@@ -112,6 +121,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
|| currentOp == CurrentOp.SendStartDataStream)
|
||||
) throw new Exception("Sequence error");
|
||||
currentOp = CurrentOp.ReadDatastream_StartStates;
|
||||
readDataOp = ReadDataOp.None;
|
||||
//TODO BUMI apply show data in dialog if config required
|
||||
//entryFormCfg.Direction = Direction.S640;
|
||||
//currentOp = CurrentOp.EnterTestStartStates;
|
||||
@@ -122,10 +132,10 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (reader != null && reader is PoseidonReader)
|
||||
{
|
||||
PoseidonReader poseidonReader = (reader as PoseidonReader);
|
||||
if (!string.IsNullOrEmpty(poseidonReader.SerialNr)
|
||||
&& waterMeters.Count > iterator)
|
||||
if (waterMeters.Count > iterator)
|
||||
{
|
||||
waterMeters[iterator].SerialNr = poseidonReader.SerialNr;
|
||||
if(!string.IsNullOrEmpty(poseidonReader.SerialNr))
|
||||
waterMeters[iterator].SerialNr = poseidonReader.SerialNr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +145,17 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
|
||||
/// <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; }
|
||||
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)
|
||||
@@ -155,16 +174,17 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
///
|
||||
void OpenBeginningDlg(EntryForm myRef)
|
||||
{
|
||||
if (!ShowForm)
|
||||
if (ShowForm == 0)
|
||||
return;
|
||||
myRef.modelessDlg = new CycleBeginningForm(TBF.Data.WMsCount, myRef.entryFormCfg,
|
||||
ProcessData.SelectedProcedure.OrderInfo != null ? ProcessData.SelectedProcedure.OrderInfo.POName : string.Empty);
|
||||
(myRef.modelessDlg as CycleBeginningForm)?.AutoClickOkAfterDelay();
|
||||
modelessDlg.Show();
|
||||
}
|
||||
///
|
||||
void OpenTestStartStatesDlg(EntryForm myRef)
|
||||
{
|
||||
if (!ShowForm)
|
||||
if (ShowForm == 0)
|
||||
return;
|
||||
myRef.modelessDlg = new TestStartEndForm(myRef.waterMeters.Count, myRef.regReaders, disabled);
|
||||
modelessDlg.Show();
|
||||
@@ -172,7 +192,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
///
|
||||
void OpenTestEndStatesDlg(EntryForm myRef)
|
||||
{
|
||||
if (!ShowForm)
|
||||
if (ShowForm == 0)
|
||||
return;
|
||||
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, wmStartStateStr, disabled, refVolume, errLimLo, errLimHi);
|
||||
modelessDlg.Show();
|
||||
@@ -181,15 +201,19 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
if (!ShowForm)
|
||||
readDataOp = ReadDataOp.None;
|
||||
readAndSetDataToMeters = false;
|
||||
filedDataToMeters = false;
|
||||
|
||||
if (ShowForm == 0)
|
||||
return ;
|
||||
|
||||
resultSaved = false;
|
||||
switch (currentOp)
|
||||
{
|
||||
case CurrentOp.SendStartDataStream:
|
||||
ReadAndSetDataToMeters();
|
||||
if (ProcessData.SelectedProcedure.OrderInfo == null || entryFormCfg.Direction != Direction.S640)
|
||||
//ReadAndSetDataToMeters();
|
||||
if (ProcessData.SelectedProcedure.OrderInfo == null)
|
||||
{
|
||||
Program.MainWnd.Invoke(new EntryFormDlgt(OpenBeginningDlg), this);
|
||||
}
|
||||
@@ -209,28 +233,81 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
}
|
||||
|
||||
private bool readAndSetDataToMeters = false;
|
||||
private bool filedDataToMeters = false;
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsPrinted</returns>
|
||||
public Event Run()
|
||||
{
|
||||
ReadAndSetDataToMeters();
|
||||
if (!readAndSetDataToMeters) // run until not finished
|
||||
readAndSetDataToMeters = 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 (ShowForm == 0)
|
||||
if(readAndSetDataToMeters)
|
||||
return Event.ModelessFormClosed;
|
||||
else
|
||||
{
|
||||
return Event.ModelessFormIsOpen;
|
||||
}
|
||||
|
||||
if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed)
|
||||
if (readAndSetDataToMeters && !filedDataToMeters)
|
||||
{
|
||||
return Event.ModelessFormIsOpen;
|
||||
if (regReaders != null)
|
||||
{
|
||||
//add data into dialog
|
||||
int item = 0;
|
||||
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
|
||||
foreach (var iRegReader in regReaders)
|
||||
{
|
||||
if (iRegReader is PoseidonReader poseidonReader)
|
||||
{
|
||||
if (dlg != null)
|
||||
{
|
||||
if (currentOp == CurrentOp.ReadDatastream_StartStates)
|
||||
{
|
||||
dlg.WMStartState[item] = poseidonReader.BeginWMState;
|
||||
dlg.WMStartStateStr[item] = poseidonReader.BeginWMState.ToString();
|
||||
}
|
||||
|
||||
if (currentOp == CurrentOp.ReadDatastream_EndStates)
|
||||
dlg.WMEndState[item] = poseidonReader.EndWMState;
|
||||
}
|
||||
}
|
||||
|
||||
item++;
|
||||
}
|
||||
|
||||
if (dlg != null)
|
||||
{
|
||||
if (dlg.InvokeRequired)
|
||||
{
|
||||
dlg.BeginInvoke(new Action(() =>
|
||||
{
|
||||
dlg.UpdateValues(currentOp == CurrentOp.ReadDatastream_StartStates, true);
|
||||
if (entryFormCfg.ShowDialogType == ShowDialogType.ContinueAutomatically)
|
||||
{
|
||||
dlg.AutoClickOkAfterDelay();
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
dlg.UpdateValues(currentOp == CurrentOp.ReadDatastream_StartStates, true);
|
||||
if (entryFormCfg.ShowDialogType == ShowDialogType.ContinueAutomatically)
|
||||
{
|
||||
dlg.AutoClickOkAfterDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
filedDataToMeters = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed)
|
||||
{
|
||||
return Event.ModelessFormIsOpen; //ModelessFormClosed ??
|
||||
}
|
||||
|
||||
if (!resultSaved) /// This is to save the result only once
|
||||
@@ -290,11 +367,13 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
modelessDlg = null;
|
||||
}
|
||||
currentOp = CurrentOp.None;
|
||||
readAndSetDataToMeters = false;
|
||||
filedDataToMeters = false;
|
||||
}
|
||||
|
||||
public bool ShowForm
|
||||
public int ShowForm
|
||||
{
|
||||
get { return entryFormCfg == null ? false : entryFormCfg.ShowDialog; }
|
||||
get { return entryFormCfg == null ? ShowDialogType.Hide.GetHashCode() : entryFormCfg.ShowDialogType.GetHashCode(); }
|
||||
set {} // only for read - svia dilalog
|
||||
}
|
||||
|
||||
@@ -303,13 +382,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
get { return entryFormCfg == null ? false : entryFormCfg.SaveCommunication;}
|
||||
}
|
||||
|
||||
//private long GetMaxtime()
|
||||
|
||||
public bool ReadAndSetDataToMeters()
|
||||
{
|
||||
bool bOperationSuccess = false;
|
||||
if (currentOp == CurrentOp.SendStartDataStream)
|
||||
{
|
||||
bool finishedReading = regReaders == null; // we can work only with register readers
|
||||
while (!finishedReading)
|
||||
while (!finishedReading) //TODO BUMI lock - fuck ?
|
||||
{
|
||||
bool bAllReadersFinished = true;
|
||||
foreach (var iRegReader in regReaders )
|
||||
@@ -326,6 +407,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
/// Send start data stream
|
||||
poseidonReader.Run();
|
||||
readDataOp = ReadDataOp.Start;
|
||||
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done
|
||||
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error))
|
||||
{
|
||||
@@ -337,10 +419,11 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (bAllReadersFinished)
|
||||
{
|
||||
finishedReading = true;
|
||||
readDataOp = ReadDataOp.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +433,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
|| (currentOp == CurrentOp.ReadDatastream_EndStates))
|
||||
{
|
||||
bool finishedReading = regReaders == null; // we can work only with register readers
|
||||
while (!finishedReading)
|
||||
while (!finishedReading) //TODO BUMI lock - fuck ?
|
||||
{
|
||||
bool bAllReadersFinished = true;
|
||||
foreach (var iRegReader in regReaders )
|
||||
@@ -383,7 +466,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
@@ -52,6 +53,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ShowDialogType
|
||||
{
|
||||
[Description("Do not Show")] Hide,
|
||||
[Description("Continue Automatically")] ContinueAutomatically,
|
||||
[Description("Continue Manually")] ContinueManually,
|
||||
Count,
|
||||
|
||||
}
|
||||
|
||||
public class EntryFormCfg : ComponentCfgBase, IComponentCfg, IParamsProvider
|
||||
{
|
||||
@@ -69,6 +79,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
public Direction Direction;
|
||||
public Orders Orders;
|
||||
public bool ShowDialog;
|
||||
public ShowDialogType ShowDialogType;
|
||||
public bool SaveCommunication;
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
@@ -89,7 +100,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
Direction = Direction.Forward_RL;
|
||||
Orders = Orders.Arbitrary;
|
||||
ShowDialog = false;
|
||||
ShowDialogType = ShowDialogType.Hide;
|
||||
SaveCommunication = false;
|
||||
}
|
||||
|
||||
@@ -115,8 +126,9 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
for (Orders o = 0; o < Orders.Count; o++) list.Add(o.ToDescription());
|
||||
return list;
|
||||
case 2:
|
||||
list.Add("True");
|
||||
list.Add("False");
|
||||
list.Add(ShowDialogType.Hide.ToDescription());
|
||||
list.Add(ShowDialogType.ContinueAutomatically.ToDescription());
|
||||
list.Add(ShowDialogType.ContinueManually.ToDescription());
|
||||
return list;
|
||||
case 3:
|
||||
list.Add("True");
|
||||
@@ -126,6 +138,19 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryFromInt<TEnum>(int value, out TEnum result)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
if (Enum.IsDefined(typeof(TEnum), value))
|
||||
{
|
||||
result = (TEnum)(object)value;
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public string ToString(int i)
|
||||
@@ -134,10 +159,10 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
case 0: return Direction.ToDescription();
|
||||
case 1: return Orders.ToDescription();
|
||||
case 2: return ShowDialog.ToString();
|
||||
case 2: return ShowDialogType.ToDescription();
|
||||
case 3: return SaveCommunication.ToString();
|
||||
default:
|
||||
return string.Format("Name={0}, Direction={1}, Orders={2}, ShowDialog={3}, StoreCommunication={4}", Name, Direction, Orders, ShowDialog, SaveCommunication);
|
||||
return string.Format("Name={0}, Direction={1}, Orders={2}, ShowDialog={3}, StoreCommunication={4}", Name, Direction, Orders, ShowDialogType, SaveCommunication);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,11 +189,14 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
bool lastSetting = ShowDialog;
|
||||
if (str == "True") ShowDialog = true;
|
||||
else ShowDialog = false;
|
||||
if (lastSetting != ShowDialog)
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
ShowDialogType lastSetting = ShowDialogType;
|
||||
for (ShowDialogType s = 0; s < ShowDialogType.Count; s++)
|
||||
if (s.ToDescription() == str)
|
||||
{
|
||||
ShowDialogType = s;
|
||||
if (lastSetting != ShowDialogType)
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -196,6 +224,11 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (ParamValues(i).Contains(str)) return true;
|
||||
break;
|
||||
case 2:
|
||||
bool exists = Enum.GetValues(typeof(ShowDialogType))
|
||||
.Cast<ShowDialogType>()
|
||||
.Any(d => d.ToDescription() == str);
|
||||
if (exists) return true;
|
||||
break;
|
||||
case 3:
|
||||
if (str == "True" || str == "False") return true;
|
||||
break;
|
||||
@@ -212,7 +245,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
prms.Direction = this.Direction;
|
||||
prms.Orders = this.Orders;
|
||||
prms.ShowDialog = this.ShowDialog;
|
||||
prms.ShowDialogType = this.ShowDialogType;
|
||||
prms.SaveCommunication = this.SaveCommunication;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.Rig.GenericDevices;
|
||||
@@ -99,9 +100,12 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
this.disabled = disabled;
|
||||
|
||||
ShuffleTextBoxes();
|
||||
ResizeDlgToFitEnabledControls();
|
||||
|
||||
WMStartState = new double[waterMetersCount];
|
||||
WMStartStateStr = new string[waterMetersCount];
|
||||
|
||||
SetUiBusy(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -130,8 +134,41 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
this.warningLimHi = 2 * errLimHi;
|
||||
|
||||
ShuffleTextBoxes();
|
||||
ResizeDlgToFitEnabledControls();
|
||||
|
||||
|
||||
WMEndState = new double[waterMetersCount];
|
||||
|
||||
SetUiBusy(true);
|
||||
}
|
||||
|
||||
private void SetUiBusy(bool busy, long deltaTime = -1)
|
||||
{
|
||||
// show wait cursor for form and children
|
||||
this.UseWaitCursor = busy;
|
||||
|
||||
// block editing textboxes
|
||||
for (int i = 0; i < enabledTextBoxes.Count; i++)
|
||||
{
|
||||
enabledTextBoxes[i].Enabled = !busy;
|
||||
}
|
||||
|
||||
// disable buttons while busy
|
||||
if (okButton != null) okButton.Enabled = !busy;
|
||||
|
||||
|
||||
// show/hide "loading..." label
|
||||
if (loadingLabel != null)
|
||||
{
|
||||
loadingLabel.Visible = busy;
|
||||
loadingLabel.Text = "Loading...";
|
||||
if (deltaTime > 0)
|
||||
{
|
||||
//show delta time in label
|
||||
loadingLabel.Visible = true;
|
||||
loadingLabel.Text = string.Format("Get: {0} s", deltaTime/1000.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -159,6 +196,43 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
TextBoxesCount = TBF.Data.WMsCount;
|
||||
}
|
||||
}
|
||||
|
||||
void ResizeDlgToFitEnabledControls()
|
||||
{
|
||||
int xMax = 0;
|
||||
int yMax = 0;
|
||||
GetMaxDimensions(startTextBoxes,WaterMetersCount,ref xMax, ref yMax);
|
||||
GetMaxDimensions(endTextBoxes,WaterMetersCount, ref xMax, ref yMax);
|
||||
|
||||
int shapeGap = 50;
|
||||
okButton.Left = xMax + shapeGap;
|
||||
xMax = okButton.Left + okButton.Width;
|
||||
|
||||
Width = xMax + shapeGap;
|
||||
Height = yMax + shapeGap;
|
||||
}
|
||||
|
||||
private void GetMaxDimensions(TextBox[] textBoxes, int waterMetersCount, ref int xMax, ref int yMax)
|
||||
{
|
||||
for (int i = 0; i < waterMetersCount; i++)
|
||||
{
|
||||
if (textBoxes[i].Left + textBoxes[i].Width > xMax)
|
||||
xMax = textBoxes[i].Left + textBoxes[i].Width;
|
||||
if (textBoxes[i].Top + textBoxes[i].Height > yMax)
|
||||
yMax = textBoxes[i].Top + textBoxes[i].Height;
|
||||
}
|
||||
}
|
||||
|
||||
// private void GetMaxDimensions(TextBox[] textBoxes, ref int xMax, ref int yMax)
|
||||
// {
|
||||
// for (int i = 0; i < textBoxes.Length; i++)
|
||||
// {
|
||||
// if(!textBoxes[i].Visible)
|
||||
// continue;
|
||||
// if (textBoxes[i].Left + textBoxes[i].Width > xMax) xMax = textBoxes[i].Left + textBoxes[i].Width;
|
||||
// if (textBoxes[i].Top + textBoxes[i].Height > yMax) yMax = textBoxes[i].Top + textBoxes[i].Height;
|
||||
// }
|
||||
// }
|
||||
|
||||
private void CycleEndForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
@@ -211,6 +285,43 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateValues(bool stratValue = true, bool enableEdit = false, long deltaTime = -1)
|
||||
{
|
||||
// Ensure we are on the UI thread
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => UpdateValues(stratValue, enableEdit)));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < TextBoxesCount; i++)
|
||||
{
|
||||
if (stratValue)
|
||||
{
|
||||
if (WMStartStateStr != null && i < WMStartStateStr.Length)
|
||||
{
|
||||
startTextBoxes[i].Text = WMStartStateStr[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// small bugfix: check WMEndState, not WMStartStateStr
|
||||
if ((WMEndState != null && i < WMEndState.Length) &&
|
||||
(WMStartStateStr != null && i < WMStartStateStr.Length && WMStartStateStr[i] != ""))
|
||||
{
|
||||
endTextBoxes[i].Text = WMEndState[i].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enableEdit)
|
||||
{
|
||||
SetUiBusy(false, deltaTime);
|
||||
}
|
||||
// if you also need to enable/disable editing, do it here,
|
||||
// it's now safely on the UI thread.
|
||||
}
|
||||
|
||||
void Localize()
|
||||
{
|
||||
Text = Strings.Water_Meter_States;
|
||||
@@ -258,6 +369,26 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
completed = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
public void AutoClickOkAfterDelay(int delayMs = 10000)
|
||||
{
|
||||
_ = AutoClickInternal(okButton, delayMs);
|
||||
}
|
||||
|
||||
private async Task AutoClickInternal(Button okButton, int delayMs)
|
||||
{
|
||||
await Task.Delay(delayMs);
|
||||
|
||||
if (okButton.IsHandleCreated && okButton.Enabled && okButton.Visible)
|
||||
{
|
||||
// Invoke on UI thread
|
||||
if (okButton.InvokeRequired)
|
||||
okButton.BeginInvoke(new Action(() => okButton.PerformClick()));
|
||||
else
|
||||
okButton.PerformClick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Forced close handling
|
||||
|
||||
|
||||
+610
-397
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
public partial class CycleBeginningForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(CycleBeginningForm));
|
||||
private static readonly ILog log_selected = LogManager.GetLogger("PurchaseOrderHistory");
|
||||
|
||||
/// <summary> Number of water meters </summary>
|
||||
public readonly int WaterMetersCount;
|
||||
@@ -264,6 +265,11 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
Disabled[i] = !checkBoxes[i].Checked;
|
||||
}
|
||||
|
||||
//TODO create logger to log selected items and their order and Order number
|
||||
string snTextArrString = SNText != null ? string.Join(", ", SNText) : string.Empty;
|
||||
log_selected.DebugFormat("Purchase DLG - Selected Order: {0}, Last selected Box: {1}, All items: {2}",
|
||||
orderComboBox.Text, purchaseBoxComboBox.Text,snTextArrString);
|
||||
|
||||
completed = true;
|
||||
Close();
|
||||
}
|
||||
@@ -718,6 +724,17 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
.SelectMany(pBox => pBox.PurchaseWaterMeterDataList)
|
||||
.Select(pWM => pWM.SerialNo);
|
||||
|
||||
try
|
||||
{
|
||||
string[] iEnumerable = serialNumbers as string[] ?? serialNumbers.ToArray();
|
||||
log_selected.Debug(
|
||||
$"Selected order: {choosenOrder} box: {choosenBox} possible serial numbers (form DB): {string.Join(", ", iEnumerable)}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log_selected.Error("Error loading serial numbers: " + e);
|
||||
}
|
||||
|
||||
//enable behaviour type
|
||||
bool addOnEndOnly = false;
|
||||
|
||||
@@ -726,6 +743,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
|
||||
if (countOfFreeBoxes < serialNumbers.Count())
|
||||
{
|
||||
log_selected.Debug(">" + serialNumbers.Count() + " Serial Numbers in box as we have free positions!");
|
||||
MessageBox.Show(this, "We have more Serial Numbers in box as we have free positions!", "Warning",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
@@ -753,6 +771,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
if (lastComboBoxSerialNo >= 0 || lastComboBoxSerialNo < enabledComboBoxes.Count)
|
||||
{
|
||||
comboBoxes[lastComboBoxSerialNo].Text = serialNumber;
|
||||
log_selected.Debug($"Added serial no: {serialNumber} to pos: {lastComboBoxSerialNo}");
|
||||
lastComboBoxSerialNo++;
|
||||
}
|
||||
}
|
||||
@@ -762,6 +781,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
if (iNextFreeNumber >= 0 || iNextFreeNumber < enabledComboBoxes.Count)
|
||||
{
|
||||
comboBoxes[iNextFreeNumber].Text = serialNumber;
|
||||
log_selected.Debug($"Added serial no: {serialNumber} to pos: {iNextFreeNumber}");
|
||||
lastComboBoxSerialNo = iNextFreeNumber;
|
||||
}
|
||||
}
|
||||
@@ -774,6 +794,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
|
||||
if (!noImplementedSerialNumbers.IsEmpty())
|
||||
{
|
||||
log_selected.Debug("No implemented serial numbers: " + noImplementedSerialNumbers);
|
||||
MessageBox.Show(this,
|
||||
string.Format("The following serial numbers were not implemented: {0}", noImplementedSerialNumbers),
|
||||
"Serial Numbers repeating!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
|
||||
@@ -2,7 +2,10 @@ namespace TBF.Rig.GenericDevices
|
||||
{
|
||||
public interface IHasFromUNIDisablePossibility
|
||||
{
|
||||
bool ShowForm { get; set; }
|
||||
/// <summary>
|
||||
/// 0 - disabled, > 1 - enabled but can have variable uses how form is shown
|
||||
/// </summary>
|
||||
int ShowForm { get; set; }
|
||||
|
||||
bool ReadAndSetDataToMeters();
|
||||
}
|
||||
|
||||
@@ -3,16 +3,42 @@
|
||||
///
|
||||
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public class OptoReceivedEventArgs : EventArgs
|
||||
{
|
||||
public string Data;
|
||||
public WaterMetrologyData WaterMetrologyData;
|
||||
public byte[] RawData;
|
||||
|
||||
public OptoReceivedEventArgs(string data)
|
||||
{
|
||||
this.Data = data;
|
||||
WaterMetrologyData = null;
|
||||
RawData = null;
|
||||
}
|
||||
|
||||
public OptoReceivedEventArgs(string data, WaterMetrologyData waterMetrologyData)
|
||||
{
|
||||
this.Data = data;
|
||||
this.WaterMetrologyData = waterMetrologyData;
|
||||
RawData = null;
|
||||
}
|
||||
|
||||
public OptoReceivedEventArgs(byte[] data)
|
||||
{
|
||||
this.RawData = data;
|
||||
Data = null;
|
||||
WaterMetrologyData = null;
|
||||
}
|
||||
|
||||
public OptoReceivedEventArgs(WaterMetrologyData data)
|
||||
{
|
||||
WaterMetrologyData = data;
|
||||
Data = null;
|
||||
RawData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,15 +506,9 @@ namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
get { return wmVolume; }
|
||||
}
|
||||
|
||||
public double BeginWMState
|
||||
{
|
||||
get { return beginWMState; }
|
||||
}
|
||||
public double BeginWMState { get { return beginWMState; } set { beginWMState = value; } }
|
||||
|
||||
public double EndWMState
|
||||
{
|
||||
get { return endWMState; }
|
||||
}
|
||||
public double EndWMState { get { return endWMState; } set { endWMState = value; } }
|
||||
|
||||
public IOperation ReadDatastreamOp()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
private readonly ILog log;
|
||||
private List<Task> taskPool = new List<Task>();
|
||||
private long startTime;
|
||||
private long incommingTime;
|
||||
|
||||
public List<Task> TaskPool { get { return taskPool; } }
|
||||
public void AddTask(Task task) { taskPool.Add(task); }
|
||||
@@ -39,6 +40,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
get => startTime;
|
||||
}
|
||||
|
||||
public long IncommingTime
|
||||
{
|
||||
get => incommingTime;
|
||||
}
|
||||
|
||||
public bool TimeOutReceived(long timeout)
|
||||
{
|
||||
return (DateTime.Now.Ticks - startTime) > timeout;
|
||||
@@ -121,6 +127,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
throw;
|
||||
}
|
||||
|
||||
//comming answer from serial port - good place for time stamp
|
||||
incommingTime = DateTime.Now.Ticks;
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
return allOutput;
|
||||
|
||||
@@ -17,18 +17,21 @@ using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.RegisterReaders.SerialStream;
|
||||
using TBF.Rig.RegisterReaders.StandingStartStop;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation
|
||||
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation, ICommonRegReader
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
|
||||
public int ComPortNr => registerReaderCfg?.ComPortNr ?? -1;
|
||||
public PoseidonCfg RegPoseidonCfg => registerReaderCfg;
|
||||
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
@@ -134,10 +137,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
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 BeginWMState { get { return beginWMState; } set { beginWMState = value;} }
|
||||
public double EndWMState { get { return endWMState; } set { endWMState = value;} }
|
||||
public double WMTestTime { get { return wmTestTime; } }
|
||||
public string SerialNr { get => wmSerialNr; }
|
||||
public string SerialNr { get => wmSerialNr; set => wmSerialNr = value; }
|
||||
|
||||
|
||||
double beginWMState;
|
||||
@@ -147,6 +150,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
int wmRefPulses;
|
||||
double wmTestTime;
|
||||
private string wmSerialNr;
|
||||
|
||||
int timeFromStart; /// [s] Time from test start to determine when the test start sample should be taken
|
||||
|
||||
|
||||
public IOperation ReadDatastreamOp()
|
||||
@@ -314,7 +319,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
private void ReadPulses()
|
||||
{
|
||||
wmRefPulses = controlBoard.RefPulses;
|
||||
wmRefPulses = controlBoard?.RefPulses ?? 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -326,13 +331,25 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
/// <summary>
|
||||
/// for debug purposes what time will consume answer
|
||||
/// </summary>
|
||||
private long startTimeInMilis, fullTimeInMilis;
|
||||
private static long SafetyTimeOut = 30 * 1000; /// 30 seconds
|
||||
private long startTimeInMilis = -1, fullTimeInMilis = -1;
|
||||
private static long SafetyTimeOut = 30 * 1000;
|
||||
private long incommingTime = -1;
|
||||
|
||||
/// 30 seconds
|
||||
|
||||
public long DeltaTime { get{return fullTimeInMilis;}}
|
||||
public long IncommingTime { get{return incommingTime;}}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>eventDone</returns>
|
||||
public Event Run()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
timeFromStart += StateMachine.Period;
|
||||
ReadPulses();
|
||||
}
|
||||
|
||||
if (_currentOp == CurrentPoseidonOp.SendStartDataStream)
|
||||
{
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
@@ -349,6 +366,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Done)
|
||||
{
|
||||
var firstTask = CliRunner.TaskPool.FindLast(t => t is Task<string>);
|
||||
|
||||
|
||||
if (firstTask != null && firstTask is Task<string>)
|
||||
{
|
||||
string data = null;
|
||||
data = (firstTask as Task<string>).Result;
|
||||
|
||||
if (data != null && TryGetDeviceId(data, out wmSerialNr))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_currentOp = CurrentPoseidonOp.Done;
|
||||
return Event.Done;
|
||||
}
|
||||
@@ -356,6 +387,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|| _currentOp == CurrentPoseidonOp.ReadDataStream_End)
|
||||
{
|
||||
startTimeInMilis = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
incommingTime = -1;
|
||||
_isReadingStart = (_currentOp == CurrentPoseidonOp.ReadDataStream_Start);
|
||||
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Running;
|
||||
@@ -366,6 +398,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|| CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
{
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
|
||||
//set time stamp - end of reading
|
||||
incommingTime = CliRunner.IncommingTime;
|
||||
}
|
||||
return Event.Busy;
|
||||
}
|
||||
@@ -379,6 +413,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
data = (first as Task<JsonDataFromPoseidon>).Result;
|
||||
|
||||
//GET serial number
|
||||
if (string.IsNullOrEmpty(wmSerialNr))
|
||||
{
|
||||
try
|
||||
{
|
||||
wmSerialNr = data?.DeviceId ?? wmSerialNr;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error("Serial Nr - parse error!");
|
||||
}
|
||||
}
|
||||
|
||||
//GET volume
|
||||
if (data != null && Double.TryParse(data.Reading, out double Volume))
|
||||
{
|
||||
double VolumeLi = Units.ConvertFrom(Unit.USgal, Volume);
|
||||
@@ -396,6 +444,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Finish reading and loop
|
||||
_currentOp = CurrentPoseidonOp.Done;
|
||||
return Event.Done;
|
||||
}
|
||||
@@ -457,34 +507,38 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
public void StartSession()
|
||||
{
|
||||
|
||||
ValidateCliFileExistence(false);
|
||||
if (DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
wmSerialNr = "777321";
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO BUMI start session - CMD send data to Poseidon
|
||||
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
CliRunner.WaitAll();
|
||||
foreach (Task task in CliRunner.TaskPool)
|
||||
{
|
||||
if (task is Task<string>)
|
||||
{
|
||||
string result = (task as Task<string>).Result;
|
||||
if (TryGetDeviceId(result, out wmSerialNr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CliRunner.Clear();
|
||||
}
|
||||
//this is no place to get device id
|
||||
}
|
||||
|
||||
// private void RetrieveDeviceIdFromResponse()
|
||||
// {
|
||||
// if (DebugLevel == DebugMode.Simulate)
|
||||
// {
|
||||
// wmSerialNr = "777321";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //TODO BUMI start session - CMD send data to Poseidon
|
||||
//
|
||||
// CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
// CliRunner.WaitAll();
|
||||
// foreach (Task task in CliRunner.TaskPool)
|
||||
// {
|
||||
// if (task is Task<string>)
|
||||
// {
|
||||
// string result = (task as Task<string>).Result;
|
||||
// if (TryGetDeviceId(result, out wmSerialNr))
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// CliRunner.Clear();
|
||||
// }
|
||||
// }
|
||||
|
||||
private static readonly Regex DeviceIdRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using System.Xml.Linq;
|
||||
using Common;
|
||||
using Common.Iperl;
|
||||
@@ -11,6 +12,8 @@ using NHibernate;
|
||||
using Sensus.iPerl.NfcHandler;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using CalibrationStruct = TBF.Rig.RegisterReaders.CommonRR.IPerl.communication.CalibrationStruct;
|
||||
@@ -45,6 +48,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
readonly PoseidonCfg _poseidonCfg;
|
||||
|
||||
|
||||
public PoseidonCfg RegPoseidonCfg { get { return _poseidonCfg; } }
|
||||
public int RfidComPortNr { get { return _poseidonCfg.RfidComPortNr; } }
|
||||
public int OptoComPortNr { get { return _poseidonCfg.OptoComPortNr; } }
|
||||
public MeterType MeterType { get { return _poseidonCfg.MeterType; } }
|
||||
@@ -86,6 +90,21 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
|
||||
float[] x;
|
||||
public float[] X { get { return x; } }
|
||||
|
||||
|
||||
|
||||
// Volume of water from the opto telegram
|
||||
private DateTime _firstSampleTime;
|
||||
private DateTime _lastSampleTime;
|
||||
|
||||
private double _averageFlow;
|
||||
private long _averageFlowCount;
|
||||
private readonly object _avgLock = new object();
|
||||
private bool _optoheadStarted = false;
|
||||
|
||||
private OptoHeadService _optoHeadService;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Passed to OptoTelegramRaw.UpdateFromString(...)
|
||||
@@ -164,9 +183,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
///
|
||||
/// Timestamp from the opto telegram
|
||||
///
|
||||
private Int64 lastTimestamp;
|
||||
private double timestampSec;
|
||||
private double timestampSec0;
|
||||
|
||||
|
||||
int timeFromStart; /// [s] Time from test start to determine when the test start sample should be taken
|
||||
|
||||
@@ -174,12 +191,22 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
/// Test start volume for metrology in seconds
|
||||
public double TimestampSecStart
|
||||
{
|
||||
get { return TimeFromSamples(optoData, optoDataCount, TestStartTelegramIx, StartEndFilterSamplesCount2); }
|
||||
get
|
||||
{
|
||||
return _lastSampleTime != DateTime.MinValue ? 1 : 0; // return one second if is initialized, 0 - is false
|
||||
//return TimeFromSamples(optoData, optoDataCount, TestStartTelegramIx, StartEndFilterSamplesCount2);
|
||||
}
|
||||
}
|
||||
/// Test end time for metrology in seconds
|
||||
public double TimestampSecEnd
|
||||
{
|
||||
get { return TimeFromSamples(optoData, optoDataCount, TestEndTelegramIx, StartEndFilterSamplesCount2); }
|
||||
get
|
||||
{
|
||||
if (_lastSampleTime == DateTime.MinValue) return 0;
|
||||
TimeSpan delta = _lastSampleTime - _firstSampleTime;
|
||||
return (delta.TotalSeconds + 1);
|
||||
//return TimeFromSamples(optoData, optoDataCount, TestEndTelegramIx, StartEndFilterSamplesCount2);
|
||||
}
|
||||
}
|
||||
///
|
||||
public bool NoSamples
|
||||
@@ -197,12 +224,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
/// Test start volume for metrology in liters
|
||||
public double VolumeLtrStart
|
||||
{
|
||||
get { return NoSamples ? 0 : VolumeFromSamples(optoData, optoDataCount, TestStartTelegramIx, ScalingFactor(), StartEndFilterSamplesCount2); }
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
//return NoSamples ? 0 : VolumeFromSamples(optoData, optoDataCount, TestStartTelegramIx, ScalingFactor(), StartEndFilterSamplesCount2);
|
||||
}
|
||||
}
|
||||
/// Test end volume for metrology in liters
|
||||
public double VolumeLtrEnd
|
||||
{
|
||||
get { return NoSamples ? 0 : VolumeFromSamples(optoData, optoDataCount, TestEndTelegramIx, ScalingFactor(), StartEndFilterSamplesCount2); }
|
||||
get
|
||||
{
|
||||
return wmVolume; // complet calculated volume (time * flowrate)
|
||||
//return NoSamples ? 0 : VolumeFromSamples(optoData, optoDataCount, TestEndTelegramIx, ScalingFactor(), StartEndFilterSamplesCount2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,9 +309,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
if (_poseidonCfg != null)
|
||||
{
|
||||
OpenOptoSerialPort($"COM{_poseidonCfg.OptoComPortNr}", 9600, Parity.None, 8, StopBits.One,
|
||||
Handshake.None);
|
||||
CloseOptoSerialPort();
|
||||
|
||||
// OpenOptoSerialPort($"COM{_poseidonCfg.OptoComPortNr}", 9600, Parity.None, 8, StopBits.One,
|
||||
// Handshake.None);
|
||||
// CloseOptoSerialPort();
|
||||
log.FatalFormat($"{Name} initialized: {this}");
|
||||
}
|
||||
else
|
||||
@@ -369,8 +405,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
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 BeginWMState { get { return beginWMState;} set => beginWMState = value; }
|
||||
public double EndWMState { get { return endWMState; } set => endWMState = value; }
|
||||
public IOperation ReadDatastreamOp()
|
||||
{
|
||||
return this;
|
||||
@@ -401,6 +437,16 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
Q2CorrRL = 0;
|
||||
Q2CorrLR = 0;
|
||||
|
||||
|
||||
lock (_avgLock)
|
||||
{
|
||||
_firstSampleTime = DateTime.MinValue;
|
||||
_lastSampleTime = DateTime.MinValue;
|
||||
_averageFlow = 0;
|
||||
_averageFlowCount = 0;
|
||||
log.Debug("Initializing datastream state");
|
||||
}
|
||||
|
||||
simulatedPcbNr = null;
|
||||
|
||||
dataStreamState = DataStreamState.Flush;
|
||||
@@ -442,6 +488,12 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
timeFromStart += StateMachine.Period;
|
||||
ReadPulses();
|
||||
|
||||
//TODO read flow
|
||||
if (_optoHeadService!= null && !_optoHeadService.IsRunning)
|
||||
StartOptohead();
|
||||
|
||||
|
||||
|
||||
if (!startSampleAcquired && (timeFromStart >= 8) && (currentTelegramIx >= 0))
|
||||
{
|
||||
@@ -462,7 +514,94 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
return Event.ReadRegisterDone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
private void StartOptohead()
|
||||
{
|
||||
lock (_avgLock)
|
||||
{
|
||||
_firstSampleTime = DateTime.MinValue;
|
||||
_lastSampleTime = DateTime.MinValue;
|
||||
_averageFlow = 0;
|
||||
_averageFlowCount = 0;
|
||||
}
|
||||
|
||||
StartOptoTestInputLoop(new EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs>(OnOptoHandler));
|
||||
}
|
||||
|
||||
private bool OpenOptoConnection(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iHeadCfg != null)
|
||||
{
|
||||
if (_optoHeadService != null) return false;
|
||||
|
||||
OptoHeadService.Con connection = new OptoHeadService.Con($"COM{iHeadCfg.OptoComPortNr}", iHeadCfg.DebugLevel);
|
||||
_optoHeadService = new OptoHeadService(connection);
|
||||
return _optoHeadService.CreateSerialConnection();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool StartOptoTestInputLoop(EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> onOptoReceivedHandler)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_optoHeadService != null)
|
||||
{
|
||||
if (_optoHeadService.IsRunning) return false;
|
||||
|
||||
_optoHeadService.RunLoop(onOptoReceivedHandler);
|
||||
//run loop runstate = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(ex.Message);
|
||||
throw ex;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnOptoHandler(object sender, CommonRR.IPerl.communication.OptoReceivedEventArgs e)
|
||||
{
|
||||
//received data from optohead
|
||||
WaterMetrologyData eWaterMetrologyData = e?.WaterMetrologyData;
|
||||
if (eWaterMetrologyData != null && eWaterMetrologyData.C7Data != null)
|
||||
{
|
||||
double flowRateLPerS = eWaterMetrologyData.C7Data?.FlowRateLPerS ?? 0;
|
||||
|
||||
lock (_avgLock)
|
||||
{
|
||||
if (_averageFlowCount == 0)
|
||||
{
|
||||
_firstSampleTime = eWaterMetrologyData.C7Data?.Dt ?? DateTime.Now;
|
||||
}
|
||||
|
||||
_lastSampleTime = eWaterMetrologyData.C7Data?.Dt ?? DateTime.Now;
|
||||
|
||||
_averageFlowCount++;
|
||||
|
||||
// Running average (no overflow)
|
||||
_averageFlow += (flowRateLPerS - _averageFlow) / _averageFlowCount;
|
||||
TimeSpan delta = _lastSampleTime - _firstSampleTime;
|
||||
if (delta.TotalMilliseconds == 0)
|
||||
wmVolume = 0;
|
||||
else
|
||||
wmVolume = _averageFlow * (delta.TotalMilliseconds / 1000); //volume in liters
|
||||
//wmVolume = Units.ConvertFrom(Unit.l, _averageFlow * (delta.TotalMilliseconds / 1000));
|
||||
log.Info("Calculated Value:" + wmVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Stop this operation
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
@@ -570,78 +709,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Q2 correction factor calculated from the last test (Q2).
|
||||
/// This factor should be used only for R800 meters.
|
||||
/// </summary>
|
||||
/// <param name="q2TestResult">A test result from which to calculate the factor</param>
|
||||
/// <param name="nominalFlow">Nominal flow in m3/h</param>
|
||||
/// <param name="currentFactor">0 or the current Q2 correction factor when updating the factor</param>
|
||||
/// <returns>Calculated Q2 correction factor</returns>
|
||||
public double CalculateQ2CorrectionFactor(Results.Entities.MeterTestRslt currentQ2Result, int currentFactor, double nominalFlow, double errorTarget = 0)
|
||||
{
|
||||
double nominalTestFlowLph = Units.ConvertTo(Unit.lph, nominalFlow);
|
||||
double volumeRefShiftedToTarget = currentQ2Result.VolumeRef * (1.0 + errorTarget / 100.0);
|
||||
double q2adjErrorShiftedToTarget = Config.Formulas.ErrorFromVolumes(currentQ2Result.VolumeMeter, volumeRefShiftedToTarget);
|
||||
|
||||
double A = 16.0 / ScalingFactor(); /// Raw units per ml: DN15=16, DN20=8, DN25=4, DN32=2, DN40=1
|
||||
const double B = 8.0; /// Raw units per minute, 8
|
||||
const double C = B * 60.0; /// Raw units per hour, 480
|
||||
double D = C / A; /// ml correction per hour
|
||||
double F = D / (nominalTestFlowLph * 10.0); /// Error corrected with 8 Raw Units per minute [%]
|
||||
double G = F / B; /// Error corrected with 1 Raw Unit per minute [%]
|
||||
|
||||
/// Do not change the factor for an invalid measurement (q2adjResult.VolumeMeter == 0)
|
||||
double q2CorrectionFactor = (Math.Abs(currentQ2Result.VolumeMeter) <= float.Epsilon) ? Convert.ToDouble(currentFactor) :
|
||||
Convert.ToDouble(currentFactor) - (q2adjErrorShiftedToTarget / G) * (volumeRefShiftedToTarget / currentQ2Result.VolumeMeter);
|
||||
|
||||
log.WarnFormat("CalculateQ2CorrectionFactor() : Pos={0}, PCB#={1}, Error={2}%, Target={3}%, Current factor={4} New factor={5}",
|
||||
Name,
|
||||
SerialNr,
|
||||
currentQ2Result.Error.ToString("F2"),
|
||||
errorTarget.ToString("F3"),
|
||||
currentFactor.ToString("F1"),
|
||||
q2CorrectionFactor.ToString("F1"));
|
||||
|
||||
return q2CorrectionFactor;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 2 Hz correction factor calculated from two Q3 tests - done at 2Hz and at 8Hz.
|
||||
/// This factors should be used only for DN32 and DN40 meters.
|
||||
/// </summary>
|
||||
/// <param name="resultAt2Hz">Test result @2Hz from which to calculate the factor</param>
|
||||
/// <param name="resultAt8Hz">Test result @8Hz from which to calculate the factor</param>
|
||||
/// <param name="hz2CorrectionFactor">The calculated Q2 correction factor</param>
|
||||
/// <returns>true = OK, false = failed</returns>
|
||||
public bool Calculate2HzCorrectionFactor(Results.Entities.MeterTestRslt resultAt2Hz,
|
||||
Results.Entities.MeterTestRslt resultAt8Hz,
|
||||
out double diff2Hz8Hz, out int hz2CorrectionFactor)
|
||||
{
|
||||
hz2CorrectionFactor = 0;
|
||||
diff2Hz8Hz = 0;
|
||||
|
||||
if ((resultAt2Hz == null) || (resultAt8Hz == null))
|
||||
{
|
||||
return false; /// Test result @2Hz and/or @8Hz is missing ==> water meter failed
|
||||
}
|
||||
|
||||
diff2Hz8Hz = resultAt2Hz.Error - resultAt8Hz.Error;
|
||||
|
||||
if (Math.Abs(diff2Hz8Hz) > 2.5) return false; /// Difference of errors > 2.5 % ==> water meter failed
|
||||
|
||||
hz2CorrectionFactor = -1 * (int)Math.Round(10 * diff2Hz8Hz);
|
||||
|
||||
log.WarnFormat("2Hz correction: Pos={0}, PCB#={1}, corrFactor={2}, erro@2Hz={3}%, erro@8Hz={4}%",
|
||||
Name,
|
||||
SerialNr,
|
||||
hz2CorrectionFactor,
|
||||
resultAt2Hz.Error.ToString("F2"),
|
||||
resultAt8Hz.Error.ToString("F2"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -703,147 +771,24 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
/// <param name="optoState">OptoState.Read or OptoState.Flush</param>
|
||||
void ReadOptoData(DataStreamState optoState)
|
||||
{
|
||||
if (optoSerialPort is null) return;
|
||||
lock (this)
|
||||
{
|
||||
int nrBytes = optoSerialPort.BytesToRead;
|
||||
if (nrBytes > 0)
|
||||
{
|
||||
char[] buffer = new char[nrBytes];
|
||||
optoSerialPort.Read(buffer, 0, nrBytes);
|
||||
string received = new string(buffer);
|
||||
|
||||
string allRcvd = partOfTelegram + received;
|
||||
|
||||
while (true)
|
||||
{
|
||||
int pos = allRcvd.IndexOf("\r\n");
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
/// No CR+LF found, wait for more characters in the next invocation
|
||||
partOfTelegram = allRcvd;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// CR+LF found
|
||||
if (optoState == DataStreamState.ProcessAndSave)
|
||||
{
|
||||
int bufferIx = BufferIdx(optoDataCount);
|
||||
|
||||
if (pos < OptoTelegramRaw.Length - 2)
|
||||
{
|
||||
/// CR+LF found too early, truncate the beginning incl CR+LF and keep scanning in this loop
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
if (synchronized)
|
||||
{
|
||||
optoData[bufferIx].Counter = optoDataCount;
|
||||
optoData[bufferIx].SetFlags(OptoTelegramFlags.SyncError);
|
||||
}
|
||||
synchronized = true;
|
||||
}
|
||||
else if (optoData[bufferIx].UpdateFromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2),
|
||||
optoDataCount,
|
||||
Convert.ToSingle(Sequences.ProcessData.RefFlow.Val),
|
||||
ref volumeRawExtLast, ref timestampExtLast))
|
||||
{
|
||||
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) && the telegram is OK
|
||||
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
|
||||
OptoTelegramReceived(optoDataCount, synchronized2, volumeRawExtLast, timestampExtLast);
|
||||
synchronized2 = synchronized;
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) but the telgram was not OK
|
||||
optoData[bufferIx].Counter = optoDataCount;
|
||||
optoDataCount++;
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
}
|
||||
|
||||
optoDataCount++;
|
||||
}
|
||||
else /// optoState == OptoState.Flush
|
||||
{
|
||||
if (pos < OptoTelegramRaw.Length - 2)
|
||||
{
|
||||
/// CR+LF found too early, truncate the beginning incl CR+LF and keep scanning in this loop
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
synchronized = true;
|
||||
}
|
||||
// CR+LF found and (pos >= OptoTelegram.Length - 2)
|
||||
else if (toBeFlushed.UpdateFromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2),
|
||||
0,
|
||||
Convert.ToSingle(Sequences.ProcessData.RefFlow.Val),
|
||||
ref volumeRawExtLast, ref timestampExtLast))
|
||||
{
|
||||
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
|
||||
synchronized2 = synchronized;
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//OnOptoReceived(this, new OptoReceivedEventArgs(s));
|
||||
}
|
||||
else
|
||||
{
|
||||
//OnOptoReceived(this, new OptoReceivedEventArgs("."));
|
||||
}
|
||||
}
|
||||
|
||||
// lock (this)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
public string ReadOptoData()
|
||||
{
|
||||
if (optoSerialPort is null) return "";
|
||||
string received = ".";
|
||||
lock (this)
|
||||
{
|
||||
int nrBytes = optoSerialPort.BytesToRead;
|
||||
if (nrBytes > 0)
|
||||
{
|
||||
char[] buffer = new char[nrBytes];
|
||||
optoSerialPort.Read(buffer, 0, nrBytes);
|
||||
received = new string(buffer);
|
||||
}
|
||||
}
|
||||
// lock (this)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
return received;
|
||||
}
|
||||
|
||||
|
||||
void OptoTelegramReceived(int currentIx, bool async, Int64 volumeRawExt, Int64 timestampRawExt)
|
||||
{
|
||||
currentTelegramIx = currentIx;
|
||||
|
||||
lastVolumeRaw = volumeRawExt;
|
||||
lastTimestamp = timestampRawExt;
|
||||
|
||||
if (volumeLtr == 0 && volumeLtr0 == 0)
|
||||
{
|
||||
volumeLtr = (double)lastVolumeRaw * ScalingFactor() / 16000.0;
|
||||
volumeLtr0 = volumeLtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
volumeLtr = (double)lastVolumeRaw * ScalingFactor() / 16000.0;
|
||||
}
|
||||
|
||||
if (timestampSec == 0 && timestampSec0 == 0)
|
||||
{
|
||||
timestampSec = (double)lastTimestamp / 8192.0;
|
||||
timestampSec0 = timestampSec;
|
||||
}
|
||||
else
|
||||
{
|
||||
timestampSec = (double)lastTimestamp / 8192.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -1002,12 +947,15 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
|
||||
void ReadPulses()
|
||||
{
|
||||
beginWMState = volumeLtr0;
|
||||
endWMState = volumeLtr;
|
||||
TimeSpan delta = _lastSampleTime - _firstSampleTime;
|
||||
double volume = _averageFlow * (delta.TotalMilliseconds / 1000);
|
||||
//log.Debug("ReadPulses - Calculated Value:" + volume);
|
||||
beginWMState = 1;
|
||||
endWMState = beginWMState + volume ;
|
||||
wmVolume = Math.Abs(endWMState - beginWMState);
|
||||
wmPulses = (int)(wmVolume * (double)PulsesPerLtr + 0.5);
|
||||
wmRefPulses = StateMachine.ControlBoardMain.RefPulses;
|
||||
wmTestTime = timestampSec - timestampSec0;
|
||||
wmTestTime = delta.TotalSeconds;
|
||||
}
|
||||
|
||||
private void OpenOptoSerialPort(string comPort, int baudRate, Parity parity, int dataBits, StopBits stopBit, Handshake handshake)
|
||||
@@ -1018,6 +966,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
/// Open serial port: 9600 Bd, 8 data bits, 1 stop bit, no parity
|
||||
try
|
||||
{
|
||||
|
||||
CloseOptoSerialPort();
|
||||
optoSerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBit);
|
||||
optoSerialPort.Handshake = handshake;
|
||||
@@ -1039,12 +988,15 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
|
||||
private void CloseOptoSerialPort()
|
||||
{
|
||||
if (optoSerialPort != null)
|
||||
if (_optoHeadService != null)
|
||||
{
|
||||
optoSerialPort.Close();
|
||||
optoSerialPort = null;
|
||||
_optoHeadService.CloseSerialConnection();
|
||||
_optoHeadService = null;
|
||||
log.FatalFormat($"{Name} OptoPort closed: {this}");
|
||||
}
|
||||
|
||||
|
||||
communication.OpticalHeadTest.SetActiveMode(_poseidonCfg);
|
||||
}
|
||||
|
||||
|
||||
@@ -1056,10 +1008,14 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenOptoSerialPort($"COM{_poseidonCfg.OptoComPortNr}", 9600, Parity.None, 8, StopBits.One, Handshake.None);
|
||||
//set test mode via the cli
|
||||
communication.OpticalHeadTest.SetTestMode(_poseidonCfg);
|
||||
//open opto serial port
|
||||
OpenOptoConnection(_poseidonCfg);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error($"{Name} OptoPort - error opening port: {_poseidonCfg.OptoComPortNr}, Details: {e.Message}");
|
||||
}
|
||||
/// Reset opto-data, etc.
|
||||
optoDataCount = 0;
|
||||
@@ -1482,8 +1438,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
|
||||
volumeLtr = 0;
|
||||
volumeLtr0 = 0;
|
||||
timestampSec = 0;
|
||||
timestampSec0 = 0;
|
||||
|
||||
|
||||
extraDataPath = null;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
using TBF.Rig.Output.Printers.Label;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils;
|
||||
using CliRunner = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.CliRunnerOld;
|
||||
using OptoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus;
|
||||
@@ -13,6 +15,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
public class NfcHeadServiceOld
|
||||
{
|
||||
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(NfcHeadServiceOld));
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
@@ -208,7 +211,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Failed to parse OptoHeadStatus from output. Result: {result}");
|
||||
log.Error($"Failed to parse OptoHeadStatus from output. Result: {result}");
|
||||
//throw new Exception($"Failed to parse OptoHeadStatus from output. Result: {result}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
||||
using TBF.Rig.Sequences;
|
||||
using SERIAL_Driver = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SERIAL_Driver;
|
||||
using WaterMetrologyData = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.WaterMetrologyData;
|
||||
|
||||
@@ -8,9 +12,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
public class OptoHeadService
|
||||
{
|
||||
|
||||
static readonly ILog log = LogManager.GetLogger("PoseidonConnection");
|
||||
|
||||
public class Con
|
||||
{
|
||||
|
||||
public string com = "COM5";
|
||||
public int baudrate = 38400;
|
||||
public int dataBits = 8;
|
||||
@@ -18,6 +24,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
public StopBits stopbits = StopBits.Two;
|
||||
public int readTimeout = 5000;
|
||||
public int writeTimeout = 1000;
|
||||
private DebugMode _debugLevel;
|
||||
public DebugMode DebugModeSetting { get => _debugLevel; }
|
||||
|
||||
public Con(string com, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout,
|
||||
int writeTimeout) : this(com)
|
||||
@@ -29,10 +37,23 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
this.readTimeout = readTimeout;
|
||||
this.writeTimeout = writeTimeout;
|
||||
}
|
||||
|
||||
public Con(DebugMode debugLevel,string com, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout,
|
||||
int writeTimeout) : this(com)
|
||||
{
|
||||
this._debugLevel = debugLevel;
|
||||
this.baudrate = baudrate;
|
||||
this.dataBits = dataBits;
|
||||
this.parity = parity;
|
||||
this.stopbits = stopbits;
|
||||
this.readTimeout = readTimeout;
|
||||
this.writeTimeout = writeTimeout;
|
||||
}
|
||||
|
||||
public Con(string com)
|
||||
public Con(string com, DebugMode debugLevel = DebugMode.Normal)
|
||||
{
|
||||
this.com = com;
|
||||
this._debugLevel = debugLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,11 +76,19 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
OnOptoReceivedHandler = null;
|
||||
bool isopen = false;
|
||||
Con con = Connection;
|
||||
if (con == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] message = {0x00};
|
||||
byte[] bytesReceived;
|
||||
|
||||
if (!driver.isOpen())
|
||||
if (con?.DebugModeSetting == DebugMode.Simulate)
|
||||
{
|
||||
isopen = true;
|
||||
}
|
||||
else if (!driver.isOpen())
|
||||
{
|
||||
|
||||
isopen = driver.OpenConnection(
|
||||
@@ -72,6 +101,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
con.writeTimeout);
|
||||
}
|
||||
|
||||
_bRunStarted = false;
|
||||
|
||||
return isopen;
|
||||
}
|
||||
|
||||
@@ -79,24 +110,39 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
dissableRunLoop = true;
|
||||
OnOptoReceivedHandler = null;
|
||||
driver.Close();
|
||||
OnOptoReceivedHandler = null;
|
||||
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
||||
{
|
||||
driver.Close();
|
||||
}
|
||||
_bRunStarted = false;
|
||||
}
|
||||
|
||||
private EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> OnOptoReceivedHandler;
|
||||
|
||||
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return !dissableRunLoop
|
||||
&& ((Connection?.DebugModeSetting != DebugMode.Simulate) ? driver.isOpen() : true)
|
||||
&& _bRunStarted;}
|
||||
}
|
||||
|
||||
public void RunLoop(EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> onOptoReceivedHandler)
|
||||
{
|
||||
log.Debug("RunLoop started on event!");
|
||||
OnOptoReceivedHandler = onOptoReceivedHandler;
|
||||
Task.Run(() => Run());
|
||||
}
|
||||
|
||||
public void RunLoop()
|
||||
{
|
||||
log.Debug("RunLoop started!");
|
||||
Task.Run(() => Run());
|
||||
}
|
||||
|
||||
private bool dissableRunLoop = false;
|
||||
private bool _bRunStarted = false;
|
||||
/// <summary>
|
||||
/// Run the service. Catch one communication to WaterMetrologyData field.
|
||||
/// </summary>
|
||||
@@ -104,10 +150,12 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
while (!dissableRunLoop)
|
||||
{
|
||||
_bRunStarted = true;
|
||||
WaterMetrologyData = ParseData(RunReading());
|
||||
if (OnOptoReceivedHandler != null && WaterMetrologyData != null)
|
||||
{
|
||||
OnOptoReceivedHandler.Invoke(this, new CommonRR.IPerl.communication.OptoReceivedEventArgs(WaterMetrologyData.ToString()));
|
||||
log.Debug($"Received OptoData: {WaterMetrologyData}");
|
||||
OnOptoReceivedHandler?.Invoke(this, new CommonRR.IPerl.communication.OptoReceivedEventArgs(WaterMetrologyData?.ToString(), WaterMetrologyData));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,13 +163,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
|
||||
byte[] RunReading()
|
||||
{
|
||||
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
||||
{
|
||||
return new byte[] {0x00};
|
||||
}
|
||||
if (driver.isOpen())
|
||||
{
|
||||
driver.SendMessage(new byte[] {0x00}, 1);
|
||||
return driver.GetRawData();
|
||||
byte[] rawData = driver.GetRawData();
|
||||
log.Debug($"Received data size: {rawData?.Length ?? 0} bytes, raw data: {(rawData==null? "" :BitConverter.ToString(rawData))}");
|
||||
return rawData;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Debug("Serial port is not open.");
|
||||
dissableRunLoop = true;
|
||||
}
|
||||
|
||||
@@ -130,6 +185,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
|
||||
public WaterMetrologyData ParseData(byte[] data)
|
||||
{
|
||||
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
||||
{
|
||||
return WaterMetrologyData.SimulateC7();
|
||||
}
|
||||
try
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
|
||||
+15
@@ -37,6 +37,21 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
public static WaterMetrologyData SimulateC7()
|
||||
{
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData.c7Data = WaterMetrologyDataC7.Simulate();
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
public static WaterMetrologyData SimulateC2()
|
||||
{
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData.c2Data = WaterMetrologyDataC2.Simulate();
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Status: {_optoHeadStatus}, C7Data: {c7Data}, C2Data: {c2Data}";
|
||||
|
||||
+37
-1
@@ -21,7 +21,17 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
public bool FastHPFC { get; set; }
|
||||
public bool FieldPolarity { get; set; }
|
||||
public bool ImpedancePolarity { get; set; }
|
||||
|
||||
|
||||
|
||||
public double FlowRateLPerS // Flow Rate in L/s metric units
|
||||
{
|
||||
get
|
||||
{
|
||||
double flowRateGPM = FlowRate / 10000; //investigation flow meter GPM
|
||||
double flowRateLPerS = flowRateGPM * 0.063090196432096 ; // conversion factor from GPM to L/s with minimal digit lost
|
||||
return flowRateLPerS;
|
||||
}
|
||||
}
|
||||
public double CalcFlowmLps
|
||||
{
|
||||
get { return FlowRate / 4.0; } // FlowRate is in 1/4 mL/s
|
||||
@@ -41,6 +51,32 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
return Parse(data, dt, dutinfo);
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC2 Simulate()
|
||||
{
|
||||
var result = new WaterMetrologyDataC2();
|
||||
|
||||
result.DutInfo = "dutinfo";
|
||||
result.Dt = DateTime.Now;
|
||||
result.AdcSample = 1;
|
||||
result.LastField = 2;
|
||||
result.FlowRate = 12456;
|
||||
result.Accumulator = 789465;
|
||||
result.FlipPeriod = 1;
|
||||
result.VinfStart = 0;
|
||||
result.VinfEnd = 0;
|
||||
result.ElectrodeDelta = 1;
|
||||
result.Impedance = 1;
|
||||
result.FieldDriveTime = 0x00 ;
|
||||
|
||||
result.IsInLowFlow = false;
|
||||
result.IsInEmptyPipe = false;
|
||||
result.FastHPFC = false; // Fast High Pass Filter Constant in bit 2
|
||||
result.FieldPolarity = false; // Field Polarity in bit 3
|
||||
result.ImpedancePolarity = false; // Impedance Polarity in bit 4
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC2 Parse(byte[] data, DateTime dt, string dutinfo)
|
||||
{
|
||||
if (data.Length < 24)
|
||||
|
||||
+41
@@ -23,6 +23,47 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
public bool IsLearningActive { get; set; }
|
||||
public bool AdcShiftsUpdated { get; set; }
|
||||
|
||||
public static WaterMetrologyDataC7 Simulate()
|
||||
{
|
||||
var result = new WaterMetrologyDataC7();
|
||||
|
||||
result.DutInfo = "dutinfo";
|
||||
result.Dt = DateTime.Now;
|
||||
result.AdcSample = 1;
|
||||
result.LastField = 2;
|
||||
result.FlowRate = 12456;
|
||||
result.Accumulator = 789465;
|
||||
result.FlipPeriod = 1;
|
||||
result.VinfStart = 0;
|
||||
result.VinfEnd = 0;
|
||||
result.ElectrodeDelta = 1;
|
||||
result.Impedance = 1;
|
||||
result.FieldDriveTime = 0x00 ;
|
||||
|
||||
result.IsInLowFlow = false;
|
||||
result.IsInEmptyPipe = false;
|
||||
result.FastHPFC = false; // Fast High Pass Filter Constant in bit 2
|
||||
result.FieldPolarity = false; // Field Polarity in bit 3
|
||||
result.ImpedancePolarity = false; // Impedance Polarity in bit 4
|
||||
|
||||
result.MagTamperState = true; // bits 5 and 6 represent MagTamperState
|
||||
result.IsLearningActive = true; // bit 7 represents IsLearningActive
|
||||
|
||||
|
||||
|
||||
result.AdcShiftsUpdated = false; // bit 0 represents AdcShiftsUpdated
|
||||
|
||||
result.LastFieldmilliGauss = 0;
|
||||
result.ImpedanceI = 0; // in phase
|
||||
result.ImpedanceQ = 0; // out of phase
|
||||
result.NoiseMetric = 0; //
|
||||
result.LearningLockout = 0;
|
||||
result.ReverseBuffer = 0;
|
||||
result.ConditionedAdc = 0;
|
||||
result.Totalalizer = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC7 Parse(string base64Data, DateTime dt, string dutinfo)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,6 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
[Description("..")] None,
|
||||
[Description("Nfc")] Nfc,
|
||||
[Description("Touch Capl")]Touched,
|
||||
[Description("cTouchRead")]Touched,
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
internal class OpticalHeadTest
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
|
||||
DebugMode _debugMode;
|
||||
public DebugMode DebugMode { get => _debugMode; set => _debugMode = value; }
|
||||
|
||||
internal static string OpenSealing(ISmartReader iHead)
|
||||
{
|
||||
@@ -26,6 +29,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
|
||||
internal static string ReadRequest_SerialNo(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
if (iHeadCfg != null && iHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "1111";
|
||||
}
|
||||
|
||||
string serialNo = null;
|
||||
try
|
||||
{
|
||||
@@ -77,6 +85,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
|
||||
internal static string SetActiveMode(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
if (iHeadCfg != null && iHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "OK";
|
||||
}
|
||||
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
$"COM{iHeadCfg.RfidComPortNr}",
|
||||
iHeadCfg.CliProgramName,
|
||||
@@ -100,6 +113,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
|
||||
internal static string SetTestMode(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
if (iHeadCfg != null && iHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "OK";
|
||||
}
|
||||
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
$"COM{iHeadCfg.RfidComPortNr}",
|
||||
iHeadCfg.CliProgramName,
|
||||
@@ -123,6 +141,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
|
||||
public static void Deactivate()
|
||||
{
|
||||
if (_lastIHeadCfg != null && _lastIHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
StopOptoTestInputLoop();
|
||||
if (_lastOptoHeadStatus != OptoHeadStatus.Unknown &&
|
||||
_lastOptoHeadStatus != OptoHeadStatus.OptoHeadDisabled &&
|
||||
@@ -142,7 +164,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
if (optoHeadService != null) return false;
|
||||
|
||||
OptoHeadService.Con connection = new OptoHeadService.Con($"COM{iHeadCfg.OptoComPortNr}");
|
||||
OptoHeadService.Con connection = new OptoHeadService.Con($"COM{iHeadCfg.OptoComPortNr}", iHeadCfg.DebugLevel);
|
||||
optoHeadService = new OptoHeadService(connection);
|
||||
optoHeadService.CreateSerialConnection();
|
||||
optoHeadService.RunLoop(onOptoReceivedHandler);
|
||||
|
||||
@@ -17,7 +17,18 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.implementations
|
||||
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation, ISmartReader
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(PoseidonReader));
|
||||
|
||||
|
||||
public PoseidonReader()
|
||||
{
|
||||
_pulsesPerLtr = 0;
|
||||
_ltrsPerPulse = 0;
|
||||
_wmPulses = 0;
|
||||
_wmRefPulses = 0;
|
||||
_wmVolume = 0;
|
||||
_beginWmState = 0;
|
||||
_endWmState = 0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}({1})", ClassName, Cfg.ToString(-1));
|
||||
@@ -101,13 +112,23 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.implementations
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public double PulsesPerLtr { get; }
|
||||
public double LtrsPerPulse { get; }
|
||||
public int WMPulses { get; }
|
||||
public int WMRefPulses { get; }
|
||||
public double WMVolume { get; }
|
||||
public double BeginWMState { get; }
|
||||
public double EndWMState { get; }
|
||||
private double _pulsesPerLtr ;
|
||||
private double _ltrsPerPulse ;
|
||||
private int _wmPulses ;
|
||||
private int _wmRefPulses ;
|
||||
private double _wmVolume ;
|
||||
private double _beginWmState ;
|
||||
private double _endWmState ;
|
||||
|
||||
|
||||
public double PulsesPerLtr { get => _pulsesPerLtr; }
|
||||
public double LtrsPerPulse { get => _ltrsPerPulse; }
|
||||
public int WMPulses { get => _wmPulses; }
|
||||
public int WMRefPulses { get =>_wmRefPulses; }
|
||||
public double WMVolume { get =>_wmVolume; }
|
||||
public double BeginWMState { get => _beginWmState; set => _beginWmState = value; }
|
||||
public double EndWMState { get => _endWmState; set => _endWmState = value; }
|
||||
|
||||
public IOperation ReadDatastreamOp()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace TBF.Rig.Scales.MettlerToledo
|
||||
public IComponent DummyComponent() { return new Scale(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Scale(cfg); }
|
||||
// wrapping to use in unit tests
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components, ISerialPort serialPort) { return new Scale(cfg, serialPort); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new ScaleCfg("WT", this); }
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace TBF.Rig.Scales.MettlerToledo
|
||||
{
|
||||
public interface ISerialPort
|
||||
{
|
||||
void Open();
|
||||
void Close();
|
||||
void Write(string text);
|
||||
string ReadExisting();
|
||||
bool IsOpen { get; }
|
||||
Handshake Handshake { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ namespace TBF.Rig.Scales.MettlerToledo
|
||||
///
|
||||
public IDrawingItem DrawingItem { get { return scaleCfg as IDrawingItem; } }
|
||||
|
||||
protected SerialPort serialPort;
|
||||
protected ISerialPort serialPort;
|
||||
protected StringBuilder stringBuilder;
|
||||
|
||||
/// <summary>The state of the mass measurement</summary>
|
||||
@@ -93,6 +93,13 @@ namespace TBF.Rig.Scales.MettlerToledo
|
||||
{
|
||||
scaleCfg = cfg as ScaleCfg;
|
||||
}
|
||||
|
||||
public Scale(Generic.IComponentCfg cfg, ISerialPort serialPort)
|
||||
: base(cfg)
|
||||
{
|
||||
scaleCfg = cfg as ScaleCfg;
|
||||
this.serialPort = serialPort;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -111,7 +118,8 @@ namespace TBF.Rig.Scales.MettlerToledo
|
||||
if (scaleCfg.DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
string comPortName = "COM" + scaleCfg.ComPortNr.ToString();
|
||||
serialPort = new SerialPort(comPortName, scaleCfg.BaudRate, scaleCfg.Parity, scaleCfg.DataBits, scaleCfg.StopBits);
|
||||
serialPort ??= new SerialPortDevice(comPortName, scaleCfg.BaudRate, scaleCfg.Parity, scaleCfg.DataBits,
|
||||
scaleCfg.StopBits);
|
||||
serialPort.Handshake = scaleCfg.Handshake;
|
||||
serialPort.Open();
|
||||
log.FatalFormat("{0} - Device successfully initialized", Name);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace TBF.Rig.Scales.MettlerToledo
|
||||
{
|
||||
public class SerialPortDevice : SerialPort, ISerialPort
|
||||
{
|
||||
public SerialPortDevice(string comPortName, int scaleCfgBaudRate, Parity scaleCfgParity, int scaleCfgDataBits, StopBits scaleCfgStopBits)
|
||||
: base(comPortName, scaleCfgBaudRate, scaleCfgParity, scaleCfgDataBits, scaleCfgStopBits)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO.Ports;
|
||||
using log4net;
|
||||
using log4net.Core;
|
||||
using log4net.Repository.Hierarchy;
|
||||
using NHibernate;
|
||||
|
||||
namespace TBF.Rig.Scales.MettlerToledo
|
||||
{
|
||||
public class SerialPortDeviceFake : ISerialPort
|
||||
{
|
||||
// write dirrectly into cmd
|
||||
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool bIsOpen = false;
|
||||
public void Open()
|
||||
{
|
||||
log.Debug( "SerialPortDeviceFake.Open()");
|
||||
bIsOpen = true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
log.Debug( "SerialPortDeviceFake.Close()");
|
||||
bIsOpen = false;
|
||||
}
|
||||
|
||||
private string lastWrite = "";
|
||||
private string lastRead = "";
|
||||
|
||||
public string LastWrite { get => lastWrite; set => lastWrite = value;}
|
||||
public string LastRead { get => lastRead; set => lastRead = value;}
|
||||
|
||||
public void Write(string text)
|
||||
{
|
||||
log.DebugFormat("SerialPortDeviceFake.Write({0})", text);
|
||||
lastWrite = text;
|
||||
}
|
||||
|
||||
private string forcedText = null;
|
||||
public void ForceReturnAnswer(string text)
|
||||
{
|
||||
forcedText = text;
|
||||
}
|
||||
|
||||
public string ReadExisting()
|
||||
{
|
||||
string result = "", end = "\r\n";
|
||||
if (forcedText != null)
|
||||
{
|
||||
result = forcedText;
|
||||
forcedText = null;
|
||||
return result + end;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(lastWrite))
|
||||
{
|
||||
if (lastWrite.Contains("S"+end))
|
||||
{
|
||||
result = "S D 170.725 kg"; // correct stable scale mass answer
|
||||
}
|
||||
else if (lastWrite.Contains("R"))
|
||||
{
|
||||
result = "RD";
|
||||
}
|
||||
|
||||
//store result
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
result = result + end;
|
||||
lastRead = result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return bIsOpen; }
|
||||
}
|
||||
|
||||
Handshake handshakeVal = Handshake.None;
|
||||
public Handshake Handshake { get => handshakeVal; set => handshakeVal = value; }
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,11 @@ namespace TBF.Rig.Sequences
|
||||
try
|
||||
{
|
||||
/// 1nd argument
|
||||
ITestMethodCfg iPerlCfgIPerl = cfg as ITestMethodCfg;
|
||||
ITestMethodCfg testMethodCfg = cfg as ITestMethodCfg;
|
||||
if (testMethodCfg == null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// 2rd argument: as is
|
||||
|
||||
@@ -68,8 +72,7 @@ namespace TBF.Rig.Sequences
|
||||
/*myRef.modelessDlg = new TestMethods.iPerlCommunication.iPerlCommunicationForm(iPerlCfg, tests, iPerlCommParams);
|
||||
myRef.modelessDlg.Show();*/
|
||||
|
||||
myRef.modelessDlg = new SmartCommunicationForm(
|
||||
testMethod , tests, iPerlCommParams);
|
||||
myRef.modelessDlg = new SmartCommunicationForm( testMethod , tests, iPerlCommParams);
|
||||
myRef.modelessDlg.Show();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -323,6 +323,22 @@ namespace TBF.Rig
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use InitializeBoardEtc() instead.")]
|
||||
public static void InitializeBoardEtc_Fake(IList<IComponent> componentList)
|
||||
{
|
||||
components = componentList;
|
||||
|
||||
// base find components - find control board!, ...
|
||||
foreach (var cmpnt in components)
|
||||
{
|
||||
if (cmpnt is ControlBoard.IControlBoard) ControlBoardMain = cmpnt as ControlBoard.IControlBoard;
|
||||
if (cmpnt is IBenchInfo) ProcessData.BenchInfo = cmpnt as IBenchInfo;
|
||||
if (cmpnt is IErrorFlags) ProcessData.ErrorFlagsComp = cmpnt as IErrorFlags;
|
||||
if (cmpnt is IStatisticsMonitoring)
|
||||
ProcessData.StatisticsMonitoringComp = cmpnt as IStatisticsMonitoring;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string CurrentlyInitializedComponentName;
|
||||
///
|
||||
|
||||
@@ -210,6 +210,7 @@ namespace TBF.Rig
|
||||
new TestMethods.StandingStartMassCollection.Single.Factory(),
|
||||
new TestMethods.StandingStartMassCollection.Compound.Factory(),
|
||||
new TestMethods.StandingStartMassCollection.HeatMeters.Factory(),
|
||||
new TestMethods.StandingStartMassCollectionPoseidon.Single.Factory(),
|
||||
new TestMethods.StandingStartMassCollectionAdvance.Single.Factory(),
|
||||
new TestMethods.StandingStartMassCollectionAdvance.Compound.Factory(),
|
||||
new TestMethods.StandingStartMassCollectionAdvance.HeatMeters.Factory(),
|
||||
|
||||
@@ -373,7 +373,7 @@ namespace TBF.Rig.TestMethods.SmartMeterFlyingStartMassCollection
|
||||
/// Show the modeless dialog with error indication
|
||||
///
|
||||
string componentName = (method as IComponent)?.Name ?? string.Empty;
|
||||
Program.MainWnd.Invoke(new SmartCommFormDlgt(OpenSmartCommForm), new object[] { this, componentName, test, testParams });
|
||||
Program.MainWnd.Invoke(new SmartCommFormDlgt(OpenSmartCommForm), new object[] { this, method, test, testParams });
|
||||
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
|
||||
|
||||
@@ -9,6 +9,7 @@ using Common;
|
||||
using TBF.Boxes;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using TBF.UiBridge;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStart
|
||||
@@ -511,6 +512,9 @@ namespace TBF.Rig.TestMethods.StandingStart
|
||||
for (int i = 0; i < waterMetersCount; i++)
|
||||
{
|
||||
GenericDevices.IRegReader rr = sensPath.RegisterReaders[i];
|
||||
|
||||
if (rr is ICommonRegReader)
|
||||
(rr as ICommonRegReader).BeginWMState = dataEntryCmpnt.WMStartState(i);
|
||||
|
||||
if (rr is Rig.RegisterReaders.StandingStartStop.RegisterReader)
|
||||
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).BeginWMState = dataEntryCmpnt.WMStartState(i);
|
||||
@@ -762,7 +766,10 @@ namespace TBF.Rig.TestMethods.StandingStart
|
||||
for (int i = 0; i < Data.WMsCount; i++)
|
||||
{
|
||||
GenericDevices.IRegReader rr = sensPath.RegisterReaders[i];
|
||||
|
||||
|
||||
if (rr is ICommonRegReader)
|
||||
(rr as ICommonRegReader).EndWMState = dataEntryCmpnt.WMEndState(i);
|
||||
|
||||
if (rr is Rig.RegisterReaders.StandingStartStop.RegisterReader)
|
||||
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).EndWMState = dataEntryCmpnt.WMEndState(i);
|
||||
|
||||
@@ -1010,6 +1017,13 @@ namespace TBF.Rig.TestMethods.StandingStart
|
||||
&& (tstRslt.ErrorFlags == 0);
|
||||
meterRslt.TestDone = true;
|
||||
tstRslt.TestDone = true;
|
||||
if (regReader is ICommonRegReader regReaderCommon)
|
||||
// if (meterRslt.WaterMeter != null
|
||||
// && tstRslt is ICommonRegReader tstRsltCommon
|
||||
// && !string.IsNullOrEmpty(tstRsltCommon.SerialNr))
|
||||
{
|
||||
meterRslt.WaterMeter.SerialNr = regReaderCommon.SerialNr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Config.Entities;
|
||||
using TBF.Boxes;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using TBF.UiBridge;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
@@ -559,7 +560,6 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
State.Create(string.Format("{0}({1}) : Enter start states of water meters", test.Method, test.Name))
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(readTempPressOps)
|
||||
.AddOperation(readStartMassOp)
|
||||
.AddOperation(testInProgress)
|
||||
.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders))
|
||||
.AddOperation(processDataLoggingOp)
|
||||
@@ -594,8 +594,15 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
{
|
||||
for (int i = 0; i < waterMetersCount; i++)
|
||||
{
|
||||
|
||||
IRegReader rr = sensPath.RegisterReaders[i];
|
||||
|
||||
|
||||
if (rr is ICommonRegReader)
|
||||
{
|
||||
(rr as ICommonRegReader).BeginWMState = dataEntryCmpnt.WMStartState(i);
|
||||
}
|
||||
|
||||
if (rr is Rig.RegisterReaders.StandingStartStop.RegisterReader)
|
||||
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).BeginWMState = dataEntryCmpnt.WMStartState(i);
|
||||
|
||||
@@ -641,6 +648,28 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//...MF...kvapkania... robime to pridanim casovej konstanty, ktora sa konfiguruje
|
||||
State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(readTempPressOps)
|
||||
.AddOperation(testInProgress)
|
||||
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
||||
.AddOperation(processDataLoggingOp)
|
||||
.EnterState();
|
||||
do
|
||||
{
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
|
||||
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
|
||||
if (e.Contains(Event.ScaleTimeout))
|
||||
{
|
||||
Bridge.OnError(this, Strings.Mass_measurement_timeout);
|
||||
retVal = Event.RecoverableError;
|
||||
goto stopTest;
|
||||
}
|
||||
}
|
||||
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -648,7 +677,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(readTempPressOps)
|
||||
.AddOperation(testInProgress)
|
||||
.AddOperation(readStartMassOp)
|
||||
//.AddOperation(readStartMassOp)
|
||||
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
||||
.AddOperation(processDataLoggingOp)
|
||||
.EnterState();
|
||||
do {
|
||||
@@ -929,6 +959,10 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
for (int i = 0; i < waterMetersCount; i++)
|
||||
{
|
||||
GenericDevices.IRegReader rr = sensPath.RegisterReaders[i];
|
||||
|
||||
if (rr is ICommonRegReader)
|
||||
(rr as ICommonRegReader).EndWMState = dataEntryCmpnt.WMEndState(i);
|
||||
|
||||
|
||||
if (rr is Rig.RegisterReaders.StandingStartStop.RegisterReader)
|
||||
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).EndWMState = dataEntryCmpnt.WMEndState(i);
|
||||
@@ -977,7 +1011,34 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//...MF...kvapkanie
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.Measuring_the_weight);
|
||||
//------------------------------------------------
|
||||
State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name))
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(readTempPressOps)
|
||||
.AddOperation(testInProgress)
|
||||
.AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
||||
.AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec))
|
||||
.AddOperation(processDataLoggingOp)
|
||||
.EnterState();
|
||||
do
|
||||
{
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
|
||||
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
|
||||
if (e.Contains(Event.ScaleTimeout))
|
||||
{
|
||||
Bridge.OnError(this, Strings.Mass_measurement_timeout);
|
||||
retVal = Event.RecoverableError;
|
||||
goto stopTest;
|
||||
}
|
||||
}
|
||||
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
|
||||
///
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.Test_completed);
|
||||
@@ -1197,6 +1258,14 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|
||||
&& (tstRslt.ErrorFlags == 0);
|
||||
meterRslt.TestDone = true;
|
||||
tstRslt.TestDone = true;
|
||||
if (regReader is ICommonRegReader regReaderCommon)
|
||||
// if (meterRslt.WaterMeter != null
|
||||
// && tstRslt is ICommonRegReader tstRsltCommon
|
||||
// && !string.IsNullOrEmpty(tstRsltCommon.SerialNr))
|
||||
{
|
||||
meterRslt.WaterMeter.SerialNr = regReaderCommon.SerialNr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Compound
|
||||
{
|
||||
public class Component : ComponentBase, GenericDevices.ITestMethod
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Component));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
public bool CanTest(MetersKind meters) { return meters == MetersKind.Combined; }
|
||||
public bool DoTransitions() { return true; }
|
||||
public bool CheckDeviceCaps(Test test, OutputPath devices, out string message)
|
||||
{
|
||||
return StandingStartMassCollection.StandingStartMassCollectionSeq.CheckDeviceCaps(test, devices, out message);
|
||||
}
|
||||
|
||||
public Component() { }
|
||||
///
|
||||
public Component(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
///
|
||||
public override void Initialize() { }
|
||||
|
||||
public IList<Event> Execute(Test test, int repetNr, bool isLastRepetition)
|
||||
{
|
||||
return (new StandingStartMassCollection.StandingStartMassCollectionSeq()).Execute(test, repetNr, isLastRepetition, true, null, DebugLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Configs.NameOnly;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Compound
|
||||
{
|
||||
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 StandingStartMassCollection.Compound.Component(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new StandingStartMassCollection.Compound.Component(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new TestMethodCfg(this.GetType().Namespace.Substring(20), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters
|
||||
{
|
||||
public class Component : ComponentBase, GenericDevices.ITestMethod
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Component));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
public bool CanTest(MetersKind meters) { return meters == MetersKind.HeatMeter; }
|
||||
public bool DoTransitions() { return true; }
|
||||
public bool CheckDeviceCaps(Test test, OutputPath devices, out string message)
|
||||
{
|
||||
return StandingStartMassCollection.StandingStartMassCollectionSeq.CheckDeviceCaps(test, devices, out message);
|
||||
}
|
||||
|
||||
|
||||
readonly TestMethodCfg testMethodCfg;
|
||||
|
||||
public Component() { }
|
||||
///
|
||||
public Component(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
testMethodCfg = cfg as TestMethodCfg;
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
///
|
||||
public override void Initialize() { }
|
||||
|
||||
public IList<Event> Execute(Test test, int repetNr, bool isLastRepetition)
|
||||
{
|
||||
return (new StandingStartMassCollectionPoseidon.StandingStartMassCollectionPoseidonSeq()).Execute(test, repetNr, isLastRepetition, false, testMethodCfg.TestParams, DebugLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters
|
||||
{
|
||||
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 StandingStartMassCollection.HeatMeters.Component(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new StandingStartMassCollection.HeatMeters.Component(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new TestMethodCfg(this.GetType().Namespace.Substring(20), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2016 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters
|
||||
{
|
||||
public class TestMethodCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestMethodCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new TestMethodCfgCtrl(); }
|
||||
|
||||
/// <summary> Test parameters </summary>
|
||||
[XmlIgnore]
|
||||
public TestParams TestParams;
|
||||
public override IParamsProvider GetRuntimeTestParamsProvider() { return TestParams; }
|
||||
public override IParamsProvider CreateTestParamsProvider() { return new TestParams(true); }
|
||||
public override IParamsProvider GetUITestParamsProvider(Test test)
|
||||
{
|
||||
return (test.Method == Name) ? base.GetUITestParamsProvider(test) : null;
|
||||
}
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TestMethodCfg()
|
||||
{
|
||||
TestParams = new TestParams(true);
|
||||
}
|
||||
|
||||
public TestMethodCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = string.Empty;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2016 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters
|
||||
{
|
||||
public partial class TestMethodCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
StandingStartMassCollection.HeatMeters.TestMethodCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as StandingStartMassCollection.HeatMeters.TestMethodCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public TestMethodCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void EntryFormCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
return flags;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
config.Name = nameTextBox.Text;
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+86
@@ -0,0 +1,86 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2016 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters
|
||||
{
|
||||
partial class TestMethodCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(137, 57);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
|
||||
this.nameTextBox.TabIndex = 5;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(27, 60);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 4;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(134, 33);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 3;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// BasicPrinterCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "BasicPrinterCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(300, 200);
|
||||
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,197 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.HeatMeters
|
||||
{
|
||||
public class TestParams : TestParamsBase, IParamsProvider, ITestParams
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TestParams) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public float ErrorLimitLo; /// [%]
|
||||
public float ErrorLimitHi; /// [%]
|
||||
public bool EvaluateVolume; /// true = evaluate also the volume, false = evaluate only energy
|
||||
public float TempWarmLo; /// Low limit for warm temperature [°C]
|
||||
public float TempWarmHi; /// High limit for warm temperature [°C]
|
||||
public float TempColdLo; /// Low limit for cold temperature [°C]
|
||||
public float TempColdHi; /// High limit for cold temperature [°C]
|
||||
public bool FlowMeasuredAtHiTempPipe; /// true = flow measured at high temp. pipe, false = flow measured at low temp. pipe
|
||||
public float DeltaTempWarm;
|
||||
public float DeltaTempCold;
|
||||
public float ChangeInTimeWarm;
|
||||
public float ChangeInTimeCold;
|
||||
public string Prompt;
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
FlowMeasuredAtHiTempPipe = false;
|
||||
}
|
||||
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
Strings.Err_limit_neg_pct_chdr,
|
||||
Strings.Err_limit_pos_pct_chdr,
|
||||
Strings.Evaluate_volume,
|
||||
"T hi min",
|
||||
"T hi max",
|
||||
"T lo min",
|
||||
"T lo max",
|
||||
"Flow measured at high temp.pipe",
|
||||
"Delta T warm",
|
||||
"Delta T cold",
|
||||
"Change in time T warm",
|
||||
"Change in time T cold",
|
||||
Strings.Prompt,
|
||||
};
|
||||
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 ErrorLimitLo.ToString();
|
||||
case 1: return ErrorLimitHi.ToString();
|
||||
case 2: return (EvaluateVolume ? Strings.yes : Strings.no);
|
||||
case 3: return TempWarmLo.ToString();
|
||||
case 4: return TempWarmHi.ToString();
|
||||
case 5: return TempColdLo.ToString();
|
||||
case 6: return TempColdHi.ToString();
|
||||
case 7: return (FlowMeasuredAtHiTempPipe ? Strings.yes : Strings.no);
|
||||
case 8: return DeltaTempWarm.ToString();
|
||||
case 9: return DeltaTempCold.ToString();
|
||||
case 10: return ChangeInTimeWarm.ToString();
|
||||
case 11: return ChangeInTimeCold.ToString();
|
||||
case 12: return Prompt;
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: ErrorLimitLo = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 1: ErrorLimitHi = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 2: EvaluateVolume = strValue.Equals(Strings.yes); return CfgUpdateFlags.None;
|
||||
case 3: TempWarmLo = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 4: TempWarmHi = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 5: TempColdLo = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 6: TempColdHi = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 7: FlowMeasuredAtHiTempPipe = strValue.Equals(Strings.yes); return CfgUpdateFlags.None;
|
||||
case 8: DeltaTempWarm = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 9: DeltaTempCold = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 10: ChangeInTimeWarm = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 11: ChangeInTimeCold = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 12: Prompt = strValue; return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
float dummy;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
if (Utils.TryParseSFloat(strValue, out dummy)) return true;
|
||||
break;
|
||||
case 2:
|
||||
case 7:
|
||||
if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true;
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
if (Utils.TryParseUFloat(strValue, out dummy)) return true;
|
||||
break;
|
||||
case 12:
|
||||
return true;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = ParamName(i) + " is invalid";
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(TestParams prms)
|
||||
{
|
||||
prms.ErrorLimitLo = ErrorLimitLo;
|
||||
prms.ErrorLimitHi = ErrorLimitHi;
|
||||
prms.EvaluateVolume = EvaluateVolume;
|
||||
prms.TempWarmLo = TempWarmLo;
|
||||
prms.TempWarmHi = TempWarmHi;
|
||||
prms.TempColdLo = TempColdLo;
|
||||
prms.TempColdHi = TempColdHi;
|
||||
prms.FlowMeasuredAtHiTempPipe = FlowMeasuredAtHiTempPipe;
|
||||
prms.DeltaTempWarm = DeltaTempWarm;
|
||||
prms.DeltaTempCold = DeltaTempCold;
|
||||
prms.ChangeInTimeWarm = ChangeInTimeWarm;
|
||||
prms.ChangeInTimeCold = ChangeInTimeCold;
|
||||
prms.Prompt = Prompt;
|
||||
}
|
||||
|
||||
public IParamsProvider Clone()
|
||||
{
|
||||
TestParams pars = new TestParams();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public override void UpdateFromDbEntity(ComponentTest dbEntity)
|
||||
{
|
||||
if (dbEntity == null) return;
|
||||
try
|
||||
{
|
||||
TestParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as TestParams;
|
||||
|
||||
testParamsEntity = dbEntity;
|
||||
componentName = dbEntity.CmpntName;
|
||||
test = dbEntity.Test;
|
||||
|
||||
if (tmp != null) tmp.CopyContentTo(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameterless constructor initializes the parameters
|
||||
/// </summary>
|
||||
public TestParams()
|
||||
{
|
||||
}
|
||||
|
||||
public TestParams(bool initialize)
|
||||
{
|
||||
if (initialize) InitializeAll();
|
||||
}
|
||||
|
||||
public TestParams(ComponentTest testParamsEntity, string componentName, Test test)
|
||||
{
|
||||
this.testParamsEntity = testParamsEntity;
|
||||
this.componentName = componentName;
|
||||
this.test = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Single
|
||||
{
|
||||
public class Component : ComponentBase, GenericDevices.ITestMethod
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Component));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
public bool CanTest(MetersKind meters) { return meters == MetersKind.Single; }
|
||||
public bool DoTransitions() { return true; }
|
||||
public bool CheckDeviceCaps(Test test, OutputPath devices, out string message)
|
||||
{
|
||||
return StandingStartMassCollection.StandingStartMassCollectionSeq.CheckDeviceCaps(test, devices, out message);
|
||||
}
|
||||
|
||||
public Component() { }
|
||||
///
|
||||
public Component(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
///
|
||||
public override void Initialize() { }
|
||||
|
||||
public IList<Event> Execute(Test test, int repetNr, bool isLastRepetition)
|
||||
{
|
||||
return (new StandingStartMassCollection.StandingStartMassCollectionSeq()).Execute(test, repetNr, isLastRepetition, false, null, DebugLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2016 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Configs.NameOnly;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.StandingStartMassCollectionPoseidon.Single
|
||||
{
|
||||
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 StandingStartMassCollection.Single.Component(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new StandingStartMassCollection.Single.Component(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new TestMethodCfg(this.GetType().Namespace.Substring(20).Replace(".Single", ""), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(TestMethodCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1311
File diff suppressed because it is too large
Load Diff
@@ -187,8 +187,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
|
||||
///
|
||||
public int WMPulses { get { return wmPulses; } }
|
||||
public int WMRefPulses { get { return wmRefPulses; } }
|
||||
public double BeginWMState { get { return beginWMState; } }
|
||||
public double EndWMState { get { return endWMState; } }
|
||||
public double BeginWMState { get { return beginWMState; } set { beginWMState = value; }}
|
||||
public double EndWMState { get { return endWMState; } set { endWMState = value;} }
|
||||
public double WMVolume { get { return wmVolume; } }
|
||||
public double WMTestTime { get { return wmTestTime; } }
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
|
||||
|
||||
using TBF.Rig.Configs.NameOnly;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
|
||||
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
{
|
||||
public interface ISmartTestMethod
|
||||
{
|
||||
public void MeterCommMilestone(int iItem, bool bValue);
|
||||
public bool IsMeterCommMilestone(int iItem);
|
||||
|
||||
public ITestMethodCfg TestMethodCfg { get; }
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
public static string SelectedTypeReader { get; set; }
|
||||
|
||||
private List<ICorrections> GetNewCorrectionList(ISmartTestMethod componentBase ,
|
||||
TestMethodCfg cfg, IList<Test> tests, IList<ITestParams> multiTestParams)
|
||||
ITestMethodCfg cfg, IList<Test> tests, IList<ITestParams> multiTestParams)
|
||||
{
|
||||
List<ICorrections> correctionsList = new List<ICorrections>();
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
{
|
||||
if (correctionsList.Any(x => x is SmartReader))
|
||||
continue;
|
||||
correctionsList.Add(new PoseidonCorrections(this));
|
||||
correctionsList.Add(new PoseidonCorrections(this,log, rfidDataLogger, componentBase, cfg, tests, multiTestParams));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
ShuffleTextBoxes(ProcessData.WMsCount, ProcessData.LineSize);
|
||||
|
||||
|
||||
this.ContextMenu = Correction.GetContextMenu();
|
||||
//this.ContextMenu = Correction.GetContextMenu();
|
||||
|
||||
}
|
||||
|
||||
@@ -325,9 +325,11 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
{
|
||||
checkBoxesEditMode = false;
|
||||
|
||||
ITestMethodCfg cfg = (componentBase as ITestMethodCfg);
|
||||
ISmartTestMethod smartTestMethod = componentBase as ISmartTestMethod;
|
||||
|
||||
//TODO get corrections based on defined meter
|
||||
_corrections = GetNewCorrectionList(componentBase as ISmartTestMethod,
|
||||
componentBase.Cfg as TestMethodCfg, tests, multiTestParams);
|
||||
_corrections = GetNewCorrectionList(smartTestMethod, smartTestMethod.TestMethodCfg, tests, multiTestParams);
|
||||
InitializeMeterTypeItems();
|
||||
UpdateHeads();
|
||||
|
||||
@@ -381,6 +383,27 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
|
||||
private void UpdateHeads()
|
||||
{
|
||||
if (!(waterMeterPositions0 == null || waterMeterPositions0.Count <= 0)
|
||||
&& labels != null && counters != null && messages != null && checkBoxes != null)
|
||||
{
|
||||
foreach (int position in waterMeterPositions0)
|
||||
{
|
||||
try
|
||||
{
|
||||
labels[position].Visible = false;
|
||||
counters[position].Visible = false;
|
||||
messages[position].Visible = false;
|
||||
checkBoxes[position].Visible = false;
|
||||
ckbIndex[position] = 0;
|
||||
ckbState[position] = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error("UpdateHeads()", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iperlHeads?.Clear();
|
||||
if (iperlHeads == null) iperlHeads = new List<ISmartReader>();
|
||||
waterMeterPositions0?.Clear();
|
||||
@@ -415,6 +438,21 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
if (wmPos >= ProcessData.WMsCount) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//we have items from the list, so we can enable the rows
|
||||
if (iperlHeads.Count > 0)
|
||||
{
|
||||
WaterMetersCount = iperlHeads.Count;
|
||||
ShuffleTextBoxes(WaterMetersCount, ProcessData.LineSize);
|
||||
|
||||
this.ContextMenu = Correction.GetContextMenu();
|
||||
Correction.PrepareForTestsActivities(WaterMetersCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ContextMenu = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,6 +496,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
/// this part works fine if we are on <b>test loop</b>
|
||||
/// - because ProcessData.RegisterReaders is initialized in test loop
|
||||
/// </summary>
|
||||
/// <param name="selectedTypeReader"></param>
|
||||
private static void InitializeSmartReaderLists()
|
||||
{
|
||||
iperlHeads = new List<ISmartReader>();
|
||||
@@ -501,43 +540,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
/// <param name="lineSize">Number of watermeters in one line</param>
|
||||
void ShuffleTextBoxes(int wmsCount, int lineSize)
|
||||
{
|
||||
labels = new Label[MaxTextBoxesCount]
|
||||
{
|
||||
wmLabel1, wmLabel2, wmLabel3, wmLabel4, wmLabel5, wmLabel6, wmLabel7, wmLabel8, wmLabel9, wmLabel10,
|
||||
wmLabel11, wmLabel12, wmLabel13, wmLabel14, wmLabel15, wmLabel16, wmLabel17, wmLabel18, wmLabel19, wmLabel20,
|
||||
wmLabel21, wmLabel22, wmLabel23, wmLabel24, wmLabel25, wmLabel26, wmLabel27, wmLabel28, wmLabel29, wmLabel30,
|
||||
wmLabel31, wmLabel32, wmLabel33, wmLabel34, wmLabel35, wmLabel36, wmLabel37, wmLabel38, wmLabel39, wmLabel40,
|
||||
wmLabel41, wmLabel42, wmLabel43, wmLabel44, wmLabel45, wmLabel46, wmLabel47, wmLabel48,
|
||||
};
|
||||
counters = new PictureBox[MaxTextBoxesCount]
|
||||
{
|
||||
pictureBox1, pictureBox2, pictureBox3, pictureBox4, pictureBox5, pictureBox6, pictureBox7, pictureBox8, pictureBox9, pictureBox10,
|
||||
pictureBox11, pictureBox12, pictureBox13, pictureBox14, pictureBox15, pictureBox16, pictureBox17, pictureBox18, pictureBox19, pictureBox20,
|
||||
pictureBox21, pictureBox22, pictureBox23, pictureBox24, pictureBox25, pictureBox26, pictureBox27, pictureBox28, pictureBox29, pictureBox30,
|
||||
pictureBox31, pictureBox32, pictureBox33, pictureBox34, pictureBox35, pictureBox36, pictureBox37, pictureBox38, pictureBox39, pictureBox40,
|
||||
pictureBox41, pictureBox42, pictureBox43, pictureBox44, pictureBox45, pictureBox46, pictureBox47, pictureBox48,
|
||||
};
|
||||
messages = new TextBox[MaxTextBoxesCount]
|
||||
{
|
||||
wmTextBox1, wmTextBox2, wmTextBox3, wmTextBox4, wmTextBox5, wmTextBox6, wmTextBox7, wmTextBox8, wmTextBox9, wmTextBox10,
|
||||
wmTextBox11, wmTextBox12, wmTextBox13, wmTextBox14, wmTextBox15, wmTextBox16, wmTextBox17, wmTextBox18, wmTextBox19, wmTextBox20,
|
||||
wmTextBox21, wmTextBox22, wmTextBox23, wmTextBox24, wmTextBox25, wmTextBox26, wmTextBox27, wmTextBox28, wmTextBox29, wmTextBox30,
|
||||
wmTextBox31, wmTextBox32, wmTextBox33, wmTextBox34, wmTextBox35, wmTextBox36, wmTextBox37, wmTextBox38, wmTextBox39, wmTextBox40,
|
||||
wmTextBox41, wmTextBox42, wmTextBox43, wmTextBox44, wmTextBox45, wmTextBox46, wmTextBox47, wmTextBox48,
|
||||
};
|
||||
checkBoxes = new CheckBoxImage[MaxTextBoxesCount]
|
||||
{
|
||||
checkBoxImage1, checkBoxImage2, checkBoxImage3, checkBoxImage4, checkBoxImage5, checkBoxImage6, checkBoxImage7, checkBoxImage8, checkBoxImage9, checkBoxImage10,
|
||||
checkBoxImage11, checkBoxImage12, checkBoxImage13, checkBoxImage14, checkBoxImage15, checkBoxImage16, checkBoxImage17, checkBoxImage18, checkBoxImage19, checkBoxImage20,
|
||||
checkBoxImage21, checkBoxImage22, checkBoxImage23, checkBoxImage24, checkBoxImage25, checkBoxImage26, checkBoxImage27, checkBoxImage28, checkBoxImage29, checkBoxImage30,
|
||||
checkBoxImage31, checkBoxImage32, checkBoxImage33, checkBoxImage34, checkBoxImage35, checkBoxImage36, checkBoxImage37, checkBoxImage38, checkBoxImage39, checkBoxImage40,
|
||||
checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45, checkBoxImage46, checkBoxImage47, checkBoxImage48,
|
||||
};
|
||||
ckbIndex = new int[MaxTextBoxesCount];
|
||||
ckbState = new bool[MaxTextBoxesCount];
|
||||
|
||||
|
||||
textBoxesCount = MaxTextBoxesCount;
|
||||
InitializeTextBoxArrays();
|
||||
///
|
||||
if (wmsCount < textBoxesCount && lineSize > 0)
|
||||
{
|
||||
@@ -576,7 +579,56 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
ResizeDlgToFitEnabledControls();
|
||||
}
|
||||
|
||||
void ResizeDlgToFitEnabledControls()
|
||||
private void InitializeTextBoxArrays()
|
||||
{
|
||||
//if is initialized before we ignore initialization
|
||||
if (labels != null
|
||||
&& counters != null
|
||||
&& messages != null
|
||||
&& checkBoxes != null
|
||||
&& ckbIndex != null
|
||||
&& ckbState != null) return;
|
||||
|
||||
labels = new Label[MaxTextBoxesCount]
|
||||
{
|
||||
wmLabel1, wmLabel2, wmLabel3, wmLabel4, wmLabel5, wmLabel6, wmLabel7, wmLabel8, wmLabel9, wmLabel10,
|
||||
wmLabel11, wmLabel12, wmLabel13, wmLabel14, wmLabel15, wmLabel16, wmLabel17, wmLabel18, wmLabel19, wmLabel20,
|
||||
wmLabel21, wmLabel22, wmLabel23, wmLabel24, wmLabel25, wmLabel26, wmLabel27, wmLabel28, wmLabel29, wmLabel30,
|
||||
wmLabel31, wmLabel32, wmLabel33, wmLabel34, wmLabel35, wmLabel36, wmLabel37, wmLabel38, wmLabel39, wmLabel40,
|
||||
wmLabel41, wmLabel42, wmLabel43, wmLabel44, wmLabel45, wmLabel46, wmLabel47, wmLabel48,
|
||||
};
|
||||
counters = new PictureBox[MaxTextBoxesCount]
|
||||
{
|
||||
pictureBox1, pictureBox2, pictureBox3, pictureBox4, pictureBox5, pictureBox6, pictureBox7, pictureBox8, pictureBox9, pictureBox10,
|
||||
pictureBox11, pictureBox12, pictureBox13, pictureBox14, pictureBox15, pictureBox16, pictureBox17, pictureBox18, pictureBox19, pictureBox20,
|
||||
pictureBox21, pictureBox22, pictureBox23, pictureBox24, pictureBox25, pictureBox26, pictureBox27, pictureBox28, pictureBox29, pictureBox30,
|
||||
pictureBox31, pictureBox32, pictureBox33, pictureBox34, pictureBox35, pictureBox36, pictureBox37, pictureBox38, pictureBox39, pictureBox40,
|
||||
pictureBox41, pictureBox42, pictureBox43, pictureBox44, pictureBox45, pictureBox46, pictureBox47, pictureBox48,
|
||||
};
|
||||
messages = new TextBox[MaxTextBoxesCount]
|
||||
{
|
||||
wmTextBox1, wmTextBox2, wmTextBox3, wmTextBox4, wmTextBox5, wmTextBox6, wmTextBox7, wmTextBox8, wmTextBox9, wmTextBox10,
|
||||
wmTextBox11, wmTextBox12, wmTextBox13, wmTextBox14, wmTextBox15, wmTextBox16, wmTextBox17, wmTextBox18, wmTextBox19, wmTextBox20,
|
||||
wmTextBox21, wmTextBox22, wmTextBox23, wmTextBox24, wmTextBox25, wmTextBox26, wmTextBox27, wmTextBox28, wmTextBox29, wmTextBox30,
|
||||
wmTextBox31, wmTextBox32, wmTextBox33, wmTextBox34, wmTextBox35, wmTextBox36, wmTextBox37, wmTextBox38, wmTextBox39, wmTextBox40,
|
||||
wmTextBox41, wmTextBox42, wmTextBox43, wmTextBox44, wmTextBox45, wmTextBox46, wmTextBox47, wmTextBox48,
|
||||
};
|
||||
checkBoxes = new CheckBoxImage[MaxTextBoxesCount]
|
||||
{
|
||||
checkBoxImage1, checkBoxImage2, checkBoxImage3, checkBoxImage4, checkBoxImage5, checkBoxImage6, checkBoxImage7, checkBoxImage8, checkBoxImage9, checkBoxImage10,
|
||||
checkBoxImage11, checkBoxImage12, checkBoxImage13, checkBoxImage14, checkBoxImage15, checkBoxImage16, checkBoxImage17, checkBoxImage18, checkBoxImage19, checkBoxImage20,
|
||||
checkBoxImage21, checkBoxImage22, checkBoxImage23, checkBoxImage24, checkBoxImage25, checkBoxImage26, checkBoxImage27, checkBoxImage28, checkBoxImage29, checkBoxImage30,
|
||||
checkBoxImage31, checkBoxImage32, checkBoxImage33, checkBoxImage34, checkBoxImage35, checkBoxImage36, checkBoxImage37, checkBoxImage38, checkBoxImage39, checkBoxImage40,
|
||||
checkBoxImage41, checkBoxImage42, checkBoxImage43, checkBoxImage44, checkBoxImage45, checkBoxImage46, checkBoxImage47, checkBoxImage48,
|
||||
};
|
||||
ckbIndex = new int[MaxTextBoxesCount];
|
||||
ckbState = new bool[MaxTextBoxesCount];
|
||||
|
||||
|
||||
textBoxesCount = MaxTextBoxesCount;
|
||||
}
|
||||
|
||||
void ResizeDlgToFitEnabledControls()
|
||||
{
|
||||
int xMax = 0;
|
||||
int yMax = 0;
|
||||
@@ -645,7 +697,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
}
|
||||
|
||||
/// Start communication process by incrementing 'currentGroup'.
|
||||
currentGroup++;
|
||||
//currentGroup++;
|
||||
|
||||
int wtId = 0;
|
||||
foreach (var wt in Correction.GetAllThreads())
|
||||
@@ -869,6 +921,7 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
if (senderCombo == null) return;
|
||||
SelectedTypeReader = senderCombo.SelectedItem?.ToString();
|
||||
UpdateHeads();
|
||||
SmartCommunicationForm_Load(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
using TBF.Rig.Configs.NameOnly;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
|
||||
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication
|
||||
{
|
||||
public abstract class SmartComponentBase : ComponentBase, ISmartTestMethod
|
||||
{
|
||||
private ITestMethodCfg cfg;
|
||||
|
||||
public abstract void MeterCommMilestone(int iItem, bool bValue);
|
||||
public abstract bool IsMeterCommMilestone(int iItem);
|
||||
|
||||
public ITestMethodCfg TestMethodCfg { get => cfg; }
|
||||
|
||||
|
||||
public SmartComponentBase()
|
||||
: base()
|
||||
{
|
||||
cfg = null;
|
||||
}
|
||||
|
||||
public SmartComponentBase(IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
this.cfg = cfg as ITestMethodCfg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Common;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common
|
||||
{
|
||||
public interface ICommonRegReader : IRegReader
|
||||
{
|
||||
new string Name { get; }
|
||||
new DebugMode DebugLevel { get; set; }
|
||||
public string SerialNr { get; set; }
|
||||
|
||||
new double BeginWMState { get; set; } /// Test begin state of the water meter
|
||||
new double EndWMState { get; set; } /// Test end state of the water meter
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,14 @@ using TBF.Rig.RegisterReaders.CommonRR;
|
||||
|
||||
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common
|
||||
{
|
||||
public interface ISmartReader : IRegReader
|
||||
public interface ISmartReader : ICommonRegReader
|
||||
{
|
||||
new string Name { get; }
|
||||
new DebugMode DebugLevel { get; set; }
|
||||
public string SerialNr { get; }
|
||||
new string SerialNr { get; set; }
|
||||
new double BeginWMState { get; set; } /// Test begin state of the water meter
|
||||
new double EndWMState { get; set; } /// Test end state of the water meter
|
||||
|
||||
public string CommInterface { get; }
|
||||
public int RfidComPortNr { get; }
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
{
|
||||
public static class EnumExtensions
|
||||
{
|
||||
public static bool TryParseByDescription<TEnum>(string description, out TEnum result)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
foreach (var field in typeof(TEnum).GetFields())
|
||||
{
|
||||
var attribute = Attribute.GetCustomAttribute(field,
|
||||
typeof(DescriptionAttribute)) as DescriptionAttribute;
|
||||
|
||||
if ((attribute != null && attribute.Description == description) ||
|
||||
field.Name == description)
|
||||
{
|
||||
result = (TEnum)field.GetValue(null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+458
-15
@@ -1,19 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
using Results.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
using TBF.Rig.RegisterReaders.PoseidonCmdStartStop;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.implementations;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
|
||||
using TBF.Rig.TestMethods.SmartTest;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using CheckBoxImage = TBF.Boxes.CheckBoxImage;
|
||||
using Factory = TBF.Rig.RegisterReaders.iPerlReaderUNI.Factory;
|
||||
using PoseidonReader = TBF.Rig.RegisterReaders.PoseidonCmdStartStop.PoseidonReader;
|
||||
|
||||
namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
{
|
||||
@@ -32,6 +41,16 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
private IList<Test> tests;
|
||||
private IList<ITestParams> multiTestParams;
|
||||
private SmartCommunicationForm _parentFrom;
|
||||
|
||||
static IList<Thread> workerThreads;
|
||||
static bool stopWorkerThreads;
|
||||
static int currentActivityStep;
|
||||
static int currentGroup;
|
||||
|
||||
/// form -> worker thread (0 = none)
|
||||
static int lastGroup;
|
||||
|
||||
static int completedCommCount;
|
||||
|
||||
|
||||
public string TypeIdentificatorName()
|
||||
@@ -56,12 +75,122 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
|
||||
public IList<ISmartReader> iperlHeads { get => ParentFrom.Heads;}
|
||||
|
||||
private Label activityLabel { get => ParentFrom?.ActivityLabel;}
|
||||
private Label[] labels { get => ParentFrom?.Labels; }
|
||||
private PictureBox[] counters{get => ParentFrom?.Counters;}
|
||||
private TextBox[] messages{get => ParentFrom?.Messages;}
|
||||
private CheckBoxImage[] checkBoxes{get => ParentFrom?.CheckBoxes;}
|
||||
private int[] ckbIndex{get => ParentFrom?.CkbIndex;}
|
||||
private bool[] ckbState{get => ParentFrom?.CkbState;}
|
||||
|
||||
|
||||
|
||||
|
||||
public void Worker(object threadData)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
int threadID = (threadData as Boxes.IntBox)?.Val ?? -1;
|
||||
|
||||
int activityStep = 0; /// activity step > 0 in case multiTestParams are used
|
||||
|
||||
for (int iMultiTestParamsItem = 0; iMultiTestParamsItem < MultiTestParams.Count; iMultiTestParamsItem++)
|
||||
{
|
||||
Test currentTest = Tests[iMultiTestParamsItem];
|
||||
ITestParams currentTestParams = MultiTestParams[iMultiTestParamsItem];
|
||||
string currentActivity = currentTestParams.Activity; /// Current activity
|
||||
|
||||
TBF.UiBridge.TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 10, 0, 140, 0, 0, 0 });
|
||||
TBF.UiBridge.Bridge.OnTestProgress(null,
|
||||
new TBF.UiBridge.TestProgressEventArgs(currentTest, Progress.JustStarted));
|
||||
|
||||
|
||||
if (threadID == 0)
|
||||
{
|
||||
StartDataStreamProcessingForActiveMeters(iMultiTestParamsItem);
|
||||
|
||||
/// A new activity starts - information into RFID data log
|
||||
rfidDataLogger.InfoFormat("");
|
||||
rfidDataLogger.WarnFormat("Activity = {0}", currentActivity);
|
||||
rfidDataLogger.InfoFormat("");
|
||||
}
|
||||
|
||||
for (int group = 1; group <= lastGroup; group++)
|
||||
{
|
||||
/// Synchronize with QuidoRS and other threads
|
||||
while (((group != currentGroup) || (activityStep != currentActivityStep)) &&
|
||||
!GetStopWorkerThreads())
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
if (GetStopWorkerThreads()) break;
|
||||
|
||||
// #if TURA_SPECIAL
|
||||
int threadIx = threadID; /// Just one thread for TURA_SPECIAL
|
||||
// #else
|
||||
// for (int threadIx = threadID; threadIx < threadID + 4; threadIx += Cfg.NrThreads)
|
||||
// #endif
|
||||
{
|
||||
bool wmFound = false;
|
||||
|
||||
for (int wmNr0 = 0; wmNr0 < iperlHeads.Count; wmNr0++)
|
||||
{
|
||||
//TODO BUMI doplnit if podomienky - last grop je teraz 1 ak existuju readre
|
||||
if(iperlHeads[wmNr0] is SmartReader ihead)
|
||||
// if ((ihead.Group == group) && (threadIx < muxBrdOrGroup14Nrs.Count) &&
|
||||
// (ihead.MuxBoardNrOrGroup14 == muxBrdOrGroup14Nrs[threadIx]))
|
||||
{
|
||||
wmFound = true;
|
||||
|
||||
WaterMeter wm = null;
|
||||
if (ProcessData.BatchRslts.Batch.WaterMeters != null)
|
||||
{
|
||||
foreach (var w in ProcessData.BatchRslts.Batch.WaterMeters)
|
||||
{
|
||||
if (w.WMPosition == wmNr0 + 1)
|
||||
{
|
||||
wm = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Do worker activity
|
||||
CommErr error = CommErr.None;
|
||||
string resultStr = string.Empty;
|
||||
|
||||
|
||||
WorkerActivity(currentActivity, ihead, wm, currentTest,
|
||||
wmNr0, ref error, ref resultStr, ckbState, threadID, currentActivityStep);
|
||||
ProcessResultOfWorkerActivity(iMultiTestParamsItem, currentActivity,
|
||||
currentGroup, ihead, wm, wmNr0, error, resultStr, ckbState, threadID);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
TBF.UiBridge.Bridge.OnTestProgress(null,
|
||||
new TBF.UiBridge.TestProgressEventArgs(Tests[iMultiTestParamsItem],
|
||||
Progress.FlowSetting));
|
||||
}
|
||||
|
||||
if (!wmFound)
|
||||
{
|
||||
SmartCommunicationForm.OnCommCompleted(null,
|
||||
new CommCompletedEventArgs(threadID, -1, null, null, string.Empty,
|
||||
CommErr.None)); /// Send negative wmNr
|
||||
}
|
||||
|
||||
if (GetStopWorkerThreads()) break;
|
||||
}
|
||||
|
||||
if (GetStopWorkerThreads()) break;
|
||||
} /// for (int group
|
||||
|
||||
TBF.UiBridge.Bridge.OnTestProgress(null,
|
||||
new TBF.UiBridge.TestProgressEventArgs(Tests[iMultiTestParamsItem], Progress.Completed));
|
||||
activityStep++;
|
||||
|
||||
if (GetStopWorkerThreads()) break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool WorkerActivity(string currentActivity, ISmartReader iHead, WaterMeter wm, Test currentTest, int wmNr0,
|
||||
@@ -78,17 +207,17 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
|
||||
public void StopWorkerThreads(bool bStopAllThreads)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
stopWorkerThreads = bStopAllThreads;
|
||||
}
|
||||
|
||||
public bool GetStopWorkerThreads()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return stopWorkerThreads;
|
||||
}
|
||||
|
||||
public IList<Thread> GetAllThreads()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return workerThreads;
|
||||
}
|
||||
|
||||
public ICorrections GetNewCorrection()
|
||||
@@ -100,37 +229,229 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ContextMenu GetContextMenu()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public void PrepareForTestsActivities( int waterMeterPositions0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
StartTime = DateTime.Now;
|
||||
StartTimeSec = StateMachine.Time;
|
||||
|
||||
///
|
||||
/// Prepare worker threads, 'rfidPortNrs', 'lastGroup', etc..
|
||||
///
|
||||
currentActivityStep = 0;
|
||||
currentGroup = 0;
|
||||
completedCommCount = 0;
|
||||
stopWorkerThreads = false;
|
||||
lastGroup = 0;
|
||||
|
||||
if (iperlHeads != null)
|
||||
{
|
||||
foreach (var iSmartReader in iperlHeads)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iSmartReader is SmartReader reader){
|
||||
if (reader != null ) lastGroup = 1;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
log.ErrorFormat("PrepareForTestsActivities: {0}", E.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
workerThreads = new List<Thread>();
|
||||
if (Cfg != null)
|
||||
{
|
||||
for (int i = 0; i < Cfg.NrThreads; i++)
|
||||
{
|
||||
Thread thread = new Thread(Worker);
|
||||
thread.CurrentCulture = CultureInfo.CurrentCulture;
|
||||
thread.CurrentUICulture = CultureInfo.CurrentUICulture;
|
||||
workerThreads.Add(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Load(Label[] labels, PictureBox[] counters, TextBox[] messages, CheckBoxImage[] checkBoxes, int[] ckbIndex,
|
||||
bool[] ckbState, IList<ISmartReader> iperlHeads, int textBoxesCount, bool checkBoxesEditMode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (iperlHeads == null)
|
||||
{
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = true;
|
||||
messages[i].Text = "---";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
///
|
||||
/// Set checkbox states accroding to iPerlHeads[i].Disabled states
|
||||
///
|
||||
for (int i = 0; i < textBoxesCount; i++)
|
||||
{
|
||||
labels[i].Visible = counters[i].Visible = messages[i].Visible = checkBoxes[i].Visible = true;
|
||||
|
||||
|
||||
ISmartReader iperlHead = iperlHeads[i];
|
||||
if (!checkBoxesEditMode && (iperlHead == null || iperlHead.Disabled))
|
||||
{
|
||||
/// iPerl position i+1 is disabled
|
||||
checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = false;
|
||||
counters[i].BackColor = iPerlCommunicationConstants.DisabledColor;
|
||||
messages[i].Text = "Strings.Head_was_disabled_by_the_user";
|
||||
}
|
||||
else
|
||||
{
|
||||
/// iPerl position i+1 is enabled
|
||||
checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = true;
|
||||
messages[i].Text = "---";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetHeadsCount()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return ParentFrom?.Heads?.Count() ?? 0;
|
||||
}
|
||||
|
||||
public void StartDataStreamProcessingForActiveMeters(int iMultiTestParamsItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/// Check whether previous activity was 'Set test mode A0' or 'A4'
|
||||
if (iMultiTestParamsItem > 0 &&
|
||||
MultiTestParams[iMultiTestParamsItem - 1].Activity.ToLower()
|
||||
.Contains(iPerlCommunicationConstants.SetTestModeStr.ToLower()) &&
|
||||
!MultiTestParams[iMultiTestParamsItem - 1].Activity.Contains("80"))
|
||||
{
|
||||
/// Start processing of opto-datastreams from all iPERL-s
|
||||
int count = 0;
|
||||
for (int wmNr0 = 0; wmNr0 < iperlHeads.Count; wmNr0++)
|
||||
{
|
||||
WaterMeter wm = (ProcessData.BatchRslts.Batch.WaterMeters != null &&
|
||||
ProcessData.BatchRslts.Batch.WaterMeters.Count > wmNr0)
|
||||
? ProcessData.BatchRslts.Batch.WaterMeters[wmNr0]
|
||||
: null;
|
||||
|
||||
ISmartReader ihead = iperlHeads[wmNr0];
|
||||
|
||||
if (ihead != null && wm != null && !wm.Disabled)
|
||||
{
|
||||
lock (ihead)
|
||||
{
|
||||
ihead.StartDataStreamProcessing();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.WarnFormat("End of activity '{0}', StartDataStreamProcessing() of {1} heads was called.",
|
||||
MultiTestParams[iMultiTestParamsItem - 1].Activity, count);
|
||||
}
|
||||
}
|
||||
|
||||
public void DoOnCommCompleted(object sender, CommCompletedEventArgs data, IList<int> waterMeterPositions0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
try
|
||||
{
|
||||
///
|
||||
/// Update the text message
|
||||
///
|
||||
if (data.WMNr0 >= 0) messages[data.WMNr0].Text = data.CommMessage;
|
||||
|
||||
///
|
||||
/// Update head active/inactive switch
|
||||
///
|
||||
if (data.WMNr0 >= 0 && data.CommErr == CommErr.HeadDisabledByUser)
|
||||
{
|
||||
/// iPerl head was disabled by the user
|
||||
ckbState[data.WMNr0] = false;
|
||||
checkBoxes[data.WMNr0].Checked = false;
|
||||
checkBoxes[data.WMNr0].Enabled = false;
|
||||
if (data.Ihead != null) data.Ihead.Disabled = true;
|
||||
if (data.Wm != null) data.Wm.Disabled = true;
|
||||
}
|
||||
else if (data.WMNr0 >= 0 && data.CommErr == CommErr.None)
|
||||
{
|
||||
/// One RFID communication successful => iPerl cannot be disabled by the user anymore
|
||||
ckbState[data.WMNr0] = true;
|
||||
checkBoxes[data.WMNr0].Checked = true;
|
||||
checkBoxes[data.WMNr0].Enabled = false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Update opto-communication indication
|
||||
///
|
||||
for (int i = 0; i < iperlHeads.Count; i++)
|
||||
{
|
||||
if (iperlHeads[i] == null || iperlHeads[i].Disabled)
|
||||
{
|
||||
counters[i].BackColor = iPerlCommunicationConstants.DisabledColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iperlHeads[i] is SmartReader iperlHead)
|
||||
{
|
||||
|
||||
OptoHeadState checkFlowDirection =
|
||||
((iperlHead == null) ? OptoHeadState.Disabled : iperlHead.CheckFlowDirection());
|
||||
switch (checkFlowDirection)
|
||||
{
|
||||
case OptoHeadState.OptoAndDirOK:
|
||||
counters[i].BackColor = iPerlCommunicationConstants.OptoAndDirOKColor;
|
||||
break;
|
||||
|
||||
case OptoHeadState.DirNok:
|
||||
counters[i].BackColor = iPerlCommunicationConstants.DirNokColor;
|
||||
break;
|
||||
|
||||
default:
|
||||
case OptoHeadState.OptoNok:
|
||||
counters[i].BackColor = iPerlCommunicationConstants.OptoNokColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !TURA_SPECIAL
|
||||
///
|
||||
/// Branch
|
||||
///
|
||||
lock (this)
|
||||
{
|
||||
if (++completedCommCount < 4) return;
|
||||
completedCommCount = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (currentGroup < lastGroup)
|
||||
{
|
||||
/// Go to the next step / next group
|
||||
currentGroup++;
|
||||
}
|
||||
else if (currentActivityStep + 1 < MultiTestParams.Count)
|
||||
{
|
||||
currentGroup = 0;
|
||||
currentActivityStep++;
|
||||
activityLabel.Text = MultiTestParams[currentActivityStep].Activity;
|
||||
currentGroup++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Wait until all threads are finished
|
||||
workerThreads[data.ThreadId].Join(2000);
|
||||
ParentFrom.NormalClose();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.ErrorFormat("DoOnCommCompleted({0}) failed: {1}", data, e.Message);
|
||||
log.FatalFormat("StackTrace : {0}{1}", Environment.NewLine, e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
public void NormalClose(IList<int> waterMeterPositions0)
|
||||
@@ -171,7 +492,129 @@ namespace TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
this.cfg = cfg;
|
||||
this.multiTestParams = multiTestParams;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
///
|
||||
private MenuItem NewMenuItem(string text, string tag)
|
||||
{
|
||||
MenuItem menuItem = new MenuItem { Text = text, Tag = tag };
|
||||
menuItem.Click += OnClick_Optical_Heads_Settings_Menu;
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
private async void OnClick_Optical_Heads_Settings_Menu(object sender, EventArgs e)
|
||||
{
|
||||
// Validate sender
|
||||
if (!(sender is MenuItem menuItem))
|
||||
{
|
||||
log?.Error("OnClick_Optical_Heads_Settings_Menu: sender is not a MenuItem");
|
||||
return;
|
||||
}
|
||||
|
||||
if (activityLabel != null)
|
||||
activityLabel.Text = menuItem.Text;
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var iSmartReader in ProcessData.SmartHeadsUni)
|
||||
{
|
||||
if (!(iSmartReader is SmartReader iHead))
|
||||
{
|
||||
continue;//ignore different types of heads
|
||||
}
|
||||
|
||||
int position = iHead.Position;
|
||||
if (position < 0 || position >= checkBoxes.Length || position >= messages.Length)
|
||||
{
|
||||
continue; // Skip this head if position is out of range
|
||||
}
|
||||
if (!checkBoxes[position].Checked)
|
||||
{
|
||||
if (position < messages.Length) messages[position].Text = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
messages[position].Text = $@"COM{iHead.RfidComPortNr}";
|
||||
Application.DoEvents(); // Refresh UI
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
string result = await ProcessTask(iHead.RegPoseidonCfg, menuItem.Tag);
|
||||
ParentFrom?.Invoke((Action)(() =>
|
||||
{
|
||||
messages[position].Text = result;
|
||||
Application.DoEvents(); // Refresh UI
|
||||
}));
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
public static bool TryParseByDescription(string description, out PoseidonImplHeadTestCtrl.Operations result)
|
||||
{
|
||||
foreach (PoseidonImplHeadTestCtrl.Operations op
|
||||
in Enum.GetValues(typeof(PoseidonImplHeadTestCtrl.Operations)))
|
||||
{
|
||||
// step-by-step compare
|
||||
var desc = ((Enum)op).ToDescription(); // uses extension above
|
||||
|
||||
// exact compare, you can use OrdinalIgnoreCase if you want
|
||||
if (string.Equals(desc, description, StringComparison.Ordinal))
|
||||
{
|
||||
result = op;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = PoseidonImplHeadTestCtrl.Operations.Empty;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private async Task<string> ProcessTask(IComponentCfg head, object tag)
|
||||
{
|
||||
string txt = "";
|
||||
PoseidonImplHeadTestCtrl.Operations operation;
|
||||
if (!TryParseByDescription((string)tag, out operation))
|
||||
{
|
||||
operation = PoseidonImplHeadTestCtrl.Operations.Empty;
|
||||
}
|
||||
|
||||
if (head is PoseidonCfg poseidonCfg)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case PoseidonImplHeadTestCtrl.Operations.ReadSerialNo:
|
||||
txt = OpticalHeadTest.ReadRequest_SerialNo(poseidonCfg);
|
||||
break;
|
||||
case PoseidonImplHeadTestCtrl.Operations.SetTestModeOn:
|
||||
txt = OpticalHeadTest.SetTestMode(poseidonCfg);
|
||||
break;
|
||||
case PoseidonImplHeadTestCtrl.Operations.SetTestModeOff:
|
||||
txt = OpticalHeadTest.SetActiveMode(poseidonCfg);
|
||||
break;
|
||||
default:
|
||||
txt = "-";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
public ContextMenu GetContextMenu()
|
||||
{
|
||||
ContextMenu cm = new ContextMenu();
|
||||
foreach (KeyValuePair<string, PoseidonImplHeadTestCtrl.Operations> itemsOperation in PoseidonImplHeadTestCtrl.ItemsOperations)
|
||||
{
|
||||
cm.MenuItems.Add(NewMenuItem(itemsOperation.Key, itemsOperation.Value.ToDescription()));
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1406,11 +1406,14 @@
|
||||
<Compile Include="Rig\RegisterReaders\StandingStartStop\Factory.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\StandingStartStop\RRProcParams.cs" />
|
||||
<Compile Include="Rig\RegValvePosition.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\ISerialPort.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\ScaleCfg.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\Scale.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\Factory.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\GetSerNumOp.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\ReadStableMassOp.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\SerialPortDevice.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\SerialPortDeviceFake.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\SetUnitsOp.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\TaringOp.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\ZeroOp.cs" />
|
||||
@@ -1643,6 +1646,21 @@
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionAdvance\Single\Component.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionAdvance\Single\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionAdvance\StandingStartMassCollectionAdvanceSeq.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\Compound\Component.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\Compound\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\Component.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\TestMethodCfg.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\TestMethodCfgCtrl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\TestMethodCfgCtrl.designer.cs">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\TestParams.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\Single\Component.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\Single\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\StandingStartMassCollectionPoseidonSeq.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollection\Compound\Component.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollection\Compound\Factory.cs" />
|
||||
<Compile Include="Rig\TestMethods\StandingStartMassCollection\HeatMeters\Component.cs" />
|
||||
@@ -2046,8 +2064,10 @@
|
||||
<Compile Include="Rig\Uni\RegValve\SetFlowOp.cs" />
|
||||
<Compile Include="Rig\Uni\RegValve\SetRegValvePositionOp.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\AllCompletedEventArgs.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\common\ICommonRegReader.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\common\ICorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\common\ISmartReader.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\EnumExtensions.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\IPerlCorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\PoseidonCorrections.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\SmartComponentBase.cs" />
|
||||
@@ -3440,6 +3460,9 @@
|
||||
<EmbeddedResource Include="Rig\TestMethods\StandingStartMassCollectionAdvance\HeatMeters\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\TestMethods\StandingStartMassCollectionPoseidon\HeatMeters\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Rig\TestMethods\StandingStartMassCollection\HeatMeters\TestMethodCfgCtrl.resx">
|
||||
<DependentUpon>TestMethodCfgCtrl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using TBF.Boxes;
|
||||
using TBF.Rig;
|
||||
using TBF.Rig.BuiltIn.Valve;
|
||||
using TBF.Rig.ControlBoard.Uni;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.Scales.MettlerToledo;
|
||||
using Factory = TBF.Rig.Scales.MettlerToledo.Factory;
|
||||
|
||||
namespace TBFTests.Rig.Scales.MettlerToledo
|
||||
{
|
||||
[TestClass]
|
||||
[TestSubject(typeof(ReadStableMassOp))]
|
||||
public class ReadStableMassOpTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void Run_ReadStableMassOp()
|
||||
{
|
||||
//
|
||||
var mockControlBoard = new Mock<TBF.Rig.ControlBoard.IControlBoard>();
|
||||
mockControlBoard.Setup(v => v.Name).Returns("UniCB");
|
||||
|
||||
IList<IComponent> componentsBoard = new List<IComponent>() { mockControlBoard.Object};
|
||||
StateMachine.InitializeBoardEtc_Fake(componentsBoard);
|
||||
|
||||
Factory factory = new Factory();
|
||||
ScaleCfg cfg = new ScaleCfg("Scale0", factory);
|
||||
cfg.Evaporation = "Evaporation0";
|
||||
//
|
||||
var mockValve = new Mock<IValve>();
|
||||
mockValve.Setup(v => v.Name).Returns(cfg.DrainValve);
|
||||
//
|
||||
var mockEvaporation = new Mock<IEvaporation>();
|
||||
mockEvaporation.Setup(v => v.Name).Returns(cfg.Evaporation);
|
||||
|
||||
|
||||
|
||||
//components
|
||||
IComponent valveObject = mockValve.Object;
|
||||
IComponent evaporationObject = mockEvaporation.Object;
|
||||
IList<IComponent> components = new List<IComponent>() { valveObject, mockControlBoard.Object, evaporationObject };
|
||||
StateMachine.InitializeBoardEtc_Fake(components);
|
||||
|
||||
ValveCfg valveCfg = new ValveCfg(new ValveFactory());
|
||||
var valveFactory = new ValveFactory();
|
||||
IComponent iComponent = valveFactory.GetComponent(valveCfg,components);
|
||||
|
||||
|
||||
SerialPortDeviceFake serialPort = new SerialPortDeviceFake();
|
||||
Scale scale = factory.GetComponent(cfg,null, serialPort) as Scale;
|
||||
scale.DebugLevel = DebugMode.Normal;
|
||||
|
||||
|
||||
|
||||
|
||||
scale.Initialize();
|
||||
|
||||
|
||||
|
||||
DoubleBox finalMass = new DoubleBox();
|
||||
ReadStableMassOp readStableMassOp = new ReadStableMassOp(scale, ref finalMass, 2, MassMethod.Scale, 4, 0.05);
|
||||
|
||||
//////////////////////////////////
|
||||
/// Start
|
||||
|
||||
readStableMassOp.Start();
|
||||
|
||||
/// Run
|
||||
bool stopLoop = false;
|
||||
while(!stopLoop)
|
||||
{
|
||||
Event run = readStableMassOp.Run();
|
||||
|
||||
if (run == Event.Abort || run == Event.ScaleDone)
|
||||
{
|
||||
stopLoop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (StateMachine.Time >= 2 && StateMachine.Time < 3) // delay
|
||||
{
|
||||
//must be send command to stabilisate mass
|
||||
Assert.IsTrue(scale.Activity == Activity.RunningOperation);
|
||||
Assert.IsTrue(serialPort.IsOpen);
|
||||
Assert.IsTrue(serialPort.LastWrite.Contains("S\r\n"));
|
||||
Assert.IsTrue(string.IsNullOrEmpty(serialPort.LastRead));
|
||||
}
|
||||
|
||||
//time gap between measurements - 60 sec
|
||||
|
||||
if (StateMachine.Time == 61) //valid measurement
|
||||
{
|
||||
//FIRST measurement
|
||||
Assert.IsTrue(scale.Activity == Activity.RunningOperation);
|
||||
//try simulate immediate measurement
|
||||
scale.Activity = Activity.ImmediateMeasurement;
|
||||
scale.RunDeviceBefore();
|
||||
Assert.IsTrue(scale.Activity == Activity.Idle);
|
||||
Assert.IsTrue(scale.MsrmntState == MsrmntState.Valid);
|
||||
Assert.IsTrue(scale.Mass-0.1 < 170.725 && scale.Mass+0.1 > 170.724); //value from fake serial port
|
||||
}
|
||||
|
||||
if (StateMachine.Time == 62) //valid measurement
|
||||
{
|
||||
//SECOND measurement - forced answer
|
||||
scale.Activity = Activity.ImmediateMeasurement;
|
||||
serialPort.ForceReturnAnswer("S S 0.000 kg");
|
||||
scale.RunDeviceBefore();
|
||||
Assert.IsTrue(scale.Activity == Activity.Idle);
|
||||
Assert.IsTrue(scale.MsrmntState == MsrmntState.Valid);
|
||||
Assert.IsTrue(scale.Mass-0.1 < 0 && scale.Mass+0.1 > 0);
|
||||
}
|
||||
|
||||
////////// ERROR CASES
|
||||
if (StateMachine.Time >= 63 && StateMachine.Time < 65) // 2x invalid parameter S_I
|
||||
{
|
||||
//FAILED in customer measurement - forced answer
|
||||
scale.Activity = Activity.ImmediateMeasurement;
|
||||
serialPort.ForceReturnAnswer("S I"); //not ready scale
|
||||
scale.RunDeviceBefore();
|
||||
Assert.IsTrue(scale.MsrmntState == MsrmntState.Failed);
|
||||
Assert.IsTrue(scale.Activity == Activity.Idle);
|
||||
}
|
||||
// SET Correct answer
|
||||
if (StateMachine.Time >= 66 && StateMachine.Time < 70) //valid parametrs - IF 4 times valid measurement finish and calculate average final mass
|
||||
{
|
||||
//FAILED in customer measurement - forced answer
|
||||
scale.Activity = Activity.ImmediateMeasurement;
|
||||
serialPort.ForceReturnAnswer("S S 120.56 kg"); //not ready scale
|
||||
scale.RunDeviceBefore();
|
||||
Assert.IsTrue(scale.MsrmntState == MsrmntState.Valid);
|
||||
Assert.IsTrue(scale.Activity == Activity.Idle);
|
||||
}
|
||||
////////// ~ ERROR CASES
|
||||
|
||||
|
||||
if (StateMachine.Time >= 70)
|
||||
{
|
||||
Assert.Fail( "Timeout");
|
||||
return;
|
||||
}
|
||||
|
||||
Thread.Sleep(10);
|
||||
StateMachine.Time += 1;
|
||||
}
|
||||
/// Stop
|
||||
readStableMassOp.Stop();
|
||||
|
||||
Assert.IsTrue(scale.Activity == Activity.Idle);
|
||||
Assert.IsTrue(scale.MsrmntState == MsrmntState.Valid);
|
||||
Assert.IsTrue(finalMass.Val-0.1 < 60.28 && finalMass.Val+0.1 > 60.28);
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using Common;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.implementations;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations;
|
||||
|
||||
namespace TBFTests.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations
|
||||
{
|
||||
[TestClass]
|
||||
[TestSubject(typeof(PoseidonCorrections))]
|
||||
public class PoseidonCorrectionsTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void TryParseByDescription_test()
|
||||
{
|
||||
PoseidonImplHeadTestCtrl.Operations testOp = PoseidonImplHeadTestCtrl.Operations.ReadSerialNo;
|
||||
ValidateOperationParsing(testOp.ToDescription());
|
||||
testOp = PoseidonImplHeadTestCtrl.Operations.SetTestModeOn;
|
||||
ValidateOperationParsing(testOp.ToDescription());
|
||||
testOp = PoseidonImplHeadTestCtrl.Operations.SetTestModeOff;
|
||||
ValidateOperationParsing(testOp.ToDescription());
|
||||
|
||||
//negative test
|
||||
ValidateOperationParsing("khvcdh jkbhvf", false);
|
||||
}
|
||||
|
||||
private static void ValidateOperationParsing(string tag, bool expectedResult = true)
|
||||
{
|
||||
PoseidonImplHeadTestCtrl.Operations operation;
|
||||
if (!PoseidonCorrections.TryParseByDescription((string)tag, out operation))
|
||||
{
|
||||
Assert.IsFalse(expectedResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(operation.ToDescription() == tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,8 @@
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\CliRunnerTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonCmdStartStop\PoseidonReaderTest.cs" />
|
||||
<Compile Include="Rig\RegisterReaders\PoseidonReader\UniHeadTestCtrlTest.cs" />
|
||||
<Compile Include="Rig\Scales\MettlerToledo\ReadStableMassOpTest.cs" />
|
||||
<Compile Include="Rig\Uni\SharedDialogs\SmartMetersCommunication\implementations\PoseidonCorrectionsTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
@@ -124,6 +126,10 @@
|
||||
<Project>{9d0dcc88-dc81-47eb-9fdd-4c3907871bfb}</Project>
|
||||
<Name>Results</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SchematicDrawing\SchematicDrawing.csproj">
|
||||
<Project>{0f79ca69-9dbc-41f3-a6fc-5a2937365343}</Project>
|
||||
<Name>SchematicDrawing</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TBF\TBF.csproj">
|
||||
<Project>{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}</Project>
|
||||
<Name>TBF</Name>
|
||||
|
||||
Reference in New Issue
Block a user