diff --git a/TBF/Rig/Output/DB/DatabaseWriter/Factory.cs b/TBF/Rig/Output/DB/DatabaseWriter/Factory.cs
new file mode 100644
index 000000000..cd076ef5c
--- /dev/null
+++ b/TBF/Rig/Output/DB/DatabaseWriter/Factory.cs
@@ -0,0 +1,33 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+
+using System.Collections.Generic;
+using TBF.Rig.Generic;
+
+namespace TBF.Rig.Output.DB.DatabaseWriter
+{
+ ///
+ /// Factory component 'DatabaseWriter' implements more storing modules
+ /// Mosules:
+ /// * store whole results in database
+ /// * store to specific mexico database structure - not implemented yet
+ /// * store configurable data SQL template to a specific database - not implemented yet
+ ///
+ public class Factory : IComponentFactory
+ {
+ public string ClassName { get { return GetType().Namespace.Substring(8); } } /// For backward compatibility
+ public override string ToString() { return ClassName; }
+
+ public IComponent DummyComponent() { return new WritingToDb(); }
+
+ public IComponent GetComponent(IComponentCfg cfg, IList components) { return new WritingToDb(cfg); }
+
+ public IComponentCfg DefaultConfig() { return new WriterCfg("DatabaseWriter", this); }
+
+ public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
+ {
+ return ComponentCfgBase.CreateFromDbEntity(WriterCfg.Serializer, component, this);
+ }
+ }
+}
diff --git a/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.cs b/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.cs
new file mode 100644
index 000000000..943b9a9c9
--- /dev/null
+++ b/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.cs
@@ -0,0 +1,148 @@
+///
+/// Copyright (c) 2018-2019 Sensus Slovensko a.s.
+///
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using Common;
+using TBF.Rig.Generic;
+
+
+namespace TBF.Rig.Output.DB.DatabaseWriter
+{
+ public partial class WriteDbCfgCtrl : Configs.ConfigCtrlUtils, IComponentCfgCtrl
+ {
+ public bool ShowMore { get { return false; } }
+
+ WriterCfg config;
+ public IComponentCfg Config
+ {
+ get { return config as IComponentCfg; }
+ set
+ {
+ config = value as WriterCfg;
+ Redraw();
+ }
+ }
+
+ public WriteDbCfgCtrl()
+ {
+ InitializeComponent();
+ }
+
+ private void WriterCfgCtrl_Load(object sender, EventArgs e)
+ {
+ if (config == null) return;
+ 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;
+ connStrTextBox.Text = config.ConnStr;
+ connStr2TextBox.Text = config.ConnStr2;
+ checkPreviousRecordsCheckBox.Checked = config.CheckPreviousRecords;
+ saveTracingRecordsCheckBox.Checked = config.SaveTracingRecords;
+
+ Network.AdapterInfo.RefreshNetAdaptersInfo();
+ IList adapters = Network.AdapterInfo.NetAdapters;
+
+ string cfgAdapter = string.Empty;
+ foreach (Network.AdapterInfo ai in adapters)
+ {
+ string record;
+
+ if (ai.IPAddress == null)
+ {
+ /// This happens with network adapters that currently have no IP address,
+ /// for instance not connected wireless or dial-up adapters
+ record = "???.???.???.???";
+ }
+ else
+ {
+ /// Do not consider IPv6 adapters as well as "Any", "Broadcast", "Loopback" or "None" addresses
+ if ((ai.IPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) ||
+ ai.IPAddress.Equals(IPAddress.Any) ||
+ ai.IPAddress.Equals(IPAddress.Broadcast) ||
+ ai.IPAddress.Equals(IPAddress.IPv6Any) ||
+ ai.IPAddress.Equals(IPAddress.IPv6Loopback) ||
+ ai.IPAddress.Equals(IPAddress.IPv6None) ||
+ ai.IPAddress.Equals(IPAddress.Loopback) ||
+ ai.IPAddress.Equals(IPAddress.None))
+ {
+ continue;
+ }
+
+ record = ai.IPAddress.ToString();
+ }
+
+ record += " - " + ai.Description;
+ int i = netAdapterComboBox.Items.Add(record);
+ if (ai.Description == config.NetAdapter)
+ {
+ /// Select the adapter currently in the configuration
+ netAdapterComboBox.SelectedIndex = i;
+ }
+ }
+
+ /// Select the first one if the adapter from the configuration does not exist on the system
+ if (netAdapterComboBox.SelectedIndex < 0 && netAdapterComboBox.Items.Count > 0)
+ {
+ netAdapterComboBox.SelectedIndex = 0;
+ }
+ }
+
+ public void Unlock()
+ {
+ nameTextBox.Enabled = true;
+ connStrTextBox.Enabled = true;
+ connStr2TextBox.Enabled = true;
+ netAdapterComboBox.Enabled = true;
+ checkPreviousRecordsCheckBox.Enabled = true;
+ saveTracingRecordsCheckBox.Enabled = true;
+ }
+
+ public CfgUpdateFlags VerifyCfg(ref string message)
+ {
+ return CfgUpdateFlags.None;
+ }
+
+ public CfgUpdateFlags UpdateCfg()
+ {
+ CfgUpdateFlags flags = CfgUpdateFlags.None;
+
+ if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
+
+ if (config.Name != nameTextBox.Text)
+ {
+ config.Name = nameTextBox.Text;
+ flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
+ }
+
+ flags |= UpdateDifferent(ref config.ConnStr, connStrTextBox.Text, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
+ flags |= UpdateDifferent(ref config.ConnStr2, connStr2TextBox.Text, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
+ flags |= UpdateDifferent(ref config.CheckPreviousRecords, checkPreviousRecordsCheckBox.Checked, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
+ flags |= UpdateDifferent(ref config.SaveTracingRecords, saveTracingRecordsCheckBox.Checked, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
+
+ /// Network adapter
+ string strAdapter = netAdapterComboBox.Text;
+ int iDash = strAdapter.IndexOf(" - ");
+ string netAdapter = (iDash < 0) ? "" : strAdapter.Substring(iDash + 3);
+ if (config.NetAdapter != netAdapter)
+ {
+ config.NetAdapter = netAdapter;
+ flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
+ }
+
+ return flags;
+ }
+ }
+}
diff --git a/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.designer.cs b/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.designer.cs
new file mode 100644
index 000000000..3d50f1b36
--- /dev/null
+++ b/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.designer.cs
@@ -0,0 +1,184 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+namespace TBF.Rig.Output.DB.DatabaseWriter
+{
+ partial class WriteDbCfgCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.nameTextBox = new System.Windows.Forms.TextBox();
+ this.nameLabel = new System.Windows.Forms.Label();
+ this.classNameLabel = new System.Windows.Forms.Label();
+ this.connStrTextBox = new System.Windows.Forms.TextBox();
+ this.connStrLabel = new System.Windows.Forms.Label();
+ this.saveTracingRecordsCheckBox = new System.Windows.Forms.CheckBox();
+ this.checkPreviousRecordsCheckBox = new System.Windows.Forms.CheckBox();
+ this.netAdapterLabel = new System.Windows.Forms.Label();
+ this.netAdapterComboBox = new System.Windows.Forms.ComboBox();
+ this.connStr2TextBox = new System.Windows.Forms.TextBox();
+ this.connStr2Label = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // nameTextBox
+ //
+ this.nameTextBox.Enabled = false;
+ this.nameTextBox.Location = new System.Drawing.Point(117, 32);
+ this.nameTextBox.Name = "nameTextBox";
+ this.nameTextBox.Size = new System.Drawing.Size(326, 20);
+ this.nameTextBox.TabIndex = 2;
+ //
+ // nameLabel
+ //
+ this.nameLabel.AutoSize = true;
+ this.nameLabel.Location = new System.Drawing.Point(5, 35);
+ this.nameLabel.Name = "nameLabel";
+ this.nameLabel.Size = new System.Drawing.Size(38, 13);
+ this.nameLabel.TabIndex = 1;
+ this.nameLabel.Text = "Name:";
+ //
+ // classNameLabel
+ //
+ this.classNameLabel.AutoSize = true;
+ this.classNameLabel.Location = new System.Drawing.Point(114, 10);
+ this.classNameLabel.Name = "classNameLabel";
+ this.classNameLabel.Size = new System.Drawing.Size(83, 13);
+ this.classNameLabel.TabIndex = 0;
+ this.classNameLabel.Text = "ComonentName";
+ //
+ // connStrTextBox
+ //
+ this.connStrTextBox.Enabled = false;
+ this.connStrTextBox.Location = new System.Drawing.Point(8, 74);
+ this.connStrTextBox.Name = "connStrTextBox";
+ this.connStrTextBox.Size = new System.Drawing.Size(435, 20);
+ this.connStrTextBox.TabIndex = 4;
+ //
+ // connStrLabel
+ //
+ this.connStrLabel.AutoSize = true;
+ this.connStrLabel.Location = new System.Drawing.Point(5, 58);
+ this.connStrLabel.Name = "connStrLabel";
+ this.connStrLabel.Size = new System.Drawing.Size(92, 13);
+ this.connStrLabel.TabIndex = 3;
+ this.connStrLabel.Text = "Connection string:";
+ //
+ // saveTracingRecordsCheckBox
+ //
+ this.saveTracingRecordsCheckBox.AutoSize = true;
+ this.saveTracingRecordsCheckBox.Enabled = false;
+ this.saveTracingRecordsCheckBox.Location = new System.Drawing.Point(117, 221);
+ this.saveTracingRecordsCheckBox.Name = "saveTracingRecordsCheckBox";
+ this.saveTracingRecordsCheckBox.Size = new System.Drawing.Size(177, 17);
+ this.saveTracingRecordsCheckBox.TabIndex = 10;
+ this.saveTracingRecordsCheckBox.Text = "Save production tracing records";
+ this.saveTracingRecordsCheckBox.UseVisualStyleBackColor = true;
+ //
+ // checkPreviousRecordsCheckBox
+ //
+ this.checkPreviousRecordsCheckBox.AutoSize = true;
+ this.checkPreviousRecordsCheckBox.Enabled = false;
+ this.checkPreviousRecordsCheckBox.Location = new System.Drawing.Point(117, 199);
+ this.checkPreviousRecordsCheckBox.Name = "checkPreviousRecordsCheckBox";
+ this.checkPreviousRecordsCheckBox.Size = new System.Drawing.Size(138, 17);
+ this.checkPreviousRecordsCheckBox.TabIndex = 9;
+ this.checkPreviousRecordsCheckBox.Text = "Check previous records";
+ this.checkPreviousRecordsCheckBox.UseVisualStyleBackColor = true;
+ //
+ // netAdapterLabel
+ //
+ this.netAdapterLabel.AutoSize = true;
+ this.netAdapterLabel.Location = new System.Drawing.Point(5, 147);
+ this.netAdapterLabel.Name = "netAdapterLabel";
+ this.netAdapterLabel.Size = new System.Drawing.Size(89, 13);
+ this.netAdapterLabel.TabIndex = 7;
+ this.netAdapterLabel.Text = "Network adapter:";
+ //
+ // netAdapterComboBox
+ //
+ this.netAdapterComboBox.Enabled = false;
+ this.netAdapterComboBox.FormattingEnabled = true;
+ this.netAdapterComboBox.Location = new System.Drawing.Point(8, 163);
+ this.netAdapterComboBox.Name = "netAdapterComboBox";
+ this.netAdapterComboBox.Size = new System.Drawing.Size(435, 21);
+ this.netAdapterComboBox.TabIndex = 8;
+ //
+ // connStr2TextBox
+ //
+ this.connStr2TextBox.Enabled = false;
+ this.connStr2TextBox.Location = new System.Drawing.Point(8, 118);
+ this.connStr2TextBox.Name = "connStr2TextBox";
+ this.connStr2TextBox.Size = new System.Drawing.Size(434, 20);
+ this.connStr2TextBox.TabIndex = 6;
+ //
+ // connStr2Label
+ //
+ this.connStr2Label.AutoSize = true;
+ this.connStr2Label.Location = new System.Drawing.Point(5, 102);
+ this.connStr2Label.Name = "connStr2Label";
+ this.connStr2Label.Size = new System.Drawing.Size(101, 13);
+ this.connStr2Label.TabIndex = 5;
+ this.connStr2Label.Text = "Connection string 2:";
+ //
+ // TracingCfgCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.connStr2TextBox);
+ this.Controls.Add(this.connStr2Label);
+ this.Controls.Add(this.netAdapterComboBox);
+ this.Controls.Add(this.netAdapterLabel);
+ this.Controls.Add(this.saveTracingRecordsCheckBox);
+ this.Controls.Add(this.checkPreviousRecordsCheckBox);
+ this.Controls.Add(this.connStrTextBox);
+ this.Controls.Add(this.connStrLabel);
+ this.Controls.Add(this.nameTextBox);
+ this.Controls.Add(this.nameLabel);
+ this.Controls.Add(this.classNameLabel);
+ this.Name = "WriteDbCfgCtrl";
+ this.Size = new System.Drawing.Size(450, 250);
+ this.Load += new System.EventHandler(this.WriterCfgCtrl_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox nameTextBox;
+ private System.Windows.Forms.Label nameLabel;
+ private System.Windows.Forms.Label classNameLabel;
+ private System.Windows.Forms.TextBox connStrTextBox;
+ private System.Windows.Forms.Label connStrLabel;
+ private System.Windows.Forms.CheckBox saveTracingRecordsCheckBox;
+ private System.Windows.Forms.CheckBox checkPreviousRecordsCheckBox;
+ private System.Windows.Forms.Label netAdapterLabel;
+ private System.Windows.Forms.ComboBox netAdapterComboBox;
+ private System.Windows.Forms.TextBox connStr2TextBox;
+ private System.Windows.Forms.Label connStr2Label;
+ }
+}
diff --git a/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.resx b/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/TBF/Rig/Output/DB/DatabaseWriter/WriteDBCfgCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TBF/Rig/Output/DB/DatabaseWriter/WriterCfg.cs b/TBF/Rig/Output/DB/DatabaseWriter/WriterCfg.cs
new file mode 100644
index 000000000..bd5eb875b
--- /dev/null
+++ b/TBF/Rig/Output/DB/DatabaseWriter/WriterCfg.cs
@@ -0,0 +1,57 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using TBF.Rig.Generic;
+
+namespace TBF.Rig.Output.DB.DatabaseWriter
+{
+ ///
+ /// Class and file name is preserved for backward compatibility
+ ///
+ public class WriterCfg : ComponentCfgBase, Generic.IComponentCfg
+ {
+ public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(WriterCfg) })[0];
+ public override XmlSerializer GetSerializer() { return Serializer; }
+
+ public IComponentCfgCtrl GetControl(IList cmpntEntities) { return new WriteDbCfgCtrl(); }
+
+
+ public string ConnStr;
+ public string ConnStr2;
+ public string NetAdapter;
+ public bool CheckPreviousRecords;
+ public bool SaveTracingRecords;
+
+
+ /// Private parameterless constructor invoked by all other (public) constructors
+ WriterCfg()
+ {
+ ParentName = string.Empty;
+ NetAdapter = string.Empty;
+ ConnStr = "server=10.42.128.24; database=sledovanie2020; uid=vyroba2020; pwd=qwerty; charset=utf8;";
+ ConnStr2 = "server=10.42.128.24; database=sledovanie2019; uid=vyroba2019; pwd=qwerty; charset=utf8;";
+ CheckPreviousRecords = true;
+ SaveTracingRecords = true;
+ }
+
+ public WriterCfg(string name, IComponentFactory factory)
+ : this()
+ {
+ this.Name = name;
+ this.Factory = factory;
+ }
+
+ public string ToString(int i)
+ {
+ return string.Format("Name={0}, CheckPrev.={1}, SaveRecords={2}, ConnStr={3}, , ConnStr2={4}",
+ Name,
+ CheckPreviousRecords,
+ SaveTracingRecords,
+ ConnStr,
+ ConnStr2);
+ }
+ }
+}
diff --git a/TBF/Rig/Output/DB/DatabaseWriter/WritingToDB.cs b/TBF/Rig/Output/DB/DatabaseWriter/WritingToDB.cs
new file mode 100644
index 000000000..f6f270fee
--- /dev/null
+++ b/TBF/Rig/Output/DB/DatabaseWriter/WritingToDB.cs
@@ -0,0 +1,577 @@
+///
+/// Copyright (c) 2018-2023 Sensus Slovensko a.s.
+///
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using Common;
+using log4net;
+using NHibernate;
+using SharedDatabase;
+using SharedDatabase.Entities;
+using TBF.Rig.Sequences;
+
+namespace TBF.Rig.Output.DB.DatabaseWriter
+{
+ public enum Retv
+ {
+ OK,
+ Error,
+ }
+
+ class DateTimeComparer : IComparer
+ {
+ public int Compare(DateTime x, DateTime y)
+ {
+ return DateTime.Compare(x, y);
+ }
+ }
+
+ public class WritingToDb : ComponentBase, IOperation, GenericDevices.IResultsWriter, GenericDevices.IStartInfoReader, Generic.IDevice
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(WritingToDb));
+ public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
+
+ public const string WorkstepName = "Test_bench";
+
+ public OrderInfo DefaultOrder;
+
+ WriterCfg tracingCfg;
+ string workplace
+ {
+ get
+ {
+ TBF.Rig.GenericDevices.IBenchInfo benchInfo = TBF.Rig.Sequences.ProcessData.BenchInfo;
+ return (benchInfo != null) ? benchInfo.TestBenchName : "TestBench";
+ }
+ }
+
+ IPAddress ipAddress;
+ IPAddress netMask;
+ public IPAddress IPAddress { get { return ipAddress; } }
+ public IPAddress NetMask { get { return netMask; } }
+
+ enum OpState
+ {
+ None,
+ CheckPreviousRecordsScheduled,
+ CheckPreviousRecordsRunning,
+ SaveTracingRecordsScheduled,
+ SaveTracingRecordsRunning,
+ }
+ ///
+ OpState currentOpState;
+ bool opCompleted;
+ bool anyError;
+
+
+ ///
+ /// Watermeters to check at the beginning of the cycle
+ ///
+ IList waterMeters;
+
+ ///
+ /// Data (tracing records) to write at the end of cycle
+ ///
+ Results.Entities.Batch batch;
+
+ public ISessionFactory SessionFactory; /// Factory to create database sessions that is initialized in the constructor
+
+
+ public WritingToDb() {}
+
+ public WritingToDb(Generic.IComponentCfg cfg)
+ : base(cfg)
+ {
+ tracingCfg = cfg as WriterCfg;
+ if (tracingCfg == null) throw new ArgumentException("tracingCfg");
+
+ Network.AdapterInfo.RefreshNetAdaptersInfo();
+ Network.AdapterInfo netadapter = Network.AdapterInfo.GetNetAdapter(tracingCfg.NetAdapter);
+ ipAddress = netadapter.IPAddress;
+
+ netMask = netadapter.NetMask;
+ currentOpState = OpState.None;
+ log.Warn(this.ToString());
+
+ DefaultOrder = null;
+ }
+
+ ///
+ /// IDevice interface implementation
+ ///
+ public override void Initialize()
+ {
+ if (tracingCfg.DebugLevel == DebugMode.Simulate) return;
+
+ string ipAddress = GetIPAddress();
+
+ ///
+ /// Session factory is used to create database sessions
+ ///
+ SharedDatabase.TracingDB.SessionFactory = this.SessionFactory =
+ FluentNHibernate.Cfg.Fluently.Configure()
+ .Database(FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard.ConnectionString(tracingCfg.ConnStr))
+ .Mappings(m => m.FluentMappings.AddFromAssemblyOf())
+ .ExposeConfiguration(SharedDatabase.TracingDB.BuildSchema)
+ .BuildSessionFactory();
+
+ try
+ {
+ using (var session = SessionFactory.OpenSession())
+ {
+ ///
+ /// Initialize DefaultOrder
+ ///
+ var dfltOrders = session.QueryOver()
+ .Where(x => x.POName == "0000001")
+ .And(x => (x.POState == (sbyte)OrderState.New || x.POState == (sbyte)OrderState.Active))
+ .List();
+ if (dfltOrders.Count > 0) DefaultOrder = dfltOrders[0];
+
+#if !DEBUG
+ ///
+ /// Register this test bench in the tracing DB for approx. 2 weeks (RELEASE version only)
+ ///
+ SharedDatabase.TracingDB.RegisterWorkplaceObsolete(session,
+ workplace,
+ CurrentUser.UserName(),
+ GetIPAddress(),
+ "",
+ WorkstepName,
+ DateTime.Now + new TimeSpan(15, 0, 0, 0));
+ session.Flush();
+#endif
+ session.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ log.ErrorFormat("Cannot load a default order from a database or regster this workplace: {0}", ex);
+ DefaultOrder = null;
+ }
+ }
+ ///
+ string GetIPAddress()
+ {
+ return (ipAddress != null) ? ipAddress.ToString() : "1.2.3.4";
+ }
+ ///
+ public void RunDeviceBefore() { }
+ public void RunDeviceAfter() { }
+ ///
+ public void StopDevice()
+ {
+ if (tracingCfg.DebugLevel != DebugMode.Normal) return;
+
+ using (ISession session = SessionFactory.OpenSession())
+ {
+ SharedDatabase.TracingDB.UnregisterWorkplaceObsolete(session, workplace);
+ session.Flush();
+ }
+ }
+ public void StopDevice2() {}
+
+ public IList ReadOrders()
+ {
+ try
+ {
+ using (var session = SessionFactory.OpenSession())
+ {
+ var result = session.QueryOver()
+ .Where(x => (x.POState == (sbyte)OrderState.New || x.POState == (sbyte)OrderState.Active))
+ .List();
+ session.Close();
+ return result;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.ErrorFormat("ReadOrders() failed: {0}", ex.Message);
+ return new List();
+ }
+ }
+
+ ///
+ /// Read reference records belonging to a specified order.
+ /// Used when retrieving housing S/N-s belonging to obtained eRegister numbers.
+ ///
+ /// DB sesson
+ /// Order
+ /// List of reference records-s
+ public IList ReadRefRecords(ISession session, OrderInfo order, OrderInfo dfltOrder = null, Process dfltWFlow = null)
+ {
+ try
+ {
+ var refRecords = session.QueryOver()
+ .Where(x => (x.POName == order.POName))
+ .List();
+ refRecords.Reverse();
+
+ if (dfltOrder != null && dfltWFlow != null)
+ {
+ var moreRecords = session.QueryOver()
+ .Where(x => (x.POName == dfltOrder.POName))
+ .And(x => (x.Workflow == dfltWFlow.Name))
+ .List();
+ for (int i = moreRecords.Count - 1; i >= 0; i--) refRecords.Add(moreRecords[i]);
+ }
+
+ return refRecords;
+ }
+ catch (Exception exc)
+ {
+ log.ErrorFormat("Cannot read ref.records from the tracing DB: {0}", exc.Message);
+ return new List();
+ }
+ }
+
+
+ ///
+ /// Read records belonging to a specified order
+ ///
+ /// DB sesson
+ /// Order
+ /// List of records
+ public IList ReadRecords(ISession session, OrderInfo order, OrderInfo dfltOrder = null, Process dfltWFlow = null)
+ {
+ try
+ {
+ var records = session.QueryOver()
+ .JoinQueryOver(rec => rec.ReferenceRecord)
+ .Where(rr => rr.POName == order.POName)
+ .List();
+ records.Reverse();
+
+ if (dfltOrder != null && dfltWFlow != null)
+ {
+ var moreRecords = session.QueryOver()
+ .JoinQueryOver(rec => rec.ReferenceRecord)
+ .Where(rr => (rr.POName == dfltOrder.POName))
+ .And(rr => (rr.Workflow == dfltWFlow.Name))
+ .List();
+ for (int i = moreRecords.Count - 1; i >= 0; i--) records.Add(moreRecords[i]);
+ }
+
+ return records;
+ }
+ catch (Exception exc)
+ {
+ log.ErrorFormat("Cannot read records from the tracing DB: {0}", exc.Message);
+ return new List();
+ }
+ }
+
+
+ ///
+ /// Reads information on start of a cycle, Events: Event.InfoRead
+ ///
+ /// Results of water meters
+ /// Reference to the operation
+ public IOperation ReadStartInfoOp(IList waterMeters)
+ {
+ if (!tracingCfg.CheckPreviousRecords)
+ {
+ return null;
+ }
+ else if ((currentOpState == OpState.CheckPreviousRecordsRunning) || (currentOpState == OpState.SaveTracingRecordsRunning))
+ {
+ throw new Exception("Sequence error");
+ }
+ else
+ {
+ this.waterMeters = waterMeters;
+ currentOpState = OpState.CheckPreviousRecordsScheduled;
+ return this;
+ }
+ }
+
+ ///
+ /// Writes the test cycle results into a file, Events: Event.ResultsWritten
+ ///
+ /// Procedure to print the results of
+ /// Results to write into the file
+ /// Reference to the operation
+ public IOperation ProcessResultsOp(Results.Entities.Batch batch)
+ {
+ if (!tracingCfg.SaveTracingRecords)
+ {
+ return null;
+ }
+ else if ((currentOpState == OpState.CheckPreviousRecordsRunning) || (currentOpState == OpState.SaveTracingRecordsRunning))
+ {
+ throw new Exception("Sequence error");
+ }
+ else
+ {
+ this.batch = batch;
+ currentOpState = OpState.SaveTracingRecordsScheduled;
+ return this;
+ }
+ }
+
+
+ /// Start this operation
+ public void Start()
+ {
+ if (currentOpState == OpState.CheckPreviousRecordsScheduled)
+ {
+ currentOpState = OpState.CheckPreviousRecordsRunning;
+ }
+ else if (currentOpState == OpState.SaveTracingRecordsScheduled)
+ {
+ currentOpState = OpState.SaveTracingRecordsRunning;
+ }
+
+ opCompleted = false;
+ anyError = false;
+ }
+
+ /// Run this operation
+ /// Event.ResultsWritten or Event.Error
+ public Event Run()
+ {
+ log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
+
+ if (currentOpState == OpState.CheckPreviousRecordsRunning)
+ {
+ if (tracingCfg.DebugLevel == DebugMode.Simulate) return Event.InfoRead;
+ if (opCompleted) return anyError ? Event.InfoNotRead : Event.InfoRead;
+
+ /// Run once
+ opCompleted = true;
+ if (CheckPreviousRecords(waterMeters) != Retv.OK) anyError = true;
+ return anyError ? Event.InfoNotRead : Event.InfoRead;
+ }
+
+ if (currentOpState == OpState.SaveTracingRecordsRunning)
+ {
+ if (tracingCfg.DebugLevel == DebugMode.Simulate || batch.WaterMeters.Count == 0) return Event.ResultsWritten;
+ if (opCompleted) return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
+
+ /// Run once
+ opCompleted = true;
+ if (SaveTracingRecords(batch) != Retv.OK) anyError = true;
+
+ if (anyError && !string.IsNullOrEmpty(SharedDatabase.EventsDB.ConnectionString))
+ {
+ try
+ {
+ NHibernate.ISession session = SharedDatabase.EventsDB.CreateSession();
+ SharedDatabase.EventsDB.LoadSubscribers(session);
+
+ TBF.UiBridge.Bridge.TriggerEvent(session, Name, EventClass.ComputerResources, Severity.Error,
+ string.Format("Nepodarilo sa uložiť výsledky do sledovacej DB: Číslo dávky={0}", batch.BatchNr),
+ string.Format("Nepodarilo sa uložiť výsledky do sledovacej DB\r\nČíslo dávky = {0}", batch.BatchNr),
+ SubscriberGroup.Metrology | SubscriberGroup.Maintenance | SubscriberGroup.Production);
+ }
+ catch (Exception exc)
+ {
+ log.ErrorFormat("Triggering event(s) failed: {0}", exc.Message);
+ }
+ }
+
+ return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
+ }
+
+ return Event.None;
+ }
+
+ /// Stop this operation
+ public void Stop()
+ {
+ currentOpState = OpState.None;
+ }
+
+
+ Retv CheckPreviousRecords(IList waterMeters)
+ {
+ Retv retVal = Retv.Error;
+
+ var sampleWM = waterMeters.FirstOrDefault(x => x != null && x.Disabled == false);
+ if (sampleWM != null)
+ {
+ using (ISession session = SessionFactory.OpenSession())
+ {
+ for (int i = 0; i < waterMeters.Count; i++)
+ {
+ Results.Entities.WaterMeter wm = waterMeters[i];
+
+ if ((wm != null) && !wm.Disabled)
+ {
+ CheckPreviousRecordOfSingleWM(session, wm);
+ }
+ }
+
+ retVal = Retv.OK; /// Successfully completed (regardless of wm.LastRecordIsNok)
+ }
+ }
+
+ return retVal; /// Returns Retv.Error if checking not completed successfully
+ }
+
+
+ Retv CheckPreviousRecordOfSingleWM(ISession session, Results.Entities.WaterMeter wm)
+ {
+ if (!string.IsNullOrEmpty(wm.SerialNr) && ProcessData.WorkflowSummary != null)
+ {
+ /// Get all reference records with Code == SerialNr from all worksteps different from 'Test_bench'
+ var refRecords = session.QueryOver()
+ .Where(rr => (rr.Code1 == wm.SerialNr))
+ .List();
+
+ if (refRecords.Count == 1)
+ {
+ ReferenceRecord refRecord = refRecords[0];
+ StepRecord previousStep = string.IsNullOrEmpty(ProcessData.WorkflowSummary.PreviousWorkstepName) ? null
+ : refRecord.StepRecords.FirstOrDefault(x => x.Workstep == ProcessData.WorkflowSummary.PreviousWorkstepName);
+
+ if (refRecord.Name1 == ProcessData.WorkflowSummary.Part1Name &&
+ refRecord.Name2 == ProcessData.WorkflowSummary.Part2Name &&
+ (ProcessData.WorkflowSummary.PreviousWorkstepName == null ||
+ (previousStep != null && previousStep.Workstep == ProcessData.WorkflowSummary.PreviousWorkstepName)))
+ {
+ wm.Workflow = ProcessData.WorkflowSummary.Workflow.Name;
+ wm.LastRecordIsNok = false; /// OK
+ return Retv.OK;
+ }
+ }
+ }
+
+ /// S/N is missing OR no records found OR workflows do not match OR previous StepRecord is missing
+ wm.Workflow = string.Empty;
+ wm.LastRecordIsNok = true; /// NOK
+ return Retv.OK;
+ }
+
+
+ ///
+ /// Write results of a batch of water meters to the DB
+ ///
+ /// DB session
+ /// Batch entity
+ Retv SaveTracingRecords(Results.Entities.Batch batch)
+ {
+ ITransaction transaction = null;
+ ISession session = null;
+
+ var order = ProcessData.OrderInfo as SharedDatabase.Entities.OrderInfo;
+ if (order != null && ProcessData.WorkflowSummary != null && !string.IsNullOrEmpty(ProcessData.WorkflowSummary.WorkstepName))
+ {
+ ///
+ /// Save to regular tracing DB
+ ///
+ try
+ {
+ session = SessionFactory.OpenSession();
+ transaction = session.BeginTransaction();
+
+ string workplace = (ProcessData.BenchInfo != null) ? ProcessData.BenchInfo.TestBenchName : "TestBench";
+ int writtenRecordsCount = 0;
+ foreach (var wm in batch.WaterMeters)
+ {
+ if (!wm.Disabled && !string.IsNullOrEmpty(wm.SerialNr))
+ {
+ writtenRecordsCount += SaveSingleWM2DB(session, wm, order.POName, ProcessData.WorkflowSummary, workplace);
+ }
+ }
+
+ transaction.Commit();
+ session.Flush();
+
+ log.WarnFormat("Batch {0}: {1} of {2} watermeters written to the regular production tracing DB",
+ batch.BatchNr, writtenRecordsCount, batch.WaterMeters.Count);
+ }
+ catch (Exception exc)
+ {
+ if (transaction != null && !transaction.WasCommitted) transaction.Rollback();
+
+ log.ErrorFormat("Failed to write results of batch {0} to production tracing DB: {1}",
+ batch.BatchNr, exc.Message);
+
+ return Retv.Error;
+ }
+ finally
+ {
+ if (session != null)
+ {
+ session.Close();
+ session.Dispose();
+ }
+ }
+ }
+
+ return Retv.OK;
+ }
+
+ ///
+ /// Write one meter results to the DB
+ ///
+ /// DB session
+ /// Watermeter entity
+ int SaveSingleWM2DB(ISession session, Results.Entities.WaterMeter wm, string poName, WorkflowSummary wflowSummary, string worplace)
+ {
+ if (string.IsNullOrEmpty(wflowSummary.WorkstepName)) return 0;
+
+ IList existingRecords = session.QueryOver()
+ .Where(x => (x.Code1 == wm.SerialNr))
+ .List();
+ if (existingRecords.Count > 1)
+ {
+ /// Unexpected error
+ log.ErrorFormat("Multiple reference records exist: Code1 = {0}", wm.SerialNr);
+ return 0;
+ }
+
+ ///
+ /// Reference record
+ ///
+ ReferenceRecord refRecord = null;
+ if (existingRecords.Count == 1)
+ {
+ /// TODO: Check if the selected worflow is the same as in the found record
+ refRecord = existingRecords[0];
+
+ refRecord.POName = poName;
+ refRecord.Workflow = wflowSummary.Workflow.Name;
+ refRecord.Code2 = wm.SerialNrAux;
+ refRecord.Code3 = wm.CompleteSerialNr;
+ refRecord.Code4 = wm.RadioAddress;
+ }
+ else
+ {
+ refRecord = new ReferenceRecord(poName,
+ wflowSummary.Workflow.Name,
+ wflowSummary.Part1Name, /// PCB (iPERL) or housing (620/640) SAP number
+ wm.SerialNr, /// PcbNumber (iPERL) or housing S/N (620/640)
+ wflowSummary.Part2Name, /// Flowtube SAP nummber (iPERL) or "eRegister#" (640) or empty
+ wm.SerialNrAux, /// Flowtube S/N (iPERL) or eRegister number (640) or empty
+ wm.CompleteSerialNr, /// Complete assigned S/N
+ wm.RadioAddress); /// Radio address (iPERL and 640)
+ }
+
+ ///
+ /// Step record
+ ///
+ StepRecord stepRecord = new StepRecord(refRecord,
+ wflowSummary.WorkstepName,
+ workplace,
+ Common.CurrentUser.UserName(),
+ wm.PassedFromTests() ? 0 : 1);
+ if (refRecord.StepRecords == null)
+ {
+ refRecord.StepRecords = new List { stepRecord };
+ }
+ else
+ {
+ refRecord.StepRecords.Add(stepRecord);
+ }
+
+ session.SaveOrUpdate(refRecord);
+ session.SaveOrUpdate(stepRecord);
+ return 1;
+ }
+ }
+}
diff --git a/TBF/Rig/TbfComponents.cs b/TBF/Rig/TbfComponents.cs
index b92a08765..639d72a98 100644
--- a/TBF/Rig/TbfComponents.cs
+++ b/TBF/Rig/TbfComponents.cs
@@ -91,6 +91,7 @@ namespace TBF.Rig
new Network.Camera.RoiForFixedStartKeyence.Factory(),
new Network.Comet.Ambient.Factory(),
new Network.RestAPI.Factory(),
+ new Output.DB.DatabaseWriter.Factory(), // 'DatabaseWriter' module implements more store specific modules
new Output.DB.ProductionTracing.Factory(),
new Output.DB.SaveDiverterCorrections.Factory(),
new Output.DB.SaveFlowmeterCorrections.Factory(),
diff --git a/TBF/Rig/TestMethods/FlyingStart/FlyingStartSeq.cs b/TBF/Rig/TestMethods/FlyingStart/FlyingStartSeq.cs
index fdc65f6b9..9efbec11d 100644
--- a/TBF/Rig/TestMethods/FlyingStart/FlyingStartSeq.cs
+++ b/TBF/Rig/TestMethods/FlyingStart/FlyingStartSeq.cs
@@ -6,10 +6,13 @@ using System.Collections.Generic;
using System.Text;
using log4net;
using Common;
+using Config.Entities;
+using Results.Entities;
using TBF.Rig;
using TBF.Rig.GenericDevices;
using TBF.Boxes;
using TBF.Resources;
+using TBF.Rig.TestMethods.GenesisCommunication.GenesisHead;
using TBF.UiBridge;
namespace TBF.Rig.TestMethods.FlyingStart
@@ -135,6 +138,8 @@ namespace TBF.Rig.TestMethods.FlyingStart
Bridge.OnTestSelected(this, new TestSelectedEventArgs(test, repetitionNr, inPath, benchPath, outPath, sensPath, heatMetersPath));
string testName = Results.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
TestStartTime = DateTime.Now;
+ // Genesis switch
+ bool atleastOneGenesis = GenesisHeadBatch.Start(sensPath.RegisterReaders, Program.LocalSettings.LastSNTexts);
///
/// Optionally display prompt to emerge temperature meters to appropriate baths for heat meters test
@@ -323,6 +328,20 @@ namespace TBF.Rig.TestMethods.FlyingStart
temperature_set:
+ //TODO genesis - check with genesis switch
+ if (atleastOneGenesis)
+ {
+ if (test.Name.ToLower().Contains("calib"))
+ {
+ GenesisHeadBatch.BatchHolder.Value.MetersLogin();
+ GenesisHeadBatch.BatchHolder.Value.MetersInitCalibration();
+
+ } else if (test.Name.ToLower().Contains("Init"))
+ {
+ GenesisHeadBatch.BatchHolder.Value.MetersLogin();
+ GenesisHeadBatch.BatchHolder.Value.MetersInitMeasurement();
+ }
+ }
///
/// Prepare cameras, ROI-s and measurementOperations
///
@@ -358,7 +377,12 @@ namespace TBF.Rig.TestMethods.FlyingStart
foreach (var rr in sensPath.RegisterReaders)
{
- if (rr is IRegReaderDatastream) (rr as IRegReaderDatastream).TestIsGoingToStartSoon(test, repetitionNr);
+ if (rr is IRegReaderDatastream)
+ (rr as IRegReaderDatastream).TestIsGoingToStartSoon(test, repetitionNr);
+
+ if (rr is GenesisHead) // Genesis - CORDONEL head
+ (rr as GenesisHead).StartRead(test.Name, BatchRslts.Batch.BatchNr, repetitionNr);
+
}
@@ -426,8 +450,21 @@ namespace TBF.Rig.TestMethods.FlyingStart
/// Measurement loop end
StopRecordingStatistics();
+
+ //TODO genesis - check with genesis switch
+ if (atleastOneGenesis)
+ {
+ if (test.Name.ToLower().Contains("calib"))
+ {
+ GenesisHeadBatch.BatchHolder.Value.MetersStopCalibration();
+ }
+ else if (test.Name.ToLower().Contains("Init"))
+ {
+ GenesisHeadBatch.BatchHolder.Value.MetersStopMeasurement();
+ }
+ }
- //------------------------------------------------
+ //------------------------------------------------
Bridge.OnActivity(this, Strings.Test_completed);
//------------------------------------------------
@@ -589,6 +626,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
GenericDevices.IRegReaderDatastream dstrReader = regReader as GenericDevices.IRegReaderDatastream;
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
GenericDevices.IRegReaderLiveCamera cameraRoi = regReader as GenericDevices.IRegReaderLiveCamera;
+ GenesisHead Genesis = regReader as GenesisHead;
if (meterRslt != null && regReader != null)
{
@@ -596,83 +634,147 @@ namespace TBF.Rig.TestMethods.FlyingStart
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
- if (dstrReader != null)
- {
- meterRslt.TimestampStart = dstrReader.TimestampSecStart;
- meterRslt.TimestampEnd = dstrReader.NoSamples ? (dstrReader.TimestampSecStart + tstRslt.TestTime) : dstrReader.TimestampSecEnd;
- meterRslt.TestTime = meterRslt.TimestampEnd - meterRslt.TimestampStart;
- meterRslt.VolumeStart = dstrReader.VolumeLtrStart; /// liter
- meterRslt.VolumeEnd = dstrReader.VolumeLtrEnd; /// liter
- meterRslt.VolumeMeter = Math.Abs(dstrReader.VolumeLtrEnd - dstrReader.VolumeLtrStart);
- meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
- meterRslt.PulsesMaster = tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
+
+ if (Genesis != null)
+ {
+ Genesis.Stop(tstRslt.TestTime, tstRslt.VolumeCTV);
- if (iPerl != null)
+ meterRslt.TimestampStart = Genesis.TimestampSecStart;
+ meterRslt.TimestampEnd = Genesis.TimestampSecEnd;
+ meterRslt.TestTime = Genesis.WMTestTime;
+ meterRslt.VolumeStart = Genesis.BeginWMState;
+ meterRslt.VolumeEnd = Genesis.EndWMState; /// liter
+ meterRslt.VolumeMeter = Math.Abs(Genesis.WMVolume);
+ meterRslt.VolumeRef = tstRslt.VolumeCTV;
+ if (GenesisHeadBatch.MeterIdDetailResults == null)
{
- if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
+ Genesis.Log("MeterIdDetailResults na!");
+ }
+ else
+ {
+ if (Genesis.DetailedResults != null)
{
- meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
+ try
+ {
+ GenesisHeadBatch.MeterIdDetailResults.Add(meterRslt.SerialNr(), Genesis.DetailedResults);
+ }
+ catch (Exception ex) { Genesis.Log(ex.Message.ToString()); }
}
-#if IPERL
- meterRslt.WaterMeter.CalibFactor = iPerl.CalibFactor;
- meterRslt.ExtraDataPath = iPerl.ExtraDataPath;
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 1) meterRslt.X1 = iPerl.X[0];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 2) meterRslt.X2 = iPerl.X[1];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 3) meterRslt.X3 = iPerl.X[2];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 4) meterRslt.X4 = iPerl.X[3];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 5) meterRslt.X5 = iPerl.X[4];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 6) meterRslt.X6 = iPerl.X[5];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 7) meterRslt.X7 = iPerl.X[6];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 8) meterRslt.X8 = iPerl.X[7];
- if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 9) meterRslt.X9 = iPerl.X[8];
-#endif
- iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
- iPerl.LastTestResult = meterRslt; /// Save this test result
- }
- }
- else if (cameraRoi != null)
- {
- meterRslt.TimestampStart = cameraRoi.TimestampStart; /// second
- meterRslt.TimestampEnd = cameraRoi.TimestampEnd; /// second
-
- meterRslt.VolumeStart = cameraRoi.VolumeStart; /// liter
- meterRslt.VolumeEnd = cameraRoi.VolumeEnd; /// liter
- meterRslt.VolumeMeter = cameraRoi.VolumeEnd - cameraRoi.VolumeStart; /// liter
-
- if (meterRslt.VolumeMeter != 0)
- {
- /// Normal measurement with camera
- meterRslt.TestTime = cameraRoi.TimestampEnd - cameraRoi.TimestampStart; /// second
- meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
- meterRslt.PulsesMaster = tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
- }
- else
- {
- /// None or one pulse from the water meter using camera
- meterRslt.TestTime = tstRslt.TestTime;
- meterRslt.VolumeRef = tstRslt.VolumeCTV;
- meterRslt.PulsesMaster = tstRslt.PulsesMaster;
+ else
+ {
+ Genesis.Log("DetailedResults na!");
+ }
}
+
+ Genesis.Log("VolumeRef=" + meterRslt.VolumeRef);
+ Genesis.Log("TestTime Meter =" + meterRslt.TestTime + "S, test time ref =" + tstRslt.TestTime + "s");
+ Genesis.Log(" results for " + test.Name);
+ Genesis.Log(" Ref Vol = " + meterRslt.VolumeRef + " m³");
+ Genesis.Log(" Ref Time = " + tstRslt.TestTime + " s");
+ Genesis.Log(" Meter Time = " + meterRslt.TestTime + " s");
+ Genesis.Log(" Meter Vol = " + meterRslt.VolumeMeter + " m³");
+
+ var calError = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
+ Genesis.Log(" MeterError = " + calError.ToString() + " %");
}
- else
- {
- meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
- meterRslt.VolumeStart = 0;
- meterRslt.VolumeEnd = 0;
- meterRslt.VolumeMeter = meterRslt.PulsesMeter * regReader.LtrsPerPulse; /// liter
- ///
- if (regReader.WMPulses >= 1)
- {
- /// Normal measurement
- meterRslt.TestTime = cBrd.TestTimeWM(regReader.Position);
- meterRslt.VolumeRef = meterRslt.PulsesMaster * tstRslt.ConstMaster; /// liter
- }
- else
- {
- /// None or one pulse from the water meter
- meterRslt.TestTime = tstRslt.TestTime;
- meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter
- }
+ else
+ {
+ if (dstrReader != null)
+ {
+ meterRslt.TimestampStart = dstrReader.TimestampSecStart;
+ meterRslt.TimestampEnd = dstrReader.NoSamples
+ ? (dstrReader.TimestampSecStart + tstRslt.TestTime)
+ : dstrReader.TimestampSecEnd;
+ meterRslt.TestTime = meterRslt.TimestampEnd - meterRslt.TimestampStart;
+ meterRslt.VolumeStart = dstrReader.VolumeLtrStart; /// liter
+ meterRslt.VolumeEnd = dstrReader.VolumeLtrEnd; /// liter
+ meterRslt.VolumeMeter =
+ Math.Abs(dstrReader.VolumeLtrEnd - dstrReader.VolumeLtrStart);
+ meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
+ meterRslt.PulsesMaster =
+ tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
+
+ if (iPerl != null)
+ {
+ if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode &
+ (int)Results.Entities.ResultCode
+ .OptoErrorCodeMask) == 0)
+ {
+ meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
+ }
+#if IPERL
+ meterRslt.WaterMeter.CalibFactor = iPerl.CalibFactor;
+ meterRslt.ExtraDataPath = iPerl.ExtraDataPath;
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 1)
+ meterRslt.X1 = iPerl.X[0];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 2)
+ meterRslt.X2 = iPerl.X[1];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 3)
+ meterRslt.X3 = iPerl.X[2];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 4)
+ meterRslt.X4 = iPerl.X[3];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 5)
+ meterRslt.X5 = iPerl.X[4];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 6)
+ meterRslt.X6 = iPerl.X[5];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 7)
+ meterRslt.X7 = iPerl.X[6];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 8)
+ meterRslt.X8 = iPerl.X[7];
+ if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 9)
+ meterRslt.X9 = iPerl.X[8];
+#endif
+ iPerl.LastTestResult2 =
+ iPerl.LastTestResult; /// Save shift previous test result
+ iPerl.LastTestResult = meterRslt; /// Save this test result
+ }
+ }
+ else if (cameraRoi != null)
+ {
+ meterRslt.TimestampStart = cameraRoi.TimestampStart; /// second
+ meterRslt.TimestampEnd = cameraRoi.TimestampEnd; /// second
+
+ meterRslt.VolumeStart = cameraRoi.VolumeStart; /// liter
+ meterRslt.VolumeEnd = cameraRoi.VolumeEnd; /// liter
+ meterRslt.VolumeMeter = cameraRoi.VolumeEnd - cameraRoi.VolumeStart; /// liter
+
+ if (meterRslt.VolumeMeter != 0)
+ {
+ /// Normal measurement with camera
+ meterRslt.TestTime =
+ cameraRoi.TimestampEnd - cameraRoi.TimestampStart; /// second
+ meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
+ meterRslt.PulsesMaster =
+ tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
+ }
+ else
+ {
+ /// None or one pulse from the water meter using camera
+ meterRslt.TestTime = tstRslt.TestTime;
+ meterRslt.VolumeRef = tstRslt.VolumeCTV;
+ meterRslt.PulsesMaster = tstRslt.PulsesMaster;
+ }
+ }
+ else
+ {
+ meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
+ meterRslt.VolumeStart = 0;
+ meterRslt.VolumeEnd = 0;
+ meterRslt.VolumeMeter = meterRslt.PulsesMeter * regReader.LtrsPerPulse; /// liter
+ ///
+ if (regReader.WMPulses >= 1)
+ {
+ /// Normal measurement
+ meterRslt.TestTime = cBrd.TestTimeWM(regReader.Position);
+ meterRslt.VolumeRef = meterRslt.PulsesMaster * tstRslt.ConstMaster; /// liter
+ }
+ else
+ {
+ /// None or one pulse from the water meter
+ meterRslt.TestTime = tstRslt.TestTime;
+ meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter
+ }
+ }
}
meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
@@ -724,10 +826,14 @@ namespace TBF.Rig.TestMethods.FlyingStart
/// Append the results to the CSV-file
allResults.Info(TestResult2CsvLine(testName, test.Part));
+ //TODO genesis - process result writing
+ //ProcessDatabaseResultsWriting(test, tstRslt);
+
if (stopCycle) retVal = Event.ErrorFlagsStop;
stopTest:
+ GenesisHeadBatch.BatchHolder.Value.RemoveAllMeters();
StopRecordingStatistics();
cBrd.StopAll(false);
@@ -748,8 +854,36 @@ namespace TBF.Rig.TestMethods.FlyingStart
return new List { retVal };
}
+ //backup how work genesis - not a clean code!
+ // private void ProcessDatabaseResultsWriting(Test test, TestRslt tstRslt)
+ // {
+ // IList e;
+ // if (!String.IsNullOrEmpty(test.Procedure.ResultsWriter))
+ // {
+ // string[] writers = StateMachine.Procedure.ResultsWriter.Split(new char[] { '~' });
+ // foreach (var writerName in writers)
+ // {
+ // IResultsWriter writer = TbfComponents.FindComponent(writerName) as IResultsWriter;
+ // if (writer != null && writer is )
+ // {
+ // var SensusLaWriter = ((DB.SensusLa.Database)writer);
+ //
+ // State.Create(string.Format("{0}({1}) : Store results into db.", test.Method, test.Name))
+ // .AddOperation(checkUiOp)
+ // .AddOperation(SensusLaWriter.WriteResultsOp(tstRslt, BatchRslts, GenesisHeadBatch.MeterIdDetailResults))
+ // .EnterState();
+ // do
+ // {
+ // e = StateMachine.WaitRunDevsRunOps();
+ // }
+ // while (!e.Contains(Event.Error) && !e.Contains(Event.ResultsWritten) && !e.Contains(Event.ResultsNotWritten));
+ // }
+ // }
+ // }
+ // }
- IList Simulate(Config.Entities.Test test, int repetitionNr, bool isLastRepetition,
+
+ IList Simulate(Config.Entities.Test test, int repetitionNr, bool isLastRepetition,
Compound.TestParams compoundTestParams,
HeatMeters.TestParams heatMetersTestParams,
Common.DebugMode debugLevel)
diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj
index d7307e586..fe5c0fc00 100644
--- a/TBF/TBF.csproj
+++ b/TBF/TBF.csproj
@@ -1031,6 +1031,15 @@
+
+
+
+ UserControl
+
+
+ WriteDBCfgCtrl.cs
+
+
@@ -3260,6 +3269,9 @@
MessageBoxForm.cs
+
+ WriteDBCfgCtrl.cs
+
TracingCfgCtrl.cs