FixedStartMassCollection modified, ControlBoard.Elde repmoved, ver. 3.1.1624
This commit is contained in:
@@ -66,7 +66,7 @@ namespace TBF.Rig.ControlBoard
|
||||
/// Error .............. unspecified error while running a test
|
||||
/// </summary>
|
||||
/// <returns>Operation running a test</returns>
|
||||
IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount);
|
||||
IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount, bool withDiverter);
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2016 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public enum Command
|
||||
{
|
||||
None = 0, /// Do nothing, just transfer data (route, etc.)
|
||||
Start = 1, /// Start the measurement
|
||||
Stop = 2, /// Stop the measurement
|
||||
ReadDivTransition = 4,
|
||||
ReadExtremasOfPulses = 6,
|
||||
ReadShapesOfPulses = 7,
|
||||
ResetShapesOfPulses = 8,
|
||||
EnduranceCycleParamsUpload = 11,
|
||||
EnduranceCycleStart = 12,
|
||||
EnduranceCycleStop = 13,
|
||||
}
|
||||
|
||||
#if FUZHOU_300 || IZRAEL_200 || TORINO_50 || BADGER_MALA_TRAT || BADGER_STREDNA_TRAT || TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL || BADGER_VELKA_TRAT || PUCHONG_200 || SLM_50 || GENESIS || MALTA_WSD25 || SLM_END || WARSAW_END || BERLIN || GELSENWASSER || SLM_150 || PETERSBURG_50 || PETERSBURG_200 || DEWA_300 || ROMA_200 || KEMPNO_50 || BAHRAIN_50 || RUM_MOB || KRAKOW_50 || JUZNA_AFRIKA_50 || IZRAEL_25 || ZAMBIA || ZODINO || FEWA_50 || FILIPINY_50 || SENTEC || FUZHOU_100 || CEVAK_200 || IZRAEL_50 || ALZIR_25
|
||||
public enum StatusP : ulong
|
||||
{
|
||||
RefFlowMeterMask = 0x7, /// bits 0,1,2
|
||||
TestCompleted = 0x10, /// bit 4
|
||||
TestInProgress = 0x20, /// bit 5
|
||||
//DiverterError = 0x20,
|
||||
MsrmntWithDivrtr = 0x80, /// bit 7
|
||||
RefPulsesMsrmnt = 0x100, /// bit 8
|
||||
SynchroMethod = 0x800, /// bit 11
|
||||
WaterMeterCalib = 0x1000, /// bit 12
|
||||
EmgcyStopActive = 0x2000, /// bit 13
|
||||
MsrmntGateActive = 0x4000, /// bit 14
|
||||
TimeMeasurement = 0x8000, /// bit 15
|
||||
FrequencyMeasured = 0x80000, /// bit 19
|
||||
CoaxRegValveBusy = 0x200000, /// bit 21
|
||||
ADCError = 0x80000000, /// bit 31
|
||||
TimeoutOccured = 0x100000000, /// bit 32
|
||||
MeretAddresses = 0x200000000, /// bit 33
|
||||
SampleBuferFull = 0x400000000, /// bit 34
|
||||
ErrorTempMeter = 0x10000000000, /// bit 40
|
||||
ErrorPressMeter1 = 0x1000000000000, /// bit 48
|
||||
ErrorPressMeter2 = 0x2000000000000, /// bit 49
|
||||
ErrorPressMeter3 = 0x4000000000000, /// bit 50
|
||||
ErrorPressMeter4 = 0x8000000000000, /// bit 51
|
||||
EndurCycleRunning = 0x200000000000000, /// bit 57
|
||||
}
|
||||
#else // DN100 || MUNICH || FUZHOU_150 || TORUN_50 || CEVAK_40 || MURES_40 || FUZHOU_50
|
||||
public enum StatusP : ulong
|
||||
{
|
||||
RefFlowMeterMask = 0x7,
|
||||
TestInProgress = 0x8,
|
||||
TestCompleted = 0x10,
|
||||
DiverterError = 0x20,
|
||||
MsrmntWithDivrtr = 0x80,
|
||||
RefPulsesMsrmnt = 0x100,
|
||||
SynchroMethod = 0x800,
|
||||
WaterMeterCalib = 0x1000,
|
||||
EmgcyStopActive = 0x2000,
|
||||
MsrmntGateActive = 0x4000,
|
||||
TimeMeasurement = 0x8000,
|
||||
FrequencyMeasured = 0x80000,
|
||||
CoaxRegValveBusy = 0x200000, /// bit 21
|
||||
ADCError = 0x80000000,
|
||||
TimeoutOccured = 0x100000000,
|
||||
MeretAddresses = 0x200000000,
|
||||
SampleBuferFull = 0x400000000,
|
||||
ErrorTempMeter = 0x10000000000,
|
||||
ErrorPressMeter1 = 0x1000000000000,
|
||||
ErrorPressMeter2 = 0x2000000000000,
|
||||
ErrorPressMeter3 = 0x4000000000000,
|
||||
ErrorPressMeter4 = 0x8000000000000,
|
||||
EndurCycleRunning = 0x200000000000000, /// bit 57
|
||||
}
|
||||
#endif
|
||||
|
||||
public enum StopDevs
|
||||
{
|
||||
None = 0,
|
||||
Reference = 0x01, /// bit 0
|
||||
Diverter = 0x02, /// bit 1
|
||||
GatePulse = 0x08, /// bit 3
|
||||
TimeMeasurement = 0x10, /// bit 4
|
||||
BypassDevCoupled2Div = 0x20, /// bit 5
|
||||
RegValveRegulation = 0x80, /// bit 7
|
||||
All = 0xFF,
|
||||
}
|
||||
|
||||
public enum TestMethods
|
||||
{
|
||||
Diverter = 0x01, /// bit 0: 1=Mass method (diverters are used), 0=Volume method
|
||||
FixedStart = 0x02, /// bit 1: 1=fixed start method, 0=flying start method
|
||||
Synchro = 0x04, /// bit 2: 1=Synchro method, 0=Pulse counting
|
||||
MassAndContinue = 0x10, /// bit 4: 1=Method with mass measurement followed by a volume method
|
||||
}
|
||||
|
||||
public enum RegulValveMode : byte
|
||||
{
|
||||
None = 0,
|
||||
PulseWidth = 1, /// Pulse width 0.05 .. 2 sec.
|
||||
TargetPosition = 2, /// Low and high position (=DAC value) limits (0..100%) are specified
|
||||
TargetFrequency = 3, /// Low and high frequency limits (0..2000Hz,0..2200Hz) are specified
|
||||
Stop = 4, /// Stop regulation
|
||||
}
|
||||
|
||||
public enum RegulValveState
|
||||
{
|
||||
Idle = 0,
|
||||
PwOrFreqRegul = 2,
|
||||
DacValueRegul = 3,
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2016 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class ControlBoardCfg : ComponentCfgBase, IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ControlBoardCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new ControlBoardCfgCtrl(); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public int ComPortNr;
|
||||
public int VirtualValvesRangeLo;
|
||||
public int VirtualValvesRangeHi;
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
ControlBoardCfg()
|
||||
{
|
||||
Name = "CB";
|
||||
ParentName = string.Empty;
|
||||
ComPortNr = 1;
|
||||
VirtualValvesRangeLo = 50;
|
||||
VirtualValvesRangeHi = 59;
|
||||
}
|
||||
|
||||
public ControlBoardCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, Com{1}, VVRangeLo={2}, VVRangeHi={3}", Name, ComPortNr, VirtualValvesRangeLo, VirtualValvesRangeHi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
partial class ControlBoardCfgCtrl
|
||||
{
|
||||
/// <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.comPortNrLabel = new System.Windows.Forms.Label();
|
||||
this.comPortNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.vValveRangeLoTextBox = new System.Windows.Forms.TextBox();
|
||||
this.vValveRangeLoLabel = new System.Windows.Forms.Label();
|
||||
this.vValveRangeHiTextBox = new System.Windows.Forms.TextBox();
|
||||
this.vValveRangeHiLabel = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// comPortNrLabel
|
||||
//
|
||||
this.comPortNrLabel.AutoSize = true;
|
||||
this.comPortNrLabel.Location = new System.Drawing.Point(42, 85);
|
||||
this.comPortNrLabel.Name = "comPortNrLabel";
|
||||
this.comPortNrLabel.Size = new System.Drawing.Size(95, 13);
|
||||
this.comPortNrLabel.TabIndex = 0;
|
||||
this.comPortNrLabel.Text = "Serial port number:";
|
||||
//
|
||||
// comPortNrTextBox
|
||||
//
|
||||
this.comPortNrTextBox.Enabled = false;
|
||||
this.comPortNrTextBox.Location = new System.Drawing.Point(166, 82);
|
||||
this.comPortNrTextBox.Name = "comPortNrTextBox";
|
||||
this.comPortNrTextBox.Size = new System.Drawing.Size(80, 20);
|
||||
this.comPortNrTextBox.TabIndex = 1;
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(163, 26);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 2;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(42, 60);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||
this.nameLabel.TabIndex = 3;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(166, 57);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(80, 20);
|
||||
this.nameTextBox.TabIndex = 4;
|
||||
//
|
||||
// vValveRangeLoTextBox
|
||||
//
|
||||
this.vValveRangeLoTextBox.Enabled = false;
|
||||
this.vValveRangeLoTextBox.Location = new System.Drawing.Point(166, 107);
|
||||
this.vValveRangeLoTextBox.Name = "vValveRangeLoTextBox";
|
||||
this.vValveRangeLoTextBox.Size = new System.Drawing.Size(80, 20);
|
||||
this.vValveRangeLoTextBox.TabIndex = 6;
|
||||
//
|
||||
// vValveRangeLoLabel
|
||||
//
|
||||
this.vValveRangeLoLabel.AutoSize = true;
|
||||
this.vValveRangeLoLabel.Location = new System.Drawing.Point(42, 110);
|
||||
this.vValveRangeLoLabel.Name = "vValveRangeLoLabel";
|
||||
this.vValveRangeLoLabel.Size = new System.Drawing.Size(118, 13);
|
||||
this.vValveRangeLoLabel.TabIndex = 5;
|
||||
this.vValveRangeLoLabel.Text = "Virtual valves range Lo:";
|
||||
//
|
||||
// vValveRangeHiTextBox
|
||||
//
|
||||
this.vValveRangeHiTextBox.Enabled = false;
|
||||
this.vValveRangeHiTextBox.Location = new System.Drawing.Point(166, 132);
|
||||
this.vValveRangeHiTextBox.Name = "vValveRangeHiTextBox";
|
||||
this.vValveRangeHiTextBox.Size = new System.Drawing.Size(80, 20);
|
||||
this.vValveRangeHiTextBox.TabIndex = 8;
|
||||
//
|
||||
// vValveRangeHiLabel
|
||||
//
|
||||
this.vValveRangeHiLabel.AutoSize = true;
|
||||
this.vValveRangeHiLabel.Location = new System.Drawing.Point(42, 135);
|
||||
this.vValveRangeHiLabel.Name = "vValveRangeHiLabel";
|
||||
this.vValveRangeHiLabel.Size = new System.Drawing.Size(116, 13);
|
||||
this.vValveRangeHiLabel.TabIndex = 7;
|
||||
this.vValveRangeHiLabel.Text = "Virtual valves range Hi:";
|
||||
//
|
||||
// ControlBoardCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.vValveRangeHiTextBox);
|
||||
this.Controls.Add(this.vValveRangeHiLabel);
|
||||
this.Controls.Add(this.vValveRangeLoTextBox);
|
||||
this.Controls.Add(this.vValveRangeLoLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Controls.Add(this.comPortNrTextBox);
|
||||
this.Controls.Add(this.comPortNrLabel);
|
||||
this.Name = "ControlBoardCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(300, 200);
|
||||
this.Load += new System.EventHandler(this.ControlBoardCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label comPortNrLabel;
|
||||
private System.Windows.Forms.TextBox comPortNrTextBox;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.TextBox vValveRangeLoTextBox;
|
||||
private System.Windows.Forms.Label vValveRangeLoLabel;
|
||||
private System.Windows.Forms.TextBox vValveRangeHiTextBox;
|
||||
private System.Windows.Forms.Label vValveRangeHiLabel;
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2015 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public partial class ControlBoardCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
ControlBoardCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as ControlBoardCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public ControlBoardCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void ControlBoardCfgCtrl_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;
|
||||
comPortNrTextBox.Text = config.ComPortNr.ToString();
|
||||
vValveRangeLoTextBox.Text = config.VirtualValvesRangeLo.ToString();
|
||||
vValveRangeHiTextBox.Text = config.VirtualValvesRangeHi.ToString();
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
comPortNrTextBox.Enabled = true;
|
||||
vValveRangeLoTextBox.Enabled = true;
|
||||
vValveRangeHiTextBox.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify current user controls for validity.
|
||||
/// Called when user wants to close/save the configuration.
|
||||
/// </summary>
|
||||
/// <returns>See VerifyFlags</returns>
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
int dummy;
|
||||
if (!int.TryParse(comPortNrTextBox.Text, out dummy) || dummy <= 0 || dummy > 999)
|
||||
{
|
||||
message += "Control board serial port number is invalid";
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
}
|
||||
if (!int.TryParse(vValveRangeLoTextBox.Text, out dummy) || dummy < 0 || dummy > 63)
|
||||
{
|
||||
message += "Virtual valves range Lo is invalid";
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
}
|
||||
if (!int.TryParse(vValveRangeHiTextBox.Text, out dummy) || dummy < 0 || dummy > 63)
|
||||
{
|
||||
message += "Virtual valves range Hi is invalid";
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save settings to the configuration class.
|
||||
/// </summary>
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
this.Name = nameTextBox.Text;
|
||||
this.config.ComPortNr = int.Parse(comPortNrTextBox.Text);
|
||||
this.config.VirtualValvesRangeLo = int.Parse(vValveRangeLoTextBox.Text);
|
||||
this.config.VirtualValvesRangeHi = int.Parse(vValveRangeHiTextBox.Text);
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
<?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>
|
||||
@@ -1,887 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO.Ports;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using Config.Entities;
|
||||
using Dirichlet.Numerics;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class CBoard : ComponentBase, IControlBoard
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(CBoard));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
const int FiltersCount = 8;
|
||||
|
||||
readonly ControlBoardCfg controlBoardCfg;
|
||||
|
||||
///
|
||||
/// Reference to the control board component
|
||||
///
|
||||
IControlCom controlCom;
|
||||
|
||||
/// <summary>
|
||||
/// Emergency stop signal state updated by RunDevice().
|
||||
/// 'modelessDlg' is notified about the changes and uses this information to change its visibility.
|
||||
/// </summary>
|
||||
//UiBridge.EmergencyStopEventArgs.State emergencyStopState;
|
||||
|
||||
|
||||
///
|
||||
/// Public read only wrappers for Elde software component fields
|
||||
///
|
||||
/// rvNr1 = 1 .. nrRegulValves (one based)
|
||||
/// wmNr0 = 0 .. nrWaterMeters-1 (zero based)
|
||||
/// tmpNr0 = 0 .. nrTempMeters-1 (zero based)
|
||||
/// prsNr0 = 0 .. nrPressureMeters-1 (zero based)
|
||||
///
|
||||
public StatusP StatusP { get { return controlCom.StatusP; } }
|
||||
public int EtPulsesK { get { return controlCom.EtPulsesK; } }
|
||||
public int EtPulses2 { get { return controlCom.EtPulses2; } } /// DEWA_300: pulses from I12
|
||||
public int EtPulses3 { get { return controlCom.EtPulses3; } } /// DEWA_300: pulses from I13
|
||||
public int WMeterReference(int wmNr0) { return controlCom.WMeterReference(wmNr0); }
|
||||
public uint RegulValveDAC(int rvNr0) { return controlCom.RegulValveDAC(rvNr0); }
|
||||
public float Pressure(int prsNr0) { return controlCom.Pressure(prsNr0); }
|
||||
public float Temperature(int tmpNr0) { return controlCom.Temperature(tmpNr0); }
|
||||
public RegulValveState RegulValveState(int rvNr1) { return (RegulValveState)controlCom.RegulValveState(rvNr1); }
|
||||
public UInt128 RRoute { get { return controlCom.RRoute; } }
|
||||
public uint DivTime(int id) { return controlCom.DivTime(id); }
|
||||
public uint FmState { get { return controlCom.FmState; } }
|
||||
public uint BeginState(int wmNr0) { return controlCom.BeginState(wmNr0); }
|
||||
public double RefFrequency { get { return controlCom.ReferenceFreq; } } /// In [Hz] 0..2500, nom.=2000
|
||||
public double ReferenceFreqs(int i) { return controlCom.ReferenceFreqs(i); }
|
||||
public double RefFlow { get { return controlCom.ReferenceFlow; } }
|
||||
public float RValvePosition(int rvNr1) { return controlCom.RValvePosition(rvNr1); }
|
||||
public float DivSamples(int time, int divIx0) { return controlCom.DivSamples(time, divIx0); } /// Time unit is 2 ms
|
||||
public int ScopeSamples(int i, int j, int k) { return controlCom.ScopeSamples(i, j, k); }
|
||||
public ulong DigitalInputs { get { return controlCom.DigitalInputs; } }
|
||||
public float AnalogInput(int adcNr0) { return controlCom.AnalogInput(adcNr0); }
|
||||
public uint AnalogInputRaw(int adcNr0, int bank) { return controlCom.AnalogInputRaw(adcNr0, bank); } /// adcNr0: 0=RV1, 1=RV2,... bank: 0=RV, 1=Temp
|
||||
public float ReferenceVolume { get { return controlCom.TotalRefVolume; } }
|
||||
public float VyslExt(int wmNr0, int what) { return controlCom.VyslExt(wmNr0, what); }
|
||||
public uint[] CyclePar { get { return controlCom.CyclePar; } set { controlCom.CyclePar = value; } }
|
||||
public uint[] WMeterCont { get { return controlCom.WMeterCont; } }
|
||||
public bool ManualUIAllowed { get { return controlCom.ManualUIAllowed; } set { controlCom.ManualUIAllowed = value; } }
|
||||
public float ValveOpenCloseTime { get { return controlCom.ValveOpenCloseTime; } }
|
||||
|
||||
public int FlowmeterId { get { return (int)(controlCom.StatusP & Legacy.StatusP.RefFlowMeterMask); } }
|
||||
|
||||
/// <summary> Extracted from the StatusP in RunDeviceBefore </summary>
|
||||
public bool EmergencyStop { get { return emergencyStop; } }
|
||||
bool emergencyStop;
|
||||
bool previousEmergencyStop;
|
||||
|
||||
|
||||
///
|
||||
/// IControlBoard interface
|
||||
///
|
||||
public int RefPulses { get { return controlCom.EtPulses(0); } }
|
||||
public double TestTime { get { return (double)controlCom.TTime; } }
|
||||
public int RefPulsesWM(int wmNr1) { return (wmNr1 > 0 && wmNr1 <= Config.Data.WMsCount) ? controlCom.EtPulses(wmNr1) : 0; }
|
||||
public int PulsesWM(int wmNr1) { return (wmNr1 > 0 && wmNr1 <= Config.Data.WMsCount) ? unwrappedWMPulses[wmNr1] : 0; }
|
||||
public double TestTimeWM(int wmNr1) { return (wmNr1 > 0 && wmNr1 <= Config.Data.WMsCount) ? (double)controlCom.ImpulseTime(wmNr1) : 0; }
|
||||
|
||||
|
||||
public void DiverterToTank(int flowMtrNr)
|
||||
{
|
||||
cbCommandQueue.Enqueue(new SendCommandArgs(Command.Start, flowMtrNr, int.MaxValue, int.MaxValue, TestMethods.Diverter | TestMethods.Synchro, StopDevs.None));
|
||||
}
|
||||
///
|
||||
public void DiverterToSink(int flowMtrNr)
|
||||
{
|
||||
cbCommandQueue.Enqueue(new SendCommandArgs(Command.Stop, 0, 0, 0, TestMethods.Diverter,
|
||||
StopDevs.Diverter | StopDevs.GatePulse | StopDevs.Reference | StopDevs.RegValveRegulation));
|
||||
}
|
||||
///
|
||||
public void ReadDiverterTransition(int flowMtrNr)
|
||||
{
|
||||
cbCommandQueue.Enqueue(new SendCommandArgs(Command.ReadDivTransition, flowMtrNr, 0, 0, TestMethods.Diverter, 0));
|
||||
}
|
||||
|
||||
///
|
||||
/// Initialization data updated by constructors of children components
|
||||
/// and sent to 'controlCom2panel' by SendCalibData() method.
|
||||
///
|
||||
#if DEWA_300 || ROMA_200
|
||||
public float[,] TempCalibData = new float[16, 5];
|
||||
#else
|
||||
public float[,] TempCalibData = new float[8, 5];
|
||||
#endif
|
||||
public uint[] DiverterEdge; /// Created and initialized in this.Initialize()
|
||||
public byte MeretProtocol = 0;
|
||||
|
||||
// Array length is the reference flowmeters count plus one
|
||||
#if DN100 || FUZHOU_150 || FUZHOU_300 || IZRAEL_200 || SENTEC || CEVAK_200
|
||||
public uint[,] RegValveCalib = new uint[8,2] {{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500}};
|
||||
public byte[] MeretRS485Address = new byte[4];
|
||||
public float[] EtCalib = new float[6] { 1, 1, 1, 1, 1, 1 };
|
||||
#elif PUCHONG_200 || GENESIS || BERLIN || GELSENWASSER || PETERSBURG_200 || RUM_MOB || SLM_150
|
||||
public uint[,] RegValveCalib = new uint[16, 2] { {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500},
|
||||
{100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500} };
|
||||
public byte[] MeretRS485Address = new byte[4];
|
||||
public float[] EtCalib = new float[7] { 1, 1, 1, 1, 1, 1, 1 };
|
||||
#elif DEWA_300
|
||||
public uint[,] RegValveCalib = new uint[16, 2] { {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500},
|
||||
{100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500} };
|
||||
public byte[] MeretRS485Address = new byte[4];
|
||||
public float[] EtCalib = new float[8] { 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
#elif ROMA_200
|
||||
public uint[,] RegValveCalib = new uint[16, 2] { {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500},
|
||||
{100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500}, {100,500} };
|
||||
public byte[] MeretRS485Address = new byte[5];
|
||||
public float[] EtCalib = new float[8] { 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
#elif MUNICH || TORINO_50 || BADGER_MALA_TRAT || BADGER_STREDNA_TRAT || TORUN_50 || CEVAK_40 || TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL || MURES_40 || FUZHOU_50 || SLM_50 || PETERSBURG_50 || KEMPNO_50 || BAHRAIN_50 || KRAKOW_50 || JUZNA_AFRIKA_50 || IZRAEL_25 || ZAMBIA || ZODINO || FEWA_50 || FILIPINY_50 || FUZHOU_100 || ALZIR_25
|
||||
public uint[,] RegValveCalib = new uint[8,2] {{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500}};
|
||||
#if IZRAEL_50
|
||||
public byte[] MeretRS485Address = new byte[6];
|
||||
#else
|
||||
public byte[] MeretRS485Address = new byte[4];
|
||||
#endif
|
||||
public float[] EtCalib = new float[5] { 1, 1, 1, 1, 1 };
|
||||
#elif IZRAEL_50 || SLM_END
|
||||
public uint[,] RegValveCalib = new uint[8,2] {{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500}};
|
||||
public byte[] MeretRS485Address = new byte[7]; /// Modbus addresses of Pr1, Pr2, Pr3, Pr4, Pr5, Pr6, T9 (Izrael) or Pr1, Pr2, Pr3, Pr4, T9, T10 (SLM END)
|
||||
public float[] EtCalib = new float[5] { 1, 1, 1, 1, 1 };
|
||||
#elif WARSAW_END
|
||||
public uint[,] RegValveCalib = new uint[8,2] {{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500}};
|
||||
public byte[] MeretRS485Address = new byte[4];
|
||||
public float[] EtCalib = new float[5] { 1, 1, 1, 1, 1 };
|
||||
#elif MALTA_WSD25
|
||||
public uint[,] RegValveCalib = new uint[8,2] {{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500}};
|
||||
public byte[] MeretRS485Address = new byte[12];
|
||||
public float[] EtCalib = new float[9] { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
#elif BADGER_VELKA_TRAT
|
||||
public uint[,] RegValveCalib = new uint[8,2] {{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500},{100,500}};
|
||||
public byte[] MeretRS485Address = new byte[4];
|
||||
public float[] EtCalib = new float[8] { 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
#else
|
||||
/// New benches => no initialization buffers at all
|
||||
public uint[,] RegValveCalib = new uint[0,0];
|
||||
public byte[] MeretRS485Address = new byte[0];
|
||||
public float[] EtCalib = new float[0];
|
||||
#endif
|
||||
|
||||
public uint[] BalanceRange = new uint[2];
|
||||
|
||||
|
||||
|
||||
Queue<SendCommandArgs> cbCommandQueue;
|
||||
|
||||
/// <summary>
|
||||
/// Route: 128-bit word representing the current state of all valves and pumps
|
||||
/// </summary>
|
||||
public UInt128 Route { get { return benchModelRoute; } }
|
||||
UInt128 benchModelRoute;
|
||||
UInt128 valvesToInvert; /// Route = valesToInvert ^ RequiredRouteWithoutInvertedVlaves
|
||||
readonly UInt128 routeMask; /// This mask masks out virtual valves, routeMask is set in the constructor
|
||||
|
||||
|
||||
public OutputPath Devices
|
||||
{
|
||||
set { devices = value; }
|
||||
get { return devices; }
|
||||
}
|
||||
OutputPath devices;
|
||||
|
||||
|
||||
int[] filters;
|
||||
float[] FMFreq;
|
||||
int regConst;
|
||||
int shortImp;
|
||||
|
||||
|
||||
private int[] unwrappedWMPulses; /// Initialized to zeros
|
||||
///
|
||||
private void UnwrapPulses()
|
||||
{
|
||||
for (int i = 1; i <= Config.Data.WMsCount; i++)
|
||||
{
|
||||
UInt16 lowerWord = controlCom.WMeterPulses(i);
|
||||
int uncorrected = (int)(((uint)unwrappedWMPulses[i] & 0xFFFF0000) | lowerWord);
|
||||
if (Math.Abs(uncorrected - unwrappedWMPulses[i]) <= Int16.MaxValue)
|
||||
{
|
||||
unwrappedWMPulses[i] = uncorrected;
|
||||
}
|
||||
else if (Math.Abs(uncorrected + 65536 - unwrappedWMPulses[i]) <= Int16.MaxValue)
|
||||
{
|
||||
unwrappedWMPulses[i] = uncorrected + 65536;
|
||||
}
|
||||
else if (Math.Abs(uncorrected - 65536 - unwrappedWMPulses[i]) <= Int16.MaxValue)
|
||||
{
|
||||
unwrappedWMPulses[i] = uncorrected - 65536;
|
||||
}
|
||||
}
|
||||
}
|
||||
///
|
||||
public void ClearProcessValues()
|
||||
{
|
||||
for (int i = 1; i <= Config.Data.WMsCount; i++)
|
||||
{
|
||||
unwrappedWMPulses[i] = 0;
|
||||
}
|
||||
UnwrapPulses();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set values to be applied during a test
|
||||
/// </summary>
|
||||
/// <param name="filters">Filters for meter pulses</param>
|
||||
/// <param name="pid">PID coefficient for flow control</param>
|
||||
/// <param name="shortPulses">Short pulses mode (0 = off)</param>
|
||||
public void SetFiltersPidShortPulses(int[] filters, float pid, int shortPulses)
|
||||
{
|
||||
this.filters = filters;
|
||||
this.regConst = (int)pid;
|
||||
this.shortImp = shortPulses;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the power of the selected pump
|
||||
/// </summary>
|
||||
/// <param name="index">Pump index 0 .. 5, invalid pump index sets all pumps to 0%</param>
|
||||
/// <param name="power">Power (0.0f .. 100.0f)</param>
|
||||
public void SetFMFreq(int index, double power)
|
||||
{
|
||||
bool pumpPowerChanged = false;
|
||||
|
||||
#if DN100 || MUNICH || FUZHOU_150
|
||||
if ((FMFreq == null) || (FMFreq.Length != 2))
|
||||
{
|
||||
FMFreq = new float[2];
|
||||
pumpPowerChanged = true; /// Forces sending a command using Command.None
|
||||
}
|
||||
#elif SLM_END || WARSAW_END
|
||||
if ((FMFreq == null) || (FMFreq.Length != 4))
|
||||
{
|
||||
FMFreq = new float[4];
|
||||
pumpPowerChanged = true; /// Forces sending a command using Command.None
|
||||
}
|
||||
#else /// all newer benches
|
||||
if ((FMFreq == null) || (FMFreq.Length != 6))
|
||||
{
|
||||
FMFreq = new float[6];
|
||||
pumpPowerChanged = true; /// Forces sending a command using Command.None
|
||||
}
|
||||
#endif
|
||||
|
||||
if (index >= 0 && index < FMFreq.Length)
|
||||
{
|
||||
if (FMFreq[index] != power)
|
||||
{
|
||||
FMFreq[index] = (float)power;
|
||||
|
||||
pumpPowerChanged = true; /// Forces sending a command using Command.None
|
||||
|
||||
string s = string.Format("FMFreq=[{0}{1}{2}{3}{4}{5}]", FMFreq[0].ToString(),
|
||||
(FMFreq.Length > 1) ? ("," + FMFreq[1].ToString()) : "",
|
||||
(FMFreq.Length > 2) ? ("," + FMFreq[2].ToString()) : "",
|
||||
(FMFreq.Length > 3) ? ("," + FMFreq[3].ToString()) : "",
|
||||
(FMFreq.Length > 4) ? ("," + FMFreq[4].ToString()) : "",
|
||||
(FMFreq.Length > 5) ? ("," + FMFreq[5].ToString()) : "");
|
||||
log.Warn(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.ErrorFormat("Wrong FM pump: index = {0}, power = {1}", index, power);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UpdateWeights()
|
||||
{
|
||||
/// Mettler-Toledo scales
|
||||
//for (int i = 0; i < MettlerToledo.Standard.BalanceDev.BalancesCount; i++)
|
||||
//{
|
||||
// controlCom.SetWeight(i, MettlerToledo.Standard.BalanceDev.Masses[i]);
|
||||
//}
|
||||
|
||||
///// Mettler-Toledo-multi scales (Badger Brno, ...)
|
||||
//for (int i = 0; i < MettlerToledo.Multi.BalanceDev.BalancesCount; i++)
|
||||
//{
|
||||
// controlCom.SetWeight(i, MettlerToledo.Multi.BalanceDev.Masses[i]);
|
||||
//}
|
||||
|
||||
///// Tanks (CEVAK, ...)
|
||||
//int firstTankIx = Math.Max(MettlerToledo.Standard.BalanceDev.BalancesCount, MettlerToledo.Multi.BalanceDev.BalancesCount);
|
||||
|
||||
//for (int i = 0; i < Various.TankWithLevelMsrmnt.Tank.TanksCount; i++)
|
||||
//{
|
||||
// controlCom.SetWeight(firstTankIx + i, Various.TankWithLevelMsrmnt.Tank.Tanks[i].Volume);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Display value in ELDE component, update UI
|
||||
/// </summary>
|
||||
/// <param name="sParam">String parameter</param>
|
||||
/// <param name="iParam">Integer parameter</param>
|
||||
/// <param name="value">Value to be displayed</param>
|
||||
public void UpdateUI(string sParam, int iParam, double value)
|
||||
{
|
||||
if (sParam == "ReservoirTemp")
|
||||
{
|
||||
controlCom.SetReservoirTemp(iParam, (float)value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public CBoard()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public CBoard(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
controlBoardCfg = cfg as ControlBoardCfg;
|
||||
|
||||
/// Buffers used in UnwrapPulses() and PulsesWM(wmNr1)
|
||||
unwrappedWMPulses = new int[Config.Data.WMsCount + 1];
|
||||
|
||||
cbCommandQueue = new Queue<SendCommandArgs>();
|
||||
lastSentFilters = new uint[FiltersCount];
|
||||
|
||||
#if DN100 || MUNICH || FUZHOU_150
|
||||
FMFreq = new float[2] { 0, 0 }; /// Nr. of pumps: Fuzhou150=2, Fuzhou300=6, newer=6
|
||||
#elif SLM_END || WARSAW_END
|
||||
FMFreq = new float[4] { 0, 0, 0, 0 };
|
||||
#else /// all newer benches
|
||||
FMFreq = new float[6] { 0, 0, 0, 0, 0, 0 };
|
||||
#endif
|
||||
emergencyStop = false;
|
||||
previousEmergencyStop = false;
|
||||
|
||||
routeMask = 0;
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
if (i < controlBoardCfg.VirtualValvesRangeLo || i > controlBoardCfg.VirtualValvesRangeHi)
|
||||
{
|
||||
routeMask = routeMask | ((UInt128)1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specific pre-initialization for control board only
|
||||
/// </summary>
|
||||
/// <param name="eldeComponent"></param>
|
||||
public void SpecifyInvertedValves(UInt128 valvesToInvert)
|
||||
{
|
||||
this.valvesToInvert = valvesToInvert;
|
||||
this.benchModelRoute = valvesToInvert;
|
||||
|
||||
if (controlBoardCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
controlCom = new ControlComSim();
|
||||
}
|
||||
else
|
||||
{
|
||||
// controlCom = new ControlComWrap(eldeComponent);
|
||||
|
||||
/// Default number of scales (and BalanceRange length) is 2.
|
||||
/// If there are more scales, BalanceRange length is larger.
|
||||
// int scalesCnt = Math.Max(2, tankCapacities.Length);
|
||||
// BalanceRange = new uint[scalesCnt];
|
||||
// for (int i = 0; i < scalesCnt; i++)
|
||||
// {
|
||||
// BalanceRange[i] = (uint)((i < tankCapacities.Length) ? tankCapacities[i] : 0);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Initialize this device</summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
//int divertersCount = Rig.Uni.Diverter.Diverter.DivertersCount;
|
||||
|
||||
//DiverterEdge = new uint[divertersCount];
|
||||
//for (int i = 0; i < divertersCount; i++)
|
||||
//{
|
||||
// DiverterEdge[i] = (uint)Rig.Uni.Diverter.Diverter.Diverters[i].StartThreshold;
|
||||
// controlCom.SetDivLimit(i, (uint)Rig.Uni.Diverter.Diverter.Diverters[i].ThresholdLo,
|
||||
// (uint)Rig.Uni.Diverter.Diverter.Diverters[i].ThresholdHi);
|
||||
//}
|
||||
|
||||
controlCom.SendCalibData(RegValveCalib,
|
||||
MeretRS485Address,
|
||||
controlBoardCfg.ComPortNr,
|
||||
TempCalibData,
|
||||
EtCalib,
|
||||
DiverterEdge,
|
||||
BalanceRange,
|
||||
MeretProtocol);
|
||||
|
||||
log.FatalFormat("Successfully initialized device {0}", ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run this device
|
||||
/// </summary>
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
if (DebugLevel == DebugMode.Simulate) return;
|
||||
controlCom.RunDeviceBefore();
|
||||
UnwrapPulses();
|
||||
}
|
||||
|
||||
///
|
||||
/// Used in RunDeviceAfter() when sending commands
|
||||
///
|
||||
UInt128 lastSentRoute;
|
||||
uint[] lastSentFilters;
|
||||
float[] lastSentFMFreq;
|
||||
int lastsentRegConst;
|
||||
int lastSentShortImp;
|
||||
|
||||
/// <summary>
|
||||
/// Run this device
|
||||
/// </summary>
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (DebugLevel == DebugMode.Simulate) return;
|
||||
|
||||
|
||||
previousEmergencyStop = emergencyStop;
|
||||
emergencyStop = (controlCom.StatusP & StatusP.EmgcyStopActive) != 0;
|
||||
///
|
||||
if (emergencyStop)
|
||||
{
|
||||
/// Modify the queue in case of an emergency stop
|
||||
cbCommandQueue.Clear();
|
||||
cbCommandQueue.Enqueue(new SendCommandArgs(Command.Stop, 0, 0, 0, 0, StopDevs.All));
|
||||
}
|
||||
///
|
||||
if (emergencyStop && !previousEmergencyStop)
|
||||
{
|
||||
/// Stop the cycle - Press 'STOP' button in the BenchControlPanel
|
||||
TBF.UiBridge.Bridge.Ui2Bench(TBF.UiBridge.UI2BenchCmd.Stop);
|
||||
|
||||
Program.MainWnd.Invoke(new ShowEmergencyStopFormDlgt(ShowEmergencyStopForm));
|
||||
}
|
||||
else if (!emergencyStop && previousEmergencyStop)
|
||||
{
|
||||
//UiBridge.Bridge.OnEmergencyStopChanged(this, UiBridge.EmergencyStopEventArgs.State.CloseForm);
|
||||
}
|
||||
|
||||
|
||||
UpdateWeights();
|
||||
|
||||
|
||||
/// Prepare uintFilters array and evaluate changes
|
||||
uint[] uintFilters = new uint[FiltersCount];
|
||||
uintFilters[0] = (filters != null && filters.Length > 0) ? (uint)filters[0] : 0;
|
||||
bool filtersAreDifferent = (uintFilters[0] != lastSentFilters[0]);
|
||||
for (int i = 1; i < FiltersCount; i++)
|
||||
{
|
||||
uintFilters[i] = (filters != null && filters.Length > i) ? (uint)filters[i] : uintFilters[i - 1];
|
||||
filtersAreDifferent |= (uintFilters[i] != lastSentFilters[i]);
|
||||
}
|
||||
|
||||
/// Evaluate FMFreq changes
|
||||
bool fmFreqsAreDifferent = false;
|
||||
if ((FMFreq == null) || (lastSentFMFreq == null) || (FMFreq.Length != lastSentFMFreq.Length))
|
||||
{
|
||||
fmFreqsAreDifferent = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < FMFreq.Length; i++)
|
||||
{
|
||||
if (FMFreq[i] != lastSentFMFreq[i])
|
||||
{
|
||||
fmFreqsAreDifferent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cbCommandQueue.Count > 0)
|
||||
{
|
||||
///
|
||||
/// There is a command in the queue
|
||||
///
|
||||
controlCom.SendCommand(cbCommandQueue.Dequeue(), (benchModelRoute & routeMask), uintFilters, FMFreq, regConst, shortImp);
|
||||
|
||||
lastSentRoute = (benchModelRoute & routeMask);
|
||||
lastsentRegConst = regConst;
|
||||
lastSentShortImp = shortImp;
|
||||
|
||||
/// Deep copy of arrays lastSentFilters and lastSentFMFreq
|
||||
if ((lastSentFilters == null) || (lastSentFilters.Length != uintFilters.Length)) lastSentFilters = new uint[(uintFilters == null) ? 0 : uintFilters.Length];
|
||||
for (int i = 0; i < lastSentFilters.Length; i++) lastSentFilters[i] = uintFilters[i];
|
||||
if ((lastSentFMFreq == null) || (lastSentFMFreq.Length != FMFreq.Length)) lastSentFMFreq = new float[(FMFreq == null) ? 0 : FMFreq.Length];
|
||||
for (int i = 0; i < lastSentFMFreq.Length; i++) lastSentFMFreq[i] = FMFreq[i];
|
||||
}
|
||||
else if (((benchModelRoute & routeMask) != lastSentRoute) ||
|
||||
filtersAreDifferent ||
|
||||
fmFreqsAreDifferent ||
|
||||
(lastsentRegConst != regConst) ||
|
||||
(lastSentShortImp != shortImp))
|
||||
{
|
||||
///
|
||||
/// Command queue is mepty, but 'route', pump frequency, PID coef., filters or shortImp have changed
|
||||
///
|
||||
controlCom.SendCommand(new SendCommandArgs(Command.None, 0, 0, 0, 0, 0), (benchModelRoute & routeMask), uintFilters, FMFreq, regConst, shortImp);
|
||||
|
||||
lastSentRoute = (benchModelRoute & routeMask);
|
||||
lastsentRegConst = regConst;
|
||||
lastSentShortImp = shortImp;
|
||||
|
||||
/// Deep copy of arrays lastSentFilters and lastSentFMFreq
|
||||
if ((lastSentFilters == null) || (lastSentFilters.Length != uintFilters.Length)) lastSentFilters = new uint[(uintFilters == null) ? 0 : uintFilters.Length];
|
||||
for (int i = 0; i < lastSentFilters.Length; i++) lastSentFilters[i] = uintFilters[i];
|
||||
if ((lastSentFMFreq == null) || (lastSentFMFreq.Length != FMFreq.Length)) lastSentFMFreq = new float[(FMFreq == null) ? 0 : FMFreq.Length];
|
||||
for (int i = 0; i < lastSentFMFreq.Length; i++) lastSentFMFreq[i] = FMFreq[i];
|
||||
}
|
||||
|
||||
controlCom.RunDeviceAfter();
|
||||
}
|
||||
|
||||
/// <summary>Stop this device</summary>
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
|
||||
|
||||
delegate void ShowEmergencyStopFormDlgt();
|
||||
///
|
||||
void ShowEmergencyStopForm()
|
||||
{
|
||||
//(new TBF.UI.Shared.EmergencyStopForm()).Show();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sends a command to the control board.
|
||||
/// </summary>
|
||||
/// <param name="cmd">See ControlBoard.Command enum</param>
|
||||
/// <param name="refFlowmtrNr">Number of the etalon/reference (1..5)</param>
|
||||
/// <param name="route">State of valves, 128-bit word</param>
|
||||
/// <param name="totalRefPulses">kolko impulzov ma trvat skuska</param>
|
||||
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
|
||||
/// <param name="filterConstant">0 = No filtering (0..255)</param>
|
||||
/// <param name="regConst">Coefficient used to control reg. valves (1..100)</param>
|
||||
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
|
||||
/// <param name="stopDevs">What to stop</param>
|
||||
public void SendCommand(Command cmd, int refFlowmtrNr, int totalRefPulses, int massRefPulses,
|
||||
TestMethods testMethods, StopDevs stopDevs)
|
||||
{
|
||||
cbCommandQueue.Enqueue(new SendCommandArgs(cmd, refFlowmtrNr, totalRefPulses, massRefPulses, testMethods, stopDevs));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set valves to new positions.
|
||||
/// </summary>
|
||||
/// <param name="valvesToOpen">'ulong' with bits of valves to open set to '1'</param>
|
||||
/// <param name="valvesToClose">'ulong' with bits of valves to close set to '1'</param>
|
||||
/// <returns>'ulong' with bits of valves that have changed set to '1'</returns>
|
||||
public UInt128 SetValves(UInt128 valvesToOpen, UInt128 valvesToClose, IList<TBF.Rig.BuiltIn.ValveEx.Valve> extendedValves)
|
||||
{
|
||||
UInt128 oldRoute = benchModelRoute;
|
||||
benchModelRoute = (((benchModelRoute ^ valvesToInvert) | valvesToOpen) & (~valvesToClose)) ^ valvesToInvert;
|
||||
foreach (var extV in extendedValves) extV.UpdateRoute(ref benchModelRoute);
|
||||
log.DebugFormat("SetValves(x,x), new route = {0}", Utils.RouteToStr(benchModelRoute));
|
||||
return oldRoute ^ benchModelRoute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set Route to value returned by RRoute. Take virtual valves into account.
|
||||
/// </summary>
|
||||
/// <returns>'ulong' with bits of valves that have changed set to '1'</returns>
|
||||
public UInt128 SyncRoute()
|
||||
{
|
||||
UInt128 oldRoute = benchModelRoute;
|
||||
benchModelRoute = (RRoute & routeMask) | (benchModelRoute & (~routeMask));
|
||||
log.DebugFormat("SyncRoute(), new route = {0}", Utils.RouteToStr(benchModelRoute));
|
||||
return oldRoute ^ benchModelRoute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Regulation valves control.
|
||||
/// </summary>
|
||||
/// <param name="valveNo">Regulation valve nr. (1..5)</param>
|
||||
/// <param name="valveMode">Valve regulation mode, see the enum</param>
|
||||
/// <param name="valveValue">Target position or target frequency or pulse duration</param>
|
||||
/// <param name="stableTime">Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.</param>
|
||||
public void ValveMove(int valveNo, RegulValveMode valveMode, double[] valveValue, int stableTime)
|
||||
{
|
||||
controlCom.ValveMove(valveNo, valveMode, valveValue, stableTime);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Open one valve and/or close one valve.
|
||||
/// Events: ValvesSet
|
||||
/// </summary>
|
||||
/// <param name="valveOpen">Valve to be opened</param>
|
||||
/// <param name="valveClose">Valve to be closed</param>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation SetValvesOp(IValve valveOpen, IValve valveClose)
|
||||
{
|
||||
return new BuiltIn.SetValvesOp(this, valveOpen, valveClose);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open and/or close multiple valves.
|
||||
/// Events: ValvesSet
|
||||
/// </summary>
|
||||
/// <param name="valvesOpen">A list of valves to be opened</param>
|
||||
/// <param name="valvesClose">A list of valves to be closed</param>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation SetValvesOp(IList<IValve> valvesOpen, IList<IValve> valvesClose)
|
||||
{
|
||||
return new BuiltIn.SetValvesOp(this, valvesOpen, valvesClose);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open start/stop valve.
|
||||
/// Events: ValvesSet, ValvesBusy, Error
|
||||
/// </summary>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation OpenStartValveOp()
|
||||
{
|
||||
return new BuiltIn.SetValvesOp(this, true, devices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close start/stop valve.
|
||||
/// Events: ValvesSet, ValvesBusy, Error
|
||||
/// </summary>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation CloseStartValveOp()
|
||||
{
|
||||
return new BuiltIn.SetValvesOp(this, false, devices);
|
||||
}
|
||||
|
||||
public IOperation SetFlowOp(double reqrdFlowLo, double reqrdFlowHi, TBF.Boxes.DoubleBox measuredFlow, int timeout)
|
||||
{
|
||||
if (Devices.RegValve == null || Devices.FlowMeter == null) return null;
|
||||
|
||||
return Devices.RegValve.SetFlowOp(Devices.FlowMeter, reqrdFlowLo, reqrdFlowHi, measuredFlow, timeout);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start a standing start-stop test
|
||||
/// </summary>
|
||||
/// <returns>Operation running a test</returns>
|
||||
public IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount)
|
||||
{
|
||||
return StartTestOp(test, false, false, true, qFrom, qTo, pulsesCount, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a flying start-stop test
|
||||
/// </summary>
|
||||
/// <returns>Operation running a test</returns>
|
||||
public IOperation FlyingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount)
|
||||
{
|
||||
return StartTestOp(test, true, false, false, qFrom, qTo, pulsesCount, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a flying start-stop test with diverter
|
||||
/// </summary>
|
||||
/// <returns>Operation running a test</returns>
|
||||
public IOperation FlyingStartStopTestWithDivOp(Test test, double qFrom, double qTo, int pulsesCount, int massPulsesCount, bool readDivTransition)
|
||||
{
|
||||
return StartTestOp(test, true, true, false, qFrom, qTo, pulsesCount, massPulsesCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a test
|
||||
/// </summary>
|
||||
/// <returns>Operation running a test</returns>
|
||||
public IOperation StartTestOp(Test test, bool isSyncMethod, bool isDivUsed, bool isStartStop, double qFrom, double qTo, int pulsesCount, int massPulsesCount)
|
||||
{
|
||||
if (controlBoardCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return new Operations.ReturnGivenEventOp(Event.TestInProgress);
|
||||
}
|
||||
|
||||
/// Get total number of pulses
|
||||
int totalPulses = Convert.ToInt32(Math.Round(test.Volume / devices.FlowMeter.LtrPerPulse));
|
||||
|
||||
/// Get method class string
|
||||
string methodClass;
|
||||
if (!StateMachine.TestMethod2Class.TryGetValue(test.Name, out methodClass)) return null;
|
||||
|
||||
if (methodClass.Contains("TestMethods.Adjustment."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.CombinedWithDetection."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass == "TestMethods.DiverterTest")
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass == "TestMethods.Dummy")
|
||||
{
|
||||
}
|
||||
if (methodClass == "TestMethods.Endurance")
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FixedStart."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, 2 * totalPulses, 10);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FixedStartAdvanced."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, 2 * totalPulses, 10);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FixedStartDefferedEval."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, 2 * totalPulses, 10);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FixedStartMassCollDeferredEval."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, 2 * totalPulses, 10);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FixedStartMassCollection."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.FixedStart), test.Qfrom, test.Qto, 2 * totalPulses, 10);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FixedStartTankCollection."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, (totalPulses * 5 / 4), 10);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FlyingStart."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FlyingStartFirstRepetWithMassColl."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FlyingStartMassCollComparative."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FlyingStartMassCollection."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FlyingStartMassCollProlonged."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses, massPulsesCount);
|
||||
}
|
||||
if (methodClass.Contains("TestMethods.FlyingStartTankCollection."))
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass == "TestMethods.PulsesTest")
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
if (methodClass == "TestMethods.PulsesTestManual")
|
||||
{
|
||||
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the measurement.
|
||||
/// Events: MeasurementStarted
|
||||
/// </summary>
|
||||
/// <param name="flowMeter">Flow meter</param>
|
||||
/// <param name="readers">An array of register readers</param>
|
||||
/// <param name="refPulses">Number of reference pulses to complete the test</param>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation StartProlongedMeasurementOp(OutputPath outputPath,
|
||||
double requiredFlowLo, double requiredFlowHi,
|
||||
int totalRefPulses, int massRefPulses, int delayBeforeFlowRegulation = 0)
|
||||
{
|
||||
if (controlBoardCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return new Operations.ReturnGivenEventOp(Event.TestInProgress);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new StartMeasurementOp(this, outputPath, TestMethods.Diverter | TestMethods.Synchro | TestMethods.MassAndContinue,
|
||||
requiredFlowLo, requiredFlowHi, totalRefPulses, massRefPulses, delayBeforeFlowRegulation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read diverter samples from the control board and calculated the transition time.
|
||||
/// Events: Event.None
|
||||
/// </summary>
|
||||
/// <param name="div">Diverter</param>
|
||||
/// <param name="runsCountWhenSendingCmd">State machine ticks from test start/end when diverter read command is issued (obsolete)</param>
|
||||
/// <param name="runsCountWhenReadingDiv">State machine ticks from test start/end when diverter samples are read</param>
|
||||
/// <param name="transitionTimeSec">FloatBox for the resulting transition time in s</param>
|
||||
/// <param name="plotter">Statistics for plotting diverter transitions</param>
|
||||
/// <param name="batchNr">Batch number</param>
|
||||
/// <param name="testName">Test name (without repetitions)</param>
|
||||
/// <param name="repetition">Repetition number</param>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation ReadDiverterTransitionOp(bool isStart, Sequences.Statistics plotter, int batchNr, string testName, int repetition)
|
||||
{
|
||||
if (controlBoardCfg.DebugLevel == DebugMode.Simulate) return new Operations.ReturnGivenEventOp(Event.None);
|
||||
|
||||
return new ReadDiverterTransitionOp(this, devices.Diverter, 1, 3, isStart, plotter, batchNr, testName, repetition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries th econtrol board whether the measurement was completed.
|
||||
/// Events: MeasurementCompleted or None
|
||||
/// </summary>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation QueryMeasurementEndOp()
|
||||
{
|
||||
return new QueryMeasurementEndOp(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop controls board flow regulation operation
|
||||
/// Events: FlowRegulationStopped
|
||||
/// </summary>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation StopFlowRegulationOp()
|
||||
{
|
||||
return new StopFlowRegulationOp(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the previous control board operation (diverter, gate, etc.)
|
||||
/// Events: PreviousStopped
|
||||
/// </summary>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation StopPreviousOp()
|
||||
{
|
||||
return new StopPreviousOp(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends commands to the control board.
|
||||
/// Events: Event.None, Event.CommandCompleted
|
||||
/// </summary>
|
||||
/// <param name="commandOnStartOp">Command sent to CB when this operation starts</param>
|
||||
/// <param name="commandOnStopOp">Command sent to CB when this operation stops</param>
|
||||
/// <param name="testMethod">Test method parameter</param>
|
||||
/// <returns>Created operation</returns>
|
||||
public IOperation ExecuteCommandOp(Command commandOnStartOp, Command commandOnStopOp, TestMethods testMethod)
|
||||
{
|
||||
return new ExecuteCommandOp(this, commandOnStartOp, commandOnStopOp, testMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,389 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2019 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Dirichlet.Numerics;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class ControlComSim : IControlCom
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ControlComSim));
|
||||
public override string ToString() { return string.Format("ControlComSim"); }
|
||||
|
||||
StatusP statusP;
|
||||
public StatusP StatusP { get { return statusP; } }
|
||||
|
||||
double referenceFreq = 650.0;
|
||||
public double ReferenceFreq { get { return referenceFreq; } }
|
||||
public double ReferenceFreqs(int i) { return 0; }
|
||||
|
||||
int[] etPulses = new int[Config.Data.WMsCount + 1];
|
||||
public int EtPulses(int wmNr1)
|
||||
{
|
||||
return etPulses[wmNr1];
|
||||
}
|
||||
|
||||
public int EtPulsesK { get { return 1; } }
|
||||
public int EtPulses2 { get { return 0; } }
|
||||
public int EtPulses3 { get { return 0; } }
|
||||
|
||||
double[] errFactor = new double[Config.Data.WMsCount + 1]; /// Internal
|
||||
double[] wMeterPulsesF = new double[Config.Data.WMsCount + 1]; /// Internal
|
||||
|
||||
UInt16[] wMeterPulses = new UInt16[Config.Data.WMsCount + 1]; /// Rounded from wMeterPulsesF
|
||||
public UInt16 WMeterPulses(int wmNr1)
|
||||
{
|
||||
return wMeterPulses[wmNr1];
|
||||
}
|
||||
|
||||
int[] wMeterReference = new int[Config.Data.WMsCount + 1];
|
||||
public int WMeterReference(int wmNr1)
|
||||
{
|
||||
return wMeterReference[wmNr1];
|
||||
}
|
||||
|
||||
public uint RegulValveDAC(int rvNr0) { return 0; }
|
||||
|
||||
public float Pressure(int prsNr0) { return 0; }
|
||||
public float Temperature(int tmpNr0) { return (float)(20 + tmpNr0); }
|
||||
public RegulValveState RegulValveState(int rvNr1) { return 0; }
|
||||
|
||||
public UInt128 RRoute { get { return simRoute; } }
|
||||
|
||||
public uint DivTime(int id) { return 0; }
|
||||
public void SetDivLimit(int divNo, uint limLoPct, uint limHiPct) { }
|
||||
|
||||
float tTime = 1;
|
||||
public float TTime { get { return tTime; } }
|
||||
public float ImpulseTime(int wmNr1) { return tTime; }
|
||||
|
||||
public uint FmState { get { return 0; } }
|
||||
public uint BeginState(int wmNr0) { return 0; }
|
||||
|
||||
double referenceFlow;
|
||||
public double ReferenceFlow { get { return referenceFlow; } }
|
||||
|
||||
public float RValvePosition(int rvNr1) { return 0; }
|
||||
public float DivSamples(int ms, int divIx0) { return 0; }
|
||||
public int ScopeSamples(int i, int j, int k) { return 0; }
|
||||
public ulong DigitalInputs { get { return 0; } }
|
||||
public float AnalogInput(int adcNr0) { return 0; }
|
||||
public uint AnalogInputRaw(int adcNr0, int bank) { return 0; } /// bank0=RV, bank1=Temp
|
||||
public float TotalRefVolume { get { return 0; } }
|
||||
public float VyslExt(int wmNr0, int what) { return 0; }
|
||||
public void SetWeight(int pos, double mass) { return; } /// not available in sim. mode
|
||||
|
||||
public uint[] CyclePar { get { return cyclePar; } set { cyclePar = value; } } /// dummy
|
||||
public uint[] WMeterCont { get { return wMeterCont; } } /// dummy
|
||||
|
||||
public float ValveOpenCloseTime { get { return 0.001f; } }
|
||||
///
|
||||
public bool ManualUIAllowed
|
||||
{
|
||||
get { return manualUIAllowed; }
|
||||
set { manualUIAllowed = value; }
|
||||
}
|
||||
bool manualUIAllowed = true;
|
||||
|
||||
public void SetReservoirTemp(int nr, float temp) { }
|
||||
|
||||
|
||||
///
|
||||
/// Private initialization data updated by contructors of children components
|
||||
/// and sent to 'controlCom2panel' by SendCalibData() method.
|
||||
///
|
||||
uint[,] regValveCalib;
|
||||
byte[] meretRS485Address;
|
||||
float[,] tempCalibData;
|
||||
float[] etCalib;
|
||||
uint[] diverterEdge;
|
||||
uint[] balanceRange;
|
||||
byte meretProtocol;
|
||||
|
||||
|
||||
uint[] cyclePar;
|
||||
uint[] wMeterCont;
|
||||
|
||||
///
|
||||
/// Private values set by SendCommand()
|
||||
///
|
||||
Command cmd;
|
||||
int refFlowmtrNr;
|
||||
UInt128 simRoute;
|
||||
int totalRefPulses;
|
||||
int massRefPulses;
|
||||
TestMethods testMethods;
|
||||
uint[] filterConstants;
|
||||
float[] FMFreq;
|
||||
int regConst;
|
||||
int shortImp;
|
||||
StopDevs stopDevs;
|
||||
|
||||
///
|
||||
/// Private values set by ValveMove()
|
||||
///
|
||||
int regulValveNo;
|
||||
RegulValveMode regulValveMode;
|
||||
double[] regulValveValue;
|
||||
|
||||
Random rand;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public ControlComSim()
|
||||
{
|
||||
rand = new Random();
|
||||
cyclePar = new uint[163];
|
||||
wMeterCont = new uint[3] { 1, 2, 3 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends calibration and configuration data to the control board.
|
||||
/// </summary>
|
||||
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
|
||||
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
|
||||
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
|
||||
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
|
||||
/// <param name="etCalib">Etalon nominal values</param>
|
||||
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
|
||||
public void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib, float[] etCalib, uint[] divEdge, uint[] balanceRange, byte meretProtocol)
|
||||
{
|
||||
log.Info("SendCalibData(...)");
|
||||
|
||||
this.regValveCalib = rvCalib;
|
||||
this.meretRS485Address = meretA;
|
||||
this.tempCalibData = tempCalib;
|
||||
this.etCalib = etCalib;
|
||||
this.diverterEdge = divEdge;
|
||||
this.balanceRange = balanceRange;
|
||||
this.meretProtocol = meretProtocol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a command to the control board.
|
||||
/// </summary>
|
||||
/// <param name="cmd">See ControlBoard.Command enum</param>
|
||||
/// <param name="refFlowmtrNr">Number of the etalon/reference (1..5)</param>
|
||||
/// <param name="route">State of valves, 128-bit word</param>
|
||||
/// <param name="refPulses">kolko impulzov ma trvat skuska</param>
|
||||
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
|
||||
/// <param name="filterConstant">0 = No filtering (0..255)</param>
|
||||
/// <param name="fmFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
|
||||
/// <param name="regConst">Coefficient used to control reg. valves (1..100)</param>
|
||||
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
|
||||
/// <param name="stopDevs">What to stop</param>
|
||||
public void SendCommand(SendCommandArgs sendCommandArgs, UInt128 route, uint[] filterConstants, float[] fmFreq, int regConst, int shortImp)
|
||||
{
|
||||
log.InfoFormat("SendCommand(Cmd={0},Ref#={1},Route={2} {3} {4} {5},TotalPls={6},MassPls={7},TstM={8},filt={9},FM=[{10}{11}{12}{13}{14}{15}],Reg={16},ShrtImp={17},Stop={18})",
|
||||
sendCommandArgs.Cmd, sendCommandArgs.RefFlowmtrNr, /// 0, 1
|
||||
((route >> 48) & 0xFFFF).ToString("X4"), /// 2
|
||||
((route >> 32) & 0xFFFF).ToString("X4"), /// 3
|
||||
((route >> 16) & 0xFFFF).ToString("X4"), /// 4
|
||||
(route & 0xFFFF).ToString("X4"), /// 5
|
||||
totalRefPulses, massRefPulses, testMethods, filterConstants, /// 6, 7, 8, 9
|
||||
fmFreq[0].ToString(), /// 10
|
||||
(fmFreq.Length > 1) ? ("," + fmFreq[1].ToString()) : "", /// 11
|
||||
(fmFreq.Length > 2) ? ("," + fmFreq[2].ToString()) : "", /// 12
|
||||
(fmFreq.Length > 3) ? ("," + fmFreq[3].ToString()) : "", /// 13
|
||||
(fmFreq.Length > 4) ? ("," + fmFreq[4].ToString()) : "", /// 14
|
||||
(fmFreq.Length > 5) ? ("," + fmFreq[5].ToString()) : "", /// 15
|
||||
regConst, shortImp, stopDevs); /// 16, 17, 18
|
||||
///
|
||||
/// Simulation
|
||||
///
|
||||
Command lastCmd = this.cmd;
|
||||
this.cmd = sendCommandArgs.Cmd;
|
||||
this.refFlowmtrNr = sendCommandArgs.RefFlowmtrNr;
|
||||
|
||||
#if FUZHOU_300
|
||||
///
|
||||
/// The following code deals with the situation that all FM controlled pums share bit #39.
|
||||
/// In settings the bits of pumps should be sent as follows: P1=50, P2=51, P3=52, P4=53, P5=54 and P7=55
|
||||
/// (in FUZHOU_300 the FM pump bit should be set set to value FMIndex+50).
|
||||
///
|
||||
bool bit39 = (route & 0x00FC000000000000) != 0; /// true if any of bits 50 through 55 is set
|
||||
route = route & 0xFF03FFFFFFFFFFFF;
|
||||
if (bit39) route = route | 0x0000008000000000;
|
||||
log.DebugFormat("SendCommand route = {0}", Utils.RouteToStr(route));
|
||||
#endif
|
||||
TestBenchSim.SimRoute = this.simRoute = route;
|
||||
this.totalRefPulses = sendCommandArgs.TotalRefPulses;
|
||||
this.massRefPulses = sendCommandArgs.MassRefPulses;
|
||||
this.testMethods = sendCommandArgs.TestMethods;
|
||||
this.stopDevs = sendCommandArgs.StopDevs;
|
||||
this.filterConstants = filterConstants;
|
||||
this.FMFreq = fmFreq;
|
||||
this.regConst = regConst;
|
||||
this.shortImp = shortImp;
|
||||
|
||||
#pragma warning disable
|
||||
statusP = (StatusP)(((ulong)statusP & (ulong)0xFFFFFFFFFFFFFFF8L) | (ulong)refFlowmtrNr);
|
||||
#pragma warning restore
|
||||
|
||||
if (cmd == Command.Start && lastCmd != Command.Start )
|
||||
{
|
||||
statusP |= StatusP.TestInProgress;
|
||||
///
|
||||
/// Clear all counters
|
||||
///
|
||||
if (etPulses != null) { for (int i = 0; i < etPulses.Length; i++) etPulses[i] = 0; }
|
||||
if (wMeterPulses != null) { for (int i = 0; i < wMeterPulses.Length; i++) wMeterPulses[i] = 0; }
|
||||
if (wMeterPulsesF != null) { for (int i = 0; i < wMeterPulsesF.Length; i++) wMeterPulsesF[i] = 0; }
|
||||
if (wMeterReference != null) { for (int i = 0; i < wMeterReference.Length; i++) wMeterReference[i] = 0; }
|
||||
if (errFactor != null)
|
||||
{
|
||||
for (int i = 0; i < errFactor.Length; i++) errFactor[i] = ((float)rand.Next(100) + 950.0f) / 1000.0f;
|
||||
}
|
||||
tTime = 0;
|
||||
}
|
||||
else if (cmd == Command.Stop)
|
||||
{
|
||||
statusP = 0;
|
||||
//statusP &= ~StatusP.Running;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control of regulating valves.
|
||||
/// </summary>
|
||||
/// <param name="regulValveNo">Regulating valve nr. (1..5)</param>
|
||||
/// <param name="regulValveMode">???</param>
|
||||
/// <param name="regulValveValue">???</param>
|
||||
/// <param name="stableTime">Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.</param>
|
||||
public void ValveMove(int regulValveNo, RegulValveMode regulValveMode, double[] regulValveValue, int stableTime)
|
||||
{
|
||||
log.InfoFormat("ValveMove({0}, {1}, [{2},{3}], {4})", regulValveNo, regulValveMode, regulValveValue[0], regulValveValue[1], stableTime);
|
||||
|
||||
this.regulValveNo = regulValveNo;
|
||||
this.regulValveMode = regulValveMode;
|
||||
this.regulValveValue = regulValveValue;
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
log.DebugFormat("RunDeviceBefore() ... regV#={0}, flowM#{1}, statusP={2}", regulValveNo, refFlowmtrNr, statusP.ToString("X"));
|
||||
TestBenchSim.RunDevice(regulValveNo, refFlowmtrNr, statusP);
|
||||
|
||||
log.DebugFormat("refFreq={0}", referenceFreq);
|
||||
|
||||
tTime += 1.0f;
|
||||
|
||||
float Qnom = (regulValveNo > 0) ? etCalib[regulValveNo] : 0;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case Command.None:
|
||||
break;
|
||||
|
||||
case Command.Start:
|
||||
if ((testMethods & TestMethods.Diverter) == TestMethods.Diverter)
|
||||
{
|
||||
TestBenchSim.SetSimDiverter(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case Command.Stop:
|
||||
if ((testMethods & TestMethods.Diverter) == TestMethods.Diverter)
|
||||
{
|
||||
TestBenchSim.SetSimDiverter(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (regulValveMode)
|
||||
{
|
||||
case RegulValveMode.TargetFrequency:
|
||||
double targetFlow = ((regulValveValue[0] + regulValveValue[1]) / 2.0) * (Qnom / 2000.0);
|
||||
TestBenchSim.UpdateSimFlow(targetFlow);
|
||||
|
||||
//if (referenceFreq < valveValue[0]) referenceFreq += ((float)rand.Next(20) + 10.0f) / 2.0f;
|
||||
//else if (referenceFreq > valveValue[1]) referenceFreq -= ((float)rand.Next(20) + 10.0f) / 2.0f;
|
||||
//else referenceFreq += ((float)rand.Next(10) - 5.0f) / 2.0f;
|
||||
referenceFreq = TestBenchSim.GetSimFlow() * 2000.0 / Qnom;
|
||||
if (referenceFreq < 0) referenceFreq = 0;
|
||||
if (referenceFreq > 2500) referenceFreq = 2500;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
referenceFlow = referenceFreq / 2000.0;
|
||||
|
||||
bool stopTest = false;
|
||||
if (cmd == Command.Start)
|
||||
{
|
||||
double pwFactor = 1.0;
|
||||
|
||||
/// Increment reference flow meters
|
||||
for (int i = 0; i <= Config.Data.WMsCount; i++)
|
||||
{
|
||||
etPulses[i] += (int)referenceFreq;
|
||||
if (etPulses[i] > totalRefPulses)
|
||||
{
|
||||
pwFactor = 1.0 - (etPulses[i] - totalRefPulses) / referenceFreq;
|
||||
etPulses[i] = totalRefPulses;
|
||||
stopTest = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Increment water meters
|
||||
double flowLtrPerSec = TestBenchSim.GetSimFlow() / 1800.0;
|
||||
for (int i = 1; i <= Config.Data.WMsCount; i++)
|
||||
{
|
||||
float wmPulsesPerLiter = 0;
|
||||
if ((Rig.Sequences.ProcessData.RegisterReaders[i - 1] != null) &&
|
||||
(Rig.Sequences.ProcessData.BatchRslts.Batch.WaterMeters.Count >= i) &&
|
||||
(Rig.Sequences.ProcessData.BatchRslts.Batch.WaterMeters[i - 1] != null))
|
||||
{
|
||||
wmPulsesPerLiter = (float)Rig.Sequences.ProcessData.RegisterReaders[i-1].PulsesPerLtr;
|
||||
}
|
||||
wMeterPulsesF[i] += errFactor[i] * pwFactor * ((float)rand.Next(100) + 450.0f) * wmPulsesPerLiter * flowLtrPerSec;
|
||||
wMeterPulses[i] = (UInt16)wMeterPulsesF[i];
|
||||
}
|
||||
|
||||
if (etPulses[0] > totalRefPulses)
|
||||
{
|
||||
statusP |= StatusP.TestCompleted;
|
||||
statusP &= ~StatusP.TestInProgress;
|
||||
}
|
||||
}
|
||||
|
||||
if (stopTest)
|
||||
{
|
||||
TestBenchSim.SetSimDiverter(false);
|
||||
statusP = (statusP | StatusP.TestCompleted);
|
||||
statusP = (statusP & ~StatusP.TestInProgress);
|
||||
}
|
||||
}
|
||||
|
||||
StatusP lastStatusP;
|
||||
UInt128 lastRoute;
|
||||
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
StatusP bufferedStatusP = StatusP;
|
||||
if (lastStatusP != bufferedStatusP)
|
||||
{
|
||||
string statusPStr = ((ulong)bufferedStatusP).ToString("x16");
|
||||
log.InfoFormat("RunDeviceAfter() StatusP = {0}", statusPStr);
|
||||
Program.MainWnd.UpdateStatusP(statusPStr);
|
||||
lastStatusP = bufferedStatusP;
|
||||
}
|
||||
|
||||
UInt128 bufferedRoute = simRoute;
|
||||
if (lastRoute != bufferedRoute)
|
||||
{
|
||||
string routeStr = bufferedRoute.ToString("x16");
|
||||
log.InfoFormat("RunDeviceAfter() Route = {0}", routeStr);
|
||||
Program.MainWnd.UpdateRoute(routeStr);
|
||||
lastRoute = bufferedRoute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2016 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class ExecuteCommandOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ExecuteCommandOp));
|
||||
public override string ToString() { return string.Format("ExecuteCommandOp( command={0}, testMethod={1} )", commandOnStartOp, testMethod); }
|
||||
|
||||
/// Set by the constructor
|
||||
readonly CBoard controlBoard;
|
||||
readonly Command commandOnStartOp;
|
||||
readonly Command commandOnStopOp;
|
||||
readonly TestMethods testMethod;
|
||||
|
||||
///
|
||||
/// Internal states of this operation
|
||||
///
|
||||
enum OpState
|
||||
{
|
||||
StartingCommand,
|
||||
CommandStarted,
|
||||
OpCompleted,
|
||||
}
|
||||
OpState opState;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Starts the measurement.
|
||||
/// Events: MeasurementStarted
|
||||
/// </summary>
|
||||
/// <param name="controlBoard">Control board component reference</param>
|
||||
/// <param name="outputPath">Specifies used components</param>
|
||||
/// <param name="testMethod">Test method</param>
|
||||
/// <param name="refPulses">Test duration in number of reference flowmeter pulses</param>
|
||||
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
|
||||
public ExecuteCommandOp(CBoard controlBoard, Command commandOnStartOp, Command commandOnStopOp, TestMethods testMethod)
|
||||
{
|
||||
if (controlBoard == null) throw new ArgumentNullException("controlBoardDev");
|
||||
|
||||
this.controlBoard = controlBoard;
|
||||
this.commandOnStartOp = commandOnStartOp;
|
||||
this.commandOnStopOp = commandOnStopOp;
|
||||
this.testMethod = testMethod;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
controlBoard.SyncRoute();
|
||||
controlBoard.SendCommand(commandOnStartOp, 0, 0, 0, testMethod, StopDevs.None);
|
||||
opState = OpState.StartingCommand;
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (opState == OpState.StartingCommand)
|
||||
{
|
||||
StatusP statusP = controlBoard.StatusP;
|
||||
log.DebugFormat("statusP = {0} {1} {2} {3}",
|
||||
(((ulong)statusP >> 48) & 0xFFFF).ToString("X4"),
|
||||
(((ulong)statusP >> 32) & 0xFFFF).ToString("X4"),
|
||||
(((ulong)statusP >> 16) & 0xFFFF).ToString("X4"),
|
||||
((ulong)statusP & 0xFFFF).ToString("X4"));
|
||||
|
||||
log.Info("Run() - StartingCommand");
|
||||
opState = OpState.CommandStarted;
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.CommandStarted)
|
||||
{
|
||||
log.InfoFormat("Run() - CommandStarted");
|
||||
opState = OpState.OpCompleted;
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.OpCompleted)
|
||||
{
|
||||
return Event.CommandCompleted;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (commandOnStopOp != Command.None)
|
||||
{
|
||||
controlBoard.SyncRoute();
|
||||
controlBoard.SendCommand(commandOnStopOp, 0, 0, 0, testMethod, StopDevs.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8); } }
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
/// <summary>Max. number of components of this class in the system</summary>
|
||||
public int MaxCount { get { return 1; } }
|
||||
|
||||
public IComponent DummyComponent() { return new CBoard(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new CBoard(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new ControlBoardCfg(this); }
|
||||
|
||||
public IComponentCfgCtrl CreateCfgCtrl() { return new ControlBoardCfgCtrl(); }
|
||||
|
||||
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
|
||||
{
|
||||
return new CBoard((ControlBoardCfg)config);
|
||||
}
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(ControlBoardCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2019 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Dirichlet.Numerics;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
interface IControlCom
|
||||
{
|
||||
StatusP StatusP { get; }
|
||||
int EtPulses(int wmNr1);
|
||||
int EtPulsesK { get; }
|
||||
int EtPulses2 { get; }
|
||||
int EtPulses3 { get; }
|
||||
UInt16 WMeterPulses(int wmNr1);
|
||||
int WMeterReference(int wmNr0);
|
||||
uint RegulValveDAC(int rvNr0);
|
||||
float Pressure(int prsNr0);
|
||||
float Temperature(int tmpNr0);
|
||||
RegulValveState RegulValveState(int rvNr1);
|
||||
UInt128 RRoute { get; }
|
||||
uint DivTime(int id); /// 50% id=0, 10% id=1, 90% id=2
|
||||
float TTime { get; }
|
||||
float ImpulseTime(int WMNr1);
|
||||
uint FmState { get; }
|
||||
uint BeginState(int wmNr0);
|
||||
double ReferenceFreq { get; }
|
||||
double ReferenceFreqs(int i); /// Frequences for doble/tripple flowmeter
|
||||
double ReferenceFlow { get; }
|
||||
float RValvePosition(int rvNr1);
|
||||
float DivSamples(int time, int divIx0); /// time unit is 2 ms
|
||||
int ScopeSamples(int i, int j, int k);
|
||||
ulong DigitalInputs { get; }
|
||||
float AnalogInput(int adcNr0);
|
||||
uint AnalogInputRaw(int adcNr0, int bank);
|
||||
float TotalRefVolume { get; }
|
||||
float VyslExt(int wmNr0, int what);
|
||||
void SetWeight(int pos, double mass);
|
||||
uint[] CyclePar { get; set; }
|
||||
uint[] WMeterCont { get; }
|
||||
bool ManualUIAllowed { get; set; }
|
||||
float ValveOpenCloseTime { get; }
|
||||
void SetDivLimit(int divNr, uint limLoPct, uint limHiPct);
|
||||
|
||||
void SetReservoirTemp(int nr, float temp);
|
||||
|
||||
/// <summary>
|
||||
/// Sends calibration and configuration data to the control board.
|
||||
/// </summary>
|
||||
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
|
||||
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
|
||||
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
|
||||
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
|
||||
/// <param name="etCalib">Etalon nominal values</param>
|
||||
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
|
||||
/// <param name="balanceRange">TODO</param>
|
||||
/// <param name="meretProtocol">TODO</param>
|
||||
void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib, float[] etCalib, uint[] divEdge, uint[] balanceRange, byte meretProtocol);
|
||||
|
||||
/// <summary>
|
||||
/// Updates a command that is regularly sent to the control board by SendCommand.
|
||||
/// </summary>
|
||||
/// <param name="sendCommandArgs">Arguments, see SendCommandArgs class</param>
|
||||
/// <param name="route">State of valves, 128-bit word</param>
|
||||
/// <param name="filterConstants">Array with length=8 of filter costants (0..255, 0 = no filtering)</param>
|
||||
/// <param name="fmFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
|
||||
/// <param name="regConst">PID coefficient for flow control</param>
|
||||
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
|
||||
void SendCommand(SendCommandArgs sendCommandArgs, UInt128 route, uint[] filterConstants, float[] fmFreq, int regConst, int shortImp);
|
||||
|
||||
/// <summary>
|
||||
/// Control of regulating valves.
|
||||
/// </summary>
|
||||
/// <param name="valveNo">Regulating valve nr. (1..5)</param>
|
||||
/// <param name="valveMode">???</param>
|
||||
/// <param name="valveValue">???</param>
|
||||
/// <param name="stableTime">Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.</param>
|
||||
void ValveMove(int valveNo, RegulValveMode valveMode, double[] valveValue, int stableTime);
|
||||
|
||||
void RunDeviceBefore();
|
||||
void RunDeviceAfter();
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class QueryMeasurementEndOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(QueryMeasurementEndOp));
|
||||
public override string ToString() { return string.Format("QueryMeasurementEndOp()"); }
|
||||
|
||||
/// Set by the constructor
|
||||
readonly CBoard controlBoard;
|
||||
|
||||
bool done;
|
||||
|
||||
/// <summary>
|
||||
/// Events: MeasurementCompleted
|
||||
/// </summary>
|
||||
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
|
||||
public QueryMeasurementEndOp(CBoard controlBoardDev)
|
||||
{
|
||||
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
|
||||
this.controlBoard = controlBoardDev;
|
||||
done = false;
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <summary> Start this operation </summary>
|
||||
public void Start()
|
||||
{
|
||||
done = false;
|
||||
}
|
||||
|
||||
/// <summary> Run this operation </summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (done) return Event.TestCompleted;
|
||||
|
||||
if (0 != (controlBoard.StatusP & StatusP.TestCompleted))
|
||||
{
|
||||
done = true;
|
||||
return Event.TestCompleted;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
/// <summary> Stop this operation </summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
using TBF.Boxes;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class ReadDiverterTransitionOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ReadDiverterTransitionOp));
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("ReadDiverterTransitionOp(.,{0},{1},{2},...)", div.Name, runsCountWhenSendingCmd, runsCountWhenReadingDiv);
|
||||
}
|
||||
|
||||
const int SamplesCount = 240; /// Should be less then or equal to 256
|
||||
float[] samples;
|
||||
|
||||
/// Set by the constructor
|
||||
readonly CBoard controlBoard;
|
||||
readonly GenericDevices.IDiverter div;
|
||||
readonly bool toTank;
|
||||
readonly int runsCountWhenSendingCmd;
|
||||
readonly int runsCountWhenReadingDiv;
|
||||
readonly Sequences.Statistics plotter;
|
||||
readonly int batchNr;
|
||||
readonly string testName;
|
||||
readonly int repetition;
|
||||
|
||||
int counter;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Starts the measurement.
|
||||
/// Events: MeasurementStarted
|
||||
/// </summary>
|
||||
/// <param name="controlBoard">Control board component reference</param>
|
||||
/// <param name="outputPath">Specifies used components</param>
|
||||
/// <param name="method">Test method</param>
|
||||
/// <param name="refPulses">Test duration in number of reference flowmeter pulses</param>
|
||||
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
|
||||
public ReadDiverterTransitionOp(CBoard controlBoard, GenericDevices.IDiverter div, int runsCountWhenSendingCmd, int runsCountWhenReadingDiv, bool toTank,
|
||||
Sequences.Statistics plotter, int batchNr, string testName, int repetition)
|
||||
{
|
||||
if (controlBoard == null) throw new ArgumentNullException("controlBoardDev");
|
||||
if (div == null) throw new ArgumentNullException("div");
|
||||
if (runsCountWhenSendingCmd < 0) throw new ArgumentNullException("runsCountWhenSendingCmd");
|
||||
if (runsCountWhenReadingDiv <= runsCountWhenSendingCmd) throw new ArgumentNullException("runsCountWhenReadingDiv");
|
||||
|
||||
this.controlBoard = controlBoard;
|
||||
this.div = div;
|
||||
this.runsCountWhenSendingCmd = runsCountWhenSendingCmd;
|
||||
this.runsCountWhenReadingDiv = runsCountWhenReadingDiv;
|
||||
this.toTank = toTank;
|
||||
this.plotter = plotter;
|
||||
this.batchNr = batchNr;
|
||||
this.testName = testName;
|
||||
this.repetition = repetition;
|
||||
|
||||
samples = new float[SamplesCount];
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
counter = 0;
|
||||
|
||||
if (runsCountWhenSendingCmd == 0 && div.DiverterNr > 0)
|
||||
{
|
||||
SendCommand();
|
||||
log.DebugFormat("Start() ... Sending a command to read diverter {0}", div.Name);
|
||||
}
|
||||
|
||||
if (plotter != null)
|
||||
{
|
||||
plotter.Start(batchNr, testName, repetition);
|
||||
log.DebugFormat("Start() ... plotter.Start({0}, {1}, {2})", batchNr, testName, repetition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
counter++;
|
||||
|
||||
if (counter == runsCountWhenSendingCmd && div.DiverterNr > 0)
|
||||
{
|
||||
SendCommand();
|
||||
log.DebugFormat("Run() ... Sending a command to read diverter {0}", div.Name);
|
||||
}
|
||||
else if (counter == runsCountWhenReadingDiv && div.DiverterNr > 0)
|
||||
{
|
||||
if (plotter == null)
|
||||
{
|
||||
ReadDiverterTransitionTimes();
|
||||
log.DebugFormat("Run() ... Reading diverter {0} transition times: {1}s", div.Name, (toTank ? div.SwitchTimeStart : div.SwitchTimeEnd).Val);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.DebugFormat("Run() ... Reading diverter {0} samples", div.Name);
|
||||
for (int i = 0; i < SamplesCount; i++)
|
||||
{
|
||||
float oneSample = controlBoard.DivSamples(i, div.DiverterNr - 1);
|
||||
samples[i] = oneSample;
|
||||
plotter.Update(oneSample);
|
||||
}
|
||||
plotter.Stop();
|
||||
|
||||
log.DebugFormat("Run() ... Calculating diverter {0} transition times: {1}s", div.Name, (toTank ? div.SwitchTimeStart : div.SwitchTimeEnd).Val);
|
||||
CalculateDiverterTransitionTimes();
|
||||
}
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
log.DebugFormat("Stop()");
|
||||
}
|
||||
|
||||
void SendCommand()
|
||||
{
|
||||
controlBoard.SyncRoute();
|
||||
controlBoard.SendCommand(Command.ReadDivTransition, 0, 0, 0, 0, StopDevs.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Diverter transition time is read from the control board
|
||||
/// </summary>
|
||||
/// <returns>true (always)</returns>
|
||||
bool ReadDiverterTransitionTimes()
|
||||
{
|
||||
(toTank ? div.SwitchTimeStart : div.SwitchTimeEnd).Val = (float)controlBoard.DivTime(2) - (float)controlBoard.DivTime(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Diverter transition time is calculated from ADC samples and threshold levels
|
||||
/// </summary>
|
||||
/// <returns>true when transition time calculated OK</returns>
|
||||
bool CalculateDiverterTransitionTimes()
|
||||
{
|
||||
bool startedRising = false;
|
||||
bool startedFalling = false;
|
||||
bool stopped = false;
|
||||
|
||||
int transitionStartIdx = 0;
|
||||
int transitionEndIdx = 0;
|
||||
|
||||
float level = samples[0];
|
||||
for (int i = 1; i < SamplesCount; i++)
|
||||
{
|
||||
if (!startedRising && !startedFalling)
|
||||
{
|
||||
if (level <= div.ThresholdLo && samples[i] > div.ThresholdLo)
|
||||
{
|
||||
transitionStartIdx = i;
|
||||
startedRising = true;
|
||||
}
|
||||
else if (level >= div.ThresholdHi && samples[i] < div.ThresholdHi)
|
||||
{
|
||||
transitionStartIdx = i;
|
||||
startedFalling = true;
|
||||
}
|
||||
}
|
||||
else if (startedRising && !stopped && level < div.ThresholdHi && samples[i] >= div.ThresholdHi)
|
||||
{
|
||||
transitionEndIdx = i;
|
||||
stopped = true;
|
||||
break;
|
||||
}
|
||||
else if (startedFalling && !stopped && level > div.ThresholdLo && samples[i] <= div.ThresholdLo)
|
||||
{
|
||||
transitionEndIdx = i;
|
||||
stopped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((startedRising || startedFalling) && stopped)
|
||||
{
|
||||
(toTank ? div.SwitchTimeStart : div.SwitchTimeEnd).Val = 0.002f * (float)(transitionEndIdx - transitionStartIdx); /// 2 ms per sample
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
using TBF.Boxes;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class ReadFlowOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
|
||||
public override string ToString() { return string.Format("ReadFlowOp({0},.,.,{1})", flowMeter.Idx1, eventDone); }
|
||||
|
||||
/// Set by the constructor
|
||||
readonly GenericDevices.IFlowMeter flowMeter;
|
||||
readonly CBoard controlBoard;
|
||||
readonly DoubleBox flowBox;
|
||||
readonly Event eventDone;
|
||||
|
||||
/// <summary>
|
||||
/// Events: FlowInDone, FlowOutDone or Error
|
||||
/// </summary>
|
||||
/// <param name="flowMeter">Flow meter reference</param>
|
||||
/// <param name="flowBox">Reference to the measured flow variable, value is in bar</param>
|
||||
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
|
||||
public ReadFlowOp(GenericDevices.IFlowMeter flowMeter, CBoard controlBoard, ref DoubleBox flowBox, Event eventDone)
|
||||
{
|
||||
if (flowMeter == null || controlBoard == null) throw new ArgumentNullException();
|
||||
|
||||
this.flowMeter = flowMeter;
|
||||
this.controlBoard = controlBoard;
|
||||
this.eventDone = eventDone;
|
||||
this.flowBox = flowBox;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
public ReadFlowOp(GenericDevices.IFlowMeter flowMeter, CBoard controlBoard, ref DoubleBox flowBox)
|
||||
: this(flowMeter, controlBoard, ref flowBox, Event.FlowMeasurementDone)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if ((int)(controlBoard.StatusP & StatusP.RefFlowMeterMask) == flowMeter.Idx1)
|
||||
{
|
||||
flowBox.Val = flowMeter.ReadFlow();
|
||||
return eventDone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Event.Error;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Dirichlet.Numerics;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class SendCommandArgs
|
||||
{
|
||||
public Command Cmd;
|
||||
public int RefFlowmtrNr;
|
||||
public int TotalRefPulses;
|
||||
public int MassRefPulses;
|
||||
public TestMethods TestMethods;
|
||||
public StopDevs StopDevs;
|
||||
|
||||
public SendCommandArgs()
|
||||
{
|
||||
}
|
||||
|
||||
public SendCommandArgs(Command cmd, int refFlowmtrNr, int totalRefPulses, int massRefPulses,
|
||||
TestMethods testMethods, StopDevs stopDevs)
|
||||
{
|
||||
Cmd = cmd;
|
||||
RefFlowmtrNr = refFlowmtrNr;
|
||||
TotalRefPulses = totalRefPulses;
|
||||
MassRefPulses = massRefPulses;
|
||||
TestMethods = testMethods;
|
||||
StopDevs = stopDevs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class StartMeasurementOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(StartMeasurementOp));
|
||||
public override string ToString() { return string.Format("StartMeasurementOp(ref={0},pulses={1})", flowMeterNr, totalRefPulses); }
|
||||
|
||||
/// Set by the constructor
|
||||
readonly CBoard controlBoard;
|
||||
readonly IRegValve regulValve;
|
||||
readonly int regulValveNr;
|
||||
readonly int regulValveStableTime;
|
||||
readonly int flowMeterNr;
|
||||
readonly double nominalFlow;
|
||||
readonly double maximalFlow;
|
||||
readonly double reqFlowLo;
|
||||
readonly double reqFlowHi;
|
||||
readonly int totalRefPulses; /// Number of reference pulses for a complete test
|
||||
readonly int massRefPulses; /// Number of reference pulses for mass collection
|
||||
readonly int delayBeforeFlowRegulation; /// Delay before flow control starts in seconds
|
||||
readonly TestMethods testMethod;
|
||||
readonly int diverterNr;
|
||||
|
||||
///
|
||||
/// Internal states of this operation
|
||||
///
|
||||
enum OpState
|
||||
{
|
||||
StartingTest,
|
||||
ResendCommand,
|
||||
WaitingBeforeValveMove,
|
||||
StartingFlowRegulation,
|
||||
OpCompleted,
|
||||
}
|
||||
OpState opState;
|
||||
|
||||
|
||||
int delayStartTime; /// StateMachine.Time snapshot when delay before flow regulation starts
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Starts the measurement.
|
||||
/// Events: MeasurementStarted
|
||||
/// </summary>
|
||||
/// <param name="controlBoard">Control board component reference</param>
|
||||
/// <param name="outputPath">Specifies used components</param>
|
||||
/// <param name="method">Test method</param>
|
||||
/// <param name="totalRefPulses">Test duration in number of reference flowmeter pulses</param>
|
||||
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
|
||||
public StartMeasurementOp(CBoard controlBoard, OutputPath outputPath, TestMethods method,
|
||||
double requiredFlowLo, double requiredFlowHi, int refPulses, int delayBeforeFlowRegulation = 0)
|
||||
: this(controlBoard, outputPath, method, requiredFlowLo, requiredFlowHi, refPulses, refPulses, delayBeforeFlowRegulation)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the measurement.
|
||||
/// Events: MeasurementStarted
|
||||
/// </summary>
|
||||
/// <param name="controlBoard">Control board component reference</param>
|
||||
/// <param name="outputPath">Specifies used components</param>
|
||||
/// <param name="method">Test method</param>
|
||||
/// <param name="refPulses">Test duration in number of reference flowmeter pulses</param>
|
||||
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
|
||||
public StartMeasurementOp(CBoard controlBoard, OutputPath outputPath, TestMethods method,
|
||||
double requiredFlowLo, double requiredFlowHi, int totalRefPulses, int massRefPulses, int delayBeforeFlowRegulation = 0)
|
||||
{
|
||||
if (controlBoard == null) throw new ArgumentNullException("controlBoardDev");
|
||||
this.controlBoard = controlBoard;
|
||||
|
||||
if (outputPath.FlowMeter == null) throw new ArgumentNullException("Flow meter is missing");
|
||||
flowMeterNr = outputPath.FlowMeter.Idx1;
|
||||
|
||||
this.regulValve = outputPath.RegValve;
|
||||
regulValveNr = 0;
|
||||
regulValveStableTime = 0;
|
||||
|
||||
if (outputPath.Diverter is TBF.Rig.Uni.Diverter.Diverter)
|
||||
{
|
||||
diverterNr = (outputPath.Diverter as TBF.Rig.Uni.Diverter.Diverter).DiverterNr;
|
||||
}
|
||||
|
||||
nominalFlow = outputPath.FlowMeter.NominalFlow;
|
||||
maximalFlow = 1.25 * nominalFlow;
|
||||
|
||||
this.testMethod = method;
|
||||
this.reqFlowLo = requiredFlowLo;
|
||||
this.reqFlowHi = requiredFlowHi;
|
||||
this.totalRefPulses = totalRefPulses;
|
||||
this.massRefPulses = massRefPulses;
|
||||
this.delayBeforeFlowRegulation = delayBeforeFlowRegulation;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
void SendStartCommand()
|
||||
{
|
||||
controlBoard.SyncRoute();
|
||||
#if TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL || BADGER_VELKA_TRAT || SLM_50
|
||||
int flowMeterIdxAndDiv = flowMeterNr + 16 * diverterNr;
|
||||
#elif BADGER_STREDNA_TRAT
|
||||
int flowMeterIdxAndDiv = flowMeterNr + 8 * (diverterNr - 1);
|
||||
#elif FILIPINY_50
|
||||
int flowMeterIdxAndDiv = flowMeterNr + ((flowMeterNr == 3) ? (4 * (diverterNr - 1)) : 0);
|
||||
#elif GELSENWASSER
|
||||
int flowMeterIdxAndDiv = flowMeterNr + ((diverterNr == 2) ? 16 : 0);
|
||||
#else
|
||||
int flowMeterIdxAndDiv = flowMeterNr;
|
||||
#endif
|
||||
log.InfoFormat("Start() : SendCommand(Cmd.Start, {0}, route, {1}, {1}, {2}, Stop.None)",
|
||||
flowMeterIdxAndDiv, totalRefPulses, testMethod);
|
||||
|
||||
controlBoard.SendCommand(Command.Start, flowMeterIdxAndDiv, totalRefPulses, massRefPulses, testMethod, StopDevs.None);
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
SendStartCommand();
|
||||
opState = OpState.StartingTest;
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.FlowInDone or Event.FlowOutDone
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (opState == OpState.StartingTest)
|
||||
{
|
||||
StatusP statusP = controlBoard.StatusP;
|
||||
log.DebugFormat("statusP = {0} {1} {2} {3}",
|
||||
(((ulong)statusP >> 48) & 0xFFFF).ToString("X4"),
|
||||
(((ulong)statusP >> 32) & 0xFFFF).ToString("X4"),
|
||||
(((ulong)statusP >> 16) & 0xFFFF).ToString("X4"),
|
||||
((ulong)statusP & 0xFFFF).ToString("X4"));
|
||||
|
||||
if ((statusP & StatusP.TestInProgress) != 0)
|
||||
{
|
||||
log.Info("Test started");
|
||||
if (delayBeforeFlowRegulation > 0)
|
||||
{
|
||||
delayStartTime = StateMachine.Time;
|
||||
opState = OpState.WaitingBeforeValveMove;
|
||||
}
|
||||
else
|
||||
{
|
||||
opState = OpState.StartingFlowRegulation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//opState = OpState.ResendCommand;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.ResendCommand)
|
||||
{
|
||||
SendStartCommand();
|
||||
opState = OpState.StartingTest;
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.WaitingBeforeValveMove)
|
||||
{
|
||||
if (StateMachine.Time - delayStartTime >= delayBeforeFlowRegulation)
|
||||
{
|
||||
opState = OpState.StartingFlowRegulation;
|
||||
}
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.StartingFlowRegulation)
|
||||
{
|
||||
///
|
||||
/// Done once, issues an appropriate ValveMove(...) command
|
||||
///
|
||||
if ((reqFlowLo >= reqFlowHi) || (reqFlowLo > maximalFlow) || (reqFlowHi <= 0))
|
||||
{
|
||||
return Event.OpArgumentError;
|
||||
}
|
||||
|
||||
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
|
||||
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi);
|
||||
|
||||
double freqLo = 2000.0 * reqFlowLo / nominalFlow;
|
||||
double freqHi = 2000.0 * reqFlowHi / nominalFlow;
|
||||
if (regulValve.IsCoax)
|
||||
{
|
||||
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
|
||||
new double[2] { (freqLo + freqHi) / 2, (freqLo + freqHi) / 2 },
|
||||
regulValveStableTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
|
||||
new double[2] { freqLo, freqHi },
|
||||
regulValveStableTime);
|
||||
}
|
||||
|
||||
opState = OpState.OpCompleted;
|
||||
return Event.None;
|
||||
}
|
||||
else if (opState == OpState.OpCompleted)
|
||||
{
|
||||
return Event.TestInProgress;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
class StopFlowRegulationOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(StopFlowRegulationOp));
|
||||
public override string ToString() { return string.Format("StopFlowRegulationOp(.)"); }
|
||||
|
||||
/// Set by the constructor
|
||||
readonly CBoard controlBoard;
|
||||
readonly int flowMeterNr;
|
||||
|
||||
/// <summary>
|
||||
/// Stop the previous control board operation (diverter, gate, etc.)
|
||||
/// Events: None or PreviousStopped
|
||||
/// </summary>
|
||||
/// <param name="controlBoardDev">Control board component reference</param>
|
||||
public StopFlowRegulationOp(CBoard controlBoardDev)
|
||||
{
|
||||
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
|
||||
this.controlBoard = controlBoardDev;
|
||||
|
||||
if (controlBoardDev.Devices.FlowMeter == null) throw new ArgumentNullException("Flow meter is missing");
|
||||
flowMeterNr = controlBoardDev.Devices.FlowMeter.Idx1;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
|
||||
void SendStopFlowRegulationCommand()
|
||||
{
|
||||
controlBoard.SyncRoute();
|
||||
controlBoard.SendCommand(Command.Stop, flowMeterNr, 0, 0, 0, StopDevs.RegValveRegulation);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
SendStopFlowRegulationCommand();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.FlowRegulationStopped</returns>
|
||||
public Event Run()
|
||||
{
|
||||
return Event.FlowRegulationStopped;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
public class StopPreviousOp : IOperation
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(StopPreviousOp));
|
||||
public override string ToString() { return string.Format("StopPreviousOp(.)"); }
|
||||
|
||||
/// Set by the constructor
|
||||
readonly CBoard controlBoard;
|
||||
|
||||
///
|
||||
/// Internal states of this operation
|
||||
///
|
||||
enum OpState
|
||||
{
|
||||
Idle = 0,
|
||||
CheckIfStopped,
|
||||
ResendCommand,
|
||||
Stopped,
|
||||
}
|
||||
OpState opState;
|
||||
|
||||
/// <summary>
|
||||
/// Stop the previous control board operation (diverter, gate, etc.)
|
||||
/// Events: None or PreviousStopped
|
||||
/// </summary>
|
||||
/// <param name="controlBoardDev">Control board component reference</param>
|
||||
public StopPreviousOp(CBoard controlBoardDev)
|
||||
{
|
||||
if (controlBoardDev == null) throw new ArgumentNullException("controlBoardDev");
|
||||
this.controlBoard = controlBoardDev;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
|
||||
void SendStopCommand()
|
||||
{
|
||||
controlBoard.SyncRoute();
|
||||
controlBoard.SendCommand(Command.Stop, 0, 0, 0, TestMethods.Diverter,
|
||||
StopDevs.Diverter | StopDevs.GatePulse | StopDevs.Reference | StopDevs.RegValveRegulation);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
SendStopCommand();
|
||||
opState = OpState.CheckIfStopped;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>
|
||||
/// Event.None or Event.PreviousStopped
|
||||
/// </returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (opState == OpState.CheckIfStopped)
|
||||
{
|
||||
if ((controlBoard.StatusP & (StatusP.TestCompleted | StatusP.TestInProgress)) == 0)
|
||||
{
|
||||
opState = OpState.Stopped;
|
||||
return Event.PreviousStopped;
|
||||
}
|
||||
else
|
||||
{
|
||||
opState = OpState.ResendCommand;
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
else if (opState == OpState.ResendCommand)
|
||||
{
|
||||
if ((controlBoard.StatusP & (StatusP.TestCompleted | StatusP.TestInProgress)) == 0)
|
||||
{
|
||||
opState = OpState.Stopped;
|
||||
return Event.PreviousStopped;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStopCommand();
|
||||
opState = OpState.CheckIfStopped;
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
else if (opState == OpState.Stopped)
|
||||
{
|
||||
return Event.PreviousStopped;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
opState = OpState.Idle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,774 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Dirichlet.Numerics;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.ControlBoard.Legacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Test bench model inherited by all classes for the simulation of devices.
|
||||
/// Define DN100, MUNICH or nothing.
|
||||
/// </summary>
|
||||
public static class TestBenchSim
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(TestBenchSim));
|
||||
|
||||
///
|
||||
/// Incremented in RunDevice() depending on diverters and valves
|
||||
///
|
||||
public static double Mass1sim; /// Volume in [ltr] or mass in [kg] in the tank1 on the balance1, filled by the diverter1
|
||||
public static double Mass2sim; /// Volume in [ltr] or mass in [kg] in the tank2 on the balance2, filled by the diverter2
|
||||
|
||||
///
|
||||
/// Set by regulation valves
|
||||
///
|
||||
public static double Flow1sim; /// flow in [m3/h] through RV1
|
||||
public static double Flow2sim; /// flow in [m3/h] through RV2
|
||||
public static double Flow3sim; /// flow in [m3/h] through RV3
|
||||
public static double Flow4sim; /// flow in [m3/h] through RV4
|
||||
public static double Flow5sim; /// flow in [m3/h] through RV5
|
||||
public static double Flow6sim; /// flow in [m3/h] through RV5
|
||||
|
||||
///
|
||||
/// Valves and diverters
|
||||
///
|
||||
public static UInt128 SimRoute;
|
||||
public static bool Div1sim;
|
||||
public static bool Div2sim;
|
||||
public static bool Div3sim;
|
||||
|
||||
static int regulValveNo; /// 0=undefined, 1..5
|
||||
static int refFlowmtrNo; /// 0=undefined, 1..4
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Mass1sim = 0; /// Initialize tanks
|
||||
Mass2sim = 0;
|
||||
Flow1sim = 0; /// Initialize regulation valves
|
||||
Flow2sim = 0;
|
||||
Flow3sim = 0;
|
||||
Flow4sim = 0;
|
||||
Flow5sim = 0;
|
||||
Flow6sim = 0;
|
||||
SimRoute = 0; /// Initialize other valves
|
||||
Div1sim = false;
|
||||
Div2sim = false;
|
||||
Div3sim = false;
|
||||
}
|
||||
|
||||
#if DN100
|
||||
/// Paths modulating the flows
|
||||
const ulong K5 = (1L << 0);
|
||||
const ulong K7 = (1L << 1);
|
||||
const ulong K10 = (1L << 2);
|
||||
const ulong K13 = (1L << 3);
|
||||
const ulong K16 = (1L << 4);
|
||||
const ulong K2 = (1L << 5);
|
||||
const ulong EmptyValve1 = (1L << 17);
|
||||
const ulong EmptyValve2 = (1L << 18);
|
||||
const ulong Vl5 = (1L << 21);
|
||||
const ulong Path1 = K2 | K5 | K7;
|
||||
const ulong Path2 = K2 | K5 | K10;
|
||||
const ulong Path3 = K2 | K5 | K13;
|
||||
const ulong Path4 = K2 | K5 | K16;
|
||||
const ulong Path5 = K2 | K5 | Vl5;
|
||||
#elif MUNICH
|
||||
const ulong VL11 = (1L << 0);
|
||||
const ulong VL13 = (1L << 1);
|
||||
const ulong VL21 = (1L << 2);
|
||||
const ulong VL23 = (1L << 3);
|
||||
const ulong VZ1 = (1L << 4);
|
||||
const ulong VP2 = (1L << 5);
|
||||
const ulong VP4 = (1L << 6);
|
||||
const ulong VP5 = (1L << 7);
|
||||
|
||||
const ulong VP6 = (1L << 8);
|
||||
const ulong VL12 = (1L << 9);
|
||||
const ulong VL22 = (1L << 10);
|
||||
const ulong VI11 = (1L << 11);
|
||||
const ulong VI12 = (1L << 12);
|
||||
const ulong VI13 = (1L << 13);
|
||||
const ulong VI21 = (1L << 14);
|
||||
const ulong VI22 = (1L << 15);
|
||||
|
||||
const ulong VI2P = (1L << 16);
|
||||
const ulong VI31 = (1L << 17);
|
||||
const ulong VI32 = (1L << 18);
|
||||
const ulong VI3P = (1L << 19);
|
||||
const ulong VI41 = (1L << 20);
|
||||
const ulong VI42 = (1L << 21);
|
||||
const ulong VI43 = (1L << 22);
|
||||
const ulong VI4P = (1L << 23);
|
||||
|
||||
const ulong VB1 = (1L << 24);
|
||||
const ulong VB1a = (1L << 25);
|
||||
const ulong VB2 = (1L << 26);
|
||||
const ulong VB2a = (1L << 27);
|
||||
const ulong VM1 = (1L << 28);
|
||||
const ulong VM2 = (1L << 29);
|
||||
const ulong VM3 = (1L << 30);
|
||||
const ulong VM4 = ((ulong)1 << 31);
|
||||
|
||||
const ulong Pump1 = ((ulong)1 << 32);
|
||||
const ulong Block = ((ulong)1 << 33);
|
||||
const ulong VZ8 = ((ulong)1 << 37);
|
||||
|
||||
const ulong EmptyValve1 = VB1 | VB1a;
|
||||
const ulong EmptyValve2 = VB2 | VB2a;
|
||||
|
||||
const ulong Path1 = VZ1 | VL12 | VI11 | VI13;
|
||||
const ulong Path2 = VZ1 | VL11 | VL12 | VI21 | VI22 | VI13;
|
||||
const ulong Path3 = VZ1 | VL11 | VL12 | VI31 | VI32;
|
||||
const ulong Path4 = VZ1 | VL11 | VL12 | VI41 | VI42;
|
||||
const ulong Path5 = VZ1 | VL11 | VL12 | VI41 | VI43;
|
||||
#elif FUZHOU_150
|
||||
const ulong VL11 = (1L << 2);
|
||||
const ulong VL13 = (1L << 3);
|
||||
const ulong VL4 = (1L << 4);
|
||||
const ulong VZ6 = (1L << 5);
|
||||
const ulong VZ7 = (1L << 6);
|
||||
const ulong VP5 = (1L << 7);
|
||||
|
||||
const ulong VP6 = (1L << 8);
|
||||
const ulong VL12 = (1L << 9);
|
||||
const ulong VZ14 = (1L << 10);
|
||||
const ulong VI11 = (1L << 11);
|
||||
const ulong VI12 = (1L << 12);
|
||||
const ulong VI13 = (1L << 13);
|
||||
const ulong VI21 = (1L << 14);
|
||||
const ulong VI22 = (1L << 15);
|
||||
|
||||
const ulong VI2p = (1L << 16);
|
||||
const ulong VI31 = (1L << 17);
|
||||
const ulong VI32 = (1L << 18);
|
||||
const ulong VI3p = (1L << 19);
|
||||
const ulong VI41 = (1L << 20);
|
||||
const ulong VI42 = (1L << 21);
|
||||
const ulong VI43 = (1L << 22);
|
||||
const ulong VI4p = (1L << 23);
|
||||
|
||||
const ulong VB1 = (1L << 24);
|
||||
const ulong VB1a = (1L << 25);
|
||||
const ulong VB2 = (1L << 26);
|
||||
const ulong VB2a = (1L << 27);
|
||||
const ulong VM1 = (1L << 28);
|
||||
const ulong VM2 = (1L << 29);
|
||||
const ulong VM3 = (1L << 20);
|
||||
|
||||
const ulong Pump1 = ((ulong)1 << 32);
|
||||
const ulong Pump4 = ((ulong)1 << 33);
|
||||
const ulong Pump2 = ((ulong)1 << 37);
|
||||
const ulong Pump3 = ((ulong)1 << 38);
|
||||
const ulong Pump5 = ((ulong)1 << 39);
|
||||
|
||||
const ulong EmptyValve1 = VB1 | VB1a;
|
||||
const ulong EmptyValve2 = VB2 | VB2a;
|
||||
|
||||
const ulong Path1 = VL12 | VI11 | VI13;
|
||||
const ulong Path2 = VL12 | VI21 | VI22 | VI13;
|
||||
const ulong Path3 = VL12 | VI31 | VI32;
|
||||
const ulong Path4 = VL12 | VI41 | VI42;
|
||||
const ulong Path5 = VL12 | VI41 | VI43;
|
||||
#elif FUZHOU_300
|
||||
const ulong VL11 = (1L << 2);
|
||||
const ulong VL13 = (1L << 3);
|
||||
const ulong VL4 = (1L << 4);
|
||||
const ulong VZ6 = (1L << 5);
|
||||
const ulong VZ7 = (1L << 6);
|
||||
const ulong VP5 = (1L << 7);
|
||||
|
||||
const ulong VP6 = (1L << 8);
|
||||
const ulong VL12 = (1L << 9);
|
||||
const ulong VZ14 = (1L << 10);
|
||||
const ulong VI11 = (1L << 11);
|
||||
const ulong VI12 = (1L << 12);
|
||||
const ulong VI13 = (1L << 13);
|
||||
const ulong VI21 = (1L << 14);
|
||||
const ulong VI22 = (1L << 15);
|
||||
|
||||
const ulong VI2p = (1L << 16);
|
||||
const ulong VI31 = (1L << 17);
|
||||
const ulong VI32 = (1L << 18);
|
||||
const ulong VI3p = (1L << 19);
|
||||
const ulong VI41 = (1L << 20);
|
||||
const ulong VI42 = (1L << 21);
|
||||
const ulong VI43 = (1L << 22);
|
||||
const ulong VI4p = (1L << 23);
|
||||
|
||||
const ulong VB1 = (1L << 24);
|
||||
const ulong VB1a = (1L << 25);
|
||||
const ulong VB2 = (1L << 26);
|
||||
const ulong VB2a = (1L << 27);
|
||||
const ulong VM1 = (1L << 28);
|
||||
const ulong VM2 = (1L << 29);
|
||||
const ulong VM3 = (1L << 20);
|
||||
|
||||
const ulong Pump1 = ((ulong)1 << 32);
|
||||
const ulong Pump4 = ((ulong)1 << 33);
|
||||
const ulong Pump2 = ((ulong)1 << 37);
|
||||
const ulong Pump3 = ((ulong)1 << 38);
|
||||
const ulong Pump5 = ((ulong)1 << 39);
|
||||
|
||||
const ulong EmptyValve1 = VB1 | VB1a;
|
||||
const ulong EmptyValve2 = VB2 | VB2a;
|
||||
|
||||
const ulong Path1 = VL12 | VI11 | VI13;
|
||||
const ulong Path2 = VL12 | VI21 | VI22 | VI13;
|
||||
const ulong Path3 = VL12 | VI31 | VI32;
|
||||
const ulong Path4 = VL12 | VI41 | VI42;
|
||||
const ulong Path5 = VL12 | VI41 | VI43;
|
||||
#elif IZRAEL_200 || PUCHONG_200 || GENESIS || BERLIN || GELSENWASSER
|
||||
const ulong VM11 = (1L << 4);
|
||||
const ulong VM12 = (1L << 5);
|
||||
const ulong VM21 = (1L << 6);
|
||||
const ulong VM22 = (1L << 7);
|
||||
|
||||
const ulong VZ14 = (1L << 8);
|
||||
const ulong VZ13 = (1L << 9);
|
||||
const ulong VL11 = (1L << 10);
|
||||
const ulong VL13 = (1L << 11);
|
||||
const ulong VL4 = (1L << 12);
|
||||
const ulong VZ6 = (1L << 13);
|
||||
const ulong VZ7 = (1L << 14);
|
||||
const ulong VP5 = (1L << 15);
|
||||
|
||||
const ulong VP6 = (1L << 16);
|
||||
const ulong VL12 = (1L << 17);
|
||||
const ulong VL51 = (1L << 18);
|
||||
const ulong VL53 = (1L << 19);
|
||||
const ulong VI11 = (1L << 20);
|
||||
const ulong VI12 = (1L << 21);
|
||||
const ulong VI13 = (1L << 22);
|
||||
const ulong VV1 = (1L << 23);
|
||||
|
||||
const ulong VI21 = (1L << 25);
|
||||
const ulong VI22 = (1L << 26);
|
||||
const ulong VI2p = (1L << 27);
|
||||
const ulong VI31 = (1L << 28);
|
||||
const ulong VI32 = (1L << 29);
|
||||
const ulong VI3p = (1L << 30);
|
||||
const ulong VI41 = (1L << 31);
|
||||
|
||||
const ulong VI42 = (1L << 32);
|
||||
const ulong VI4p = (1L << 33);
|
||||
const ulong VI43 = (1L << 37);
|
||||
|
||||
const ulong VM1 = (1L << 50);
|
||||
const ulong VM2 = (1L << 51);
|
||||
const ulong VM3 = (1L << 52);
|
||||
|
||||
const ulong VB1 = (1L << 41);
|
||||
const ulong VB1a = (1L << 42);
|
||||
const ulong VB2 = (1L << 43);
|
||||
const ulong VB2a = (1L << 44);
|
||||
|
||||
const ulong Pump1 = (1L << 48);
|
||||
const ulong Pump4 = (1L << 49);
|
||||
const ulong Pump2 = (1L << 38);
|
||||
const ulong Pump3 = (1L << 39);
|
||||
const ulong Pump5 = (1L << 40);
|
||||
|
||||
const ulong EmptyValve1 = VB1 | VB1a;
|
||||
const ulong EmptyValve2 = VB2 | VB2a;
|
||||
|
||||
const ulong Path1 = VL12 | VI11 | VI13;
|
||||
const ulong Path2 = VL12 | VI21 | VI22 | VI13;
|
||||
const ulong Path3 = VL12 | VI31 | VI32;
|
||||
const ulong Path4 = VL12 | VI41 | VI42;
|
||||
const ulong Path5 = VL12 | VI41 | VI43;
|
||||
#elif BADGER_MALA_TRAT || BADGER_STREDNA_TRAT || BADGER_VELKA_TRAT
|
||||
const ulong VZ34 = (1L << 0);
|
||||
const ulong VZ35 = (1L << 1);
|
||||
const ulong VZ39 = (1L << 2);
|
||||
const ulong VZ37 = (1L << 3);
|
||||
const ulong VZ38 = (1L << 4);
|
||||
const ulong VL31 = (1L << 5);
|
||||
const ulong VV1 = (1L << 6);
|
||||
const ulong VS33 = (1L << 7);
|
||||
|
||||
const ulong VS31 = (1L << 8);
|
||||
const ulong VS32 = (1L << 9);
|
||||
const ulong VV2 = (1L << 10);
|
||||
const ulong VL32 = (1L << 11);
|
||||
const ulong VI31 = (1L << 12);
|
||||
const ulong VI32 = (1L << 13);
|
||||
const ulong VI33 = (1L << 14);
|
||||
const ulong VI34 = (1L << 15);
|
||||
|
||||
const ulong DIV1 = (1L << 16);
|
||||
const ulong DIV2 = (1L << 17);
|
||||
const ulong VB1 = (1L << 18);
|
||||
const ulong VB1a = (1L << 19);
|
||||
const ulong VB2 = (1L << 20);
|
||||
const ulong VB2a = (1L << 21);
|
||||
const ulong P1 = (1L << 22);
|
||||
const ulong P2 = (1L << 23);
|
||||
|
||||
const ulong EmptyValve1 = VB1 | VB1a;
|
||||
const ulong EmptyValve2 = VB2 | VB2a;
|
||||
|
||||
const ulong Path1 = VI31;
|
||||
const ulong Path2 = VI32;
|
||||
const ulong Path3 = VI33;
|
||||
const ulong Path4 = VI34;
|
||||
const ulong Path5 = 0;
|
||||
#elif CEVAK_40 || MURES_40 || FUZHOU_50 || SLM_50 || MALTA_WSD25
|
||||
const ulong VL11 = (1L << 0);
|
||||
const ulong VL13 = (1L << 1);
|
||||
const ulong VL18 = (1L << 2);
|
||||
const ulong VZ12 = (1L << 3);
|
||||
const ulong VL15 = (1L << 4);
|
||||
const ulong VL21 = (1L << 5);
|
||||
const ulong VL23 = (1L << 6);
|
||||
const ulong VL28 = (1L << 7);
|
||||
|
||||
const ulong VZ5 = (1L << 8);
|
||||
const ulong VI1 = (1L << 9);
|
||||
const ulong VI2 = (1L << 10);
|
||||
const ulong VI3 = (1L << 11);
|
||||
const ulong VZ9 = (1L << 12);
|
||||
const ulong VBa = (1L << 13);
|
||||
const ulong VB = (1L << 14);
|
||||
const ulong DIV1 = (1L << 15);
|
||||
|
||||
const ulong P1 = (1L << 16);
|
||||
const ulong P2 = (1L << 17);
|
||||
const ulong VL9 = (1L << 18);
|
||||
const ulong VV1 = (1L << 19);
|
||||
const ulong VV2 = (1L << 20);
|
||||
const ulong VZ6 = (1L << 21);
|
||||
const ulong VV3 = (1L << 22);
|
||||
const ulong Gate = (1L << 23);
|
||||
|
||||
const ulong EmptyValve1 = VB | VBa;
|
||||
const ulong EmptyValve2 = 0x0000FFFFFFFFFFFF;
|
||||
|
||||
const ulong Path1 = VI1;
|
||||
const ulong Path2 = VI2;
|
||||
const ulong Path3 = VI3;
|
||||
const ulong Path4 = 0;
|
||||
const ulong Path5 = 0;
|
||||
#elif TORINO_50
|
||||
const ulong nic1 = (1L << 0);
|
||||
const ulong nic2 = (1L << 1);
|
||||
const ulong VL11 = (1L << 2);
|
||||
const ulong VL13 = (1L << 3);
|
||||
const ulong VL18 = (1L << 4);
|
||||
const ulong VZ13 = (1L << 5);
|
||||
const ulong VL15 = (1L << 6);
|
||||
const ulong VZ10 = (1L << 7);
|
||||
|
||||
const ulong VZ6 = (1L << 8);
|
||||
const ulong VV1 = (1L << 9);
|
||||
const ulong VV4 = (1L << 10);
|
||||
const ulong VL12 = (1L << 11);
|
||||
const ulong VI1 = (1L << 12);
|
||||
const ulong VI2 = (1L << 13);
|
||||
const ulong VI3 = (1L << 14);
|
||||
const ulong VI4 = (1L << 15);
|
||||
|
||||
const ulong VB1 = (1L << 16);
|
||||
const ulong VB1a = (1L << 17);
|
||||
const ulong VB2 = (1L << 18);
|
||||
const ulong VB2a = (1L << 19);
|
||||
const ulong DIV1 = (1L << 20);
|
||||
const ulong DIV2 = (1L << 21);
|
||||
const ulong P1 = (1L << 22);
|
||||
const ulong P3 = (1L << 23);
|
||||
|
||||
const ulong P2 = (1L << 24);
|
||||
|
||||
const ulong EmptyValve1 = VB1 | VB1a;
|
||||
const ulong EmptyValve2 = VB2 | VB2a;
|
||||
|
||||
const ulong Path1 = VI1;
|
||||
const ulong Path2 = VI2;
|
||||
const ulong Path3 = VI3;
|
||||
const ulong Path4 = VI4;
|
||||
const ulong Path5 = 0;
|
||||
#elif TORUN_50 || TURA_IPERL || TURA_IPERL_NEW
|
||||
const ulong VL11 = (1L << 0);
|
||||
const ulong VL13 = (1L << 1);
|
||||
const ulong VL15 = (1L << 2);
|
||||
const ulong VL21 = (1L << 3);
|
||||
const ulong VL23 = (1L << 4);
|
||||
const ulong VL18 = (1L << 5);
|
||||
const ulong VL28 = (1L << 6);
|
||||
const ulong VZ5 = (1L << 7);
|
||||
|
||||
const ulong VZ6 = (1L << 8);
|
||||
const ulong DIV1 = (1L << 9);
|
||||
const ulong DIV2 = (1L << 10);
|
||||
const ulong P1 = (1L << 11);
|
||||
const ulong P2 = (1L << 12);
|
||||
const ulong P3 = (1L << 13);
|
||||
const ulong DIV3 = (1L << 14);
|
||||
const ulong rez1 = (1L << 15);
|
||||
|
||||
const ulong nic1 = (1L << 16);
|
||||
const ulong nic2 = (1L << 17);
|
||||
const ulong VI1 = (1L << 18);
|
||||
const ulong VI2 = (1L << 19);
|
||||
const ulong VI3 = (1L << 20);
|
||||
const ulong VI4 = (1L << 21);
|
||||
const ulong VI5 = (1L << 22);
|
||||
const ulong VB1 = (1L << 23);
|
||||
|
||||
const ulong VV12 = (1L << 24);
|
||||
const ulong VV22 = (1L << 25);
|
||||
const ulong VI6 = (1L << 26);
|
||||
const ulong VV3 = (1L << 27);
|
||||
const ulong VB2 = (1L << 28);
|
||||
|
||||
const ulong EmptyValve1 = VB1;
|
||||
const ulong EmptyValve2 = VB2;
|
||||
|
||||
const ulong Path1 = VI1;
|
||||
const ulong Path2 = VI2;
|
||||
const ulong Path3 = VI3;
|
||||
const ulong Path4 = VI4;
|
||||
const ulong Path5 = VI5;
|
||||
const ulong Path6 = VI6;
|
||||
#elif TURA_SPECIAL
|
||||
const ulong VL11 = (1L << 0);
|
||||
const ulong VL13 = (1L << 1);
|
||||
const ulong VL15 = (1L << 2);
|
||||
const ulong VL21 = (1L << 3);
|
||||
const ulong VL23 = (1L << 4);
|
||||
const ulong VL18 = (1L << 5);
|
||||
const ulong VL28 = (1L << 6);
|
||||
const ulong VZ5 = (1L << 7);
|
||||
|
||||
const ulong VZ6 = (1L << 8);
|
||||
const ulong DIV1 = (1L << 9);
|
||||
const ulong DIV2 = (1L << 10);
|
||||
const ulong P1 = (1L << 11);
|
||||
const ulong P2 = (1L << 12);
|
||||
const ulong P3 = (1L << 13);
|
||||
const ulong DIV3 = (1L << 14);
|
||||
const ulong rez1 = (1L << 15);
|
||||
|
||||
const ulong nic1 = (1L << 16);
|
||||
const ulong nic2 = (1L << 17);
|
||||
const ulong VI1 = (1L << 18);
|
||||
const ulong VI2 = (1L << 19);
|
||||
const ulong VI3 = (1L << 20);
|
||||
const ulong VI4 = (1L << 21);
|
||||
const ulong VI5 = (1L << 22);
|
||||
const ulong VB1 = (1L << 23);
|
||||
|
||||
const ulong VV12 = (1L << 24);
|
||||
const ulong VV22 = (1L << 25);
|
||||
const ulong VI6 = (1L << 26);
|
||||
const ulong VV3 = (1L << 27);
|
||||
const ulong VB2 = (1L << 28);
|
||||
|
||||
const ulong EmptyValve1 = VB1;
|
||||
const ulong EmptyValve2 = VB2;
|
||||
|
||||
const ulong Path1 = VI1;
|
||||
const ulong Path2 = VI2;
|
||||
const ulong Path3 = VI3;
|
||||
const ulong Path4 = VI4;
|
||||
const ulong Path5 = VI5;
|
||||
const ulong Path6 = VI6;
|
||||
#else
|
||||
/// Paths modulating the flows
|
||||
const ulong V1 = (1L << 1);
|
||||
const ulong V2 = (1L << 2);
|
||||
const ulong V3 = (1L << 3);
|
||||
const ulong V3b = (1L << 4);
|
||||
const ulong V4 = (1L << 5);
|
||||
const ulong V4b = (1L << 6);
|
||||
const ulong V5 = (1L << 7);
|
||||
const ulong V5b = (1L << 8);
|
||||
const ulong EmptyValve1 = (1L << 9); // =Ve1
|
||||
const ulong EmptyValve2 = (1L << 10); // =Ve2
|
||||
const ulong Path1 = V1 | V3 | V3b | V4 | V4b;
|
||||
const ulong Path2 = V2 | V3 | V3b | V5 | V5b;
|
||||
const ulong Path3 = 0;
|
||||
const ulong Path4 = 0;
|
||||
const ulong Path5 = 0;
|
||||
#endif
|
||||
/// <summary>Run this device</summary>
|
||||
public static void RunDevice(int regulValveNo, int refFlowmtrNo, StatusP statusP)
|
||||
{
|
||||
TestBenchSim.regulValveNo = regulValveNo;
|
||||
TestBenchSim.refFlowmtrNo = refFlowmtrNo;
|
||||
double time = 1.0;
|
||||
|
||||
#if DN100
|
||||
if (Div1sim && (SimRoute & Path1) == Path1) Mass1sim += DiffKg(Flow1sim, time);
|
||||
if (Div1sim && (SimRoute & Path2) == Path2) Mass1sim += DiffKg(Flow2sim, time);
|
||||
if (Div2sim && (SimRoute & Path3) == Path3) Mass2sim += DiffKg(Flow3sim, time);
|
||||
if (Div2sim && (SimRoute & Path4) == Path4) Mass2sim += DiffKg(Flow4sim, time);
|
||||
if (Div1sim && (SimRoute & Path5) == Path5) Mass1sim += DiffKg(Flow5sim, time);
|
||||
#elif MUNICH || FUZHOU_150 || FUZHOU_300 || IZRAEL_200 || PUCHONG_200 || GENESIS || BERLIN || GELSENWASSER
|
||||
if (Div1sim && (SimRoute & Path1) == Path1)
|
||||
{
|
||||
double diff = DiffKg(Flow1sim, time);
|
||||
Mass1sim += diff;
|
||||
log.WarnFormat("Path1: Div1, Mass1+={0}kg, flow={1}m3/h, Mass1={2}kg", diff, Flow1sim, Mass1sim);
|
||||
}
|
||||
if (Div1sim && (SimRoute & Path2) == Path2)
|
||||
{
|
||||
double diff = DiffKg(Flow2sim, time);
|
||||
Mass1sim += diff;
|
||||
log.WarnFormat("Path2: Div1, Mass1 += {0}kg, flow={1}m3/h, Mass1={2}kg", diff, Flow1sim, Mass1sim);
|
||||
}
|
||||
if (Div2sim && (SimRoute & Path3) == Path3)
|
||||
{
|
||||
double diff = DiffKg(Flow3sim, time);
|
||||
Mass2sim += diff;
|
||||
log.WarnFormat("Path3: Div2, Mass2 += {0}kg, flow={1}m3/h, Mass2={2}kg", diff, Flow1sim, Mass2sim);
|
||||
}
|
||||
if (Div3sim && (SimRoute & Path4) == Path4)
|
||||
{
|
||||
double diff = DiffKg(Flow4sim, time);
|
||||
Mass2sim += diff;
|
||||
log.WarnFormat("Path4: Div3, Mass2 += {0}kg, flow={1}m3/h, Mass2={2}kg", diff, Flow1sim, Mass2sim);
|
||||
}
|
||||
if (Div3sim && (SimRoute & Path5) == Path5)
|
||||
{
|
||||
double diff = DiffKg(Flow5sim, time);
|
||||
Mass2sim += diff;
|
||||
log.WarnFormat("Path5: Div3, Mass2 += {0}kg, flow={1}m3/h, Mass2={2}kg", diff, Flow1sim, Mass2sim);
|
||||
}
|
||||
#elif BADGER_MALA_TRAT || BADGER_STREDNA_TRAT || BADGER_VELKA_TRAT || TORINO_50 /// Path1,2 do WT1, Path3,4 do WT2
|
||||
if (Div1sim && (SimRoute & Path1) == Path1) Mass1sim += DiffKg(Flow1sim, time);
|
||||
if (Div1sim && (SimRoute & Path2) == Path2) Mass1sim += DiffKg(Flow2sim, time);
|
||||
if (Div2sim && (SimRoute & Path3) == Path3) Mass2sim += DiffKg(Flow3sim, time);
|
||||
if (Div2sim && (SimRoute & Path4) == Path4) Mass2sim += DiffKg(Flow4sim, time);
|
||||
#elif CEVAK_40 || MURES_40 || FUZHOU_50 || SLM_50 || MALTA_WSD25 /// Path1,2,3 do WT1
|
||||
if (Div1sim && (SimRoute & Path1) == Path1) Mass1sim += DiffKg(Flow1sim, time);
|
||||
if (Div1sim && (SimRoute & Path2) == Path2) Mass1sim += DiffKg(Flow2sim, time);
|
||||
if (Div1sim && (SimRoute & Path3) == Path3) Mass1sim += DiffKg(Flow3sim, time);
|
||||
#elif TORUN_50 || TURA_IPERL || TURA_IPERL_NEW /// Path1,2,3,4,5 do WT1, Path6 do WT2
|
||||
if (Div1sim && (SimRoute & Path1) == Path1) Mass1sim += DiffKg(Flow1sim, time);
|
||||
if (Div1sim && (SimRoute & Path2) == Path2) Mass1sim += DiffKg(Flow2sim, time);
|
||||
if (Div1sim && (SimRoute & Path3) == Path3) Mass1sim += DiffKg(Flow3sim, time);
|
||||
if (Div2sim && (SimRoute & Path4) == Path4) Mass1sim += DiffKg(Flow4sim, time);
|
||||
if (Div2sim && (SimRoute & Path5) == Path5) Mass1sim += DiffKg(Flow5sim, time);
|
||||
if (Div3sim && (SimRoute & Path6) == Path6) Mass2sim += DiffKg(Flow4sim, time);
|
||||
#elif TURA_SPECIAL
|
||||
if (Div1sim && (SimRoute & Path1) == Path1) Mass1sim += DiffKg(Flow1sim, time);
|
||||
if (Div1sim && (SimRoute & Path2) == Path2) Mass1sim += DiffKg(Flow2sim, time);
|
||||
if (Div1sim && (SimRoute & Path3) == Path3) Mass1sim += DiffKg(Flow3sim, time);
|
||||
if (Div2sim && (SimRoute & Path4) == Path4) Mass1sim += DiffKg(Flow4sim, time);
|
||||
if (Div2sim && (SimRoute & Path5) == Path5) Mass1sim += DiffKg(Flow5sim, time);
|
||||
if (Div3sim && (SimRoute & Path6) == Path6) Mass2sim += DiffKg(Flow4sim, time);
|
||||
#else
|
||||
if (Div1sim && (SimRoute & Path1) == Path1) Mass1sim += DiffKg(Flow1sim, time);
|
||||
if (Div2sim && (SimRoute & Path2) == Path2) Mass2sim += DiffKg(Flow2sim, time);
|
||||
#endif
|
||||
|
||||
if ((SimRoute & EmptyValve1) == EmptyValve1) Mass1sim -= DiffKg(100.0, time);
|
||||
if (Mass1sim < 0) Mass1sim = 0;
|
||||
|
||||
if ((SimRoute & EmptyValve2) == EmptyValve2) Mass2sim -= DiffKg(10.0, time);
|
||||
if (Mass2sim < 0) Mass2sim = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the mass change from the flow and the time period
|
||||
/// </summary>
|
||||
/// <param name="flowM3H">Flow in [m3/h]</param>
|
||||
/// <param name="timeSec">Time period in [s]</param>
|
||||
/// <returns>Mass change in [kg]</returns>
|
||||
static double DiffKg(double flowM3H, double timeSec)
|
||||
{
|
||||
return timeSec * flowM3H / 3.6;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the simulated mass. Use the balance range to distinguish the balances.
|
||||
/// </summary>
|
||||
/// <param name="balanceNr">0-based balance number</param>
|
||||
/// <returns>Simulated mass reading [kg]</returns>
|
||||
public static double GetSimMass(int balanceNr)
|
||||
{
|
||||
if (balanceNr == 0) return Mass1sim;
|
||||
else if (balanceNr == 1) return Mass2sim;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the simulated diverter. Use the nominal flow to distinguish the path.
|
||||
/// </summary>
|
||||
/// <param name="toTank">Diverter state: true = to the tank</param>
|
||||
/// <param name="nominalFlow">Nominal flow of the path [m3/h]</param>
|
||||
public static void SetSimDiverter(bool toTank)
|
||||
{
|
||||
#if DN100
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
Div2sim = toTank;
|
||||
break;
|
||||
default:
|
||||
if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#elif MUNICH || FUZHOU_150 || FUZHOU_300 || IZRAEL_200 || PUCHONG_200 || GENESIS || BERLIN || GELSENWASSER
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
case 3:
|
||||
Div2sim = toTank;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
Div3sim = toTank;
|
||||
break;
|
||||
default:
|
||||
//if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#elif BADGER_MALA_TRAT || BADGER_STREDNA_TRAT || TORINO_50
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
Div2sim = toTank;
|
||||
break;
|
||||
default:
|
||||
if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#elif BADGER_VELKA_TRAT
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 7:
|
||||
case 2:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
case 3:
|
||||
Div2sim = toTank;
|
||||
break;
|
||||
default:
|
||||
if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#elif CEVAK_40 || MURES_40 || FUZHOU_50 || SLM_50 || MALTA_WSD25
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
default:
|
||||
if (toTank) { /* throw (new Exception()); */ }
|
||||
break;
|
||||
}
|
||||
#elif TORUN_50 || TURA_IPERL || TURA_IPERL_NEW
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
Div2sim = toTank;
|
||||
break;
|
||||
case 6:
|
||||
Div3sim = toTank;
|
||||
break;
|
||||
default:
|
||||
if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#elif TURA_SPECIAL
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
Div1sim = toTank;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
Div2sim = toTank;
|
||||
break;
|
||||
case 6:
|
||||
Div3sim = toTank;
|
||||
break;
|
||||
default:
|
||||
if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1: Div1sim = toTank; break;
|
||||
case 2: Div2sim = toTank; break;
|
||||
default:
|
||||
if (toTank) { throw (new Exception()); }
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the simulated flow in [m3/h].
|
||||
/// </summary>
|
||||
/// <returns>Simulated flow [m3/h]</returns>
|
||||
public static double GetSimFlow()
|
||||
{
|
||||
switch (refFlowmtrNo)
|
||||
{
|
||||
case 1: return ((SimRoute & Path1) == Path1) ? Flow1sim : 0;
|
||||
case 2: return ((SimRoute & Path2) == Path2) ? Flow2sim : 0;
|
||||
case 3: return ((SimRoute & Path3) == Path3) ? Flow3sim : 0;
|
||||
case 4: return (((SimRoute & Path4) == Path4) ? Flow4sim : 0) +
|
||||
(((SimRoute & Path5) == Path5) ? Flow5sim : 0);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Update simulated flow. Use the nominal flow to distinguish the path.
|
||||
/// </summary>
|
||||
/// <param name="targetFlow">Target flow [m3/h]</param>
|
||||
/// <param name="nominalFlow">Nominal flow of the path [m3/h]</param>
|
||||
public static void UpdateSimFlow(double targetFlow)
|
||||
{
|
||||
double A = 0.7; /// higher value -> slower regulation
|
||||
double B = 1.0 - A;
|
||||
|
||||
switch (regulValveNo)
|
||||
{
|
||||
case 1: Flow1sim = A * Flow1sim + B * targetFlow; break;
|
||||
case 2: Flow2sim = A * Flow2sim + B * targetFlow; break;
|
||||
case 3: Flow3sim = A * Flow3sim + B * targetFlow; break;
|
||||
case 4: Flow4sim = A * Flow4sim + B * targetFlow; break;
|
||||
case 5: Flow5sim = A * Flow5sim + B * targetFlow; break;
|
||||
case 6: Flow6sim = A * Flow6sim + B * targetFlow; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,7 +439,7 @@ namespace TBF.Rig.ControlBoard.Papouch
|
||||
/// Start a standing start-stop test
|
||||
/// </summary>
|
||||
/// <returns>Operation</returns>
|
||||
public IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount)
|
||||
public IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount, bool withDiverter)
|
||||
{
|
||||
currentTest = test;
|
||||
return new Operations.ReturnGivenEventOp(Event.TestInProgress);
|
||||
|
||||
@@ -16,9 +16,11 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
readonly UniCB uniCB;
|
||||
readonly TBF.Rig.Uni.RegValve.RegValve regV;
|
||||
readonly TBF.Rig.Uni.FlowMeter.FlowMeter flowMeter;
|
||||
readonly TBF.Rig.Uni.Diverter.Diverter diverter;
|
||||
readonly double qFrom;
|
||||
readonly double qTo;
|
||||
readonly int pulsesCount; /// Number of reference pulses for a complete test
|
||||
readonly int pulsesCount; /// Number of reference pulses for a complete test
|
||||
readonly bool withDiverter; /// Test with diverter (and scale)
|
||||
|
||||
/// <summary>
|
||||
/// Operation for a Standing start-stop test (constructor)
|
||||
@@ -34,7 +36,7 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
/// <param name="qFrom">Flow lower limit</param>
|
||||
/// <param name="qTo">Flow upper limit</param>
|
||||
/// <param name="pulsesCount">Test duration - number of reference flow meter pulses</param>
|
||||
public StandingStartStopTestOp(UniCB cb, OutputPath devices, double qFrom, double qTo, int pulsesCount)
|
||||
public StandingStartStopTestOp(UniCB cb, OutputPath devices, double qFrom, double qTo, int pulsesCount, bool withDiverter)
|
||||
{
|
||||
this.uniCB = cb;
|
||||
|
||||
@@ -47,6 +49,13 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
this.qFrom = qFrom;
|
||||
this.qTo = qTo;
|
||||
this.pulsesCount = pulsesCount;
|
||||
this.withDiverter = withDiverter;
|
||||
|
||||
if (withDiverter)
|
||||
{
|
||||
diverter = devices.Diverter as TBF.Rig.Uni.Diverter.Diverter;
|
||||
if (diverter == null) throw new ArgumentNullException("Invalid diverter");
|
||||
}
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
@@ -69,7 +78,8 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
log.InfoFormat("Op.Start() RV#={0} Et#={1} Qfrom={2} Qto={3}", regV.Idx1, flowMeter.Idx1, qFrom, qTo);
|
||||
|
||||
/// Start the test (and the flow measurement)
|
||||
uniCB.StartTest(false, flowMeter.Idx1, 0, 0, false, false, true, false, pulsesCount);
|
||||
uniCB.StartTest(false, flowMeter.Idx1, (withDiverter ? diverter.DiverterNr : 0), 0,
|
||||
false, withDiverter, true, false, pulsesCount);
|
||||
|
||||
opState = OpState.StartingTest;
|
||||
}
|
||||
|
||||
@@ -559,9 +559,9 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
/// Start a standing start-stop test
|
||||
/// </summary>
|
||||
/// <returns>Operation running a test</returns>
|
||||
public IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount)
|
||||
public IOperation StandingStartStopTestOp(Test test, double qFrom, double qTo, int pulsesCount, bool withDiverter)
|
||||
{
|
||||
return new StandingStartStopTestOp(this, devices, qFrom, qTo, pulsesCount);
|
||||
return new StandingStartStopTestOp(this, devices, qFrom, qTo, pulsesCount, withDiverter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user