Compare commits

..
4254 changed files with 57292 additions and 3955651 deletions
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Root Type="DevExpress.CodeRush.Foundation.CodePlaces.Options.FavoritesListContainer">
<Options Language="Neutral">
<Groups />
</Options>
</Root>
+8 -42
View File
@@ -1,5 +1,3 @@
AppDiagnostic/bin/
AppDiagnostic/obj/
Common/bin/
Common/obj/
Config/bin/
@@ -18,6 +16,8 @@ Encrypt/bin/
Encrypt/obj/
EventViewer/bin/
EventViewer/obj/
Events/bin/
Events/obj/
FeatureVectorCalculator/bin/
FeatureVectorCalculator/obj/
GemCard/bin/
@@ -28,18 +28,10 @@ GenericTest/bin/
GenericTest/obj/
GraphLib/bin/
GraphLib/obj/
LabelPrinting/bin/
LabelPrinting/obj/
MergeResultsDBs/bin/
MergeResultsDBs/obj/
NfcC7_Dll/bin/
NfcC7_Dll/obj/
NfcC7_DLL.Tests/bin/
NfcC7_DLL.Tests/obj/
OrderManagement/bin/
OrderManagement/obj/
ProductionTracing/bin/
ProductionTracing/obj/
RecordProcessing/bin/
RecordProcessing/obj/
ResetBatchNr/bin/
@@ -52,52 +44,26 @@ ResultsBrowser/bin/
ResultsBrowser/obj/
ResultsParser/bin/
ResultsParser/obj/
S640TestApp/bin/
S640TestApp/obj/
SharedComponents/bin/
SharedComponents/obj/
SharedDatabase/bin/
SharedDatabase/obj/
SchematicDrawing/bin/
SchematicDrawing/obj/
SharedDatabase/bin
SharedDatabase/obj
SchematicDrawing/bin
SchematicDrawing/obj
Statistics/bin/
Statistics/obj/
TBF/bin/
TBF/obj/
TBFTests/bin/
TBFTests/obj/
ToFirstMonitor/bin/
ToFirstMonitor/obj/
ToSecondMonitor/bin/
ToSecondMonitor/obj/
Users/bin/
Users/obj/
UserManagement/bin/
UserManagement/obj/
WorkflowConfigurator/bin/
WorkflowConfigurator/obj/
Workplace/bin/
Workplace/obj/
DataStreamInterfaceTest/bin/
DataStreamInterfaceTest/obj/
DataStreamMeter/bin/
DataStreamMeter/obj/
Events/bin/
Events/obj/
TracingDB/bin/
TracingDB/obj/
Users/bin/
Users/obj/
.vs/
.idea/
*.suo
*.bak
TBF.sln.DotSettings.user
/ExternalProjects
/GenesisCordonelTester
/packages
/GenesisCordonelInterface/bin/Debug/GenesisCordonelInterfaceLogger.log
/GenesisCordonelInterface/bin/Debug/GenesisCordonelTesterLogger.log
/GenesisCordonelInterface/bin/Debug/SirtConfig.json
/GenesisCordonelInterface/bin/Release
/GenesisCordonelInterface/obj/Debug
/GenesisCordonelInterface/obj/Release
/ExternalProjects
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<log4net>
<appender name="LogCacheAppender" type="Namespace.LogCacheAppender, AssemblyName">
<param name="Cache" value="YourCacheInstance" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogCacheAppender" />
</root>
</log4net>
</configuration>
-105
View File
@@ -1,105 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FA9ABAD1-7184-4295-ADE8-D44F2E3DE6B2}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>AppDiagnostic</RootNamespace>
<AssemblyName>AppDiagnostic</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.3.0.3\lib\net462\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BufferedListView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="DiagApi.cs" />
<Compile Include="LogAdapter.cs" />
<Compile Include="LogFilter.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedComponents\SharedComponents.csproj">
<Project>{8f942729-f454-4c99-ba6c-746962065ae3}</Project>
<Name>SharedComponents</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Resources\TBF_icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
-16
View File
@@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
public class BufferedListView : ListView
{
public BufferedListView()
{
// Zapne dvojité bufferovanie pre ListView
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.UpdateStyles();
}
}
-32
View File
@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppDiagnostic
{
public class DiagApi
{
private static MainForm diagWindow; // Udržiava referenciu na existujúce okno
public DiagApi()
{
if (diagWindow == null || diagWindow.IsDisposed) // Ak okno neexistuje, vytvoríme ho
{
diagWindow = new MainForm();
diagWindow.FormClosing += (s, e) =>
{
diagWindow = null; // Keď sa zavrie, vyčistíme referenciu
};
diagWindow.Show();
}
else
{
diagWindow.BringToFront(); // Ak už beží, len ho presunieme na vrch
diagWindow.WindowState = FormWindowState.Normal; // Ak je minimalizované, obnovíme ho
}
}
}
}
-174
View File
@@ -1,174 +0,0 @@
using SharedComponents;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppDiagnostic
{
public class LogAdapter
{
private ListView _listView;
public string _filterText = string.Empty;
private bool _isUserScrolling = false; // Indikátor, že používateľ manuálne scrolluje
private bool _autoScrollEnabled = true; // Indikátor, že automatické scrollovanie je povolené
private Timer _refreshTimer;
private const int RefreshInterval = 1000;
public LogAdapter(ListView listView)
{
_listView = listView;
// Nastavenie ListView
_listView.View = View.Details;
_listView.Columns.Clear();
_listView.Columns.Add("Logs");
_listView.Scrollable = true;
// Nastavenie šírky stĺpca na celú šírku ListView
AdjustColumnWidth();
// Udalosť pre dynamickú zmenu veľkosti stĺpca pri zmene veľkosti ListView
_listView.Resize += (sender, args) => AdjustColumnWidth();
// Pridanie udalosti pre manuálne skrolovanie
_listView.MouseWheel += ListView_MouseWheel;
// Inicializácia časovača na pravidelný refresh
_refreshTimer = new Timer { Interval = RefreshInterval };
_refreshTimer.Tick += (sender, args) => RefreshListView();
_refreshTimer.Start();
}
private void ListView_MouseWheel(object sender, MouseEventArgs e)
{
_isUserScrolling = true;
// Ak sa manuálnym scrollovaním používateľ dostane na koniec, obnovíme automatické scrollovanie
if (IsOnLastItem())
{
_isUserScrolling = false;
_autoScrollEnabled = true;
}
else
{
_autoScrollEnabled = false;
}
}
public void RefreshListView()
{
//LiveLogCache.Instance.AddLog(string.Format("-------------------------------RunDeviceAfter()-------------------------------"));
if (_listView.InvokeRequired)
{
_listView.Invoke(new Action(RefreshListView));
return;
}
_listView.BeginUpdate();
try
{
// Získanie pozície prvého viditeľného prvku pre stabilizáciu scrollovania
int topIndexBeforeRefresh = _listView.TopItem?.Index ?? 0;
// Pred pridaním nových položiek si pamätáme, či bol používateľ na poslednej položke
bool wasOnLastItem = IsOnLastItem();
// Uchovanie aktuálne označených položiek (indexov)
var selectedIndices = _listView.SelectedIndices.Cast<int>().ToList();
// Načítanie logov
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.GetCount())
.Where(log => string.IsNullOrEmpty(_filterText) ||
log.IndexOf(_filterText, StringComparison.OrdinalIgnoreCase) >= 0)
.ToList();
// Vymazanie existujúcich položiek a pridanie nových
_listView.Items.Clear();
foreach (var log in logs)
{
var item = new ListViewItem(log)
{
BackColor = _listView.Items.Count % 2 == 0 ? Color.White : Color.FromArgb(240, 240, 240)
};
_listView.Items.Add(item);
}
// Obnovenie označených položiek
foreach (var index in selectedIndices)
{
if (index < _listView.Items.Count)
{
_listView.Items[index].Selected = true;
}
}
// Ak bol používateľ na poslednom prvku, nastavíme focus a scroll na posledný prvok
if (_autoScrollEnabled && wasOnLastItem && _listView.Items.Count > 0)
{
var lastItemIndex = _listView.Items.Count - 1;
_listView.EnsureVisible(lastItemIndex);
_listView.Items[lastItemIndex].Focused = true;
}
else
{
// Ak používateľ nebol na spodku, vrátime sa na predchádzajúcu pozíciu scrollu
if (topIndexBeforeRefresh < _listView.Items.Count)
{
_listView.TopItem = _listView.Items[topIndexBeforeRefresh];
}
}
}
finally
{
_listView.EndUpdate();
}
}
public void ApplyFilter(string filterText)
{
_filterText = filterText?.Trim() ?? string.Empty;
RefreshListView();
}
private bool IsOnLastItem()
{
if (_listView.Items.Count == 0)
return false;
// Získame poslednú položku
int lastItemIndex = _listView.Items.Count - 1;
var lastItem = _listView.Items[lastItemIndex];
// Overíme, či je posledná položka úplne viditeľná
return lastItem.Bounds.Bottom <= _listView.ClientRectangle.Bottom;
}
public void EnableAutoScroll()
{
_autoScrollEnabled = true;
}
public void DisableAutoScroll()
{
_autoScrollEnabled = false;
}
private void AdjustColumnWidth()
{
if (_listView.Columns.Count > 0)
{
_listView.Columns[0].Width = _listView.ClientSize.Width;
}
}
}
}
-91
View File
@@ -1,91 +0,0 @@
using SharedComponents;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppDiagnostic
{
public class LogFilter
{
private ListView _listView;
private string _filterText = string.Empty; // Pre uloženie aktuálneho filtrovaného reťazca
// Konstruktor
public LogFilter(ListView listView)
{
_listView = listView;
}
// Metóda na aplikovanie filtra na ListView
public void ApplyFilter(string filterText)
{
_filterText = filterText.ToLower(); // Ukladáme text filtra bez ohľadu na veľkosť písmen
// Po aplikovaní filtra obnovíme zobrazenie
RefreshListView();
}
public void RefreshListView()
{
try
{
// Skontrolujeme, či sme na hlavnom vlákne a v prípade potreby použijeme Invoke
if (_listView.InvokeRequired)
{
// Použijeme Invoke, ak nie sme na hlavnom vlákne
_listView.Invoke(new Action(RefreshListView));
}
else
{
// Vymazanie existujúcich položiek
_listView.Items.Clear();
// Načítame všetky logy (ideálne z cache alebo databázy)
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.Logs.Count);
// Pridáme len tie logy, ktoré spĺňajú filter
foreach (var log in logs)
{
if (log.ToLower().Contains(_filterText)) // Kontrola, či log obsahuje filter text
{
var listViewItem = new ListViewItem(log);
// Striedanie farieb riadkov
if (_listView.Items.Count % 2 == 0) // Párny index => biela
{
listViewItem.BackColor = Color.White;
}
else // Nepárny index => svetlá sivá
{
listViewItem.BackColor = Color.FromArgb(240, 240, 240); // Veľmi svetlá sivá
}
// Pridanie efektu pre novú položku
ApplyNewItemEffect(listViewItem);
// Pridanie položky do ListView
_listView.Items.Add(listViewItem);
}
}
}
}
catch (Exception ex)
{
// Zachytíme výnimku, ak sa niečo pokazí, a zobrazíme ju užívateľovi
MessageBox.Show($"An error occurred while refreshing the log view: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Môžete pridať ďalšie metódy na zobrazenie alebo efekt pre nové položky, ak je to potrebné
private void ApplyNewItemEffect(ListViewItem item)
{
// Prípadný efekt pre nový pridaný log
// Môžete pridať animáciu alebo zmenu farby atď.
item.ForeColor = Color.Green; // Napríklad zmeníme farbu písma na zelenú
}
}
}
-278
View File
@@ -1,278 +0,0 @@
using System.Windows.Forms;
namespace AppDiagnostic
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
//private BufferedListView memoListView;
private System.Windows.Forms.ColumnHeader columnHeaderTime;
private System.Windows.Forms.ColumnHeader columnHeaderMessage;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.columnHeaderTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderMessage = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.panel1 = new System.Windows.Forms.Panel();
this.refreshMemoButton = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.filterManagementPanel = new System.Windows.Forms.Panel();
this.button5 = new System.Windows.Forms.Button();
this.filterButton = new System.Windows.Forms.Button();
this.filterTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.wndControlPanel = new System.Windows.Forms.Panel();
this.button2 = new System.Windows.Forms.Button();
this.flowControlsPanel = new System.Windows.Forms.Panel();
this.runButton = new System.Windows.Forms.Button();
this.stopButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.memoListView = new BufferedListView();
this.panel1.SuspendLayout();
this.filterManagementPanel.SuspendLayout();
this.wndControlPanel.SuspendLayout();
this.flowControlsPanel.SuspendLayout();
this.SuspendLayout();
//
// columnHeaderTime
//
this.columnHeaderTime.Text = "Time";
this.columnHeaderTime.Width = 150;
//
// columnHeaderMessage
//
this.columnHeaderMessage.Text = "Message";
this.columnHeaderMessage.Width = 350;
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.panel1.Controls.Add(this.refreshMemoButton);
this.panel1.Controls.Add(this.button6);
this.panel1.Controls.Add(this.button7);
this.panel1.Location = new System.Drawing.Point(189, 356);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(283, 26);
this.panel1.TabIndex = 16;
//
// refreshMemoButton
//
this.refreshMemoButton.Location = new System.Drawing.Point(108, 0);
this.refreshMemoButton.Name = "refreshMemoButton";
this.refreshMemoButton.Size = new System.Drawing.Size(84, 26);
this.refreshMemoButton.TabIndex = 17;
this.refreshMemoButton.Text = "Refresh memo";
this.refreshMemoButton.UseVisualStyleBackColor = true;
this.refreshMemoButton.Click += new System.EventHandler(this.refreshMemoButton_Click);
//
// button6
//
this.button6.Location = new System.Drawing.Point(0, 0);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(102, 26);
this.button6.TabIndex = 4;
this.button6.Text = "Clean diag cache";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.button6_Click);
//
// button7
//
this.button7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.button7.Location = new System.Drawing.Point(198, 0);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(72, 26);
this.button7.TabIndex = 5;
this.button7.Text = "Save logs";
this.button7.UseVisualStyleBackColor = true;
this.button7.Click += new System.EventHandler(this.button7_Click);
//
// filterManagementPanel
//
this.filterManagementPanel.Controls.Add(this.button5);
this.filterManagementPanel.Controls.Add(this.filterButton);
this.filterManagementPanel.Controls.Add(this.filterTextBox);
this.filterManagementPanel.Controls.Add(this.label2);
this.filterManagementPanel.Location = new System.Drawing.Point(127, 6);
this.filterManagementPanel.Name = "filterManagementPanel";
this.filterManagementPanel.Size = new System.Drawing.Size(393, 26);
this.filterManagementPanel.TabIndex = 15;
//
// button5
//
this.button5.Enabled = false;
this.button5.Location = new System.Drawing.Point(294, 4);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(81, 20);
this.button5.TabIndex = 11;
this.button5.Text = "Add new filter";
this.button5.UseVisualStyleBackColor = true;
//
// filterButton
//
this.filterButton.Location = new System.Drawing.Point(225, 4);
this.filterButton.Name = "filterButton";
this.filterButton.Size = new System.Drawing.Size(64, 20);
this.filterButton.TabIndex = 10;
this.filterButton.Text = "Set filter";
this.filterButton.UseVisualStyleBackColor = true;
this.filterButton.Click += new System.EventHandler(this.filterButton_Click_1);
//
// filterTextBox
//
this.filterTextBox.Location = new System.Drawing.Point(33, 4);
this.filterTextBox.Name = "filterTextBox";
this.filterTextBox.Size = new System.Drawing.Size(187, 20);
this.filterTextBox.TabIndex = 7;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 8);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Filter";
//
// wndControlPanel
//
this.wndControlPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.wndControlPanel.Controls.Add(this.button2);
this.wndControlPanel.Location = new System.Drawing.Point(831, 356);
this.wndControlPanel.Name = "wndControlPanel";
this.wndControlPanel.Size = new System.Drawing.Size(70, 26);
this.wndControlPanel.TabIndex = 14;
//
// button2
//
this.button2.Location = new System.Drawing.Point(3, 0);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(64, 26);
this.button2.TabIndex = 2;
this.button2.Text = "Close";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// flowControlsPanel
//
this.flowControlsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.flowControlsPanel.Controls.Add(this.runButton);
this.flowControlsPanel.Controls.Add(this.stopButton);
this.flowControlsPanel.Location = new System.Drawing.Point(12, 356);
this.flowControlsPanel.Name = "flowControlsPanel";
this.flowControlsPanel.Size = new System.Drawing.Size(133, 26);
this.flowControlsPanel.TabIndex = 13;
//
// runButton
//
this.runButton.Enabled = false;
this.runButton.Location = new System.Drawing.Point(0, 0);
this.runButton.Name = "runButton";
this.runButton.Size = new System.Drawing.Size(64, 26);
this.runButton.TabIndex = 4;
this.runButton.Text = "Run";
this.runButton.UseVisualStyleBackColor = true;
this.runButton.Click += new System.EventHandler(this.runButton_Click);
//
// stopButton
//
this.stopButton.Location = new System.Drawing.Point(69, 0);
this.stopButton.Name = "stopButton";
this.stopButton.Size = new System.Drawing.Size(64, 26);
this.stopButton.TabIndex = 5;
this.stopButton.Text = "Stop";
this.stopButton.UseVisualStyleBackColor = true;
this.stopButton.Click += new System.EventHandler(this.stopButton_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 13);
this.label1.TabIndex = 12;
this.label1.Text = "Flow of events";
//
// memoListView
//
this.memoListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.memoListView.FullRowSelect = true;
this.memoListView.GridLines = true;
this.memoListView.HideSelection = false;
this.memoListView.Location = new System.Drawing.Point(12, 38);
this.memoListView.Name = "memoListView";
this.memoListView.Size = new System.Drawing.Size(889, 312);
this.memoListView.TabIndex = 0;
this.memoListView.UseCompatibleStateImageBehavior = false;
this.memoListView.View = System.Windows.Forms.View.Details;
this.memoListView.DoubleClick += new System.EventHandler(this.MemoListView_DoubleClick);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(913, 388);
this.Controls.Add(this.memoListView);
this.Controls.Add(this.panel1);
this.Controls.Add(this.filterManagementPanel);
this.Controls.Add(this.wndControlPanel);
this.Controls.Add(this.flowControlsPanel);
this.Controls.Add(this.label1);
this.Name = "MainForm";
this.Text = "Application live diagnostic";
this.panel1.ResumeLayout(false);
this.filterManagementPanel.ResumeLayout(false);
this.filterManagementPanel.PerformLayout();
this.wndControlPanel.ResumeLayout(false);
this.flowControlsPanel.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.Button button7;
private System.Windows.Forms.Panel filterManagementPanel;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button filterButton;
private System.Windows.Forms.TextBox filterTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel wndControlPanel;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Panel flowControlsPanel;
private System.Windows.Forms.Button runButton;
private System.Windows.Forms.Button stopButton;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button refreshMemoButton;
private BufferedListView memoListView;
}
}
-268
View File
@@ -1,268 +0,0 @@
using log4net.Config;
using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using log4net.Appender;
using SharedComponents;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.IO; // Pre File.WriteAllLines a prácu so súbormi
using System.Linq;
namespace AppDiagnostic
{
public partial class MainForm : Form
{
private bool stopUpdate = false; // Premenná na zastavenie aktualizácie
private int lastDisplayedLogIndex = 0;
private bool autoScrollEnabled = true; // Automatický posun, predvolene povolený
private MainForm appDiagnosticForm;
private Timer refreshTimer;
private LogAdapter _logAdapter; // Pre LogAdapter
private LogFilter _logFilter; // LogFilter objekt pre filtráciu
public MainForm()
{
this.Icon = Properties.Resources.TBF_icon;
InitializeComponent();
// Inicializujeme LogAdapter a priradíme ho k memoListView
_logAdapter = new LogAdapter(memoListView);
RefreshLogView();
// Pripojenie na udalosť pri pridaní nového logu
// nakoľko sa memo refreshuje cyklicky, tak refresh na udalosť nepotrebujem
//LiveLogCache.Instance.LogAdded += OnLogAdded;
// Vytvoríme LogFilter objekt
//_logFilter = new LogFilter(memoListView);
}
private void OnLogAdded(string log)
{
try
{
RefreshLogView();
}
catch (Exception ex)
{
MessageBox.Show($"Error in OnLogAdded: {ex.Message}");
throw;
}
}
private void RefreshLogView()
{
// Skontrolujte, či voláme z iného vlákna
if (InvokeRequired)
{
Invoke((Action)RefreshLogView);
return;
}
memoListView.BeginUpdate(); // Zabraňuje vizuálnym aktualizáciám počas vykresľovania
try
{
// Skontrolujte, či je užívateľ na poslednom viditeľnom zázname
if (memoListView.Items.Count > 0)
{
var lastVisibleIndex = memoListView.TopItem.Index + memoListView.ClientRectangle.Height / memoListView.Items[0].Bounds.Height;
autoScrollEnabled = lastVisibleIndex >= memoListView.Items.Count - 1;
}
// Získajte nové logy od posledného indexu
var logs = LiveLogCache.Instance.GetLogs(lastDisplayedLogIndex, LiveLogCache.Instance.Logs.Count - lastDisplayedLogIndex);
// Pridajte len nové logy
foreach (var log in logs)
{
memoListView.Items.Add(new ListViewItem(log));
}
// Aktualizujte posledný zobrazený index
lastDisplayedLogIndex = LiveLogCache.Instance.Logs.Count;
// Ak je autoScrollEnabled, posuňte sa na posledný záznam
if (autoScrollEnabled && memoListView.Items.Count > 0)
{
memoListView.EnsureVisible(memoListView.Items.Count - 1);
}
}
finally
{
memoListView.EndUpdate(); // Umožní vizuálne aktualizácie
}
}
// Táto metóda sa spustí pri scrollovaní v memoListView (tzn. ak sa používateľ dostane na spodok listu)
private void memoListView_Scroll(object sender, EventArgs e)
{
// Skontrolujte, či používateľ dosiahol spodok ListView
if (memoListView.Items.Count > 0 &&
memoListView.Items[memoListView.Items.Count - 1].Bounds.Bottom <= memoListView.ClientSize.Height)
{
// Ak áno, načítame ďalšie logy
RefreshLogView();
}
}
private void button6_Click(object sender, EventArgs e)
{
//LiveLogCache.Instance.AddLog("Nový log z hlavnej aplikácie");
LiveLogCache.Instance.ClearLogs();
ClearListView();
}
private void runButton_Click(object sender, EventArgs e)
{
if (stopUpdate) // Ak je časovač zastavený, spustíme ho
{
stopUpdate = false; // Zastav aktualizáciu
runButton.Enabled = false; // Zakážeme tlačidlo Start počas behu
stopButton.Enabled = true; // Povolenie tlačidla Stop
refreshTimer.Start();
}
}
private void stopButton_Click(object sender, EventArgs e)
{
if (!stopUpdate) // Ak časovač beží, môžeme ho zastaviť
{
stopUpdate = true; // Spusti aktualizáciu
runButton.Enabled = true; // Povolenie tlačidla Start
stopButton.Enabled = false; // Zakážeme tlačidlo Stop
refreshTimer.Stop();
}
}
private void ClearListView()
{
if (InvokeRequired)
{
Invoke(new Action(ClearListView));
return;
}
memoListView.Items.Clear();
}
private void refreshMemoButton_Click(object sender, EventArgs e)
{
}
private void button7_Click(object sender, EventArgs e)
{
SaveLogsToFile();
//LiveLogCache.Instance.AddLog("Toto je nový log.");
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
// Odpojenie udalosti, keď sa okno zatvára, inak môže po opätovnom spustení okna a pridaní nového itemu do listu zhhodiť program
// nakoľko sa memo refreshuje cyklicky, tak refresh na udalosť nepotrebujem
//LiveLogCache.Instance.LogAdded -= OnLogAdded;
_logAdapter = null;
base.OnFormClosing(e);
}
private void filterButton_Click_1(object sender, EventArgs e)
{
// Aplikujeme filter na základe textu z filterTextBox
string filterText = filterTextBox.Text;
//_logFilter.ApplyFilter(filterText); // Aplikovanie filtra
_logAdapter.ApplyFilter(filterText);
}
private void SubForm_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
// Vaša logika pri uzatváraní formy
// this.Hide(); // Podforma sa len skryje
}
catch (Exception ex)
{
// Ošetrenie výnimky
MessageBox.Show("Chyba pri zatváraní pod-aplikácie: " + ex.Message);
}
}
private void SaveLogsToFile()
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
saveFileDialog.Title = "Save TBF live logs";
saveFileDialog.DefaultExt = "txt";
saveFileDialog.FileName = "TBFLiveLogs.txt";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
// Načítanie všetkých logov z LiveLogCache
var logs = LiveLogCache.Instance.GetLogs(0, LiveLogCache.Instance.GetCount());
// Uloženie logov do vybraného súboru
File.WriteAllLines(saveFileDialog.FileName, logs);
MessageBox.Show("Logs saved successfully.", "Save TBF live logs", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred while saving TBF live logs: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
//this.Hide(); // Podforma sa len skryje
}
private void MemoListView_DoubleClick(object sender, EventArgs e)
{
if (memoListView.SelectedItems.Count > 0)
{
var selectedItem = memoListView.SelectedItems[0];
int selectedIndex = memoListView.Items.IndexOf(selectedItem);
if (selectedIndex >= 0)
{
// Zrušenie filtra
_logAdapter._filterText = string.Empty;
// Načítanie logov od indexu vybraného riadku
var logs = LiveLogCache.Instance.GetLogs(selectedIndex, LiveLogCache.Instance.GetCount() - selectedIndex);
// Obnovenie ListView s novými údajmi
memoListView.BeginUpdate();
memoListView.Items.Clear();
foreach (var log in logs)
{
var item = new ListViewItem(log)
{
BackColor = memoListView.Items.Count % 2 == 0 ? Color.White : Color.FromArgb(240, 240, 240)
};
memoListView.Items.Add(item);
}
memoListView.EndUpdate();
}
}
}
}
}
-120
View File
@@ -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>
-22
View File
@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppDiagnostic
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
-33
View File
@@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("AppDiagnostic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AppDiagnostic")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fa9abad1-7184-4295-ade8-d44f2e3de6b2")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
-73
View File
@@ -1,73 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AppDiagnostic.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AppDiagnostic.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon TBF_icon {
get {
object obj = ResourceManager.GetObject("TBF_icon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
}
}
-124
View File
@@ -1,124 +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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="TBF_icon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\TBF_icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
-30
View File
@@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AppDiagnostic.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
@@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="3.0.3" targetFramework="net472" />
</packages>
+4 -13
View File
@@ -17,7 +17,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -30,17 +30,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.5.2.2\lib\net46\NLog.dll</HintPath>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@@ -69,7 +64,6 @@
<DependentUpon>ModelessForm.cs</DependentUpon>
</Compile>
<Compile Include="Formulas.cs" />
<Compile Include="CurrentUser.cs" />
<Compile Include="GlobalData.cs" />
<Compile Include="IMeasurementCorrection.cs" />
<Compile Include="IOrderInfo.cs" />
@@ -82,7 +76,6 @@
</Compile>
<Compile Include="QuitAppException.cs" />
<Compile Include="SerializableDictionary.cs" />
<Compile Include="StatisticalMetrics.cs" />
<Compile Include="Telegram.cs" />
<Compile Include="UIControls\CoolButtonCtrl.cs">
<SubType>UserControl</SubType>
@@ -95,9 +88,7 @@
<Compile Include="Utils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<EmbeddedResource Include="Forms\ListViewEx.resx">
<DependentUpon>ListViewEx.cs</DependentUpon>
-132
View File
@@ -1,132 +0,0 @@
///
/// Copyright (c) 2021-2022 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Common
{
class UserAndForm
{
public readonly IUser User;
public readonly Form Form;
public UserAndForm(IUser user, Form form)
{
User = user;
Form = form;
}
}
public static class CurrentUser
{
public const string AdminUsername = "admin";
public const string AdminPassword = "staratura";
public static int MinPasswdLength = 0;
public static int PasswdExpirationPeriodDays = 0;
public static DBSettings RemoteUsersDB = null;
public static DBSettings LocalUsersDB = null;
static readonly Stack<UserAndForm> userStack = new Stack<UserAndForm>();
public static Common.AuthorizedAs AuthorizedAs;
public static DateTime LastAuthorization = DateTime.Now;
/// <summary>
/// Push a new user into the stack of users and form references.
/// Prevent double user stack entry for the same Windows form.
/// </summary>
/// <param name="newUser">New user</param>
/// <param name="currentForm">Reference to the current form</param>
public static void Change(IUser newUser, Form currentForm)
{
if (userStack.Count > 0 && userStack.Peek().Form == currentForm)
{
userStack.Pop();
}
userStack.Push(new UserAndForm(newUser, currentForm));
}
/// <summary>
/// Restore an original user from the stack of users - remove user at the top of the stack.
/// Prevent restoring when there is no entry for the form currently being closed.
/// </summary>
/// <param name="formBeingClosed">Reference to the form currently being closed</param>
/// <returns>true = current user was restored, false = no current user change</returns>
public static bool Restore(Form formBeingClosed)
{
if (userStack.Count > 0 && userStack.Peek().Form == formBeingClosed)
{
userStack.Pop();
return true;
}
return false;
}
/// <summary>
/// Return the user currenty at the top of the stack of users.
/// </summary>
public static IUser User()
{
return (userStack.Count > 0) ? userStack.Peek().User : null; /// TODO: Return default user when stack is empty
}
public static IUser User2;
public static IUser User3;
/// <summary>
/// Return the current user name or an empty string
/// </summary>
public static string UserName()
{
if (User() == null || User().UserName == null)
return string.Empty;
else if (User2 == null || User2.UserName == null)
return User().UserName;
else if (User3 == null || User3.UserName == null)
return string.Format("{0},{1}", User().UserName, User2.UserName);
else
return string.Format("{0},{1},{2}", User().UserName, User2.UserName, User3.UserName);
}
public static string GetEncodedString(string legalizator)
{
if (User() == null || User().UserName == null) return string.Empty;
return string.Format("{0}~{1}~{2}",
User().UserName,
User().FullName == null ? string.Empty : User().FullName,
legalizator == null ? string.Empty : legalizator);
}
/// <summary>
/// Return the current user number or 0
/// </summary>
public static int Number()
{
return (User() != null) ? User().Number : 0;
}
public static bool IsPowerUser()
{
return (User() != null) ? User().IsPowerUser() : false;
}
public static bool IsMemberOf(GID groupId)
{
return (User() != null) ? User().IsMemberOf(groupId) : false;
}
public static bool IsMemberOf(GID[] groupIds)
{
return (User() != null) ? User().IsMemberOf(groupIds) : (groupIds == null);
}
}
}
+2 -2
View File
@@ -10,14 +10,14 @@ namespace Common
/// </summary>
public class DBSettings : ICloneable
{
public DBType DbType;
public Common.DBType DbType;
public string ConnectionString;
public DBSettings()
{
}
public DBSettings(DBType dbType, string connectionString)
public DBSettings(Common.DBType dbType, string connectionString)
{
this.DbType = dbType;
this.ConnectionString = connectionString;
+8 -94
View File
@@ -1,10 +1,9 @@
///
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Common
{
@@ -186,70 +185,16 @@ namespace Common
Count,
}
public enum FlowNames
{
QnQtQmin = 0,
Q3Q2Q1 = 1,
QpQi = 2,
Count,
}
public enum ProfileType
{
Q3R,
QnClassColdWater,
QnClassHotWater,
QpQi,
CompoundQ3RQ3R,
CompoundQnClassQnClass,
CompoundQ3RQnClass,
CompoundQnClassQ3R,
CompoundQpQiQpQi,
Manual,
Count,
}
public enum FlowId
{
Any,
Q4,
Q3,
Q2,
Q1,
Q4Main,
Q3Main,
Q2Main,
Q1Main,
Q4Aux,
Q3Aux,
Q2Aux,
Q1Aux,
Qmax,
Qn,
Qt,
Qmin,
QmaxMain,
QnMain,
QtMain,
QminMain,
QmaxAux,
QnAux,
QtAux,
QminAux,
Qp,
Qp10,
Qi,
QpMain,
Qp10Main,
QiMain,
QpAux,
Qp10Aux,
QiAux,
Qdetected,
Qfall,
Qrise,
}
public enum ErrorLimitType
{
Manual,
@@ -290,20 +235,11 @@ namespace Common
CompoundAux,
Compound,
HeatMeterVolume,
HeatMeterMass,//...MF
HeatMeterEnergy,
HeatMeterEnergy,
SingleOrCompound, /// Only used when querying results
}
public enum PulsesTypeByQuantity : short
{
[Description("dm3")] Volume_dm3,
[Description("kg")] Mass_kg,
Count
}
public enum Medium
public enum Medium
{
[Description("")] NotSpecified,
#if LANG_PL
@@ -330,13 +266,11 @@ namespace Common
[Description("V")] V, /// vertical
[Description("STR")] S, /// standrohre
[Description("F")] F, /// fall
[Description("H/V")] HV, /// horizontal / vertical
#else
[Description("H")] H, /// horizontal
[Description("V")] V, /// vertical
[Description("S")] S, /// steig
[Description("F")] F, /// fall
[Description("H/V")] HV, /// horizontal / vertical
[Description("H")] H, /// horizontal
[Description("V")] V, /// vertical
[Description("S")] S, /// steig
[Description("F")] F, /// fall
#endif
Count
}
@@ -530,10 +464,8 @@ namespace Common
public enum TestProfile
{
UserDefined,
UserDefinedCompound,
UserDefinedHeatMeter,
Protected, /// The first protected one
ProtectedCompound,
ProtectedHeatMeter,
}
@@ -708,16 +640,7 @@ namespace Common
Count,
}
public enum DivResolution : int
{
[Description("1 ms (0.25 s)")] _1ms = 0,
[Description("2 ms (0.5 s)")] _2ms = 1,
[Description("4 ms (1 s)")] _4ms = 2,
[Description("8 ms (2 s)")] _8ms = 3,
Count,
}
public enum ImageRotation
public enum ImageRotation
{
[Description("0 deg")] None,
[Description("90 deg")] Deg90,
@@ -839,15 +762,6 @@ namespace Common
E63 = (1L << 62),
}
//...MF
public enum FlowType : int
{
none,
volume,
mass,
Count,
}
#region iPERL enums
public enum Side
-3
View File
@@ -61,9 +61,6 @@ namespace Common.Forms
private const int HDN_ITEMCHANGINGW = (HDN_FIRST-20);
#endregion
public MySortOrder SortOrder = MySortOrder.None;
public int SortColumn = -1;
/// <summary>
/// Required designer variable.
/// </summary>
+1 -4
View File
@@ -1,7 +1,4 @@
///
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
///
using System;
using System;
namespace Common.Forms
{
+4 -7
View File
@@ -1,7 +1,4 @@
///
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
///
using System;
using System;
using System.Drawing;
using System.Windows.Forms;
@@ -56,20 +53,20 @@ namespace Common.Forms
public event EventHandler<MessageEventArgs> UpdateMessageHandler;
void OnUpdateMessage(object sender, MessageEventArgs args)
{
if (args != null && args.Message != null) label1.Text = args.Message;
if (args.Message != null) label1.Text = args.Message;
}
/// <summary>
/// Called from the state machine when an operation forces a modeless dialog close.
/// </summary>
public void CloseForm()
public static void CloseForm()
{
if (CloseFormHandler == null) return;
try { CloseFormHandler(null, null); }
catch (Exception) { }
}
public event EventHandler<EventArgs> CloseFormHandler;
static public event EventHandler<EventArgs> CloseFormHandler;
void OnCloseForm(object sender, EventArgs args)
{
DialogResult = DialogResult.Cancel;
+2 -2
View File
@@ -213,9 +213,9 @@ namespace Common
/// </summary>
public static double ErrorFromVolumes(double measuredVolume, double trueVolume)
{
if (Math.Abs(trueVolume) <= float.Epsilon)
if (trueVolume <= float.Epsilon)
{
if (Math.Abs(measuredVolume) <= float.Epsilon)
if (measuredVolume <= float.Epsilon)
{
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, -100.0);
return -100.0;
+29 -1
View File
@@ -5,10 +5,38 @@ using System;
namespace Common
{
public static class GlobalData
public class GlobalData
{
public static double SampleDensity = 0; /// sample water density measured in an accredited labo [kg/m3]
public static double SampleTemp = 0; /// sample temperature when density measured in an accredited labo [°C]
public static double Buoyancy = 0;
public const string AdminUsername = "admin";
public const string AdminPassword = "staratura";
public static DBSettings RemoteUsersDB = null;
public static DBSettings LocalUsersDB = null;
public static IUser CurrentUser;
public static IUser CurrentUser2;
public static IUser CurrentUser3;
public static Common.AuthorizedAs AuthorizedAs;
public static DateTime LastAuthorization = DateTime.Now;
public static int MinPasswdLength = 0;
public static int PasswdExpirationPeriodDays = 0;
public static string GetCurrentUserName()
{
if (CurrentUser == null || CurrentUser.UserName == null)
return string.Empty;
else if (CurrentUser2 == null || CurrentUser2.UserName == null)
return CurrentUser.UserName;
else if (CurrentUser3 == null || CurrentUser3.UserName == null)
return string.Format("{0},{1}", CurrentUser.UserName, CurrentUser2.UserName);
else
return string.Format("{0},{1},{2}", CurrentUser.UserName, CurrentUser2.UserName, CurrentUser3.UserName);
}
}
}
+2 -2
View File
@@ -5,7 +5,7 @@ namespace Common
public interface IMeasurementCorrection
{
int RangeIx { get; set; }
double Measurement { get; set; }
double Correction { get; set; }
float Measurement { get; set; }
float Correction { get; set; }
}
}
-1
View File
@@ -10,7 +10,6 @@ namespace Common
int Number { get; }
/// Access rights
bool IsPowerUser();
bool IsMemberOf(GID group);
bool IsMemberOf(GID[] groups);
bool IsCorrectPassword(string password);
+6 -8
View File
@@ -35,7 +35,7 @@ namespace Common.Iperl
public float RefFlow; /// [m3/h]
public int Counter;
public Int32 EmfRaw; /// Signed EMF from iPerl opto data
public UInt32 EmfRaw; /// From iPerl opto data
public Int16 MagneticFieldRaw;
public Int16 FlowRaw;
public UInt32 VolumeRaw;
@@ -50,13 +50,14 @@ namespace Common.Iperl
///
public double EMF()
{
return 0.000000333 * (double)EmfRaw;
Int32 signedEmf = (EmfRaw > 0x7FFFFF) ? ((int)EmfRaw - 0x1000000) : (int)EmfRaw;
return 0.000000333 * (double)signedEmf;
}
public double MagneticField() { return (double)MagneticFieldRaw; }
public double Flow(double scalingFactor) { return 0.225 * scalingFactor * (double)FlowRaw; }
public double Volume(double scalingFactor) { return 0.0000625 * scalingFactor * (double)VolumeRawExt; }
public Int32 FlipTime() { return Impedance; }
public decimal TimestampDec() { return (decimal)TimestampExt; }
public decimal TimestampDec() { return (decimal)TimestampExt / (decimal)8192; }
public double VolumeDelta(double scalingFactor, OptoTelegramRaw previous) { return (previous == null) ? 0 : Volume(scalingFactor) - previous.Volume(scalingFactor); }
public decimal TimeDelta() { return TimestampDec() - TestStartTimestampDec; }
public string Label()
@@ -119,10 +120,7 @@ namespace Common.Iperl
return false;
}
UInt32 uEmfRaw;
bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uEmfRaw);
EmfRaw = (uEmfRaw > 0x7FFFFF) ? ((int)uEmfRaw - 0x1000000) : (int)uEmfRaw;
bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out EmfRaw);
bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticFieldRaw);
bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw);
bool f4 = UInt32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
@@ -245,7 +243,7 @@ namespace Common.Iperl
DateTime.Second.ToString("D2"),
DateTime.Millisecond.ToString("D4"),
Counter,
(EmfRaw & 0x00FFFFFF).ToString("X6"),
EmfRaw.ToString("X6"),
MagneticFieldRaw.ToString("X4"),
FlowRaw.ToString("X4"),
VolumeRaw.ToString("X6"),
-338
View File
@@ -1,338 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common.Iperl;
namespace Common
{
public static class Extensions
{
public static float[] SubArray(this float[] array, int offset, int length)
{
float[] result = new float[length];
Array.Copy(array, offset, result, 0, length);
return result;
}
}
public class StatisticalMetrics
{
const int VectorSize = 7;
const int MinLength = 100;
const float AdcBit = (float)57e-9;
const int NeighbourhoodSize = 30; /// To determine extended outliers
/// <summary>
/// Calculates a 7-dimensional vector with these components:
/// x[0] = X1 = Number of outliers
/// x[1] = X2 = Relative cal-factor shift due to outliers
/// x[2] = X3 = Standard deviation of high-pass filteres ++++ demodulation of EMF (cut-off at Nyquist frequency)
/// x[3] = X4 = Robust standard deviation of high-pass filtered ++++ demodulation
/// x[4] = X5 = Peak-to-peak of low-pass filtered ++++ demodulation of EMF (cut-off TBD)
/// x[5] = X6 = Peak-to-peak of reference flow rate
/// x[6] = X7 = Mean impedance (++-- demodulation)
/// </summary>
/// <param name="optoData"></param>
/// <param name="optoDataCount"></param>
/// <param name="startIx"></param>
/// <param name="endIx"></param>
/// <returns></returns>
public static float[] Calculate(OptoTelegramRaw[] optoData, int optoDataCount, int startIx, int endIx, bool downsample,
out float[] offsetV, out float[] kOhmsR, out float[] kOhmsC, out float[] dutFlow,
out float[] refFlow, out float[] flowRatio, out float[] magField, out float[] emfV,
out PointF[] outliers, out PointF[] extendedOutliers)
{
offsetV = kOhmsR = kOhmsC = dutFlow = refFlow = flowRatio = magField = emfV = null;
outliers = extendedOutliers = null;
if (optoData == null || optoData.Length < optoDataCount ||
startIx < 0 || endIx >= optoDataCount || endIx <= startIx + MinLength + 3) return null;
float[] modulatedData = GetModulatedEmf(optoData, optoDataCount, AdcBit);
FindShiftAndDemodulate(modulatedData, downsample,
new float[] { +1, +1, +1, +1 }, out offsetV,
new float[] { +1, +1, -1, -1 }, out kOhmsR,
new float[] { +1, -1, -1, +1 }, out kOhmsC,
new float[] { +1, -1, +1, -1 }, out dutFlow);
//offsetV = FirFilter(modulatedData, new float[] { 1, 3, 4, 4, 3, 1}, 0.0625F);
magField = GetMagField(optoData, optoDataCount, downsample, new float[] { 1, 1, 1, 1 });
refFlow = GetRefFlow(optoData, optoDataCount, downsample, new float[] { 1, 1, 1, 1 });
flowRatio = new float[Math.Min(dutFlow.Length, refFlow.Length)];
for (int i = 0; i < flowRatio.Length; i++)
{
flowRatio[i] = (refFlow[i] != 0) ? dutFlow[i] / refFlow[i] : 1;
}
float[] x = new float[VectorSize];
/// X1 = Number of outliers
int outliersCount = GetOutliers(flowRatio, out outliers, out extendedOutliers);
/// X2 = Relative cal-factor shift due to outliers
/// X3 = Standard deviation of high-pass filteres ++++ demodulation of EMF (cut-off at Nyquist frequency)
/// X4 = Robust standard deviation of high-pass filtered ++++ demodulation
/// X5 = Peak-to-peak of low-pass filtered ++++ demodulation of EMF (cut-off TBD)
/// X6 = Peak-to-peak of reference flow rate
/// X7 = Mean impedance (++-- demodulation)
double sum = 0;
foreach (var z in kOhmsR) sum += z;
x[6] = Convert.ToSingle(sum / kOhmsR.Length);
return x;
}
static float[] GetModulatedEmf(OptoTelegramRaw[] optoData, int optoDataCount, float factor)
{
if (optoData == null || optoDataCount < 0) return null;
float[] result = new float[optoDataCount];
for (int i = 0; i < optoDataCount; i++)
{
result[i] = optoData[i].EmfRaw * factor;
}
return result;
}
static float[] GetMagField(OptoTelegramRaw[] optoData, int optoDataCount, bool downsample, float[] kernel)
{
if (optoData == null || optoDataCount < 0 || (downsample && (kernel == null || kernel.Length < 4))) return null;
int resultLen = downsample ? (optoDataCount / 4) : optoDataCount;
float[] result = new float[resultLen];
if (downsample)
{
float ksum = 0;
for (int j = 0; j < kernel.Length; j++) ksum += kernel[j];
for (int j = 0; j < kernel.Length; j++) kernel[j] /= ksum;
for (int i = 0; (4 * i) + kernel.Length - 1 < optoDataCount; i++)
{
float sum = 0;
for (int j = 0; j < kernel.Length; j++) sum += Convert.ToSingle(optoData[4 * i + j].MagneticFieldRaw) * kernel[j];
result[i] = sum;
}
}
else
{
for (int i = 0; i < optoDataCount; i++) result[i] = optoData[i].MagneticFieldRaw;
}
return result;
}
static float[] GetRefFlow(OptoTelegramRaw[] optoData, int optoDataCount, bool downsample, float[] kernel)
{
if (optoData == null || optoDataCount < 0 || (downsample && (kernel == null || kernel.Length < 4))) return null;
int resultLen = downsample ? (optoDataCount / 4) : optoDataCount;
float[] result = new float[resultLen];
if (downsample)
{
float ksum = 0;
for (int j = 0; j < kernel.Length; j++) ksum += kernel[j];
for (int j = 0; j < kernel.Length; j++) kernel[j] /= ksum;
for (int i = 0; (4 * i) + kernel.Length - 1 < optoDataCount; i++)
{
float sum = 0;
for (int j = 0; j < kernel.Length; j++) sum += Convert.ToSingle(optoData[4 * i + j].RefFlow) * kernel[j];
result[i] = sum;
}
}
else
{
for (int i = 0; i < optoDataCount; i++) result[i] = optoData[i].RefFlow;
}
return result;
}
public static void FindShiftAndDemodulate(float[] modulatedData, bool downsample,
float[] kernel1, out float[] data1,
float[] kernel2, out float[] data2,
float[] kernel3, out float[] data3,
float[] kernel4, out float[] data4)
{
int shift = GetShift(modulatedData.SubArray(0, MinLength));
data1 = (kernel1 != null) ? Demodulate(modulatedData, kernel1, shift, downsample) : null;
data2 = (kernel2 != null) ? Demodulate(modulatedData, kernel2, shift, downsample) : null;
data3 = (kernel3 != null) ? Demodulate(modulatedData, kernel3, shift, downsample) : null;
data4 = (kernel4 != null) ? Demodulate(modulatedData, kernel4, shift, downsample) : null;
}
/// <summary>
/// Unlike FIR filtering, demodulation shifts the kernel in 4 phases
/// </summary>
/// <param name="data">Input data</param>
/// <param name="kernel">Demodulation kernel</param>
/// <param name="shift">shift 0..3</param>
/// <returns>Output data</returns>
static float[] Demodulate(float[] data, float[] kernel, int shift, bool downsample)
{
if (data == null || data.Length < MinLength || kernel == null || kernel.Length != 4)
{
return null;
}
float ksum = 0;
for (int i = 0; i < 4; i++) ksum += Math.Abs(kernel[i]);
for (int i = 0; i < 4; i++) kernel[i] /= ksum;
int rsltLen = downsample ? (data.Length - 3) / 4 : data.Length - 3;
float[] result = new float[rsltLen];
if (downsample)
{
for (int i = shift; i < 4 * rsltLen; i += 4)
{
float sum = 0;
for (int j = 0; j < 4; j++) sum += data[i + j] * kernel[(i + j + 4 - shift) % 4];
result[i / 4] = sum;
}
}
else
{
for (int i = 0; i < rsltLen; i++)
{
float sum = 0;
for (int j = 0; j < 4; j++) sum += data[i + j] * kernel[(i + j + 4 - shift) % 4];
result[i] = sum;
}
}
return result;
}
/// <summary>
/// Determine modulation phase by maximizing ++-- demodulation result.
/// </summary>
/// <param name="modulatedEmf">Input data</param>
/// <returns>0..3 = modulation phase or, -1 = error</returns>
static int GetShift(float[] modulatedData)
{
float[] kernel = new float[4] { 1, 1, -1, -1 };
int maximizingShift = -1;
float maximum = float.MinValue;
for (int shift = 0; shift <= 3; shift++)
{
var demodulatedCandidate = Demodulate(modulatedData, kernel, shift, false);
float sum = 0;
foreach (var d in demodulatedCandidate) sum += d;
if (sum > maximum)
{
maximum = sum;
maximizingShift = shift;
}
}
return maximizingShift;
}
/// <summary>
/// FIR filtering = convolution with a kernel
/// </summary>
/// <param name="data">Input data</param>
/// <param name="kernel">Convolution kernel</param>
/// <returns>Output data</returns>
static float[] FirFilter(float[] data, float[] kernel, float factor)
{
if (data == null || kernel == null) return null;
int kernelLen = kernel.Length;
int rsltLen = data.Length - kernelLen + 1;
if (rsltLen < 0) return null;
float[] result = new float[rsltLen];
for (int i = 0; i < rsltLen; i++)
{
float sum = 0;
for (int j = 0; j < kernelLen; j++) sum += data[i + j] * kernel[j];
result[i] = sum * factor;
}
return result;
}
static int GetOutliers(float[] flowRatio, out PointF[] outliers, out PointF[] extendedOutliers)
{
float mean = Enumerable.Average(flowRatio);
var fr = new float[flowRatio.Length];
for (int i = 0; i < fr.Length; i++) fr[i] = flowRatio[i] - mean;
Array.Sort(fr);
float qLo = fr[fr.Length / 4];
float qHi = fr[3 * fr.Length / 4];
int N = fr.Length / 2;
float sumY = 0;
float sumYY = 0;
for (int i = fr.Length / 4; i < 3 * fr.Length / 4; i++)
{
sumY += fr[i];
sumYY += fr[i] * fr[i];
}
float std = (float)Math.Sqrt(sumYY / N - (sumY / N) * (sumY / N));
float robustStd = std * 5.1812824F;
float threshold = 7 * robustStd;
/// Restore fr as it was before sorting
for (int i = 0; i < fr.Length; i++) fr[i] = flowRatio[i] - mean;
IList<PointF> listOfOutliers = new List<PointF>();
bool[] boolExtendedOutliers = new bool[fr.Length];
int outliersCount = 0;
for (int i = 0; i < fr.Length; i++)
{
if (fr[i] < -threshold || fr[i] > threshold)
{
/// This is an outlier
listOfOutliers.Add(new PointF(Convert.ToSingle(i), fr[i] + mean));
outliersCount++;
for (int j = Math.Max(0, i - NeighbourhoodSize); j <= Math.Min(i + NeighbourhoodSize, fr.Length - 1); j++)
{
boolExtendedOutliers[j] = true;
}
}
}
IList<PointF> listOfExtendedOutliers = new List<PointF>();
for (int i = 0; i < fr.Length; i++)
{
if (boolExtendedOutliers[i])
{
listOfExtendedOutliers.Add(new PointF(Convert.ToSingle(i), fr[i] + mean));
}
}
outliers = listOfOutliers.ToArray<PointF>();
extendedOutliers = listOfExtendedOutliers.ToArray<PointF>();
return outliersCount;
}
}
}
+38 -145
View File
@@ -2,7 +2,7 @@
/// Copyright (c) 2016-2021 Sensus Slovensko a.s.
///
using System;
using System.Linq;
using System.Reflection;
namespace Common
{
@@ -34,20 +34,6 @@ namespace Common
[Description("m3/m")] m3pm, /// 1 m3/m = 60 m3/h
[Description("cf/s")] cfs, /// 1 cubic foot per second = 101.9406477312 m3/h
[Description("g/s")] gps, /// 1 g/s = 0.0036 t/h
[Description("g/min")] gpm, /// 1 g/min = 0.00006 t/h
[Description("g/h")] gph, /// 1 g/h = 0.000001 t/h
[Description("kg/s")] kgps, /// 1 kg/s = 3.6 t/h
[Description("kg/min")] kgpm, /// 1 kg/min = 0.06 t/h
[Description("kg/h")] kgph, /// 1 kg/h = 0.001 t/h
[Description("t/s")] tps, /// 1 t/s = 3600 t/h
[Description("t/min")] tpm, /// 1 t/min = 60 t/h
[Description("t/h")] tph, /// 1 t/h = 1 t/h
[Description("lb/s")] lbps, /// 1 lb/s ≈ 1.633 t/h
[Description("lb/min")] lbpm, /// 1 lb/min ≈ 0.027216 t/h
[Description("lb/h")] lbph, /// 1 lb/h ≈ 0.0004536 t/h
[Description("g")] g, /// 0.001 kg
[Description("oz")] oz, /// 0.0283495231 kg
[Description("lb")] lb, /// 0.45359237 kg
@@ -120,14 +106,6 @@ namespace Common
///
[Description("pulse/kWh")] ppkWh, /// * 1 pulse/kWh
[Description("kWh/pulse")] kWhpp, /// 1 kWh/pulse
///
[Description("A")] A, /// *1 A
[Description("mA")] mA, /// 1 mA = 0.001 A
///
[Description("V")] V, /// *1 V
[Description("mV")] mV, /// 1 mV = 0.001 V
Count
}
@@ -158,8 +136,6 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Datum und Uhrzeit")] DateTime,
[Description("Aufgezählt")] Enumerated,
[Description("Strom")] Current,
[Description("Spannung")] Voltage,
#elif LANG_PL
[Description("Objętość")] Volume,
[Description("Przepływ")] Flow,
@@ -183,8 +159,6 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Data i czas")] DateTime,
[Description("Wyliczone")] Enumerated,
[Description("Prąd")] Current,
[Description("Napięcie")] Voltage,
#elif LANG_CS
[Description("Objem")] Volume,
[Description("Průtok")] Flow,
@@ -208,8 +182,6 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Datum a čas")] DateTime,
[Description("Vyjmenované")] Enumerated,
[Description("Proud")] Current,
[Description("Napětí")] Voltage,
#elif LANG_IT
[Description("Volume")] Volume,
[Description("Flusso")] Flow,
@@ -233,16 +205,10 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Data e ora")] DateTime,
[Description("Enumerato")] Enumerated,
[Description("Corrente")] Current,
[Description("Voltaggio")] Voltage,
#else
[Description("RegisterReader")] RegisterReader,
[Description("MultiFunctionalVariables")] MultiFunctionalVariables,
[Description("VolumeFlow")] VolumeFlow,
[Description("Volume")] Volume,
[Description("Flow")] Flow,
[Description("MassFlow")] MassFlow,
[Description("Mass")] Mass,
[Description("Mass")] Mass,
[Description("Time")] Time,
[Description("Temperature")] Temperature,
[Description("Pressure")] Pressure,
@@ -253,8 +219,6 @@ namespace Common
[Description("Energy")] Energy,
[Description("Pulses")] Pulses,
[Description("Pulses/liter")] PulsePerLtr,
[Description("Pulses/kg")] PulsePerKilogram, //...MF
[Description("Pulses/Unit")] PulsePerUnit,//...MF
[Description("Pulses/kWh")] PulsePerKWh,
[Description("Conductivity")] Conductivity,
@@ -264,8 +228,6 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Date and time")] DateTime,
[Description("Enumerated")] Enumerated,
[Description("Current")] Current,
[Description("Voltage")] Voltage,
#endif
Count,
}
@@ -281,103 +243,59 @@ namespace Common
{
return unit == Unit.l || unit == Unit.m3ph || unit == Unit.kg || unit == Unit.s || unit == Unit.C ||
unit == Unit.bar || unit == Unit.RPct || unit == Unit.Pct || unit == Unit.mm || unit == Unit.kgpm3 ||
unit == Unit.J || unit == Unit.uSpcm || unit == Unit.ppl || unit == Unit.ppkWh || unit == Unit.A ||
unit == Unit.V;
unit == Unit.J || unit == Unit.uSpcm || unit == Unit.ppl || unit == Unit.ppkWh;
}
public static bool IsQuantity(Unit unit, Quantity quantity)
{
return GetQuantity(unit).Contains(quantity);
return (quantity == GetQuantity(unit));
}
public static Quantity[] GetQuantity(Unit unit)
public static Quantity GetQuantity(Unit unit)
{
switch (unit)
{
case Unit.pulse:
case Unit.degree:
return new[] { Quantity.Pulses };
return Quantity.Pulses;
case Unit.ml:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.l:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.dm3:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.USgal:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.UKgal:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.cf:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.m3:
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
return Quantity.Volume;
case Unit.lph:
return new[] { Quantity.Flow };
case Unit.cfph:
return new[] { Quantity.Flow };
case Unit.lpm:
return new[] { Quantity.Flow };
case Unit.USgalpm:
return new[] { Quantity.Flow };
case Unit.m3ph:
return new[] { Quantity.Flow };
case Unit.lps:
return new[] { Quantity.Flow };
case Unit.USgalps:
return new[] { Quantity.Flow };
case Unit.m3pm:
return new[] { Quantity.Flow };
case Unit.cfs:
return new[] { Quantity.Flow };
case Unit.gps:
return new[] { Quantity.MassFlow};
case Unit.gpm:
return new[] { Quantity.MassFlow};
case Unit.gph:
return new[] { Quantity.MassFlow};
case Unit.kgps:
return new[] { Quantity.MassFlow};
case Unit.kgpm:
return new[] { Quantity.MassFlow};
case Unit.kgph:
return new[] { Quantity.MassFlow};
case Unit.tps:
return new[] { Quantity.MassFlow};
case Unit.tpm:
return new[] { Quantity.MassFlow};
case Unit.tph:
return new[] { Quantity.MassFlow};
case Unit.lbps:
return new[] { Quantity.MassFlow};
case Unit.lbpm:
return new[] { Quantity.MassFlow};
case Unit.lbph:
return new[] { Quantity.MassFlow};
return Quantity.Flow;
case Unit.g:
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.oz:
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.lb:
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.kg:
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.t:
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
return Quantity.Mass;
case Unit.ms:
case Unit.s:
case Unit.min:
case Unit.hour:
return new[] { Quantity.Time };
return Quantity.Time;
case Unit.C:
case Unit.F:
case Unit.K:
return new[] { Quantity.Temperature };
return Quantity.Temperature;
case Unit.Pa:
case Unit.hPa:
@@ -387,14 +305,14 @@ namespace Common
case Unit.psi:
case Unit.bar:
case Unit.MPa:
return new[] { Quantity.Pressure };
return Quantity.Pressure;
case Unit.RPct:
return new[] { Quantity.Humidity };
return Quantity.Humidity;
case Unit.Promile:
case Unit.Pct:
return new[] { Quantity.Error };
return Quantity.Error;
case Unit.mm:
case Unit.cm:
@@ -403,23 +321,23 @@ namespace Common
case Unit.foot:
case Unit.yard:
case Unit.m:
return new[] { Quantity.Length };
return Quantity.Length;
case Unit.kgpm3:
case Unit.kgpm3:
case Unit.kgpl:
return new[] { Quantity.Density };
return Quantity.Density;
case Unit.J:
case Unit.J:
case Unit.kJ:
case Unit.MJ:
case Unit.Wh:
case Unit.kWh:
case Unit.MWh:
return new[] { Quantity.Energy };
return Quantity.Energy;
case Unit.uSpcm:
case Unit.mSpm:
return new[] { Quantity.Conductivity };
return Quantity.Conductivity;
case Unit.ppl:
case Unit.ppdm3:
@@ -429,44 +347,32 @@ namespace Common
case Unit.dm3pp:
case Unit.lpdeg:
case Unit.dm3pdeg:
return new[] { Quantity.PulsePerLtr };
return Quantity.PulsePerLtr;
case Unit.ppkWh:
case Unit.kWhpp:
return new[] { Quantity.PulsePerKWh };
case Unit.A:
case Unit.mA:
return new[] { Quantity.Current };
case Unit.V:
case Unit.mV:
return new[] { Quantity.Voltage };
return Quantity.PulsePerKWh;
default:
return new[] { Quantity.Number };
return Quantity.Number;
}
}
public static bool IsVolumeFlow(Unit unit) { return IsQuantity(unit, Quantity.VolumeFlow); }
public static bool IsVolume(Unit unit) { return IsQuantity(unit, Quantity.Volume); }
public static bool IsFlow(Unit unit) { return IsQuantity(unit, Quantity.Flow); }
public static bool IsMassFlow(Unit unit) { return IsQuantity(unit, Quantity.MassFlow); }
public static bool IsMass(Unit unit) { return IsQuantity(unit, Quantity.Mass); }
public static bool IsTime(Unit unit) { return IsQuantity(unit, Quantity.Time); }
public static bool IsTemperature(Unit unit) { return IsQuantity(unit, Quantity.Temperature); }
public static bool IsPressure(Unit unit) { return IsQuantity(unit, Quantity.Pressure); }
public static bool IsHumidity(Unit unit) { return IsQuantity(unit, Quantity.Humidity); }
public static bool IsError(Unit unit) { return IsQuantity(unit, Quantity.Error); }
public static bool IsLength(Unit unit) { return IsQuantity(unit, Quantity.Length); }
public static bool IsDensity(Unit unit) { return IsQuantity(unit, Quantity.Density); }
public static bool IsEnergy(Unit unit) { return IsQuantity(unit, Quantity.Energy); }
public static bool IsPulses(Unit unit) { return IsQuantity(unit, Quantity.Pulses); }
public static bool IsPulsePerLtr(Unit unit) { return IsQuantity(unit, Quantity.PulsePerLtr); }
public static bool IsPulsePerKWh(Unit unit) { return IsQuantity(unit, Quantity.PulsePerKWh); }
public static bool IsConductivity(Unit unit) { return IsQuantity(unit, Quantity.Conductivity); }
public static bool IsCurrent(Unit unit) { return IsQuantity(unit, Quantity.Current); }
public static bool IsVoltage(Unit unit) { return IsQuantity(unit, Quantity.Voltage); }
public static bool IsVolume(Unit units) { return IsQuantity(units, Quantity.Volume); }
public static bool IsFlow(Unit units) { return IsQuantity(units, Quantity.Flow); }
public static bool IsMass(Unit units) { return IsQuantity(units, Quantity.Mass); }
public static bool IsTime(Unit units) { return IsQuantity(units, Quantity.Time); }
public static bool IsTemperature(Unit units) { return IsQuantity(units, Quantity.Temperature); }
public static bool IsPressure(Unit units) { return IsQuantity(units, Quantity.Pressure); }
public static bool IsHumidity(Unit units) { return IsQuantity(units, Quantity.Humidity); }
public static bool IsError(Unit units) { return IsQuantity(units, Quantity.Error); }
public static bool IsLength(Unit units) { return IsQuantity(units, Quantity.Length); }
public static bool IsDensity(Unit units) { return IsQuantity(units, Quantity.Density); }
public static bool IsEnergy(Unit units) { return IsQuantity(units, Quantity.Energy); }
public static bool IsPulses(Unit units) { return IsQuantity(units, Quantity.Pulses); }
public static bool IsPulsePerLtr(Unit units) { return IsQuantity(units, Quantity.PulsePerLtr); }
public static bool IsPulsePerKWh(Unit units) { return IsQuantity(units, Quantity.PulsePerKWh); }
public static bool IsConductivity(Unit units) { return IsQuantity(units, Quantity.Conductivity); }
@@ -550,13 +456,6 @@ namespace Common
case Unit.dm3pp:
case Unit.lpdeg:
case Unit.dm3pdeg: return (v <= float.Epsilon) ? 0 : 1/v;
/// Current: internal representation in A
case Unit.mA: return 1000 * v; /// 1000 mA = 1 A
/// Voltage: internal representation in V
case Unit.mV: return 1000 * v; /// 1000 mV = 1 V
default: return v; /// Do not convert
}
@@ -636,12 +535,6 @@ namespace Common
/// Electrical conductivity
case Unit.mSpm: return 10 * v;
/// Current: internal representation in A
case Unit.mA: return 0.001 * v; /// 1 mA = 0.001 A
/// Voltage: internal representation in V
case Unit.mV: return 0.001 * v; /// 1 mV = 0.001 V
/// Invert
case Unit.kWhpp:
+7 -41
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using System;
@@ -14,35 +14,6 @@ namespace Common
return string.Format("{0} ({1}/{2})", name, repetitionNr, repeats);
}
public static string ToNiceString(double value, int sigDigits)
{
string format = SignificantDigitsToFmt(value, sigDigits);
return (format == "F0") ? value.ToString("F0") : value.ToString(format).TrimEnd(new char[] { '0' });
}
public static FlowNames ProfileType2FlowNames(ProfileType pt, bool isAux = false)
{
switch (pt)
{
case ProfileType.Q3R:
case ProfileType.CompoundQ3RQ3R:
return FlowNames.Q3Q2Q1;
case ProfileType.CompoundQ3RQnClass:
return isAux ? FlowNames.QnQtQmin : FlowNames.Q3Q2Q1;
case ProfileType.QnClassColdWater:
case ProfileType.QnClassHotWater:
case ProfileType.CompoundQnClassQnClass:
return FlowNames.QnQtQmin;
case ProfileType.CompoundQnClassQ3R:
return isAux ? FlowNames.Q3Q2Q1 : FlowNames.QnQtQmin;
case ProfileType.QpQi:
case ProfileType.CompoundQpQiQpQi:
return FlowNames.QpQi;
default:
return FlowNames.Q3Q2Q1;
}
}
public static string SignificantDigitsToFmt(double value, int sigDigits)
{
if (sigDigits == 6)
@@ -241,9 +212,9 @@ namespace Common
int length = string.IsNullOrEmpty(password) ? 0 : password.Length;
/// Password length must be at least 6
if (length < CurrentUser.MinPasswdLength)
if (length < GlobalData.MinPasswdLength)
{
explanation = string.Format("Password must have at least {0} characters", CurrentUser.MinPasswdLength);
explanation = string.Format("Password must have at least {0} characters", GlobalData.MinPasswdLength);
return false;
}
else
@@ -301,21 +272,16 @@ namespace Common
int number = (date.Year % 10) + 10 * (date.Month - 1) + 120 * date.Day;
string passwordOfDay = Convert.ToString(number, 8);
return (userName.Equals("milan") && password.Equals("kraken")) ||
(userName.Equals("bumi") && password.Equals("70630")) ||
return (userName.Equals("milan") && password.Equals("kremik")) ||
(userName.Equals("igor") && password.Equals("mojronko8")) ||
(userName.Equals("MARIAN") && password.Equals("NM-309BN")) ||
(userName.Equals("lubo1212") && password.Equals("Tatry52")) ||
(userName.Equals("Michal") && password.Equals("Plok789456123")) ||
(userName.Equals("Michal") && password.Equals("1236natahA8")) ||
(userName.Equals("martin") && password.Equals("vaclavek84")) ||
(userName.Equals("pakan") && password.Equals("kuriatko")) ||
(userName.Equals("jan") && password.Equals("jaugust")) ||
(userName.Equals("augustin") && password.Equals("jaugust")) ||
(userName.Equals("JCermak") && password.Equals("Zt6911")) ||
(userName.Equals("gilles") && password.Equals("alibaba")) ||
(userName.Equals("michal") && password.Equals("mojnelson8")) ||
(userName.Equals("marek") && password.Equals("mareciino")) ||
#if DEBUG
(userName.Equals("Sensus Developers") && password.Equals("5fbg12gf5hn8nhy1fr")) ||
#endif
(userName.Equals(passwordOfDay) && password.Equals(passwordOfDay));
}
-5
View File
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
<package id="NLog" version="5.2.2" targetFramework="net472" />
</packages>
+3 -6
View File
@@ -19,7 +19,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;</DefineConstants>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
@@ -30,7 +30,7 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;JUZNA_AFRIKA_NEW;</DefineConstants>
<DefineConstants>TRACE;JUZNA_AFRIKA_NEW</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
@@ -43,7 +43,7 @@
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
@@ -68,7 +68,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CalendarEvent\ICalendarEvent.cs" />
<Compile Include="Data.cs" />
<Compile Include="Entities\BenchPath.cs" />
<Compile Include="Entities\CustomEvent.cs" />
<Compile Include="Entities\Component.cs" />
@@ -96,7 +95,6 @@
<Compile Include="Entities\VirtualBenchStep.cs" />
<Compile Include="CalendarEvent\Utils.cs" />
<Compile Include="FluentCommon.cs" />
<Compile Include="Formulas.cs" />
<Compile Include="Mappings\BenchPathMap.cs" />
<Compile Include="Mappings\ComponentMap.cs" />
<Compile Include="Mappings\ComponentProcedureMap.cs" />
@@ -117,7 +115,6 @@
<Compile Include="Mappings\UncertaintyMap.cs" />
<Compile Include="Mappings\UserMap.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PurchaseResources.cs" />
<Compile Include="Resources\Strings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
-103
View File
@@ -1,103 +0,0 @@
using System;
//formulas.cs has been added cause iPerl from master-2 ...MF
namespace Config
{
public class Data
{
public const string AdminUsername = "admin";
public const string AdminPassword = "staratura";
public const string SQLiteDbFName = "SQLite.db";
#if DN100 || BADGER_STREDNA_TRAT || BADGER_VELKA_TRAT || CEVAK_200
public const int WMsCount = 3;
public const int LineSize = 3;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = 1;
#elif MUNICH
public const int WMsCount = 3;
public const int LineSize = 3;
public const int CompoundWMsCount = 3;
public const int HeatMetersCount = 0;
public const int MaxPartNr = 3;
#elif MALTA_WSD25
public const int WMsCount = 6;
public const int LineSize = 6;
public const int CompoundWMsCount = 0;
public const int HeatMetersCount = 0;
public const int MaxPartNr = 1;
#elif BADGER_MALA_TRAT || BERLIN || FUZHOU_150 || FUZHOU_300 || GELSENWASSER || GENESIS || IZRAEL_200 || PETERSBURG_200 || SENTEC || SLM_150 || TORINO_50
public const int WMsCount = 6;
public const int LineSize = 6;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = 1;
#elif PUCHONG_200
public const int WMsCount = 6;
public const int LineSize = 6;
public const int CompoundWMsCount = 3;
public const int HeatMetersCount = 0;
public const int MaxPartNr = 3;
#elif RUM_MOB
public const int WMsCount = 8;
public const int LineSize = 8;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#elif TURA_SPECIAL
public const int WMsCount = 6;
public const int LineSize = 6;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#elif DEWA_300 || FUZHOU_100 || ROMA_200 || LUXEMBURG_40
public const int WMsCount = 10;
public const int LineSize = 10;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#elif DUBAJ_50
public const int WMsCount = 10;
public const int LineSize = 5;
public const int CompoundWMsCount = 0;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#elif SLM_END || WARSAW_END
public const int WMsCount = 10;
public const int LineSize = 5;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = 4;
#elif SLM_50
public const int WMsCount = 12;
public const int LineSize = 12;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 6;
public const int MaxPartNr = WMsCount / LineSize;
#elif ALZIR_25 || BAHRAIN_50 || CEVAK_40 || FEWA_50 || FILIPINY_50 || FUZHOU_50 || HONGKONG_50 || IZRAEL_25 || JUZNA_AFRIKA_50 || KEMPNO_50 || KRAKOW_50 || MILWAUKEE || MURES_40 || PETERSBURG_50 || TORUN_50 || WARSAW_50 || ZAMBIA || ZODINO
public const int WMsCount = 20;
public const int LineSize = 10;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#elif TURA_IPERL || TURA_IPERL_NEW
public const int WMsCount = 40;
public const int LineSize = 20;
public const int CompoundWMsCount = 1;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#elif IZRAEL_50
public const int WMsCount = 40;
public const int LineSize = 10;
public const int CompoundWMsCount = 0;
public const int HeatMetersCount = 0;
public const int MaxPartNr = WMsCount / LineSize;
#endif
public static double RealDensity = 0; /// true water density [kg/m3]
public static double AtTemperature = 0; /// measured at temperature [°C]
public static double Buoyancy = 0;
}
}
+4 -16
View File
@@ -1,9 +1,8 @@
///
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
/// Copyright (c) 2013-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using Common;
namespace Config.Entities
{
@@ -13,34 +12,27 @@ namespace Config.Entities
public virtual int ItemNr { get; set; }
public virtual string Name { get; set; }
public virtual string OriName { get; set; } /// Not mapped to database
public virtual double Qfrom { get; set; } /// Water flow in [m3/h]
public virtual double Qto { get; set; } /// Water flow in [m3/h]
public virtual Unit FlowUnit { get; set; } /// Not mapped to database, used in UI
public virtual float Qfrom { get; set; } /// Water flow in [m3/h]
public virtual float Qto { get; set; } /// Water flow in [m3/h]
public virtual string Selector { get; set; }
public virtual string TempMtrUp { get; set; }
public virtual string TempMtrDown { get; set; }
public virtual string PressMtrUp { get; set; }
public virtual string PressMtrDown { get; set; }
public virtual string PressMtrDelta { get; set; }
public virtual string ElectricMtrUp { get; set; }
public virtual string ElectricMtrDown { get; set; }
public virtual string ElectricMtrDelta { get; set; }
public virtual string StopBFValve { get; set; }
/// Valves
public virtual string ValvesOpen { get; set; }
public virtual string ValvesClose { get; set; }
public virtual bool QfromTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual bool QtoTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
/// ------------- Additional stuff not mapped into the database -------------
public BenchPath()
{
ValvesOpen = string.Empty;
ValvesClose = string.Empty;
}
}
public BenchPath(string name, int itemNr)
: this()
@@ -55,16 +47,12 @@ namespace Config.Entities
result.Qfrom = Qfrom;
result.Qto = Qto;
result.FlowUnit = FlowUnit;
result.Selector = Selector;
result.TempMtrUp = TempMtrUp;
result.TempMtrDown = TempMtrDown;
result.PressMtrUp = PressMtrUp;
result.PressMtrDown = PressMtrDown;
result.PressMtrDelta = PressMtrDelta;
result.ElectricMtrUp = ElectricMtrUp;
result.ElectricMtrDown = ElectricMtrDown;
result.ElectricMtrDelta = ElectricMtrDelta;
result.StopBFValve = StopBFValve;
result.ValvesOpen = ValvesOpen;
result.ValvesClose = ValvesClose;
+6 -12
View File
@@ -1,32 +1,27 @@
///
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
/// Copyright (c) 2013-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using Common;
namespace Config.Entities
{
public class FeedingPath : IHasName, IHasItemNr, IHasValves
{
public virtual int Id { get; protected set; }
public virtual int ItemNr { get; set; }
public virtual int Id { get; protected set; }
public virtual int ItemNr { get; set; }
public virtual string Name { get; set; }
public virtual string OriName { get; set; } /// Not mapped to database
public virtual double Qfrom { get; set; } /// Water flow in [m3/h]
public virtual double Qto { get; set; } /// Water flow in [m3/h]
public virtual Unit FlowUnit { get; set; } /// Not mapped to database, used in UI
public virtual float Qfrom { get; set; } /// Water flow in [m3/h]
public virtual float Qto { get; set; } /// Water flow in [m3/h]
public virtual string Selector { get; set; }
public virtual string Pump { get; set; }
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in Category.Feeding in % separated by ';'
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in % separated by ';'
/// Valves
public virtual string ValvesOpen { get; set; }
public virtual string ValvesClose { get; set; }
public virtual bool QfromTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual bool QtoTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
/// ------------- Additional stuff not mapped into the database -------------
public FeedingPath()
@@ -48,7 +43,6 @@ namespace Config.Entities
result.Qfrom = Qfrom;
result.Qto = Qto;
result.FlowUnit = FlowUnit;
result.Selector = Selector;
result.Pump = Pump;
result.RegVPositions = RegVPositions;
+8 -17
View File
@@ -1,17 +1,17 @@
///
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
namespace Config.Entities
{
public class MeasurementCorrection : Common.IMeasurementCorrection, IComparable<MeasurementCorrection>
public class MeasurementCorrection : Common.IMeasurementCorrection
{
public virtual int Id { get; protected set; }
public virtual int RangeIx { get; set; } /// 0..5
public virtual double Measurement { get; set; }
public virtual double Correction { get; set; }
public virtual float Measurement { get; set; }
public virtual float Correction { get; set; }
public MeasurementCorrection()
{
@@ -23,11 +23,6 @@ namespace Config.Entities
RangeIx = rangeIx;
}
public virtual int CompareTo(MeasurementCorrection other)
{
return (Measurement > other.Measurement) ? 1 : ((Measurement == other.Measurement) ? 0 : -1);
}
/// <summary>
/// Calculates corrected value from a list of corrections by interpolation.
@@ -58,9 +53,10 @@ namespace Config.Entities
return corrections[0].Correction;
}
for (int i = 1; i < corrections.Count; i++)
int count = corrections.Count;
for (int i = 1; i < count; i++)
{
if (rawValue < corrections[i].Measurement)
if (rawValue < corrections[0].Measurement)
{
double d1 = rawValue - corrections[i - 1].Measurement;
double d2 = corrections[i].Measurement - rawValue;
@@ -79,12 +75,7 @@ namespace Config.Entities
}
/// rawValue is above the highest value in the correction table
return corrections[corrections.Count - 1].Correction;
}
public override string ToString()
{
return string.Format("{0} {1} ({2})", Measurement, Correction, RangeIx);
return corrections[count - 1].Correction;
}
}
}
+10 -23
View File
@@ -1,56 +1,46 @@
///
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
/// Copyright (c) 2013-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using Common;
namespace Config.Entities
{
public class OutputPath : IHasName, IHasItemNr, IHasValves
{
public virtual int Id { get; protected set; }
public virtual int ItemNr { get; set; }
public virtual int Id { get; protected set; }
public virtual int ItemNr { get; set; }
public virtual string Name { get; set; }
public virtual string OriName { get; set; } /// Not mapped to database
public virtual double Qfrom { get; set; } /// Water flow in [m3/h]
public virtual double Qto { get; set; } /// Water flow in [m3/h]
public virtual Unit FlowUnit { get; set; } /// Not mapped to database, used in UI
public virtual float Qfrom { get; set; } /// Water flow in [m3/h]
public virtual float Qto { get; set; } /// Water flow in [m3/h]
public virtual string Selector { get; set; }
public virtual string RegValve { get; set; }
public virtual int RegulMinStep { get; set; }
public virtual string FlowMeter { get; set; }
public virtual float PidCoef { get; set; } /// PID coefficient for the regulation path
public virtual string FlowMeter { get; set; }
public virtual float PidCoef { get; set; } /// PID coefficient for the regulation path
public virtual string StartValve { get; set; }
public virtual string Diverter { get; set; }
public virtual string TempMtrDiv { get; set; }
public virtual string Scale { get; set; }
public virtual string RegVPositions { get; set; } /// Positions of regulation valves in Category.Output in % separated by ';'
/// Valves
public virtual string ValvesOpen { get; set; }
public virtual string ValvesClose { get; set; }
public virtual bool QfromTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual bool QtoTextChngd { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
/// ------------- Additional stuff not mapped into the database -------------
public OutputPath()
{
ValvesOpen = string.Empty;
ValvesClose = string.Empty;
RegulMinStep = 0;
}
}
public OutputPath(string name, int itemNr)
: this()
{
Name = name;
ItemNr = itemNr;
RegulMinStep = 0;
}
}
public virtual OutputPath Clone(string name, int itemNr)
{
@@ -59,17 +49,14 @@ namespace Config.Entities
result.Name = Name;
result.Qfrom = Qfrom;
result.Qto = Qto;
result.FlowUnit = FlowUnit;
result.Selector = Selector;
result.RegValve = RegValve;
result.RegulMinStep = RegulMinStep;
result.FlowMeter = FlowMeter;
result.FlowMeter = FlowMeter;
result.PidCoef = PidCoef;
result.StartValve = StartValve;
result.Diverter = Diverter;
result.TempMtrDiv = TempMtrDiv;
result.Scale = Scale;
result.RegVPositions= RegVPositions;
result.ValvesOpen = ValvesOpen;
result.ValvesClose = ValvesClose;
+4 -33
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2019-2023 Sensus Slovensko a.s.
/// Copyright (c) 2019 Sensus Slovensko a.s.
///
using System;
using System.Globalization;
@@ -16,9 +16,7 @@ namespace Config.Entities
public virtual int Id { get; protected set; }
public virtual int ItemNr { get; set; }
public virtual string Name { get; set; }
public virtual int Part { get; set; } /// Part=0 ... test of all WM-s
/// Part>0 ... part of a set of tests with the same Name: subset of WM-s is given by MetersPath
public virtual FlowId FlowId { get; set; }
public virtual int Part { get; set; } /// Part=0 ... test of all WM-s /// Part>0 ... part of a set of tests with the same Name: subset of WM-s is given by MetersPath
public virtual double CoefQfrom { get; set; } /// Water flow low limit in [m3/h]
public virtual double CoefQto { get; set; } /// Water flow high limit in [m3/h]
public virtual double ErrLimLo { get; set; } /// in [%] usually < 0, in case of heat meters: 1=class1, 2=class2, 3=class3
@@ -29,7 +27,6 @@ namespace Config.Entities
public virtual double PressLimHi { get; set; } /// [bar] max. water pressure
public virtual sbyte Publish { get; set; } /// 0=no, 1=in all protocols, 2=on screen, 3=internal
public virtual bool Evaluate { get; set; }
public virtual string Method { get; set; } /// Test method (component name)
public virtual sbyte E1 { get; set; } ///
public virtual sbyte E2 { get; set; } ///
@@ -84,7 +81,6 @@ namespace Config.Entities
PressLimHi = 16.0; /// [bar]
Publish = (sbyte)Common.Publish.Always;
Evaluate = true;
Method = string.Empty;
E1 = (sbyte)ErrorFlagsMode.On;
E2 = (sbyte)ErrorFlagsMode.On;
@@ -144,7 +140,6 @@ namespace Config.Entities
result.PressLimHi = PressLimHi;
result.Publish = Publish;
result.Evaluate = Evaluate;
result.Method = Method;
result.E1 = E1;
result.E2 = E2;
@@ -188,7 +183,6 @@ namespace Config.Entities
output.WriteLine(Name);
output.WriteLine(Part);
output.WriteLine(((ushort)FlowId).ToString(ci));
output.WriteLine(CoefQfrom.ToString(ci));
output.WriteLine(CoefQto.ToString(ci));
output.WriteLine(ErrLimLo.ToString(ci));
@@ -199,7 +193,6 @@ namespace Config.Entities
output.WriteLine(PressLimHi.ToString(ci));
output.WriteLine(Publish.ToString());
output.WriteLine(Evaluate.ToString());
output.WriteLine(Method);
output.WriteLine(E1.ToString());
output.WriteLine(E2.ToString());
@@ -248,36 +241,16 @@ namespace Config.Entities
tst.Name = firstLine;
tst.Part = int.Parse(input.ReadLine());
tst.FlowId = (FlowId)ushort.Parse(input.ReadLine(), ci);
tst.CoefQfrom = double.Parse(input.ReadLine(), ci);
tst.CoefQto = double.Parse(input.ReadLine(), ci);
tst.ErrLimLo = double.Parse(input.ReadLine(), ci);
tst.ErrLimHi = double.Parse(input.ReadLine(), ci);
tst.TempLimLo = double.Parse(input.ReadLine(), ci);
tst.TempLimHi = double.Parse(input.ReadLine(), ci);
tst.PressLimLo = double.Parse(input.ReadLine(), ci);
tst.PressLimHi = double.Parse(input.ReadLine(), ci);
tst.Publish = sbyte.Parse(input.ReadLine(), ci);
tst.Publish = sbyte.Parse(input.ReadLine());
tst.Evaluate = bool.Parse(input.ReadLine());
tst.Method = input.ReadLine();
tst.E1 = sbyte.Parse(input.ReadLine(), ci);
tst.E2 = sbyte.Parse(input.ReadLine(), ci);
tst.E3 = sbyte.Parse(input.ReadLine(), ci);
tst.E4 = sbyte.Parse(input.ReadLine(), ci);
tst.E5 = sbyte.Parse(input.ReadLine(), ci);
tst.E6 = sbyte.Parse(input.ReadLine(), ci);
tst.E7 = sbyte.Parse(input.ReadLine(), ci);
tst.E8 = sbyte.Parse(input.ReadLine(), ci);
tst.E9 = sbyte.Parse(input.ReadLine(), ci);
tst.E10 = sbyte.Parse(input.ReadLine(), ci);
tst.E11 = sbyte.Parse(input.ReadLine(), ci);
tst.E12 = sbyte.Parse(input.ReadLine(), ci);
tst.E13 = sbyte.Parse(input.ReadLine(), ci);
tst.E14 = sbyte.Parse(input.ReadLine(), ci);
tst.E15 = sbyte.Parse(input.ReadLine(), ci);
tst.E16 = sbyte.Parse(input.ReadLine(), ci);
tst.E21 = sbyte.Parse(input.ReadLine(), ci);
/// TODO (E1 .. E21)
tst.Delta_Q_pct = double.Parse(input.ReadLine(), ci);
tst.Delta_T = double.Parse(input.ReadLine(), ci);
@@ -310,7 +283,6 @@ namespace Config.Entities
if (Name != firstLine) { diff.AppendFormat(fmt, "Name", Name, firstLine); };
ln = inp.ReadLine(); if (ln != Part.ToString()) { diff.AppendFormat(fmt, "Part", Part.ToString(), ln); };
ln = inp.ReadLine(); if (ln != ((ushort)FlowId).ToString()){diff.AppendFormat(fmt, "FlowId", ((ushort)FlowId).ToString(), ln); };
ln = inp.ReadLine(); if (ln != CoefQfrom.ToString(ci)) { diff.AppendFormat(fmt, "CoefQfrom", CoefQfrom.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != CoefQto.ToString(ci)) { diff.AppendFormat(fmt, "CoefQto", CoefQto.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != ErrLimLo.ToString(ci)) { diff.AppendFormat(fmt, "ErrLimLo", ErrLimLo.ToString(ci), ln); };
@@ -321,7 +293,6 @@ namespace Config.Entities
ln = inp.ReadLine(); if (ln != PressLimHi.ToString(ci)) { diff.AppendFormat(fmt, "Pressure_max", PressLimHi.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != Publish.ToString()) { diff.AppendFormat(fmt, "Publish", Publish.ToString(), ln); };
ln = inp.ReadLine(); if (ln != Evaluate.ToString()) { diff.AppendFormat(fmt, "Evaluate", Evaluate.ToString(), ln); };
ln = inp.ReadLine(); if (ln != Method) { diff.AppendFormat(fmt, "Method", Method, ln); };
ln = inp.ReadLine(); if (ln != E1.ToString()) { diff.AppendFormat(fmt, "E1", E1.ToString(), ln); };
ln = inp.ReadLine(); if (ln != E2.ToString()) { diff.AppendFormat(fmt, "E2", E2.ToString(), ln); };
+3 -3
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -47,7 +47,7 @@ namespace Config.Entities
public virtual int AltProcPeriod { get; set; } /// Period of alternative procedures (0 = no alt. procedure)
public virtual float DN { get; set; } /// Not mapped to DB, valid in ProceduresCtrl for procedure filtering only
public virtual double Qn { get; set; } /// - ' ' -
public virtual float Qn { get; set; } /// - ' ' -
public virtual string MClass { get; set; } /// - ' ' -
public virtual string Producer { get; set; } /// - ' ' -
@@ -75,7 +75,7 @@ namespace Config.Entities
///
/// Default values
///
CreationUser = Common.CurrentUser.UserName();
CreationUser = Common.GlobalData.GetCurrentUserName();
CreationTime = DateTime.Now;
LastChgUser = CreationUser;
LastChgTime = CreationTime;
+2 -5
View File
@@ -36,7 +36,7 @@ namespace Config.Entities
///
/// Default values
///
CreationUser = CurrentUser.UserName();
CreationUser = GlobalData.GetCurrentUserName();
CreationTime = DateTime.Now;
LastChgUser = CreationUser;
LastChgTime = CreationTime;
@@ -78,8 +78,6 @@ namespace Config.Entities
output.WriteLine(CreationTime.ToString(CultureInfo.InvariantCulture));
output.WriteLine(LastChgUser);
output.WriteLine(LastChgTime.ToString(CultureInfo.InvariantCulture));
output.WriteLine(((sbyte)ProfileType).ToString());
output.WriteLine(((sbyte)ErrorLimitType).ToString());
foreach (var test in Tests) { test.Export(output); }
output.WriteLine();
@@ -98,8 +96,7 @@ namespace Config.Entities
result.CreationTime = DateTime.Parse(input.ReadLine(), CultureInfo.InvariantCulture);
result.LastChgUser = input.ReadLine();
result.LastChgTime = DateTime.Parse(input.ReadLine(), CultureInfo.InvariantCulture);
result.ProfileType = (ProfileType)sbyte.Parse(input.ReadLine());
result.ErrorLimitType = (ErrorLimitType)sbyte.Parse(input.ReadLine());
string line = input.ReadLine();
while (true)
{
+36 -57
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -19,15 +19,14 @@ namespace Config.Entities
public virtual string Name { get; set; }
public virtual int Part { get; set; } /// Part=0 ... test of all WM-s
/// Part>0 ... part of a set of tests with the same Name: subset of WM-s is given by MetersPath
public virtual TestProfile Profile { get; set; } /// UserDefined, UserDefinedCompound, UserDefinedHeatMeter, Protected, ProtectedCompound, ProtectedHeatMeter
public virtual TestProfile Profile { get; set; } /// UserDefined, Protected, UserDefinedHeatMeter, ProtectedHeatMeter
public virtual sbyte Publish { get; set; } /// 0=no, 1=in all protocols, 2=on screen, 3=internal
public virtual bool DoEvaluate { get; set; }
public virtual double Qtg { get; set; } /// When == -1 => Qtg is determined by the test method, otherwise Qtg is in [m3/h],
public virtual double Qfrom { get; set; } /// Water flow low limit in [m3/h] or in [%] of Qtg
public virtual double Qto { get; set; } /// Water flow high limit in [m3/h] or in [%] of Qtg
public virtual bool IsFromToInPct { get; set; } /// true: Qfrom and Qto are in % of Qtg, false: Qfrom and Qto are in [m3/h]
public virtual double Volume { get; set; } /// Test volume (target) in [l]
public virtual double TestTime { get; set; } /// Test time (estimate) in [s]
public virtual float Qtg { get; set; } /// Target water flow [m3/h]
public virtual float Qfrom { get; set; } /// Water flow low limit in [m3/h]
public virtual float Qto { get; set; } /// Water flow high limit in [m3/h]
public virtual float Volume { get; set; } /// Test volume (target) in [l]
public virtual float TestTime { get; set; } /// Test time (estimate) in [s]
public virtual string Method { get; set; }
public virtual float ErrLimLo { get; set; } /// in [%] usually < 0, in case of heat meters: 1=class1, 2=class2, 3=class3
public virtual float ErrLimHi { get; set; } /// in [%] usually > 0, in case of heat meters: -Qn in m3/h
@@ -35,10 +34,10 @@ namespace Config.Entities
public virtual int Repeats { get; set; }
public virtual bool DoDraining { get; set; }
public virtual bool DoDrainingAfter { get; set; }
public virtual bool DoControlWaterTemp { get; set; }
public virtual float TempLimLo { get; set; } /// Lower limit for the controlled temperature
public virtual float TempLimHi { get; set; } /// Upper limit for the controlled temperature
public virtual string TempControl { get; set; } /// Water temperature controller, null or empty = Do not control water temp
public virtual float PumpPower { get; set; } /// Power of the pump in [%] in the range 0 .. 100.0f, use values 0% and 100% for non-FM pumps
public virtual float PumpPower { get; set; } /// Power of the pump in [%] in the range 0 .. 100.0f, use values 0% and 100% for non-FM pumps
public virtual int MassRepeats { get; set; } /// Number of mass. measurements at the beginning/end of test, 0 = default (=5)
public virtual float MassSpread { get; set; } /// Max spread of mass. measurements at the beginning/end of test, 0 = default
public virtual MassMethod MassMethod { get; set; } /// method of mass. measurement at the beginning/end of test: false=slow (precise), true=using immediate mass measurement and evaluation
@@ -58,11 +57,6 @@ namespace Config.Entities
public virtual string TransBetween { get; set; }
public virtual string TransAfter { get; set; }
public virtual IList<ComponentTest> MoreParams { get; set; }
public virtual Procedure Procedure { get; set; }
/// Additional stuff not mapped into the database
public virtual bool IsOuterLoopStart { get; set; } /// Not mapped to database
public virtual bool IsOuterLoopEnd { get; set; } /// Not mapped to database
@@ -78,17 +72,12 @@ namespace Config.Entities
public virtual Unit TempUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual Unit PressUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual Unit LengthUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual Unit ElectricUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
/// Wrappers
public virtual double QfromM3ph()
{
return !IsFromToInPct ? Qfrom : Qtg >= 0 ? Qtg * Qfrom / 100 : 0;
}
public virtual double QtoM3ph()
{
return !IsFromToInPct ? Qto : Qtg >= 0 ? Qtg * Qto / 100 : 0;
}
public virtual IList<ComponentTest> MoreParams { get; set; }
public virtual Procedure Procedure { get; set; }
/// ------------- Additional stuff not mapped into the database -------------
public Test()
{
@@ -101,16 +90,15 @@ namespace Config.Entities
Profile = TestProfile.UserDefined;
Publish = (sbyte)Common.Publish.Always;
DoEvaluate = true;
IsFromToInPct = false;
ErrLimLo = -2.0f; /// [%] lower error limit
ErrLimHi = 2.0f; /// [%] upper error limit
Uncertainty = 0;
Repeats = 1;
Repeats = 1;
DoDraining = false;
DoDrainingAfter = false;
DoControlWaterTemp = false;
TempLimLo = 15.0f;
TempLimHi = 25.0f;
TempControl = string.Empty;
ErrLimLo = -2.0f; /// [%] lower error limit
ErrLimHi = 2.0f; /// [%] upper error limit
Uncertainty = 0;
PumpPower = 60.0f; /// [%]
MassRepeats = 0; /// default
MassSpread = 0; /// default
@@ -171,8 +159,7 @@ namespace Config.Entities
result.Qtg = Qtg;
result.Qfrom = Qfrom;
result.Qto = Qto;
result.IsFromToInPct = IsFromToInPct;
result.Volume = Volume;
result.Volume = Volume;
result.TestTime = TestTime;
result.Method = Method;
result.ErrLimLo = ErrLimLo;
@@ -181,10 +168,10 @@ namespace Config.Entities
result.Repeats = Repeats;
result.DoDraining = DoDraining;
result.DoDrainingAfter = DoDrainingAfter;
result.DoControlWaterTemp = DoControlWaterTemp;
result.TempLimLo = TempLimLo;
result.TempLimHi = TempLimHi;
result.TempControl = TempControl;
result.PumpPower = PumpPower;
result.PumpPower = PumpPower;
result.MassRepeats = MassRepeats;
result.MassSpread = MassSpread;
result.MassMethod = MassMethod;
@@ -205,12 +192,10 @@ namespace Config.Entities
result.TransAfter = TransAfter;
result.VolumeUnit = VolumeUnit;
result.FlowUnit = FlowUnit;
result.FlowUnit = FlowUnit;
result.MassUnit = MassUnit;
result.TempUnit = TempUnit;
result.PressUnit = PressUnit;
result.LengthUnit = LengthUnit;
result.ElectricUnit = ElectricUnit;
foreach (var prms in MoreParams) { result.MoreParams.Add(prms.Clone()); }
return result;
@@ -227,7 +212,6 @@ namespace Config.Entities
output.WriteLine(Qtg.ToString(ci));
output.WriteLine(Qfrom.ToString(ci));
output.WriteLine(Qto.ToString(ci));
output.WriteLine(IsFromToInPct.ToString());
output.WriteLine(Volume.ToString(ci));
output.WriteLine(TestTime.ToString(ci));
output.WriteLine(Method);
@@ -237,10 +221,10 @@ namespace Config.Entities
output.WriteLine(Repeats.ToString(ci));
output.WriteLine(DoDraining.ToString());
output.WriteLine(DoDrainingAfter.ToString());
output.WriteLine(DoControlWaterTemp.ToString());
output.WriteLine(TempLimLo.ToString(ci));
output.WriteLine(TempLimHi.ToString(ci));
output.WriteLine((TempControl != null) ? TempControl : string.Empty);
output.WriteLine(PumpPower.ToString(ci));
output.WriteLine(PumpPower.ToString(ci));
output.WriteLine(MassRepeats.ToString(ci));
output.WriteLine(MassSpread.ToString(ci));
output.WriteLine(((byte)MassMethod).ToString(ci));
@@ -277,12 +261,11 @@ namespace Config.Entities
tst.Part = int.Parse(input.ReadLine(), ci);
tst.Publish = sbyte.Parse(input.ReadLine(), ci);
tst.DoEvaluate = bool.Parse(input.ReadLine());
tst.Qtg = double.Parse(input.ReadLine(), ci);
tst.Qfrom = double.Parse(input.ReadLine(), ci);
tst.Qto = double.Parse(input.ReadLine(), ci);
tst.IsFromToInPct = bool.Parse(input.ReadLine());
tst.Volume = double.Parse(input.ReadLine(), ci);
tst.TestTime = double.Parse(input.ReadLine(), ci);
tst.Qtg = float.Parse(input.ReadLine(), ci);
tst.Qfrom = float.Parse(input.ReadLine(), ci);
tst.Qto = float.Parse(input.ReadLine(), ci);
tst.Volume = float.Parse(input.ReadLine(), ci);
tst.TestTime = float.Parse(input.ReadLine(), ci);
tst.Method = input.ReadLine();
tst.ErrLimLo = float.Parse(input.ReadLine(), ci);
tst.ErrLimHi = float.Parse(input.ReadLine(), ci);
@@ -290,10 +273,10 @@ namespace Config.Entities
tst.Repeats = int.Parse(input.ReadLine(), ci);
tst.DoDraining = bool.Parse(input.ReadLine());
tst.DoDrainingAfter = bool.Parse(input.ReadLine());
tst.DoControlWaterTemp = bool.Parse(input.ReadLine());
tst.TempLimLo = float.Parse(input.ReadLine(), ci);
tst.TempLimHi = float.Parse(input.ReadLine(), ci);
tst.TempControl = input.ReadLine();
tst.PumpPower = float.Parse(input.ReadLine(), ci);
tst.PumpPower = float.Parse(input.ReadLine(), ci);
tst.MassRepeats = int.Parse(input.ReadLine(), ci);
tst.MassSpread = float.Parse(input.ReadLine(), ci);
tst.MassMethod = (MassMethod)byte.Parse(input.ReadLine(), ci);
@@ -310,11 +293,8 @@ namespace Config.Entities
tst.TransBetween = input.ReadLine();
string line = input.ReadLine();
tst.Profile = line.Equals(TestProfile.ProtectedHeatMeter.ToString()) ? TestProfile.ProtectedHeatMeter
: line.Equals(TestProfile.ProtectedCompound.ToString()) ? TestProfile.ProtectedCompound
: line.Equals(TestProfile.Protected.ToString()) ? TestProfile.Protected
: line.Equals(TestProfile.UserDefinedHeatMeter.ToString()) ? TestProfile.UserDefinedHeatMeter
: line.Equals(TestProfile.UserDefinedCompound.ToString()) ? TestProfile.UserDefinedCompound
: TestProfile.UserDefined; /// UserDefined is the default
: line.Equals(TestProfile.UserDefinedHeatMeter.ToString()) ? TestProfile.UserDefinedHeatMeter
: line.Equals(TestProfile.Protected.ToString()) ? TestProfile.Protected : TestProfile.UserDefined; /// UserDefined is the default
tst.TransAfter = input.ReadLine();
while (true)
@@ -347,7 +327,6 @@ namespace Config.Entities
ln = inp.ReadLine(); if (ln != Qtg.ToString(ci)) { diff.AppendFormat(fmt, "Qtg", Qtg.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != Qfrom.ToString(ci)) { diff.AppendFormat(fmt, "Qfrom", Qfrom.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != Qto.ToString(ci)) { diff.AppendFormat(fmt, "Qto", Qto.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != IsFromToInPct.ToString()) { diff.AppendFormat(fmt, "IsFromToInPct", IsFromToInPct.ToString(), ln); };
ln = inp.ReadLine(); if (ln != Volume.ToString(ci)) { diff.AppendFormat(fmt, "Volume", Volume.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != TestTime.ToString(ci)) { diff.AppendFormat(fmt, "TstTime", TestTime.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != Method) { diff.AppendFormat(fmt, "Method", Method, ln); };
@@ -355,11 +334,11 @@ namespace Config.Entities
ln = inp.ReadLine(); if (ln != ErrLimHi.ToString(ci)) { diff.AppendFormat(fmt, "ErrLimHi", ErrLimHi.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != Uncertainty.ToString(ci)) { diff.AppendFormat(fmt, "Uncertainty", Uncertainty.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != Repeats.ToString(ci)) { diff.AppendFormat(fmt, "Repeats", Repeats.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != DoDraining.ToString()) { diff.AppendFormat(fmt, "DoDraining", DoDraining.ToString(), ln); };
ln = inp.ReadLine(); if (ln != DoDrainingAfter.ToString()) { diff.AppendFormat(fmt, "DoDrainingAfter", DoDrainingAfter.ToString(), ln); };
ln = inp.ReadLine(); if (ln != DoDraining.ToString(ci)) { diff.AppendFormat(fmt, "DoDraining", DoDraining.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != DoDrainingAfter.ToString(ci)) { diff.AppendFormat(fmt, "DoDrainingAfter", DoDrainingAfter.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != DoControlWaterTemp.ToString()) { diff.AppendFormat(fmt, "DoControlWaterTemp", DoControlWaterTemp.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != TempLimLo.ToString(ci)) { diff.AppendFormat(fmt, "TempLimLo", TempLimLo.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != TempLimHi.ToString(ci)) { diff.AppendFormat(fmt, "TempLimHi", TempLimHi.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != TempControl) { diff.AppendFormat(fmt, "TempController", TempControl, ln); };
ln = inp.ReadLine(); if (ln != PumpPower.ToString(ci)) { diff.AppendFormat(fmt, "PumpPower", PumpPower.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != MassRepeats.ToString(ci)) { diff.AppendFormat(fmt, "MassRepeats", MassRepeats.ToString(ci), ln); };
ln = inp.ReadLine(); if (ln != MassSpread.ToString(ci)) { diff.AppendFormat(fmt, "MassSpread", MassSpread.ToString(ci), ln); };
+2 -2
View File
@@ -157,14 +157,14 @@ namespace Config.Entities
/// <returns></ returns>
public virtual bool IsPasswordExpired()
{
if (IsPowerUser() || IsMemberOf(GID.Administrators) || CurrentUser.PasswdExpirationPeriodDays == 0)
if (IsPowerUser() || IsMemberOf(GID.Administrators) || GlobalData.PasswdExpirationPeriodDays == 0)
{
/// Password cannot expirate for this user or this feature is disabled in Backup and Security options
return false;
}
/// Password expiration time is 3 months
return (DateTime.Now - LastPwChange > new TimeSpan(CurrentUser.PasswdExpirationPeriodDays, 0, 0, 0));
return (DateTime.Now - LastPwChange > new TimeSpan(GlobalData.PasswdExpirationPeriodDays, 0, 0, 0));
}
/// <summary>
+8 -9
View File
@@ -28,13 +28,13 @@ namespace Config
switch (dbType)
{
default:
case DBType.SQLite:
cfg = cfg.Database(SQLiteConfiguration.Standard.UsingFile(connectionString));
break;
case DBType.MySql:
cfg = cfg.Database(MySQLConfiguration.Standard.ConnectionString(connectionString));
break;
case DBType.SQLite:
cfg = cfg.Database(SQLiteConfiguration.Standard.UsingFile(connectionString));
break;
}
}
switch (database)
{
@@ -105,11 +105,11 @@ namespace Config
///
var admin = new Config.Entities.User
{
UserName = CurrentUser.AdminUsername,
UserName = GlobalData.AdminUsername,
FullName = Strings.Administrator,
LastPwChange = DateTime.Now
};
admin.SetPassword(CurrentUser.AdminPassword);
admin.SetPassword(GlobalData.AdminPassword);
///
/// Prepare all groups, add some of them to admin
@@ -128,11 +128,10 @@ namespace Config
case GID.Administrators:
#if TURA_IPERL || TURA_IPERL_NEW || TURA_SPECIAL
case GID.TraceabilityManagement:
//#elif LANG_PL
#endif
#elif KEMPNO_50 || KRAKOW_50 || TORUN_50 || WARSAW_END
case GID.MetrologicalAuthority:
case GID.WaterMeterAuthority:
#endif
admin.AddGroup(group);
session.SaveOrUpdate(group); /// Save this group
break;
-410
View File
@@ -1,410 +0,0 @@
///
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using log4net;
using Common;
//formulas.cs has been added cause iPerl from master-2 ...MF
namespace Config
{
public static class Formulas
{
private static readonly ILog log = LogManager.GetLogger(typeof(Formulas));
///
/// Wrappers
///
public static double RealDensity() { return Data.RealDensity; }
public static double AtTemperature() { return Data.AtTemperature; }
public static double Buoyancy() { return Data.Buoyancy; }
/// Private tables with coeficients to calculate specific enthalpy
static readonly int[] Ii;
static readonly int[] Ji;
static readonly double[] ni;
/// Private table with coeficients to calculate temperature of a platinum thermometer
static readonly double[] Di;
/// <summary>
/// Constructor
/// </summary>
static Formulas()
{
///
/// Initialize tables to calculate specific enthalpies
///
Ii = new int[34] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 8, 8, 21, 23, 29, 30, 31, 32 };
Ji = new int[34] { -2, -1, 0, 1, 2, 3, 4, 5, -9, -7, -1, 0, 1, 3, -3, 0, 1, 3, 17, -4, 0, 6, -5, -2, 10, -8, -11, -6, -29, -31, -38, -39, -40, -41 };
ni = new double[34] {
0.14632971213167, /// 1
-0.84548187169114, /// 2
-0.37563603672040E1, /// 3
0.33855169168385E1, /// 4
-0.95791963387872, /// 5
0.15772038513228, /// 6
-0.16616417199501E-1, /// 7
0.81214629983568E-3, /// 8
0.28319080123804E-3, /// 9
-0.60706301565874E-3, /// 10
-0.18990068218419E-1, /// 11
-0.32529748770505E-1, /// 12
-0.21841717175414E-1, /// 13
-0.52838357969930E-4, /// 14
-0.47184321073267E-3, /// 15
-0.30001780793026E-3, /// 16
0.47661393906987E-4, /// 17
-0.44141845330846E-5, /// 18
-0.72694996297594E-15, /// 19
-0.31679644845054E-4, /// 20
-0.28270797985312E-5, /// 21
-0.85205128120103E-9, /// 22
-0.22425281908000E-5, /// 23
-0.65171222895601E-6, /// 24
-0.14341729937924E-12, /// 25
-0.40516996860117E-6, /// 26
-0.12734301741641E-8, /// 27
-0.17424871230634E-9, /// 28
-0.68762131295531E-18, /// 29
0.14478307828521E-19, /// 30
0.26335781662795E-22, /// 31
-0.11947622640071E-22, /// 32
0.18228094581404E-23, /// 33
-0.93537087292458E-25, /// 34
};
///
/// Initialize a table to calculate temperature of a platinum thermometer from resistance
///
Di = new double[]
{
439.932854,
472.418020,
37.684494,
7.472018,
2.920828,
0.005184,
-0.963864,
-0.188732,
0.191203,
0.049025,
};
}
/// <summary>
/// Calculate density of distilled water from temperature
/// </summary>
/// <param name="t">ITS-90 temperature in [°C]</param>
/// <returns>Density in [kg/m3]</returns>
public static double DistilledWaterDensityFromTemp(double t)
{
if (t <= 40)
{
const double c0 = 999.839564;
const double c1 = 0.067998613;
const double c2 = -0.0091101468;
const double c3 = 0.00010058299;
const double c4 = -0.0000011275659;
const double c5 = 6.5985371e-09;
return ((((c5 * t + c4) * t + c3) * t + c2) * t + c1) * t + c0;
}
else
{
const double a0 = 9.9983952E2;
const double a1 = 1.6952577E1;
const double a2 = -7.9905127E-3;
const double a3 = -4.6241757E-5;
const double a4 = 1.0584601E-7;
const double a5 = -2.8103006E-10;
const double b = 1.6887236E-2;
return (((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t + a0) / (1.0 + b * t);
}
}
/// <summary>
/// Calculate density of distilled water from temperature (obsolete)
/// </summary>
/// <param name="t">IPTS-68 temperature in [°C]</param>
/// <returns>Density in [kg/m3]</returns>
public static double DistilledWaterDensityFromTempIPTS68(double t)
{
const double a0 = 999.842594;
const double a1 = 0.06793952;
const double a2 = -0.009095290;
const double a3 = 0.0001001685;
const double a4 = -0.000001120083;
const double a5 = 6.536332e-09;
return ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t + a0;
}
/// <summary>
/// Calculate density by comparing calculated data and data from a certificate
/// </summary>
/// <param name="realDensity">Density from a certificate in [kg/m3]</param>
/// <param name="atTemperature">Temperature from a certificate in [°C]</param>
/// <returns>Density correction in [kg/m3]</returns>
public static double DensityCorrection(double realDensity, double atTemperature)
{
/// Calculated data
double calculatedDensity = DistilledWaterDensityFromTemp(atTemperature);
return realDensity - calculatedDensity;
}
/// <summary>
/// Calculate corrected (real) water density from temperature
/// </summary>
/// <param name="t">Temperature in [°C]</param>
/// <returns>Density in [kg/m3]</returns>
public static double WaterDensityFromTemp(double t)
{
return DistilledWaterDensityFromTemp(t) + DensityCorrection(RealDensity(), AtTemperature());
}
/// <summary>
/// Calculate corrected (real) water density from temperature
/// </summary>
/// <param name="t">Temperature in [°C]</param>
/// <returns>Density in [kg/m3]</returns>
public static double WaterDensityFromTempPress(double temp, double pressure)
{
double x0 = 5.08821E-10;
double x1 = 1.2639418;
double x2 = 0.2660269;
double x3 = 0.3734838;
double x4 = 2.0205242;
double theta = temp / 100.0;
double B = x0 * (((x3 * theta + x2) * theta + x1) * theta + 1) / (1 + x4 * theta);
return WaterDensityFromTemp(temp) * (1 + B * Units.ConvertTo(Unit.Pa, pressure));
}
public static float AirDensityFromAmbientVales(float tempC, float pressureBar, float humiPct)
{
double pressurePa = 100000.0 * (double)pressureBar; /// [Pa]
double tempKelvin = 273.15 + (double)tempC;
double coef1 = 1.2811805 / 10000.0 * tempKelvin * tempKelvin
- 1.950987 / 100.0 * tempKelvin
+ 34.04926034
- 6.353631 * 1000.0 / tempKelvin;
double coef3 = humiPct / 100.0 * System.Math.Exp(coef1) / pressurePa;
double airDensityKgm3 = 0.00348353 * pressurePa * (1.0 - 0.378 * coef3) / tempKelvin; /// kg/m3
return (float)airDensityKgm3;
}
/// <summary>
/// Convert 'pulses' to 'volume', prevent division by zero
/// </summary>
public static double VolumeFromPulses(int pulses, double pulsesPerLiter)
{
if (pulsesPerLiter <= double.Epsilon) return 0;
return Convert.ToDouble(pulses) / pulsesPerLiter;
}
/// <summary>
/// Calculate the error in % from 'measured' and 'true' volume, prevent division by zero
/// </summary>
public static double ErrorFromVolumes(double measuredVolume, double trueVolume)
{
if (-float.Epsilon <= trueVolume && trueVolume <= float.Epsilon)
{
if (-float.Epsilon <= measuredVolume && measuredVolume <= float.Epsilon)
{
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, -100.0);
return -100.0;
}
log.WarnFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, 99.0);
return 99.0;
}
double error = 100.0 * (measuredVolume - trueVolume) / trueVolume;
log.InfoFormat("ErrorFromVolumes({0},{1}) returns {2}", measuredVolume, trueVolume, error);
return error;
}
/// <summary>
/// Calculates corrected value from a list of corrections by interpolation.
/// It is assumed that values in the list 'corrections' are sorted.
/// </summary>
/// <param name="rawMeasurement">Raw uncorrected value</param>
/// <param name="corrections">Sorted (value, correction) pairs</param>
/// <returns>Corrected value</returns>
public static double CorrectedValue(double rawValue, IList<IMeasurementCorrection> corrections)
{
return rawValue + GetCorrection(rawValue, corrections);
}
/// <summary>
/// Get a correction from a list of corrections by interpolation.
/// It is assumed that values in the list 'corrections' are sorted.
/// </summary>
/// <param name="rawMeasurement">Raw uncorrected value</param>
/// <param name="corrections">Sorted (value, correction) pairs</param>
/// <returns>Corrected value</returns>
public static double GetCorrection(double rawValue, IList<IMeasurementCorrection> corrections)
{
if ((corrections == null) || (corrections.Count == 0)) return 0; /// No correction
if (rawValue < corrections[0].Measurement)
{
/// rawValue is below the lowest value in the correction table
return corrections[0].Correction;
}
int count = corrections.Count;
for (int i = 1; i < count; i++)
{
if (rawValue < corrections[i].Measurement)
{
double d1 = rawValue - corrections[i - 1].Measurement;
double d2 = corrections[i].Measurement - rawValue;
if (d1 + d2 <= float.Epsilon)
{
/// Neigboring values in the corection table are close to each other -> calculate the average
return (corrections[i - 1].Correction + corrections[i].Correction) / 2.0;
}
else
{
/// Interpolate the correction from neigboring values in the corection table
return (corrections[i - 1].Correction * d2 + corrections[i].Correction * d1) / (d1 + d2);
}
}
}
/// rawValue is above the highest value in the correction table
return corrections[count - 1].Correction;
}
/// <summary>
/// Converts a measurement error to a correction (used when preparing correction tables).
/// </summary>
/// <param name="measuredValue">Measured value (in arbitrary units)</param>
/// <param name="error">Measurement error in %</param>
/// <returns>Correction in the same units as the measured value</returns>
public static double CorrectionFromError(double measuredValue, double error)
{
double trueValue = measuredValue / (1 + error/100);
double correction = trueValue - measuredValue;
return correction;
}
/// <summary>
/// Calculates the heat coefficient for water
/// </summary>
/// <param name="pressure">Pressure [bar]</param>
/// <param name="T_in">Inlet temperature [°C]</param>
/// <param name="T_out">Outlet temperature [°C]</param>
/// <param name="flowMeasuredAtInlet">true = flow measured @inlet, false = flow measured @outlet</param>
/// <returns> Heat coefficient for water [J/(m3 K)]</returns>
public static double HeatCoefficientWater(double pressure, double T_in, double T_out, bool flowMeasuredAtInlet)
{
if (T_in == T_out) return 0;
const double R = 461.526; /// [J kg^-1 K^-1]
const double p_star_Pa = 16.53E6; /// [Pa] (=16.53 MPa)
const double T_star = 1386.0; /// [K]
double T_in_K = Units.ConvertTo(Unit.K, T_in);
double T_out_K = Units.ConvertTo(Unit.K, T_out);
double tau_in = T_star / T_in_K;
double tau_out = T_star / T_out_K;
double pi = Units.ConvertTo(Unit.Pa, pressure) / p_star_Pa;
double h_in = tau_in * GammaTau(pi, tau_in) * R * T_in_K;
double h_out = tau_out * GammaTau(pi, tau_out) * R * T_out_K;
double ni = flowMeasuredAtInlet ? GammaPi(pi, tau_in) * R * T_in_K / p_star_Pa
: GammaPi(pi, tau_out) * R * T_out_K / p_star_Pa;
return (h_in - h_out) / (ni * (T_in - T_out));
}
/// <summary>
/// gamma(pi) see also STN EN 1434-1 Annex A (A.4)
/// </summary>
/// <param name="pi">pi = p / p* where p* = 16.53 MPa</param>
/// <param name="tau">tau = T* / T where T* = 1386 K</param>
/// <returns>gamma(pi)</returns>
static double GammaPi(double pi, double tau)
{
double result = 0;
for (int i = 0; i < 34; i++)
{
result -= ni[i] * Ii[i] * Math.Pow(7.1 - pi, Ii[i] - 1) * Math.Pow(tau - 1.222, Ji[i]);
}
return result;
}
/// <summary>
/// gamma(tau) see also STN EN 1434-1 Annex A (A.7)
/// </summary>
/// <param name="pi">pi = p / p* where p* = 16.53 MPa</param>
/// <param name="tau">tau = T* / T where T* = 1386 K</param>
/// <returns>gamma(tau)</returns>
static double GammaTau(double pi, double tau)
{
double result = 0;
for (int i = 0; i < 34; i++)
{
result += ni[i] * Math.Pow(7.1 - pi, Ii[i]) * Ji[i] * Math.Pow(tau - 1.222, Ji[i] - 1);
}
return result;
}
/// <summary>
/// Conversion of measured resistance of a platinum thermometer to temperature according to ITS-90
/// </summary>
/// <param name="R">Measured resistance in [°C]</param>
/// <param name="R001C">Calibrated resistance in Ohm at 0.01°C</param>
/// <param name="a7">Calibrated ITS-90 coefficient a7</param>
/// <param name="b7">Calibrated ITS-90 coefficient b7</param>
/// <param name="c7">Calibrated ITS-90 coefficient c7</param>
/// <returns>Temperature in [°C]</returns>
public static double PlatinumResistanceTM_ITS90_R2T(double R, double R001C, double a7, double b7, double c7)
{
double w = R / R001C; /// ratio
double r1 = w - 1.0;
double dw = r1 * (a7 + r1 * (b7 + r1 * c7)); /// = a7*r1 + b7*r1^2 + c7*r1^3
double wr = w - dw;
double x = (wr - 2.64) / 1.64;
double sum = 0;
for (int i = Di.Length - 1; i >= 0; i--)
{
sum = sum * x + Di[i];
}
return sum;
}
/// <summary>
/// Conversion of measured resistance of a platinum thermometer to temperature using Callendar-Van Dusen equations
/// </summary>
/// <param name="R">Measured resistance in [°C]</param>
/// <param name="R0">Calibrated resistance in Ohm at 0°C</param>
/// <param name="A">Calibration coefficient a</param>
/// <param name="B">Calibration coefficient b</param>
/// <returns>Temperature in [°C]</returns>
public static double PlatinumResistanceTM_ITS27_R2T(double R, double R0, double A, double B)
{
if (R0 * R0 * A * A - 4 * R0 * B * (R0 - R) <= 0) return 0; /// Out of range
return (-(R0 * A) + Math.Sqrt(R0 * R0 * A * A - 4 * R0 * B * (R0 - R))) / (2 * R0 * B);
}
}
}
-3
View File
@@ -21,9 +21,6 @@ namespace Config.Mappings
Map(x => x.PressMtrUp);
Map(x => x.PressMtrDown);
Map(x => x.PressMtrDelta);
//Map(x => x.ElectricMtrUp);
//Map(x => x.ElectricMtrDown);
//Map(x => x.ElectricMtrDelta);
Map(x => x.StopBFValve);
Map(x => x.ValvesOpen)
.CustomType("StringClob")
+2 -2
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
/// Copyright (c) 2013-2019 Sensus Slovensko a.s.
///
using FluentNHibernate.Mapping;
using Config.Entities;
@@ -19,7 +19,7 @@ namespace Config.Mappings
Map(x => x.LogLevel);
Map(x => x.Parameters)
.CustomType("StringClob")
.CustomSqlType("varchar(12000)");
.CustomSqlType("varchar(8000)");
HasMany(x => x.Corrections)
.OrderBy("Measurement")
.Cascade.All();
+2 -4
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
/// Copyright (c) 2013-2015 Sensus Metering Systems
///
using FluentNHibernate.Mapping;
using Config.Entities;
@@ -17,14 +17,12 @@ namespace Config.Mappings
Map(x => x.Qto);
Map(x => x.Selector);
Map(x => x.RegValve);
Map(x => x.RegulMinStep).Nullable();//older databases may not have this column
Map(x => x.FlowMeter);
Map(x => x.FlowMeter);
Map(x => x.PidCoef);
Map(x => x.StartValve);
Map(x => x.Diverter);
Map(x => x.TempMtrDiv);
Map(x => x.Scale);
Map(x => x.RegVPositions);
Map(x => x.ValvesOpen)
.CustomType("StringClob")
.CustomSqlType("varchar(8000)");
+1 -3
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2019-2023 Sensus Slovensko a.s.
/// Copyright (c) 2019 Sensus Slovensko a.s.
///
using FluentNHibernate.Mapping;
using Config.Entities;
@@ -14,7 +14,6 @@ namespace Config.Mappings
Map(x => x.ItemNr);
Map(x => x.Name);
Map(x => x.Part);
Map(x => x.FlowId);
Map(x => x.CoefQfrom);
Map(x => x.CoefQto);
Map(x => x.ErrLimLo);
@@ -25,7 +24,6 @@ namespace Config.Mappings
Map(x => x.PressLimHi);
Map(x => x.Publish);
Map(x => x.Evaluate);
Map(x => x.Method);
Map(x => x.E1);
Map(x => x.E2);
Map(x => x.E3);
+4 -5
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2023 Sensus Slovensko a.s.
/// Copyright (c) 2013-2017 Sensus Metering Systems
///
using FluentNHibernate.Mapping;
using Config.Entities;
@@ -20,16 +20,15 @@ namespace Config.Mappings
Map(x => x.Qtg);
Map(x => x.Qfrom);
Map(x => x.Qto);
Map(x => x.IsFromToInPct);
Map(x => x.Volume);
Map(x => x.Volume);
Map(x => x.TestTime);
Map(x => x.Repeats);
Map(x => x.DoDraining);
Map(x => x.DoDrainingAfter);
Map(x => x.DoControlWaterTemp);
Map(x => x.TempLimLo);
Map(x => x.TempLimHi);
Map(x => x.TempControl);
Map(x => x.PumpPower);
Map(x => x.PumpPower);
Map(x => x.MassRepeats);
Map(x => x.MassSpread);
Map(x => x.MassMethod)
-7
View File
@@ -1,7 +0,0 @@
namespace Config
{
public class PurchaseResources
{
}
}
@@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
@@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Decrypt
{
if ((args.Length < 1) || !File.Exists(args[0]))
{
Console.WriteLine(@"Usage: Decode <file>");
Console.WriteLine("Usage: Decode <file>");
Console.ReadKey();
return;
}
+3 -2
View File
@@ -40,8 +40,9 @@
<StartupObject>DeviceTest.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
<Reference Include="log4net, Version=1.2.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
+15 -32
View File
@@ -423,7 +423,7 @@ namespace DeviceTest
{
parentCfg = parentFactory.DefaultConfig();
}
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
ComponentParametersDlg cfgForm = new ComponentParametersDlg();
cfgForm.CmpntEntities = new List<Config.Entities.Component>();
IComponentCfgCtrl cfgControl = parentCfg.GetControl(cfgForm.CmpntEntities);
@@ -452,7 +452,7 @@ namespace DeviceTest
{
component1Cfg = component1Factory.DefaultConfig();
}
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
ComponentParametersDlg cfgForm = new ComponentParametersDlg();
///
var compEntities = new List<Config.Entities.Component>();
if (parentFactory != null && parentCfg != null) compEntities.Add(parentCfg.CreateDbEntity());
@@ -486,7 +486,7 @@ namespace DeviceTest
{
component2Cfg = component2Factory.DefaultConfig();
}
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
ComponentParametersDlg cfgForm = new ComponentParametersDlg();
///
var compEntities = new List<Config.Entities.Component>();
if (parentFactory != null && parentCfg != null) compEntities.Add(parentCfg.CreateDbEntity());
@@ -521,7 +521,7 @@ namespace DeviceTest
{
component3Cfg = component3Factory.DefaultConfig();
}
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
ComponentParametersDlg cfgForm = new ComponentParametersDlg();
///
var compEntities = new List<Config.Entities.Component>();
if (parentFactory != null && parentCfg != null) compEntities.Add(parentCfg.CreateDbEntity());
@@ -678,16 +678,11 @@ namespace DeviceTest
{
operation1 = (tbfComponent1forOp as TBF.Rig.Network.Camera.Roi.Roi).RoiDetectionOp();
}
else if (tbfComponent1forOp is TBF.Rig.Modbus.TempControl.Easytherm.TControl)
else if (tbfComponent1forOp is TBF.Rig.Modbus.Easytherm.Easytherm)
{
operation1 = (tbfComponent1forOp as TBF.Rig.Modbus.TempControl.Easytherm.TControl).SetTemperatureSetpointOp(10);
operation2 = (tbfComponent1forOp as TBF.Rig.Modbus.TempControl.Easytherm.TControl).SetTemperatureSetpointOp(20);
operation1 = (tbfComponent1forOp as TBF.Rig.Modbus.Easytherm.Easytherm).SetTemperatureOp(10);
operation2 = (tbfComponent1forOp as TBF.Rig.Modbus.Easytherm.Easytherm).SetTemperatureOp(20);
}
else if (tbfComponent1forOp is TBF.Rig.Modbus.TempControl.Novus.TControl)
{
operation1 = (tbfComponent1forOp as TBF.Rig.Modbus.TempControl.Novus.TControl).SetTemperatureSetpointOp(10);
operation2 = (tbfComponent1forOp as TBF.Rig.Modbus.TempControl.Novus.TControl).SetTemperatureSetpointOp(20);
}
else if (tbfComponent1forOp is TBF.Rig.Modbus.UltrasoundLevelMeter.LevelMeter)
{
operation1 = (tbfComponent1forOp as TBF.Rig.Modbus.UltrasoundLevelMeter.LevelMeter).ReadLevelOp(ref dblBox1);
@@ -722,16 +717,11 @@ namespace DeviceTest
{
operation21 = (tbfComponent2forOp as TBF.Rig.Network.Camera.Roi.Roi).RoiDetectionOp();
}
else if (tbfComponent2forOp is TBF.Rig.Modbus.TempControl.Easytherm.TControl)
else if (tbfComponent2forOp is TBF.Rig.Modbus.Easytherm.Easytherm)
{
operation21 = (tbfComponent2forOp as TBF.Rig.Modbus.TempControl.Easytherm.TControl).SetTemperatureSetpointOp(10);
operation22 = (tbfComponent2forOp as TBF.Rig.Modbus.TempControl.Easytherm.TControl).SetTemperatureSetpointOp(20);
operation21 = (tbfComponent2forOp as TBF.Rig.Modbus.Easytherm.Easytherm).SetTemperatureOp(10);
operation22 = (tbfComponent2forOp as TBF.Rig.Modbus.Easytherm.Easytherm).SetTemperatureOp(20);
}
else if (tbfComponent2forOp is TBF.Rig.Modbus.TempControl.Novus.TControl)
{
operation21 = (tbfComponent2forOp as TBF.Rig.Modbus.TempControl.Novus.TControl).SetTemperatureSetpointOp(10);
operation22 = (tbfComponent2forOp as TBF.Rig.Modbus.TempControl.Novus.TControl).SetTemperatureSetpointOp(20);
}
else if (tbfComponent2forOp is TBF.Rig.Modbus.UltrasoundLevelMeter.LevelMeter)
{
operation21 = (tbfComponent2forOp as TBF.Rig.Modbus.UltrasoundLevelMeter.LevelMeter).ReadLevelOp(ref dblBox1);
@@ -766,16 +756,11 @@ namespace DeviceTest
{
operation31 = (tbfComponent3forOp as TBF.Rig.Network.Camera.Roi.Roi).RoiDetectionOp();
}
else if (tbfComponent3forOp is TBF.Rig.Modbus.TempControl.Easytherm.TControl)
{
operation31 = (tbfComponent3forOp as TBF.Rig.Modbus.TempControl.Easytherm.TControl).SetTemperatureSetpointOp(10);
operation32 = (tbfComponent3forOp as TBF.Rig.Modbus.TempControl.Easytherm.TControl).SetTemperatureSetpointOp(20);
}
else if (tbfComponent3forOp is TBF.Rig.Modbus.TempControl.Novus.TControl)
{
operation31 = (tbfComponent3forOp as TBF.Rig.Modbus.TempControl.Novus.TControl).SetTemperatureSetpointOp(10);
operation32 = (tbfComponent3forOp as TBF.Rig.Modbus.TempControl.Novus.TControl).SetTemperatureSetpointOp(20);
}
else if (tbfComponent3forOp is TBF.Rig.Modbus.Easytherm.Easytherm)
{
operation31 = (tbfComponent3forOp as TBF.Rig.Modbus.Easytherm.Easytherm).SetTemperatureOp(10);
operation32 = (tbfComponent3forOp as TBF.Rig.Modbus.Easytherm.Easytherm).SetTemperatureOp(20);
}
else if (tbfComponent3forOp is TBF.Rig.Modbus.UltrasoundLevelMeter.LevelMeter)
{
operation31 = (tbfComponent3forOp as TBF.Rig.Modbus.UltrasoundLevelMeter.LevelMeter).ReadLevelOp(ref dblBox1);
@@ -899,8 +884,6 @@ namespace DeviceTest
{
Cursor = Cursors.WaitCursor;
CurrentUser.Restore(this);
if (workerThread != null)
{
workerThreadRunning = false;
+2 -27
View File
@@ -1,28 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup></configuration>
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+1 -1
View File
@@ -18,7 +18,7 @@ namespace Encrypt
{
if ((args.Length < 1) || !File.Exists(args[0]))
{
Console.WriteLine(@"Usage: Encode <file>");
Console.WriteLine("Usage: Encode <file>");
Console.ReadKey();
return;
}
+1 -1
View File
@@ -291,7 +291,7 @@ namespace EventViewer
{
try
{
CurrentUser.RemoteUsersDB = new DBSettings(DBType.MySql, Program.LocalSettings.UsersDBConnString);
GlobalData.RemoteUsersDB = new DBSettings(DBType.MySql, Program.LocalSettings.UsersDBConnString);
SharedDatabase.Forms.LoginDlg dlg = new SharedDatabase.Forms.LoginDlg();
if (dlg.ShowDialog() == DialogResult.OK)
{
+69
View File
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5D9B49E3-CDF9-4A27-80B4-58141D0EB0E0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Events</RootNamespace>
<AssemblyName>Events</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentNHibernate">
<HintPath>..\packages\FluentNHibernate.2.0.3.0\lib\net40\FluentNHibernate.dll</HintPath>
</Reference>
<Reference Include="Iesi.Collections">
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="NHibernate">
<HintPath>..\packages\NHibernate.4.0.4.4000\lib\net40\NHibernate.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TBFTests")]
[assembly: AssemblyTitle("Events")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TBFTests")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyProduct("Events")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("77eb589f-c670-4489-aad6-2a3c02061fd1")]
[assembly: Guid("3a68150f-6cfc-4f15-a813-cef63bc8bb47")]
// Version information for an assembly consists of the following four values:
//
Binary file not shown.
+23 -206
View File
@@ -30,46 +30,21 @@
{
this.rawFileComboBox = new System.Windows.Forms.ComboBox();
this.browseButton = new System.Windows.Forms.Button();
this.processButton = new System.Windows.Forms.Button();
this.resultsTextBox = new System.Windows.Forms.TextBox();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
this.splitContainer3 = new System.Windows.Forms.SplitContainer();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.tabPage5 = new System.Windows.Forms.TabPage();
this.tabPage6 = new System.Windows.Forms.TabPage();
this.tabPage7 = new System.Windows.Forms.TabPage();
this.tabPage8 = new System.Windows.Forms.TabPage();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
this.splitContainer2.Panel1.SuspendLayout();
this.splitContainer2.Panel2.SuspendLayout();
this.splitContainer2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit();
this.splitContainer3.Panel1.SuspendLayout();
this.splitContainer3.Panel2.SuspendLayout();
this.splitContainer3.SuspendLayout();
this.tabControl1.SuspendLayout();
this.SuspendLayout();
//
// rawFileComboBox
//
this.rawFileComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.rawFileComboBox.FormattingEnabled = true;
this.rawFileComboBox.Location = new System.Drawing.Point(0, 0);
this.rawFileComboBox.Location = new System.Drawing.Point(29, 28);
this.rawFileComboBox.Name = "rawFileComboBox";
this.rawFileComboBox.Size = new System.Drawing.Size(1040, 21);
this.rawFileComboBox.Size = new System.Drawing.Size(715, 21);
this.rawFileComboBox.TabIndex = 0;
//
// browseButton
//
this.browseButton.Location = new System.Drawing.Point(7, 0);
this.browseButton.Location = new System.Drawing.Point(769, 19);
this.browseButton.Name = "browseButton";
this.browseButton.Size = new System.Drawing.Size(66, 37);
this.browseButton.TabIndex = 1;
@@ -77,184 +52,37 @@
this.browseButton.UseVisualStyleBackColor = true;
this.browseButton.Click += new System.EventHandler(this.browseButton_Click);
//
// processButton
//
this.processButton.Location = new System.Drawing.Point(29, 66);
this.processButton.Name = "processButton";
this.processButton.Size = new System.Drawing.Size(91, 46);
this.processButton.TabIndex = 2;
this.processButton.Text = "Process";
this.processButton.UseVisualStyleBackColor = true;
this.processButton.Click += new System.EventHandler(this.processButton_Click);
//
// resultsTextBox
//
this.resultsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.resultsTextBox.Location = new System.Drawing.Point(0, 0);
this.resultsTextBox.Location = new System.Drawing.Point(29, 131);
this.resultsTextBox.Multiline = true;
this.resultsTextBox.Name = "resultsTextBox";
this.resultsTextBox.Size = new System.Drawing.Size(1127, 156);
this.resultsTextBox.Size = new System.Drawing.Size(715, 181);
this.resultsTextBox.TabIndex = 3;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.splitContainer2);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.tabControl1);
this.splitContainer1.Size = new System.Drawing.Size(1127, 733);
this.splitContainer1.SplitterDistance = 200;
this.splitContainer1.TabIndex = 4;
//
// splitContainer2
//
this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer2.Location = new System.Drawing.Point(0, 0);
this.splitContainer2.Name = "splitContainer2";
this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer2.Panel1
//
this.splitContainer2.Panel1.Controls.Add(this.splitContainer3);
//
// splitContainer2.Panel2
//
this.splitContainer2.Panel2.Controls.Add(this.resultsTextBox);
this.splitContainer2.Size = new System.Drawing.Size(1127, 200);
this.splitContainer2.SplitterDistance = 40;
this.splitContainer2.TabIndex = 3;
//
// splitContainer3
//
this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer3.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.splitContainer3.Location = new System.Drawing.Point(0, 0);
this.splitContainer3.Name = "splitContainer3";
//
// splitContainer3.Panel1
//
this.splitContainer3.Panel1.Controls.Add(this.rawFileComboBox);
//
// splitContainer3.Panel2
//
this.splitContainer3.Panel2.Controls.Add(this.browseButton);
this.splitContainer3.Size = new System.Drawing.Size(1127, 40);
this.splitContainer3.SplitterDistance = 1040;
this.splitContainer3.TabIndex = 0;
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Controls.Add(this.tabPage4);
this.tabControl1.Controls.Add(this.tabPage5);
this.tabControl1.Controls.Add(this.tabPage6);
this.tabControl1.Controls.Add(this.tabPage7);
this.tabControl1.Controls.Add(this.tabPage8);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(1127, 529);
this.tabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(1119, 503);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "OffsetV";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tabPage2
//
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(1119, 503);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "KOhmsR";
this.tabPage2.UseVisualStyleBackColor = true;
//
// tabPage3
//
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(1119, 503);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "KOhmsC";
this.tabPage3.UseVisualStyleBackColor = true;
//
// tabPage4
//
this.tabPage4.Location = new System.Drawing.Point(4, 22);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Size = new System.Drawing.Size(1119, 503);
this.tabPage4.TabIndex = 3;
this.tabPage4.Text = "DutFlowLph";
this.tabPage4.UseVisualStyleBackColor = true;
//
// tabPage5
//
this.tabPage5.Location = new System.Drawing.Point(4, 22);
this.tabPage5.Name = "tabPage5";
this.tabPage5.Size = new System.Drawing.Size(1119, 503);
this.tabPage5.TabIndex = 4;
this.tabPage5.Text = "RefFlowLph";
this.tabPage5.UseVisualStyleBackColor = true;
//
// tabPage6
//
this.tabPage6.Location = new System.Drawing.Point(4, 22);
this.tabPage6.Name = "tabPage6";
this.tabPage6.Size = new System.Drawing.Size(1119, 503);
this.tabPage6.TabIndex = 5;
this.tabPage6.Text = "FlowRatio";
this.tabPage6.UseVisualStyleBackColor = true;
//
// tabPage7
//
this.tabPage7.Location = new System.Drawing.Point(4, 22);
this.tabPage7.Name = "tabPage7";
this.tabPage7.Size = new System.Drawing.Size(1119, 503);
this.tabPage7.TabIndex = 6;
this.tabPage7.Text = "MagField";
this.tabPage7.UseVisualStyleBackColor = true;
//
// tabPage8
//
this.tabPage8.Location = new System.Drawing.Point(4, 22);
this.tabPage8.Name = "tabPage8";
this.tabPage8.Size = new System.Drawing.Size(1119, 503);
this.tabPage8.TabIndex = 7;
this.tabPage8.Text = "EmfV";
this.tabPage8.UseVisualStyleBackColor = true;
//
// CalculatorWnd
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1127, 733);
this.Controls.Add(this.splitContainer1);
this.ClientSize = new System.Drawing.Size(859, 335);
this.Controls.Add(this.resultsTextBox);
this.Controls.Add(this.processButton);
this.Controls.Add(this.browseButton);
this.Controls.Add(this.rawFileComboBox);
this.Name = "CalculatorWnd";
this.Text = "Feature vector calculator";
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.splitContainer2.Panel1.ResumeLayout(false);
this.splitContainer2.Panel2.ResumeLayout(false);
this.splitContainer2.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
this.splitContainer2.ResumeLayout(false);
this.splitContainer3.Panel1.ResumeLayout(false);
this.splitContainer3.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit();
this.splitContainer3.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
@@ -262,19 +90,8 @@
private System.Windows.Forms.ComboBox rawFileComboBox;
private System.Windows.Forms.Button browseButton;
private System.Windows.Forms.Button processButton;
private System.Windows.Forms.TextBox resultsTextBox;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.SplitContainer splitContainer2;
private System.Windows.Forms.SplitContainer splitContainer3;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.TabPage tabPage4;
private System.Windows.Forms.TabPage tabPage5;
private System.Windows.Forms.TabPage tabPage6;
private System.Windows.Forms.TabPage tabPage7;
private System.Windows.Forms.TabPage tabPage8;
}
}
+34 -93
View File
@@ -4,20 +4,13 @@
using System;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Common.Iperl;
using System.Globalization;
using System.Drawing;
namespace FeatureVectorCalculator
{
public partial class CalculatorWnd : Form
{
public const int MaxOptoDataCount = 40000;
public const bool Downsample = true;
public const bool Extend = true;
OptoTelegramRaw[] optoData;
Int64 volumeRawExtLast;
Int64 timestampExtLast;
@@ -34,115 +27,63 @@ namespace FeatureVectorCalculator
}
}
void ClearOutput()
{
resultsTextBox.Clear();
tabControl1.TabPages[0].Controls.Clear();
tabControl1.TabPages[1].Controls.Clear();
tabControl1.TabPages[2].Controls.Clear();
tabControl1.TabPages[3].Controls.Clear();
tabControl1.TabPages[4].Controls.Clear();
tabControl1.TabPages[5].Controls.Clear();
tabControl1.TabPages[6].Controls.Clear();
tabControl1.TabPages[7].Controls.Clear();
}
private void browseButton_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
rawFileComboBox.Text = ofd.FileName;
ProcessRawDataFile(ofd.FileName);
}
var dr = ofd.ShowDialog();
rawFileComboBox.Text = ofd.FileName;
}
void ProcessRawDataFile(string fileName)
private void processButton_Click(object sender, EventArgs e)
{
if (optoData == null) return;
int counter = 0;
int startIx = -1;
int endIx = -1;
ClearOutput();
resultsTextBox.Text = string.Format("File name: {0}{1}", fileName, Environment.NewLine);
try
using (StreamReader reader = new StreamReader(rawFileComboBox.Text))
{
using (StreamReader reader = new StreamReader(fileName))
string line;
while ((line = reader.ReadLine()) != null && counter < MaxOptoDataCount)
{
string line;
while ((line = reader.ReadLine()) != null && counter < MaxOptoDataCount)
int ix = line.IndexOf(" :\t");
if (ix >= 0)
{
int ix = line.IndexOf(" :\t");
string[] items = line.Split('\t');
if (items.Length > 18)
if (optoData[counter].UpdateFromString(line.Substring(ix + 3), counter, 0, ref volumeRawExtLast, ref timestampExtLast, true))
{
string telegram = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\r\n",
items[2], items[3], items[4], items[5], items[6], items[7], items[8]);
if (optoData[counter].UpdateFromString(telegram, counter, 0, ref volumeRawExtLast, ref timestampExtLast))
if (line.EndsWith("#### start test ####"))
{
if (line.EndsWith("#### start test ####"))
{
startIx = counter;
optoData[counter].Flags = OptoTelegramFlags.OK_TestStart;
}
else if (line.EndsWith("#### end of test ####"))
{
endIx = counter;
optoData[counter].Flags = OptoTelegramFlags.OK_TestEnd;
}
else
{
optoData[counter].Flags = OptoTelegramFlags.OK;
}
startIx = counter;
optoData[counter].Flags = OptoTelegramFlags.OK_TestStart;
}
else if (line.EndsWith("#### end of test ####"))
{
endIx = counter;
optoData[counter].Flags = OptoTelegramFlags.OK_TestEnd;
}
optoData[counter].RefFlow = float.Parse(items[15].Replace(',', '.'), CultureInfo.InvariantCulture);
}
else
{
optoData[counter].Flags = OptoTelegramFlags.InvalidTelegram;
}
counter++;
}
else
{
optoData[counter].Flags = OptoTelegramFlags.InvalidTelegram;
}
reader.Close();
counter++;
}
reader.Close();
}
catch (Exception exc)
float[] featureVector = new float[9];
Common.Utils.CalculateFeatureVector(optoData, counter, startIx, endIx, ref featureVector);
resultsTextBox.Clear();
for (int i = 0; i < 9; i++)
{
MessageBox.Show(string.Format("Exception: {0}", exc.Message));
return;
resultsTextBox.Text += string.Format("X{0} = {1}\r\n", i + 1, featureVector[i]);
}
int start = Extend ? 0 : startIx;
int end = Extend ? (counter - 1) : endIx;
float[] offsetV, kOhmsR, kOhmsC, dutFlow, refFlow, flowRatio, magField, emfV;
PointF[] outliers, extendedOutliers;
float[] featureVector = Common.StatisticalMetrics.Calculate(optoData, counter, start, end, Downsample,
out offsetV, out kOhmsR, out kOhmsC, out dutFlow,
out refFlow, out flowRatio, out magField, out emfV,
out outliers, out extendedOutliers);
for (int i = 0; i < Math.Min(9, featureVector.Length); i++)
{
resultsTextBox.Text += string.Format("X{0} = {1}{2}", i + 1, featureVector[i], Environment.NewLine);
}
float period = Downsample ? 0.5F : 0.125F;
if (offsetV != null) tabControl1.TabPages[0].Controls.Add(SignalChart.GetChart(offsetV, period, "OffsetV", "OffsetV [μV]"));
if (kOhmsR != null) tabControl1.TabPages[1].Controls.Add(SignalChart.GetChart(kOhmsR, period, "kOhmsR", "kΩ"));
if (kOhmsC != null) tabControl1.TabPages[2].Controls.Add(SignalChart.GetChart(kOhmsC, period, "kOhmsC", "kΩ"));
if (dutFlow != null) tabControl1.TabPages[3].Controls.Add(SignalChart.GetChart(dutFlow, period, "dutFlow", "L/h"));
if (refFlow != null) tabControl1.TabPages[4].Controls.Add(SignalChart.GetChart(refFlow, period, "refFlow", "L/h"));
if (flowRatio != null) tabControl1.TabPages[5].Controls.Add(SignalChart.GetChart(flowRatio, period, "flowRatio", "", true, extendedOutliers, outliers));
if (magField != null) tabControl1.TabPages[6].Controls.Add(SignalChart.GetChart(magField, period, "magField", "μV", false));
if (emfV != null) tabControl1.TabPages[7].Controls.Add(SignalChart.GetChart(emfV, period, "emfV", "μV"));
}
}
}
@@ -37,7 +37,6 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms.DataVisualization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -56,7 +55,6 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SignalChart.cs" />
<EmbeddedResource Include="CalculatorWnd.resx">
<DependentUpon>CalculatorWnd.cs</DependentUpon>
</EmbeddedResource>
-108
View File
@@ -1,108 +0,0 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace FeatureVectorCalculator
{
public class SignalChart
{
public static Chart GetChart(float[] data, float period, string caption, string captionY, bool fromZero = true,
PointF[] extendedOutliers = null, PointF[] outliers = null)
{
Series series1 = null, series2 = null, series3 = null;
series1 = new Series { Name = caption, ChartArea = "area1", ChartType = SeriesChartType.Line, Color = Color.DeepSkyBlue };
float minY = float.MaxValue;
float maxY = float.MinValue;
for (int x = 0; x < data.Length; x++)
{
float y = data[x];
if (minY > y) minY = y;
if (maxY < y) maxY = y;
series1.Points.AddXY(x * period, y);
}
if (extendedOutliers != null)
{
series2 = new Series { Name = "extended outliers", ChartArea = "area1", ChartType = SeriesChartType.Point, Color = Color.Yellow };
for (int i = 0; i < extendedOutliers.Length; i++)
{
series2.Points.AddXY(extendedOutliers[i].X * period, extendedOutliers[i].Y);
}
}
if (outliers != null)
{
series3 = new Series { Name = "outliers", ChartArea = "area1", ChartType = SeriesChartType.Point, Color = Color.DarkRed };
for (int i = 0; i < outliers.Length; i++)
{
series3.Points.AddXY(outliers[i].X * period, outliers[i].Y);
}
}
ChartArea chArea = new ChartArea { Name = "area1" };
chArea.AxisX.Title = "Time [s]";
chArea.AxisX.IsLogarithmic = false;
chArea.AxisX.IsLabelAutoFit = true;
chArea.AxisX.Minimum = 0;
chArea.AxisX.Maximum = (data.Length - 1) * period;
// for (int j = i; j < i + 3; j++)
// {
// CustomLabel cl = new CustomLabel();
// cl.Text = string.Format("{0} {1}", xs[j], flowUnit.ToDescription());
// cl.FromPosition = Math.Log10(xs[j] * spacer);
// cl.ToPosition = Math.Log10(xs[j] / spacer);
// chArea.AxisX.CustomLabels.Add(cl);
// }
chArea.AxisY.Title = captionY;
chArea.AxisY.IsLogarithmic = false;
chArea.AxisY.IsLabelAutoFit = true;
if (!fromZero)
{
/// fromZero = false
chArea.AxisY.IsStartedFromZero = false;
float diff = maxY - minY;
chArea.AxisY.Minimum = minY - 0.05 * diff;
chArea.AxisY.Maximum = maxY + 0.05 * diff;
}
else if (minY >= 0)
{
/// fromZero = true, All points are above zero
chArea.AxisY.IsStartedFromZero = true;
chArea.AxisY.Minimum = 0;
chArea.AxisY.Maximum = 1.05 * maxY;
}
else if (maxY <= 0)
{
/// fromZero = true, All points are below zero
chArea.AxisY.IsStartedFromZero = true;
chArea.AxisY.Minimum = 1.05 * minY;
chArea.AxisY.Maximum = 0;
}
else
{
/// Points are both below and above zero
chArea.AxisY.IsStartedFromZero = false;
float diff = maxY - minY;
chArea.AxisY.Minimum = minY - 0.05 * diff;
chArea.AxisY.Maximum = maxY + 0.05 * diff;
}
if (chArea.AxisY.Maximum == chArea.AxisY.Minimum)
{
chArea.AxisY.Maximum = chArea.AxisY.Maximum + 1;
}
Chart chart = new Chart { Text = caption, Dock = DockStyle.Fill };
chart.ChartAreas.Add(chArea);
chart.Series.Add(series1);
if (series2 != null) chart.Series.Add(series2);
if (series3 != null) chart.Series.Add(series3);
return chart;
}
}
}
+1 -3
View File
@@ -35,7 +35,7 @@
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<OldToolsVersion>2.0</OldToolsVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
@@ -76,7 +76,6 @@
<WarningLevel>4</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
@@ -100,7 +99,6 @@
<WarningLevel>4</WarningLevel>
<DebugType>none</DebugType>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System">
+2 -2
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2019-2022 Sensus Slovensko a.s.
/// Copyright (c) 2019 Sensus Slovensko a.s.
///
using System;
using System.Drawing;
@@ -11,7 +11,7 @@ namespace GenericTest
Undefined = 0, /// Undefined (only used in OnActivity(..) when start/stop info message is issued)
SNisMissing, /// S/N is missing in the parsed record
SNisInvalid, /// S/N in the parsed record is invalid
NoRefRecordOrNoMatchingWorkflow, /// No record with this S/N in tracing DB or no matching workflow for this record
NoRecordAtAll, /// No record with this S/N in tracing DB
VerificationIsDisabled, /// ...
NoVerificationForThisProcess,
VerificationPassed, /// Verification of a previous record passed
+3 -8
View File
@@ -20,22 +20,17 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;LASER_NANJING</DefineConstants>
<DefineConstants>TRACE;DEBUG;RF_TEST_400_900</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;LASER_NANJING</DefineConstants>
<DefineConstants>TRACE;RF_TEST_400_900</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject>GenericTest.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentNHibernate">
@@ -49,7 +44,7 @@
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
+18 -17
View File
@@ -35,12 +35,12 @@
this.vertSplitContainer = new System.Windows.Forms.SplitContainer();
this.resultsGroupBox = new System.Windows.Forms.GroupBox();
this.activityListView = new System.Windows.Forms.ListView();
this.logoutButton = new System.Windows.Forms.Button();
this.startButton = new System.Windows.Forms.Button();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.filteredSensorValueLabel = new System.Windows.Forms.Label();
this.sensorNameLabel = new System.Windows.Forms.Label();
this.immediateSensorValueLabel = new System.Windows.Forms.Label();
this.logoutButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.horizSplitContainer)).BeginInit();
this.horizSplitContainer.Panel1.SuspendLayout();
this.horizSplitContainer.Panel2.SuspendLayout();
@@ -63,7 +63,7 @@
this.settingsButton.Name = "settingsButton";
this.settingsButton.Size = new System.Drawing.Size(90, 30);
this.settingsButton.TabIndex = 0;
this.settingsButton.Text = "Settings";
this.settingsButton.Text = "Nastavenia";
this.settingsButton.UseVisualStyleBackColor = true;
this.settingsButton.Click += new System.EventHandler(this.settingsButton_Click);
//
@@ -130,7 +130,7 @@
this.vertSplitContainer.Panel2.Controls.Add(this.startButton);
this.vertSplitContainer.Panel2.Controls.Add(this.stopButton);
this.vertSplitContainer.Size = new System.Drawing.Size(1033, 151);
this.vertSplitContainer.SplitterDistance = 945;
this.vertSplitContainer.SplitterDistance = 939;
this.vertSplitContainer.SplitterWidth = 1;
this.vertSplitContainer.TabIndex = 2;
//
@@ -140,7 +140,7 @@
this.resultsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.resultsGroupBox.Location = new System.Drawing.Point(0, 0);
this.resultsGroupBox.Name = "resultsGroupBox";
this.resultsGroupBox.Size = new System.Drawing.Size(945, 151);
this.resultsGroupBox.Size = new System.Drawing.Size(939, 151);
this.resultsGroupBox.TabIndex = 1;
this.resultsGroupBox.TabStop = false;
this.resultsGroupBox.Text = "Aktivita";
@@ -152,22 +152,11 @@
this.activityListView.Location = new System.Drawing.Point(3, 16);
this.activityListView.Name = "activityListView";
this.activityListView.Scrollable = false;
this.activityListView.Size = new System.Drawing.Size(939, 132);
this.activityListView.Size = new System.Drawing.Size(933, 132);
this.activityListView.TabIndex = 0;
this.activityListView.UseCompatibleStateImageBehavior = false;
this.activityListView.View = System.Windows.Forms.View.Details;
//
// logoutButton
//
this.logoutButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.logoutButton.Location = new System.Drawing.Point(1, 116);
this.logoutButton.Name = "logoutButton";
this.logoutButton.Size = new System.Drawing.Size(90, 30);
this.logoutButton.TabIndex = 13;
this.logoutButton.Text = "Logout";
this.logoutButton.UseVisualStyleBackColor = true;
this.logoutButton.Click += new System.EventHandler(this.logoutButton_Click);
//
// startButton
//
this.startButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
@@ -175,7 +164,7 @@
this.startButton.Name = "startButton";
this.startButton.Size = new System.Drawing.Size(90, 30);
this.startButton.TabIndex = 1;
this.startButton.Text = "Start";
this.startButton.Text = "Štart";
this.startButton.UseVisualStyleBackColor = true;
this.startButton.Click += new System.EventHandler(this.startButton_Click);
//
@@ -232,6 +221,17 @@
this.immediateSensorValueLabel.TabIndex = 1;
this.immediateSensorValueLabel.Text = "60.7 °C";
//
// logoutButton
//
this.logoutButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.logoutButton.Location = new System.Drawing.Point(1, 116);
this.logoutButton.Name = "logoutButton";
this.logoutButton.Size = new System.Drawing.Size(90, 30);
this.logoutButton.TabIndex = 13;
this.logoutButton.Text = "Logout";
this.logoutButton.UseVisualStyleBackColor = true;
this.logoutButton.Click += new System.EventHandler(this.logoutButton_Click);
//
// GenericTestDlg
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -239,6 +239,7 @@
this.ClientSize = new System.Drawing.Size(1164, 207);
this.Controls.Add(this.splitContainer1);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "GenericTestDlg";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "RF Power New / Oracle / Printing";
+131 -103
View File
@@ -1,11 +1,11 @@
///
/// Copyright (c) 2019-2022 Sensus Slovensko a.s.
/// Copyright (c) 2019 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.IO.Ports;
using System.Threading;
using System.Windows.Forms;
using log4net;
@@ -33,47 +33,46 @@ namespace GenericTest
#if RF_TEST
public RecordProcessing.RecordType RcrdType = RecordType.RF_Test;
public const string WorkflowStep = "rf_power";
public const string WorkflowStep = "RF_Power";
public const string DfltWorkplaceName = "RF Test";
#elif RF_TEST_400_900
public RecordProcessing.RecordType RcrdType = RecordType.RF_Test_400_900;
public const string WorkflowStep = "rf_power";
public const string WorkflowStep = "RF_Power";
public const string DfltWorkplaceName = "RF Test";
#elif COMM_TEST
public RecordProcessing.RecordType RcrdType = RecordType.CommTest;
public const string WorkflowStep = "comm_test";
public const string WorkflowStep = "Comm_Test";
public const string DfltWorkplaceName = "Comm Test";
#elif FLOWTUBE_TEST_HE
public RecordProcessing.RecordType RcrdType = RecordType.FlowtubeTestHe;
public const string WorkflowStep = "helium_test";
public const string WorkflowStep = "Helium_Test";
public const string DfltWorkplaceName = "Helium Test";
#elif FLOWTUBE_TEST_AIR
public RecordProcessing.RecordType RcrdType = RecordType.FlowtubeTestAir;
public const string WorkflowStep = "helium_test";
public const string WorkflowStep = "Helium_Test";
public const string DfltWorkplaceName = "Helium Test";
#elif LASER_NANJING
public RecordProcessing.RecordType RcrdType = RecordType.LaserNanjing;
public const string WorkflowStep = "laser";
public const string DfltWorkplaceName = "Laser 1";
#else
public RecordProcessing.RecordType RcrdType = RecordType.None;
public const string WorkflowStep = "generic_test";
public const string WorkflowStep = "Generic_Test";
public const string DfltWorkplaceName = "Generic Test";
#endif
const int ActivityMsgsCount = 7;
ActivityEventArgs[] activityEvents; /// Activity messages displayed in the main window
ActivityEventArgs[] activityEvents; /// Activity messages displayed in the main window
Common.Forms.ModelessForm modelessForm;
NHibernate.ISession dbSession; /// MySQL database session
static OracleConnection oracleConn; /// Oracle database connection (server is in Stara Tura)
NHibernate.ISession dbSession; /// MySQL database session
static OracleConnection oracleConn; /// Oracle database connection (server is in Stara Tura)
#if RF_TEST_400_900
static OracleConnection oracleConn2; /// Oracle database connection for Flexnet ID (server is in Ludwigshafen)
static OracleConnection oracleConn2; /// Oracle database connection for Flexnet ID (server is in Ludwigshafen)
#endif
IList<WorkflowSummary> workflowSummaries; /// Workflows from the database with last step verification information
DateTime lastUpdateOfWorkflows;
IList<Process> processes; /// Processes from the database
Dictionary<int, Process> processDictionary; /// Maps a process Id to a process
Dictionary<int, IList<Workstep>> workstepsDictionary; /// Maps a process Id to worksteps with name "RF_Power" (Count = 0 or 1)
static Dictionary<int, ScanVerificationInfo> verificationInfos;
/// Maps process Id to verification info
DateTime lastUpdateOfProcesses;
RecordProcessing.RecordProcessing recordProcessing;
@@ -95,30 +94,13 @@ namespace GenericTest
/// </summary>
public GenericTestDlg()
{
/// Open a modeless form that is closed after initialization and loading the main window
new Thread(() => Application.Run(new Common.Forms.ModelessForm("Načítavanie procesov z databázy"))).Start();
InitializeComponent();
try
{
string culture = Program.LocalSettings.Language.Replace('_', '-');
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(culture);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(culture);
}
catch (Exception exc)
{
string msg = exc.Message;
MessageBox.Show("Selected language is not supported.\nUsing English.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
}
Localize();
UpdateTitle();
/// Open a modeless form that is closed after initialization and loading the main window
modelessForm = new Common.Forms.ModelessForm("Loading workflows from a database");
new Thread(() => Application.Run(modelessForm)).Start();
activityEvents = new ActivityEventArgs[ActivityMsgsCount];
activityListView.Columns.Add(Strings.Time, 60);
#if FLOWTUBE_TEST_AIR || FLOWTUBE_TEST_HE
@@ -141,15 +123,6 @@ namespace GenericTest
ReadProcesses_RegisterWorkplace_Etc();
}
void Localize()
{
messageLabel.Text = string.IsNullOrEmpty(Program.LocalSettings.Workplace) ? "Laser" : Program.LocalSettings.Workplace;
startButton.Text = Strings.Start;
stopButton.Text = Strings.Stop;
settingsButton.Text = Strings.Settings;
logoutButton.Text = Strings.Logout;
}
private void GenericTestDlg_Load(object sender, EventArgs e)
{
Settings2UI();
@@ -160,7 +133,7 @@ namespace GenericTest
StarSensorReading();
}
if (modelessForm != null) modelessForm.CloseForm(); /// Close the modeless information form
Common.Forms.ModelessForm.CloseForm(); /// Close the modeless information form
}
private void startButton_Click(object sender, EventArgs e)
@@ -177,11 +150,13 @@ namespace GenericTest
private void settingsButton_Click(object sender, EventArgs e)
{
if (new LoginDlg(Program.SettingsAccessLevel, this).ShowDialog() == DialogResult.OK)
IUser oriUser = GlobalData.CurrentUser; /// Save the original user (= tester)
if (new LoginDlg(Program.SettingsAccessLevel).ShowDialog() == DialogResult.OK)
{
/// Logged in at 'TraceabilityManagement' level
CurrentUser.Restore(this); /// Restore the original user (= tester)
GlobalData.CurrentUser = oriUser; /// Restore the original user (= tester)
string oriWorkplace = Program.LocalSettings.Workplace;
///
@@ -194,7 +169,7 @@ namespace GenericTest
TracingDB.UnregisterWorkplaceObsolete(dbSession, oriWorkplace);
TracingDB.RegisterWorkplaceObsolete(dbSession,
Program.LocalSettings.Workplace,
CurrentUser.UserName(),
GlobalData.GetCurrentUserName(),
"1.2.3.4",
"<multiple>",
WorkflowStep,
@@ -594,8 +569,8 @@ namespace GenericTest
try
{
dbSession = TracingDB.CreateSession(Program.LocalSettings.ConnectionString);
workflowSummaries = TracingDB.ReadWorkflowSummariesFromDB(dbSession, WorkflowStep);
lastUpdateOfWorkflows = DateTime.Now;
processes = TracingDB.ReadWorkflowsFromDB(dbSession, WorkflowStep, out processDictionary, out workstepsDictionary, out verificationInfos);
lastUpdateOfProcesses = DateTime.Now;
}
catch (Exception exc)
{
@@ -713,14 +688,14 @@ namespace GenericTest
if (!string.IsNullOrEmpty(Program.LocalSettings.UsersDBConnString))
{
CurrentUser.LocalUsersDB = new DBSettings(DBType.MySql, Program.LocalSettings.UsersDBConnString);
GlobalData.LocalUsersDB = new DBSettings(DBType.MySql, Program.LocalSettings.UsersDBConnString);
}
UpdateTitle();
TracingDB.RegisterWorkplaceObsolete(dbSession,
Program.LocalSettings.Workplace,
CurrentUser.UserName(),
GlobalData.GetCurrentUserName(),
"1.2.3.4",
"<multiple>",
WorkflowStep,
@@ -758,13 +733,6 @@ namespace GenericTest
Program.LocalSettings.ArchiveFolder, true);
break;
case RecordType.LaserNanjing:
recordProcessing = new RecordProcessing.RecordProcessing(RecordType.LaserNanjing,
RecordPostproc.Move,
Program.LocalSettings.TestResultsFolder, false, "*.csv",
Program.LocalSettings.ArchiveFolder, true);
break;
case RecordType.None:
default:
recordProcessing = null;
@@ -830,9 +798,7 @@ namespace GenericTest
}
#endif
if (Program.LocalSettings.DoCheckSNsValidity &&
(Program.LocalSettings.ValidSNPrefixes != null)
&& !Program.LocalSettings.ValidSNPrefixes.Contains(testerRecord.SN.Substring(0, 3)))
if (Program.LocalSettings.DoCheckSNsValidity && (Program.LocalSettings.ValidSNPrefixes != null) && !Program.LocalSettings.ValidSNPrefixes.Contains(testerRecord.SN.Substring(0, 3)))
{
/// PCB number did not pass a validity check (is not on a list of valid PCB numbers)
verifState = VerifState.SNisInvalid;
@@ -844,6 +810,9 @@ namespace GenericTest
/// A valid serial number is available => proceed
///
ITransaction transaction = null;
string proc = null;
string order = null;
bool readingFromTracingDBFailed = false; /// Reading form tracing DB failed (equipment error)
bool savingToTracingDBFailed = false; /// Writing to tracoing DB failed (equipment error)
bool verificationFailed = false; /// Reading/writing from/to tracing DB OK, but verification failed (product error)
@@ -855,55 +824,110 @@ namespace GenericTest
transaction = dbSession.BeginTransaction();
/// Get a process of the last reference record with this PCB number
var refRecord = TracingDB.FindReferenceRecord(dbSession, testerRecord.SN, 1);
WorkflowSummary wSum = (refRecord == null) ? null :
workflowSummaries.FirstOrDefault(x => x.Workflow.Name == refRecord.Workflow);
proc = TracingDB.GetWorkflow(dbSession, testerRecord.SN, 1, out order);
if (refRecord == null || wSum == null)
/// Check if a record from the previous workplace exists
if (proc == null)
{
verifState = VerifState.NoRefRecordOrNoMatchingWorkflow;
verificationFailed = true;
savingToTracingDBFailed = false;
/// Any previous reference record with this s/n is missing => process cannot be determined
verifState = VerifState.NoRecordAtAll;
}
else if (!Program.LocalSettings.DoCheckPreviousTracingRecords)
{
/// The process was determined but checking previous records is disbled => everything is OK so far
verifState = VerifState.VerificationIsDisabled;
}
else
{
if (!Program.LocalSettings.DoCheckPreviousTracingRecords)
/// Process is known AND the system is checking previous records => verify previous step
/// Get an appropriate verification info
ScanVerificationInfo verInfo;
bool verInfoObtained = verificationInfos.TryGetValue(proc.Id, out verInfo);
if (!verInfoObtained && (DateTime.Now - lastUpdateOfProcesses) > new TimeSpan(0, 5, 0))
{
/// The process was determined but checking previous records is disbled => everything is OK so far
verifState = VerifState.VerificationIsDisabled;
verificationFailed = false;
/// No verification info was obtained and more then 5 minutes elapsed => read processes again
processes = TracingDB.ReadWorkflowsFromDB(dbSession, WorkflowStep, out processDictionary, out workstepsDictionary, out verificationInfos);
lastUpdateOfProcesses = DateTime.Now;
verInfoObtained = verificationInfos.TryGetValue(proc.Id, out verInfo);
}
if (!verInfoObtained)
{
/// No verification info for the process obtained from the reference record found
verifState = VerifState.NoVerificationForThisProcess;
}
else
{
/// Process is known AND the system is checking previous records => verify previous step
if (verInfo.VerifyReferencePart)
{
/// Fetch all GOOD reference records with given code
IList<ReferenceRecord> refRecords = dbSession.QueryOver<ReferenceRecord>()
.Where(rr => ((rr.Code1 == testerRecord.SN) && (rr.Result == 0)))
.And(rr => (rr.Workstep == verInfo.Workstep))
.JoinQueryOver<Workstep>(rr => rr.Workstep)
.Where(ws => (ws.ReferencePart.Id == verInfo.Part.Id))
.List();
StepRecord prevStep = refRecord.StepRecords.FirstOrDefault(x => (x.Workstep == wSum.PreviousWorkstepName && x.Result == 0));
verificationFailed = (prevStep == null);
verifState = (prevStep != null) ? VerifState.VerificationPassed : VerifState.VerificationFailed;
verifState = (refRecords.Count > 0) ? VerifState.VerificationPassed : VerifState.VerificationFailed;
}
else
{
IList<Record> records = dbSession.QueryOver<Record>()
.Where(rec => (rec.Code == testerRecord.SN))
.And(rec => (rec.Part == verInfo.Part))
.List();
verifState = (records.Count > 0) ? VerifState.VerificationPassed : VerifState.VerificationFailed;
}
}
/// result: 0=OK, 1=test failed, 2=OK but previous step is missing, 3=failed and previous step is missing
int result = ((testerRecord.Status == Status.Passed) ? 0 : 1) + ((verifState == VerifState.VerificationFailed) ? 2 : 0);
string workplace = Program.LocalSettings.Workplace;
string user = "user";
///
StepRecord stepRecord = new StepRecord(refRecord, wSum.WorkstepName, workplace, user, result);
refRecord.Timestamp = stepRecord.Timestamp;
refRecord.StepRecords.Add(stepRecord);
dbSession.SaveOrUpdate(stepRecord);
dbSession.SaveOrUpdate(refRecord);
transaction.Commit();
savingToTracingDBFailed = false;
}
verificationFailed = verifState == VerifState.NoRecordAtAll ||
verifState == VerifState.NoVerificationForThisProcess ||
verifState == VerifState.VerificationFailed;
///
savingToTracingDBFailed = true;
if ((proc != null) && (verifState != VerifState.NoRecordAtAll))
{
IList<Workstep> worksteps;
if (workstepsDictionary.TryGetValue(proc.Id, out worksteps) && (worksteps.Count == 1))
{
/// Save a new reference record to the production tracing DB
dbSession.SaveOrUpdate(new ReferenceRecord(order, proc, worksteps[0], testerRecord.SN,
GlobalData.GetCurrentUserName(),
Program.LocalSettings.Workplace,
verificationFailed ? 2 : ((testerRecord.Status == Status.Passed) ? 0 : 1)));
}
else
{
/// Save a reference record with WORKSTEP=null to the production tracing DB
dbSession.SaveOrUpdate(new ReferenceRecord(order, proc, null, testerRecord.SN,
GlobalData.GetCurrentUserName(),
Program.LocalSettings.Workplace,
verificationFailed ? 2 : ((testerRecord.Status == Status.Passed) ? 0 : 1)));
}
}
else
{
/// Save a reference record with PORDER=null, PROCESS=null and WORKSTEP=null to the production tracing DB
savingToTracingDBFailed = true;
dbSession.SaveOrUpdate(new ReferenceRecord(null, null, null, testerRecord.SN,
GlobalData.GetCurrentUserName(),
Program.LocalSettings.Workplace,
(testerRecord.Status == Status.Passed) ? 0 : 1));
}
transaction.Commit();
savingToTracingDBFailed = false;
}
catch (Exception)
{
readingFromTracingDBFailed = !savingToTracingDBFailed;
if ((transaction != null) && !transaction.WasCommitted) transaction.Rollback();
savingToTracingDBFailed = true;
}
///
/// Write the test result to Oracle DB
///
@@ -931,8 +955,8 @@ namespace GenericTest
///
bool printingFailed = false;
if (Program.LocalSettings.DoPrintLabels && testerRecord.CanPrintRecord()
&& (!Program.LocalSettings.DoPrintGoodLabelsOnly ||
!(savingToTracingDBFailed || verificationFailed || savingToOracleDBFailed || testerRecord.Status != Status.Passed)))
&& (!Program.LocalSettings.DoPrintGoodLabelsOnly || !(readingFromTracingDBFailed || savingToTracingDBFailed || verificationFailed
|| savingToOracleDBFailed || (testerRecord.Status != Status.Passed))))
{
/// Conditions for printing results are satisfied
@@ -981,7 +1005,11 @@ namespace GenericTest
/// Display the test result and related activity on the screen.
/// Process the most severe errors first.
///
if (verificationFailed)
if (readingFromTracingDBFailed)
{
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Reading_from_Tracing_DB_failed, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
}
else if (verificationFailed)
{
/// Verification is enabled, but a record from the previous workplace is missing
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Previous_workflow_step_is_missing_or_failed, ActivityCode.Failed, Color.Blue, 5000, Color.LightBlue));
@@ -1036,7 +1064,7 @@ namespace GenericTest
void UpdateTitle()
{
Text = string.Format("{0} v.{1} ({2}, {3})", DfltWorkplaceName, Program.Version, Program.LocalSettings.Workplace, CurrentUser.UserName());
Text = string.Format("{0} v.{1} ({2}, {3})", DfltWorkplaceName, Program.Version, Program.LocalSettings.Workplace, GlobalData.GetCurrentUserName());
}
}
}
+6 -8
View File
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2019-2022 Sensus Slovensko a.s.
/// Copyright (c) 2019-2021 Sensus Slovensko a.s.
///
using System;
using System.IO;
@@ -13,7 +13,7 @@ namespace GenericTest
/// <summary>
/// Class to be serialized to an XML file...
/// </summary>
[XmlRootAttribute("GenericTest")]
[XmlRootAttribute("GenericTesterTracer")]
public class LocalSettings
{
static XmlSerializer serializer = XmlSerializer.FromTypes(new[] { typeof(LocalSettings) })[0];
@@ -25,7 +25,6 @@ namespace GenericTest
public string Workplace;
public bool IsUserLoginRequired;
public string Language;
public string ConnectionString;
public string UsersDBConnString;
@@ -65,19 +64,18 @@ namespace GenericTest
{
/// Default settings
Workplace = GenericTestDlg.DfltWorkplaceName;
Language = "en";
ConnectionString = "SERVER=10.116.192.200; DATABASE=nanjingshared; UID=nanjingshared; PASSWORD=C1ern4V0d4; CHARSET=utf8;";
UsersDBConnString = "SERVER=10.116.192.200; DATABASE=nanjingshared; UID=nanjingshared; PASSWORD=C1ern4V0d4; CHARSET=utf8;";
ConnectionString = "SERVER=10.42.128.24; DATABASE=sledovanie2019; UID=vyroba2019; PASSWORD=qwerty; CHARSET=utf8";
UsersDBConnString = "SERVER=10.42.128.24; DATABASE=st_wr_shared_config; UID=u9305784; PASSWORD=p89344390; CHARSET=utf8;";
TestResultsFolder = "C:\\FTS\\HookSpool\\Filemover";
ArchiveFolder = "C:\\FTS\\HookSpool\\Filemover";
DoCheckSNsValidity = false;
ValidSNPrefixes = "297,298,299,300,301,302";
DoCheckPreviousTracingRecords = true;
DoSaveTestResultToOracle = false;
DoSaveTestResultToOracle = true;
OracleMode = Mode.Production;
DoPrintLabels = true;
DoPrintGoodLabelsOnly = false;
DoPrintGoodLabelsOnly = true;
MaximizeWindowOnError = false;
MainWndMaximized = false;
+2 -2
View File
@@ -153,7 +153,7 @@ namespace GenericTest
{
try
{
CurrentUser.LocalUsersDB = new DBSettings(DBType.MySql, LocalSettings.UsersDBConnString);
GlobalData.LocalUsersDB = new DBSettings(DBType.MySql, LocalSettings.UsersDBConnString);
if (new SharedDatabase.Forms.LoginDlg().ShowDialog() != DialogResult.OK) return;
}
@@ -174,7 +174,7 @@ namespace GenericTest
{
if (exc is QuitAppException)
{
//Common.Forms.ModelessForm.CloseForm();
Common.Forms.ModelessForm.CloseForm();
log.FatalFormat(Strings.Program_was_not_started_0, exc.Message);
MessageBox.Show(exc.Message,
Strings.Warning,
+3 -3
View File
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GenericTest")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.0.2")]
[assembly: AssemblyFileVersion("3.0.2")]
[assembly: AssemblyVersion("2.1.134.0")]
[assembly: AssemblyFileVersion("2.1.134.0")]
-36
View File
@@ -105,15 +105,6 @@ namespace GenericTest.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Logout.
/// </summary>
internal static string Logout {
get {
return ResourceManager.GetString("Logout", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Message.
/// </summary>
@@ -267,15 +258,6 @@ namespace GenericTest.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
internal static string Settings {
get {
return ResourceManager.GetString("Settings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Something failed.
/// </summary>
@@ -285,24 +267,6 @@ namespace GenericTest.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Start.
/// </summary>
internal static string Start {
get {
return ResourceManager.GetString("Start", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stop.
/// </summary>
internal static string Stop {
get {
return ResourceManager.GetString("Stop", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Test failed {0}.
/// </summary>
-12
View File
@@ -132,9 +132,6 @@
<data name="Error" xml:space="preserve">
<value>Error</value>
</data>
<data name="Logout" xml:space="preserve">
<value>Logout</value>
</data>
<data name="Message" xml:space="preserve">
<value>Message</value>
</data>
@@ -186,18 +183,9 @@
<data name="Serial_number_is_missing" xml:space="preserve">
<value>Serial number is missing</value>
</data>
<data name="Settings" xml:space="preserve">
<value>Settings</value>
</data>
<data name="Something_failed" xml:space="preserve">
<value>Something failed</value>
</data>
<data name="Start" xml:space="preserve">
<value>Start</value>
</data>
<data name="Stop" xml:space="preserve">
<value>Stop</value>
</data>
<data name="Test_failed_0" xml:space="preserve">
<value>Test failed {0}</value>
</data>
-12
View File
@@ -132,9 +132,6 @@
<data name="Error" xml:space="preserve">
<value>Chyba</value>
</data>
<data name="Logout" xml:space="preserve">
<value>Odhlásiť</value>
</data>
<data name="Message" xml:space="preserve">
<value>Správa</value>
</data>
@@ -183,18 +180,9 @@
<data name="Serial_number_is_missing" xml:space="preserve">
<value>Sériové číslo chýba</value>
</data>
<data name="Settings" xml:space="preserve">
<value>Nastavenia</value>
</data>
<data name="Something_failed" xml:space="preserve">
<value>Niečo sa nepodarilo</value>
</data>
<data name="Start" xml:space="preserve">
<value>Štart</value>
</data>
<data name="Stop" xml:space="preserve">
<value>Stop</value>
</data>
<data name="Test_failed_0" xml:space="preserve">
<value>Test neprešiel {0}</value>
</data>
+2 -27
View File
@@ -1,28 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
-17
View File
@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenesisCordonelInterface.API
{
public class Enums
{
public enum DataStorageReaderTypes : sbyte
{
LoginPasswordsReader,
CalibrationParamsReader
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,785 +0,0 @@
using CordonelPreadjustmentUi;
using CordonelPreadjustmentUi.Processes.Itinerary;
using GenesisCordonelInterface.Core.DataStorage.Config;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common.Models;
using GenesisCordonelInterface.Core.DataStorage.Reading.Implementation.MeterLoginPasswords;
using GenesisCordonelInterface.Core.DataStorage.Reading.Implementation.PreAdjustmentCalibrationParams;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
using Xylem.Common.Ui.CordonelPreadjustmentUi;
using static GenesisCordonelInterface.API.PublicModels;
namespace GenesisCordonelInterface.API
{
/// <summary>
/// Public-facing facade for external applications integrating with
/// Genesis Cordonel Interface.
/// </summary>
/// <remarks>
/// This class exposes a simplified and controlled API for external callers.
/// It validates public input, maps public request models to internal models,
/// forwards operations to the internal GCI implementation and exposes status
/// notifications for meter batch changes.
///
/// This layer should stay thin. Business logic and meter communication are
/// handled by <see cref="InterfaceGCIToLaatzen"/>.
/// </remarks>
public class InterfaceOutsideToGCI
{
/// <summary>
/// Internal GCI implementation used by this public facade.
/// </summary>
public readonly InterfaceGCIToLaatzen _innerMeterAPI;
/// <summary>
/// Occurs when meter batch status information changes.
/// </summary>
public event Action<List<MeterBatchDebugStatus>> MeterBatchStatusChanged;
private readonly IMeterLoginPasswordReader loginPasswordsReader;
private readonly IPreAdjustmentCalibrationParamsReader calibrationParamsReader;
/// <summary>
/// Initializes a new instance of the public GCI facade.
/// </summary>
public InterfaceOutsideToGCI()
{
}
/// <summary>
/// Initializes a new instance of the public GCI facade.
/// </summary>
public InterfaceOutsideToGCI(
InterfaceGCIToLaatzen innerMeterApi,
IMeterLoginPasswordReader passwordReader,
IPreAdjustmentCalibrationParamsReader calibrationReader)
{
_innerMeterAPI = innerMeterApi?? throw new ArgumentNullException(nameof(innerMeterApi));
loginPasswordsReader = passwordReader ?? throw new ArgumentNullException(nameof(passwordReader));
calibrationParamsReader = calibrationReader ?? throw new ArgumentNullException(nameof(calibrationReader));
//init handlers
//_innerMeterAPI._progressProcess.OnRequestedCalibrationParamsFromDb += RequestedCalibrationParamsFromDb;
}
private async void RequestedCalibrationParamsFromDb(
object sender,
EventArgsProcessProgress e)
{
try
{
DataQuery query = new DataQuery();
query.QueryParams.Add(((int)e.Value.Setting.MeterSize).ToString());
Dictionary<string, UInt32> calibrationParams = await ReadPreAdjustmentCalibrationParamsAsync(query).ConfigureAwait(false);
e.Value.PushedCalibrationParams = calibrationParams;
}
catch (Exception ex)
{
e.Value.DebugMessage(
$"Calibration params reading failed: {ex.Message}");
}
finally
{
e.Value.CalibrationParamsReadEvent.Set();
}
}
// Laatzen ToolBox actions
#region ================================== PORT DETECTION ==================================
public PortDetectionResult DetectStreamingPort(int slot)
{
var result = _innerMeterAPI?.DetectStreamingPort(slot);
//RaiseMeterBatchStatusChanged();
return result;
}
public async Task<PortDetectionResult> DetectStreamingPortAsync(
int slot,
CancellationToken token = default(CancellationToken))
{
var result = await _innerMeterAPI?.DetectStreamingPortAsync(slot, token);
//RaiseMeterBatchStatusChanged();
return result;
}
public PortDetectionResult DetectRequestPort(int slot)
{
var result = _innerMeterAPI?.DetectRequestPort(slot);
//RaiseMeterBatchStatusChanged();
return result;
}
public async Task<PortDetectionResult> DetectRequestPortAsync(
int slot,
CancellationToken token = default(CancellationToken))
{
var result = await _innerMeterAPI?.DetectRequestPortAsync(slot, token);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== INIT/UPDATE/GET slot ==================================
/// <summary>
/// Initializes a meter slot using the provided slot configuration.
/// </summary>
/// <param name="request">
/// Slot initialization request containing slot id, configuration source,
/// password source, request port and streaming port.
/// </param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Result describing whether the slot was created, updated, already existed or failed.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown when <paramref name="request"/> is null.
/// </exception>
public async Task<GciInitSlotResult> InitSlotAsync(
GciInitSlotRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var result = await _innerMeterAPI.InitSlotAsync(
request.SlotId,
ModelsMapping.MapConfigSource(request.ConfigSource),
ModelsMapping.MapPasswordSource(request.PasswordSource),
ModelsMapping.MapPort(request.RequestPort),
ModelsMapping.MapPort(request.StreamingPort),
token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
/// <summary>
/// Updates configuration of an existing meter slot.
/// </summary>
/// <param name="request">
/// Slot configuration request containing updated configuration source,
/// password source and port settings.
/// </param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Result describing whether the slot update succeeded or failed.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown when <paramref name="request"/> is null.
/// </exception>
public async Task<GciInitSlotResult> UpdateSlotAsync(
GciInitSlotRequest request,
CancellationToken token = default)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
var result = await _innerMeterAPI.UpdateSlotAsync(
request.SlotId,
ModelsMapping.MapConfigSource(request.ConfigSource),
ModelsMapping.MapPasswordSource(request.PasswordSource),
ModelsMapping.MapPort(request.RequestPort),
ModelsMapping.MapPort(request.StreamingPort),
token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
/// <summary>
/// Gets information about one meter slot.
/// </summary>
/// <param name="slotId">Slot id to query. Must be greater than zero.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Slot information including existence, connection state, login state,
/// PCB id and configured communication ports.
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="slotId"/> is invalid.
/// </exception>
public async Task<GciSlotInfo> GetSlotAsync(
int slotId,
CancellationToken token = default)
{
if (slotId <= 0)
throw new ArgumentException("Invalid slot id.");
var result = await _innerMeterAPI.GetOneMeterInfo(slotId, token).ConfigureAwait(false);
return result;
}
/// <summary>
/// Gets information about all currently initialized meter slots.
/// </summary>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Collection of slot information records for all known meters.
/// </returns>
public async Task<GciAllSlotsInfo> GetAllSlotsAsync(
CancellationToken token = default)
{
var result = await _innerMeterAPI.GetAllMetersInfo(token).ConfigureAwait(false);
return result;
}
/// <summary>
/// Cleans one meter slot and releases its runtime resources.
/// </summary>
/// <param name="slot">Slot id to clean. Must be greater than zero.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Result describing whether the slot cleanup succeeded or failed.
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="slot"/> is invalid.
/// </exception>
public async Task<GciCleanSlotResult> CleanSlotAsync(
int slot,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.", nameof(slot));
var result = await _innerMeterAPI.CleanSlotAsync(slot, token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
/// <summary>
/// Cleans all initialized meter slots and releases related runtime resources.
/// </summary>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Result describing whether cleanup of all slots succeeded or failed.
/// </returns>
public async Task<GciCleanAllSlotsResult> CleanAllSlotsAsync(
CancellationToken token = default)
{
var result = await _innerMeterAPI.CleanAllSlotsAsync(token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== PASSWORD ==================================
/// <summary>
/// Sets runtime password for the meter assigned to the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="password">Password to assign to the meter.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>Result containing password update status.</returns>
/// <exception cref="ArgumentException">
/// Thrown when slot id is invalid or password is empty.
/// </exception>
public async Task<GciSetPasswordResult> SetPasswordAsync(
int slot,
string password,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.");
if (string.IsNullOrWhiteSpace(password))
throw new ArgumentException("Password is empty.");
var result = await _innerMeterAPI.SetMeterPasswordAsync(slot, password, token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== LOGIN ==================================
/// <summary>
/// Logs in to the meter assigned to the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>Login result containing login state and status message.</returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="slot"/> is invalid.
/// </exception>
public async Task<PublicModels.GciLoginResult> LoginOneSlotAsync(
int slot,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.");
var result = await _innerMeterAPI.LoginOneSlotAsync(slot, token).ConfigureAwait(false);
return result;
//RaiseMeterBatchStatusChanged();
}
#endregion
#region ================================== CONNECTION ==================================
/// <summary>
/// Connects the meter assigned to the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>Connection result containing connection state and status message.</returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="slot"/> is invalid.
/// </exception>
public async Task<GciConnectResult> ConnectOneSlotAsync(
int slot,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.");
var result = await _innerMeterAPI.ConnectOneSlotAsync(slot, token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
/// <summary>
/// Disconnects the meter assigned to the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>Disconnect result containing final connection state and status message.</returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="slot"/> is invalid.
/// </exception>
public async Task<GciDisconnectResult> DisconnectAsync(
int slot,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.");
var result = await _innerMeterAPI.DisconnectAsync(slot, token).ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== PCB ==================================
/// <summary>
/// Reads PCB identifier from the meter assigned to the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>Result containing PCB id and read status.</returns>
/// <exception cref="ArgumentException">
/// Thrown when <paramref name="slot"/> is invalid.
/// </exception>
public async Task<GciGetPcbIdResult> GetPcbIdAsync(
int slot,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.");
var result = await _innerMeterAPI.GetPcbIdAsync(slot, token).ConfigureAwait(false);
return result;
}
#endregion
#region ================================== READ ==================================
/// <summary>
/// Reads a firmware register value from the meter assigned to the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="registerName">Register identifier to read.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Register read result containing raw register value and operation status.
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when slot id or register name is invalid.
/// </exception>
public async Task<RegisterReadResult> ReadRegisterAsync(
int slot,
string registerName,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.", nameof(slot));
if (string.IsNullOrWhiteSpace(registerName))
throw new ArgumentException("Register name is empty.", nameof(registerName));
var result = await _innerMeterAPI
.ReadRegisterAsync(slot, registerName, token)
.ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== WRITE ==================================
/// <summary>
/// Writes a value to a firmware register.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="registerName">Register identifier to write.</param>
/// <param name="value">Value to write.</param>
/// <param name="storeToDevice">
/// Indicates whether configuration should be permanently stored.
/// </param>
/// <param name="refreshSystemState">
/// Indicates whether firmware system state should be refreshed after write.
/// </param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Register write result describing write status.
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when slot id or register name is invalid.
/// </exception>
public async Task<RegisterWriteResult> WriteRegisterAsync(
int slot,
string registerName,
object value,
bool storeToDevice = false,
bool refreshSystemState = false,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.", nameof(slot));
if (string.IsNullOrWhiteSpace(registerName))
throw new ArgumentException("Register name is empty.", nameof(registerName));
var result = await _innerMeterAPI
.WriteRegisterAsync(
slot,
registerName,
value,
storeToDevice,
refreshSystemState,
token)
.ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== Password ==================================
/// <summary>
/// Updates meter password for the specified slot.
/// </summary>
/// <param name="slot">Slot id. Must be greater than zero.</param>
/// <param name="password">New password.</param>
/// <param name="token">Cancellation token used to cancel the asynchronous operation.</param>
/// <returns>
/// Password update result.
/// </returns>
/// <exception cref="ArgumentException">
/// Thrown when slot id or password is invalid.
/// </exception>
public async Task<GciSetPasswordResult> SetMeterPasswordAsync(
int slot,
string password,
CancellationToken token = default)
{
if (slot <= 0)
throw new ArgumentException("Invalid slot id.", nameof(slot));
if (string.IsNullOrWhiteSpace(password))
throw new ArgumentException("Password is empty.", nameof(password));
var result = await _innerMeterAPI
.SetMeterPasswordAsync(slot, password, token)
.ConfigureAwait(false);
//RaiseMeterBatchStatusChanged();
return result;
}
#endregion
#region ================================== DEBUG STATUS ==================================
/// <summary>
/// Gets runtime diagnostic information for all active workers.
/// </summary>
/// <returns>
/// Collection containing worker state, queue information,
/// current operation and activity timestamps.
/// </returns>
public List<WorkerDebugStatus> GetWorkerDebugStatuses()
{
return _innerMeterAPI?.GetWorkerDebugStatuses();
}
/// <summary>
/// Gets runtime diagnostic information for all meter slots.
/// </summary>
/// <returns>
/// Collection containing slot state, connection state,
/// selected state and communication configuration.
/// </returns>
public List<MeterBatchDebugStatus> GetMeterBatchDebugStatuses()
{
return _innerMeterAPI?.GetMeterBatchDebugStatuses();
}
/// <summary>
/// Raises meter batch status change notification.
/// </summary>
/// <remarks>
/// Intended to notify external consumers after changes in meter state.
/// </remarks>
public void RaiseMeterBatchStatusChanged()
{
var statuses = GetMeterBatchDebugStatuses();
var handler = MeterBatchStatusChanged;
if (handler != null)
handler(statuses);
}
#endregion
#region ================================== SLOT SELECTION ==================================
/// <summary>
/// Sets selection state for a slot.
/// </summary>
/// <param name="slot">Slot id.</param>
/// <param name="selected">Selection state.</param>
public void SetSlotSelected(int slot, bool selected)
{
_innerMeterAPI?.SetSlotSelected(slot, selected);
RaiseMeterBatchStatusChanged();
}
/// <summary>
/// Determines whether the specified slot is selected.
/// </summary>
/// <param name="slot">Slot id.</param>
/// <returns>
/// True if slot is selected; otherwise false.
/// </returns>
public bool IsSlotSelected(int slot)
{
return (bool)(_innerMeterAPI?.IsSlotSelected(slot));
}
/// <summary>
/// Gets all selected slot identifiers.
/// </summary>
/// <returns>
/// Ordered collection of selected slot ids.
/// </returns>
public List<int> GetSelectedSlots()
{
return _innerMeterAPI?.GetSelectedSlots();
}
#endregion
#region ================================== Register names ==================================
/// <summary>
/// Gets all available firmware register identifiers.
/// </summary>
/// <returns>
/// Ordered collection of register names.
/// </returns>
public List<string> GetAllRegisterNames()
{
return _innerMeterAPI?.GetAllRegisterNames();
}
#endregion
// Laatzen Preadjustment processes
#region ================================== PreAdjustment ==================================
public PreAdjustmentInitializationResult Preadjustment_Initialization(
ProcessProgress pp,
List<MeterStateControl> mc)
{
//init handlers
pp.OnRequestedCalibrationParamsFromDb += RequestedCalibrationParamsFromDb;
return _innerMeterAPI?.Preadjustment_Initialization(pp, mc);
}
public Task<PreadjustmentDetectResult> PreAdjustment_DetectAsync(
IEnumerable<PublicModels.MeterBatchDebugStatus> selectedSlots,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_DetectAsync(selectedSlots, token);
}
public PreadjustmentDetectResult PreAdjustment_DetectDirect(
IEnumerable<PublicModels.MeterBatchDebugStatus> selectedSlots,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_DetectDirect(selectedSlots, token);
}
public Task<PreAdjustmentProcessResult> PreAdjustment_PreparationAsync(
int slot,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_PreparationAsync(slot, token);
}
public PreAdjustmentProcessResult PreAdjustment_PreparationDirect()
{
return _innerMeterAPI.PreAdjustment_PreparationDirect();
}
public Task<PreAdjustmentProcessResult> PreAdjustment_AmplitudeTestAsync(
int slot,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_AmplitudeTestAsync(slot, token);
}
public PreAdjustmentProcessResult PreAdjustment_AmplitudeTestDirect()
{
return _innerMeterAPI.PreAdjustment_AmplitudeTestDirect();
}
public Task<PreAdjustmentProcessResult> PreAdjustment_TemperatureCalibrationAsync(
int slot,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_TemperatureCalibrationAsync(slot, token);
}
public PreAdjustmentProcessResult PreAdjustment_TemperatureCalibrationDirect()
{
return _innerMeterAPI.PreAdjustment_TemperatureCalibrationDirect();
}
public bool PreAdjustment_PushTemperature(
double temperature)
{
return _innerMeterAPI.PreAdjustment_PushTemperature(temperature);
}
public Task<PreAdjustmentProcessResult> PreAdjustment_OffsetTestAsync(
int slot,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_OffsetTestAsync(slot, token);
}
public PreAdjustmentProcessResult PreAdjustment_OffsetTestDirect()
{
return _innerMeterAPI.PreAdjustment_OffsetTestDirect();
}
public Task<PreAdjustmentProcessResult> PreAdjustment_CompletionAsync(
int slot,
CancellationToken token = default)
{
return _innerMeterAPI.PreAdjustment_CompletionAsync(slot, token);
}
public PreAdjustmentProcessResult PreAdjustment_CompletionDirect()
{
return _innerMeterAPI.PreAdjustment_CompletionDirect();
}
#endregion
#region ================================== UNI DATA STORAGE READER ==================================
//LoginPasswords reading
/// <summary>
/// Reads meter login password from configured GCI data storage.
/// </summary>
/// <param name="query">
/// Data query containing PCB ID or another configured lookup value.
/// </param>
/// <param name="token">
/// Cancellation token used to cancel the asynchronous operation.
/// </param>
/// <returns>
/// Password if found; otherwise null.
/// </returns>
public Task<string> ReadMeterLoginPasswordAsync(
DataQuery query,
CancellationToken token = default)
{
return loginPasswordsReader.ReadMeterLoginPasswordAsync(
query,
token);
}
//CalibrationParams reading
/// <summary>
/// Reads pre-adjustment calibration parameters
/// from configured GCI data storage.
/// </summary>
/// <param name="query">
/// Data query containing meter size or another configured lookup value.
/// </param>
/// <param name="token">
/// Cancellation token used to cancel the asynchronous operation.
/// </param>
/// <returns>
/// Dictionary:
///
/// Key:
/// Calibration parameter name
///
/// Value:
/// Calibration parameter value
/// </returns>
public Task<Dictionary<string, UInt32>> ReadPreAdjustmentCalibrationParamsAsync(
DataQuery query,
CancellationToken token = default)
{
return calibrationParamsReader.ReadCalibrationParamsAsync(
query,
token);
}
#endregion
}
}
@@ -1,170 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
using static GenesisCordonelInterface.API.InterfaceOutsideToGCI;
using static GenesisCordonelInterface.API.PublicModels;
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
namespace GenesisCordonelInterface.API
{
/// <summary>
/// Public data contract layer for the Genesis Cordonel Interface (GCI).
///
/// This class defines all Data Transfer Objects (DTOs) that are exposed
/// to external consumers (e.g. TBF, UI, or other integration layers).
///
/// Responsibilities:
/// - Provide stable, dependency-free models for external usage
/// - Decouple internal GCI implementation (GenesisMeter, Xylem libraries)
/// from external systems
/// - Define request/response contracts for all supported operations
/// - Contain mapping methods between public DTOs and internal domain models
///
/// Architecture:
/// External world (TBF / UI)
/// ↓
/// GciPublicModels (this layer)
/// ↓
/// Internal GCI API (InterfaceGCIToLaatzen, GenesisMeter, etc.)
///
/// Notes:
/// - Public models must NOT expose internal types (e.g. GenesisMeter, IPort, etc.)
/// - All mapping between internal and external representations must be done here
/// - DTOs are designed to be simple, serializable, and stable over time
/// - Any change in internal implementation should not affect these models
///
/// Pattern:
/// Each operation follows a consistent structure:
/// Request → Operation → Result
///
/// Example:
/// GciInitSlotRequest → InitSlot → GciInitSlotResult
/// GetSlot → GciSlotInfo
/// GetPcbId → GciGetPcbIdResult
///
/// This layer acts as a boundary between domain logic and integration logic.
/// </summary>
public class ModelsMapping
{
/// <summary>
/// Mapping methods between public DTOs and internal GCI models.
/// Ensures separation between external contracts and internal domain objects.
/// </summary>
#region ================================== OUTERN/INTERN and back models mapping ==================================
public static PasswordSource MapPasswordSource(PublicModels.GciPasswordSource src)
{
return (PasswordSource)src;
}
public static ConfigSource MapConfigSource(PublicModels.GciConfigSource src)
{
return (ConfigSource)src;
}
public static Xylem.Common.Hardware.Interfaces.Ports.PortCore.PortConfig? MapPort(PublicModels.GciPortConfig port)
{
if (port == null)
return null;
Xylem.Common.Hardware.Interfaces.Ports.PortCore.PortConfig result = new Xylem.Common.Hardware.Interfaces.Ports.PortCore.PortConfig();
result.PortName = port.PortName;
result.Type = port.Type;
return result;
}
public static PublicModels.GciInitSlotResult MapInitResult(PublicModels.GciInitSlotResult result)
{
if (result == null)
return null;
return new PublicModels.GciInitSlotResult
{
SlotId = result.SlotId,
Success = result.Success,
Message = result.Message
};
}
public static PublicModels.GciPasswordSource MapPasswordSourceBack(PasswordSource src)
{
return (PublicModels.GciPasswordSource)src;
}
public static PublicModels.GciConfigSource MapConfigSourceBack(ConfigSource src)
{
return (PublicModels.GciConfigSource)src;
}
public static PublicModels.GciPortConfig MapPortBack(PortConfig? port)
{
if (!port.HasValue)
return null;
PortConfig value = port.Value;
return new PublicModels.GciPortConfig
{
PortName = value.PortName,
Type = value.Type
};
}
public static PublicModels.GciPortConfig MapPortBack(IPort port)
{
if (port == null)
return null;
return new PublicModels.GciPortConfig
{
PortName = port.GetPortName(),
Type = port.GetType().Name
};
}
public static PublicModels.GciPortConfig MapPortBack(string portName, string portTyoe)
{
return new PublicModels.GciPortConfig
{
PortName = portName,
Type = portTyoe
};
}
public static MeterBatchDebugStatus ToMeterBatchDebugStatus(GciSlotInfo slot)
{
if (slot == null)
return null;
return new MeterBatchDebugStatus
{
Slot = slot.SlotId,
Selected = true,
PcbId = slot.PcbId,
IsConnected = false,
IsLoggedOn = false,
RequestPort = slot.RequestPort == null ? "" : slot.RequestPort.PortName,
StreamingPort = slot.StreamingPort == null ? "" : slot.StreamingPort.PortName,
FwVersion = "",
InterfaceVersion = ""
};
}
public static List<MeterBatchDebugStatus> ToMeterBatchDebugStatusList(
IEnumerable<GciSlotInfo> slots)
{
if (slots == null)
return new List<MeterBatchDebugStatus>();
return slots
.Where(x => x != null)
.Select(ToMeterBatchDebugStatus)
.ToList();
}
#endregion
}
}
@@ -1,504 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
using static GenesisCordonelInterface.API.InterfaceOutsideToGCI;
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
namespace GenesisCordonelInterface.API
{
/// <summary>
/// Public data contract layer for the Genesis Cordonel Interface (GCI).
///
/// This class defines all Data Transfer Objects (DTOs) that are exposed
/// to external consumers (e.g. TBF, UI, or other integration layers).
///
/// Responsibilities:
/// - Provide stable, dependency-free models for external usage
/// - Decouple internal GCI implementation (GenesisMeter, Xylem libraries)
/// from external systems
/// - Define request/response contracts for all supported operations
/// - Contain mapping methods between public DTOs and internal domain models
///
/// Architecture:
/// External world (TBF / UI)
/// ↓
/// GciPublicModels (this layer)
/// ↓
/// Internal GCI API (InterfaceGCIToLaatzen, GenesisMeter, etc.)
///
/// Notes:
/// - Public models must NOT expose internal types (e.g. GenesisMeter, IPort, etc.)
/// - All mapping between internal and external representations must be done here
/// - DTOs are designed to be simple, serializable, and stable over time
/// - Any change in internal implementation should not affect these models
///
/// Pattern:
/// Each operation follows a consistent structure:
/// Request → Operation → Result
///
/// Example:
/// GciInitSlotRequest → InitSlot → GciInitSlotResult
/// GetSlot → GciSlotInfo
/// GetPcbId → GciGetPcbIdResult
///
/// This layer acts as a boundary between domain logic and integration logic.
/// </summary>
public class PublicModels
{
public static bool HideSensitiveValues { get; set; } = true;
private static string FormatPassword(string password)
{
if (!HideSensitiveValues)
return password ?? "<null>";
if (string.IsNullOrEmpty(password))
return "<empty>";
return "********";
}
/// <summary>
/// Public DTOs exposed to external systems.
/// These models represent the contract of the GCI API.
/// They must remain stable and independent of internal implementation.
/// </summary>
#region ================================== PUBLIC MODELS ===========================================
public class RegisterReadResult
{
public bool Success { get; set; }
public string RegisterName { get; set; }
public string RawHex { get; set; }
public string ErrorMessage { get; set; }
public override string ToString()
{
return string.Format(
"Success={0}, RegisterName={1}, RawHex={2}, ErrorMessage={3}",
Success,
RegisterName,
RawHex,
ErrorMessage);
}
}
public class WorkerDebugStatus
{
public int Slot { get; set; }
public string Name { get; set; }
public int QueueLength { get; set; }
public bool IsBusy { get; set; }
public string CurrentOperation { get; set; }
public string LastError { get; set; }
public DateTime LastActivity { get; set; }
}
public class MeterBatchDebugStatus
{
public int Slot { get; set; }
public bool Selected { get; set; }
public string PcbId { get; set; }
public bool IsConnected { get; set; }
public bool IsLoggedOn { get; set; }
public string RequestPort { get; set; }
public string StreamingPort { get; set; }
public string RequestPortType { get; set; }
public string FwVersion { get; set; }
public string InterfaceVersion { get; set; }
}
public class RegisterWriteResult
{
public bool Success { get; set; }
public string RegisterName { get; set; }
public object WrittenValue { get; set; }
public bool StoreToDevice { get; set; }
public bool RefreshSystemState { get; set; }
public string ErrorMessage { get; set; }
public override string ToString()
{
return $"Success={Success}, " +
$"Register={RegisterName ?? "<null>"}, " +
$"Value={WrittenValue ?? "<null>"}, " +
$"StoreToDevice={StoreToDevice}, " +
$"RefreshSystemState={RefreshSystemState}, " +
$"Error={ErrorMessage ?? "<none>"}";
}
}
public class PortDetectionResult
{
public bool Success { get; set; }
public int Slot { get; set; }
public string PortName { get; set; }
public string PcbId { get; set; }
public string ErrorMessage { get; set; }
public override string ToString()
{
return string.Format(
"Slot={0}, Success={1}, PortName={2}, PcbId={3}, ErrorMessage={4}",
Slot,
Success,
PortName,
PcbId,
ErrorMessage);
}
}
public class GciSlotInfo
{
public int SlotId { get; set; }
public bool Exists { get; set; }
public bool Success { get; set; }
public bool IsConnected { get; set; }
public bool IsLoggedOn { get; set; }
public string Message { get; set; }
public string PcbId { get; set; }
public string Password { get; set; }
public GciConfigSource ConfigSource { get; set; }
public GciPasswordSource PasswordSource { get; set; }
public GciPortConfig RequestPort { get; set; }
public GciPortConfig StreamingPort { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Exists={1}, Success={2}, IsConnected={3}, IsLoggedOn={4}, Message={5}, PcbId={6}, Password={7}, ConfigSource={8}, PasswordSource={9}, RequestPort={10}, StreamingPort={11}",
SlotId,
Exists,
Success,
IsConnected,
IsLoggedOn,
Message,
PcbId,
FormatPassword(Password),
ConfigSource,
PasswordSource,
RequestPort,
StreamingPort);
}
}
public class GciAllSlotsInfo
{
public bool Success { get; set; }
public string Message { get; set; }
public List<GciSlotInfo> Slots { get; set; }
public override string ToString()
{
return $"Success={Success}, Count={Slots?.Count ?? 0}, Message={Message}";
}
}
public class Result
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, Message={2}",
SlotId,
Success,
Message);
}
}
public enum GciPasswordSource
{
RestApi = 0,
OfflineFile = 1,
InterfaceInputPassword = 2,
}
public enum GciConfigSource
{
FileConfig = 0,
InterfaceInputConfig = 1,
}
/// <summary>
/// Collection of port settings
/// </summary>
public class GciPortConfig
{
public string PortName { get; set; }
public string Type { get; set; }
public override string ToString()
{
return string.Format("PortName={0}, Type={1}", PortName, Type);
}
}
public static GciPortConfig CreatePortConfig(string portName, string type)
{
if (string.IsNullOrWhiteSpace(portName))
return null;
return new GciPortConfig
{
PortName = portName,
Type = MapPortType(type)
};
}
public static string MapPortType(string type)
{
switch ((type ?? "").Trim().ToUpperInvariant())
{
case "RFID":
return "Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.RfidSerialPort";
case "UART":
return "Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.UartSerialPort";
case "IRDA":
return "Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.IrdaSerialPort";
default:
return "Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.IrdaSerialPort";
}
}
public class GciInitSlotRequest
{
public int SlotId { get; set; }
public GciConfigSource ConfigSource { get; set; }
public GciPasswordSource PasswordSource { get; set; }
public GciPortConfig RequestPort { get; set; }
public GciPortConfig StreamingPort { get; set; }
public string Password { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, GciConfigSource={1}, PasswordSource={2}, RequestPort={3}, StreamingPort={4}, Password={5}",
SlotId,
ConfigSource,
PasswordSource,
RequestPort,
StreamingPort,
FormatPassword(Password));
}
}
public class GciInitSlotResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public string PcbId { get; set; }
public bool Created { get; set; }
public bool Updated { get; set; }
public bool AlreadyExists { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, Message={2}, PcbId={3}, Created={4}, Updated={5}, AlreadyExists={6}",
SlotId,
Success,
Message,
PcbId,
Created,
Updated,
AlreadyExists);
}
}
public class GciCleanAllSlotsResult
{
public bool Success { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"Success={0}, Message={1}",
Success,
Message);
}
}
public class GciCleanSlotResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, Message={2}",
SlotId,
Success,
Message);
}
}
public class GciGetPcbIdResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string PcbId { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, PcbId={2}, Message={3}",
SlotId,
Success,
PcbId,
Message);
}
}
public class GciConnectResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string PcbId { get; set; }
public bool IsConnected { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, PcbId={2}, IsConnected={3}, Message={4}",
SlotId,
Success,
PcbId,
IsConnected,
Message);
}
}
public class GciLoginResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string PcbId { get; set; }
public bool IsLoggedOn { get; set; }
public string Message { get; set; }
public override string ToString()
{
return $"Slot={SlotId}, Success={Success}, PcbId={PcbId}, IsLoggedOn={IsLoggedOn}, Message={Message ?? "<none>"}";
}
}
public class GciRegisterSnapshot
{
public string Name { get; set; }
public string Type { get; set; }
public string RawValue { get; set; }
public string Min { get; set; }
public string Max { get; set; }
public string Description { get; set; }
public string Version { get; set; }
public string IsAvailable { get; set; }
public string Privilege { get; set; }
}
public class GciDisconnectResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, Message={2}",
SlotId,
Success,
Message);
}
}
public class GciSetPasswordResult
{
public int SlotId { get; set; }
public bool Success { get; set; }
public string Password { get; set; }
public string Message { get; set; }
public override string ToString()
{
return string.Format(
"SlotId={0}, Success={1}, Password={2}, Message={3}",
SlotId,
Success,
FormatPassword(Password),
Message);
}
}
public class PreAdjustmentProcessResult
{
public bool Success { get; set; }
public int Slot { get; set; }
public string ProcessName { get; set; }
public string ErrorMessage { get; set; }
/// <inheritdoc />
public override string ToString()
{
return
$"Success={Success}, " +
$"Slot={Slot}, " +
$"Process={ProcessName}, " +
$"Error={ErrorMessage ?? "None"}";
}
}
public class PreadjustmentDetectResult
{
public bool Success { get; set; }
public int DetectedMeterCount { get; set; }
public int DetectedThermometerCount { get; set; }
public string ErrorMessage { get; set; }
/// <inheritdoc />
public override string ToString()
{
return
$"Success={Success}, " +
$"Meters={DetectedMeterCount}, " +
$"Thermometers={DetectedThermometerCount}, " +
$"Error={ErrorMessage ?? "None"}";
}
}
public class PreAdjustmentInitializationResult
{
public bool Success { get; set; }
public string Slots { get; set; }
public string ErrorMessage { get; set; }
/// <inheritdoc />
public override string ToString()
{
return
$"Success={Success}, " +
$"Slots={Slots}, " +
$"Error={ErrorMessage ?? "None"}";
}
}
#endregion
}
}
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Xylem.Common.CommonCore" publicKeyToken="null" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.8.18.17954" newVersion="2.8.18.17954" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,36 +0,0 @@
{
"_Comment": "GCI DataStorage configuration",
"DataStorage": {
"MeterLoginPasswords": {
"___Documentation___": {
"Description": "Reads login passwords for meters by PCB ID",
"Type": "Supported: LocalDatabase, RemoteDatabase, LocalCsv, LocalJson, RestApi",
"DataSource": "Database connection string",
"QueryTemplate": "QUERYPARAM is placeholder for runtime value. Example: WHERE [PcbId]=QUERYPARAM -> PCB ID provided during GetPasswordAsync()."
},
"Name": "MeterLoginPasswords",
"Type": "LocalDatabase",
"DataSource": "Server=(localdb)\\MojaDB;Database=UnionTownCalibAndSkeleton;Integrated Security=True;",
"QueryTemplate": "SELECT [Password] FROM [dbo].[SkeletonKeys] WHERE [PcbId] = QUERYPARAM"
},
"PreAdjustmentCalibrationParams": {
"___Documentation___": {
"Description": "Reads pre-adjustment calibration parameters by meter size",
"Type": "Supported: LocalDatabase, RemoteDatabase, LocalCsv, LocalJson, RestApi",
"DataSource": "Database connection string",
"QueryTemplate": "QUERYPARAM is placeholder for runtime value. Example: WHERE [MeterSize]=QUERYPARAM -> meter size provided during ReadCalibrationParamsAsync()."
},
"Name": "PreAdjustmentCalibrationParams",
"Type": "LocalDatabase",
"DataSource": "Server=(localdb)\\MojaDB;Database=UnionTownCalibAndSkeleton;Integrated Security=True;",
"QueryTemplate": "SELECT [ParameterName], [ParameterValue] FROM [dbo].[PreAdjustmentCalibrationParams] WHERE [MeterSize] = QUERYPARAM"
}
}
}
@@ -1,32 +0,0 @@
namespace GenesisCordonelInterface.Core.Config
{
/// <summary>
/// Root GCI configuration object loaded from gci_config.json.
///
/// This class represents the top-level configuration structure
/// and serves as an entry point for all configurable GCI features.
///
/// Example:
///
/// {
/// "DataStorageSection":
/// {
/// ...
/// }
/// }
/// </summary>
public class GciConfig
{
/// <summary>
/// Data storage configuration section.
///
/// Contains definitions for all configured readers and writers,
/// such as:
///
/// - MeterLoginPasswords
/// - PreAdjustmentCalibrationParams
/// - future storage providers
/// </summary>
public DataStorage.Config.GciDataStorageConfig DataStorageSection { get; set; }
}
}
@@ -1,177 +0,0 @@
using System;
using System.IO;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common.Models;
using Newtonsoft.Json;
namespace GenesisCordonelInterface.Core.Config
{
/// <summary>
/// Loads GCI configuration from gci_config.json.
///
/// Responsibilities:
/// - Locate configuration file
/// - Deserialize JSON into strongly typed objects
/// - Normalize relative file paths
/// - Preserve database connection strings and REST URLs
///
/// Example:
///
/// Config/
/// gci_config.json
///
/// Data/
/// meter_passwords.csv
///
/// Relative paths:
/// Data\file.csv
///
/// become:
///
/// C:\App\bin\Debug\Data\file.csv
///
/// Database sources remain unchanged:
///
/// Server=(localdb)\MojaDB;Database=...
/// </summary>
public static class GciConfigLoader
{
/// <summary>
/// Loads default GCI configuration from:
///
/// Config\gci_config.json
/// </summary>
/// <returns>
/// Loaded GCI configuration.
/// </returns>
public static GciConfig LoadDefault()
{
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
string configPath = Path.Combine(
baseDirectory,
"Config",
"gci_config.json");
return Load(configPath, baseDirectory);
}
/// <summary>
/// Loads GCI configuration from specified file.
/// </summary>
/// <param name="configPath">
/// Path to configuration json file.
/// </param>
/// <param name="baseDirectory">
/// Base directory used for resolving relative paths.
/// </param>
/// <returns>
/// Loaded configuration object.
/// </returns>
public static GciConfig Load(
string configPath,
string baseDirectory = null)
{
if (string.IsNullOrWhiteSpace(configPath))
throw new ArgumentException(
"Config path must not be empty.",
nameof(configPath));
if (!File.Exists(configPath))
throw new FileNotFoundException(
"GCI config file was not found.",
configPath);
string json = File.ReadAllText(configPath);
GciConfig config =
JsonConvert.DeserializeObject<GciConfig>(json);
if (config == null)
throw new InvalidOperationException(
"GCI config could not be loaded.");
NormalizeDataStoragePaths(
config,
baseDirectory ?? Path.GetDirectoryName(configPath));
return config;
}
/// <summary>
/// Normalizes paths for all configured data storage entries.
///
/// Converts relative file paths into absolute paths.
/// Database connection strings remain untouched.
/// </summary>
/// <param name="config">
/// Loaded configuration object.
/// </param>
/// <param name="baseDirectory">
/// Base path used for relative resolution.
/// </param>
private static void NormalizeDataStoragePaths(
GciConfig config,
string baseDirectory)
{
if (config.DataStorageSection == null)
return;
NormalizePath(
config.DataStorageSection.MeterLoginPasswords,
baseDirectory);
NormalizePath(
config.DataStorageSection.PreAdjustmentCalibrationParams,
baseDirectory);
}
/// <summary>
/// Converts relative file paths into absolute paths.
///
/// Applies only to:
/// - LocalCsv
/// - RemoteCsv
/// - LocalJson
/// - RemoteJson
///
/// Does not modify:
/// - Database connection strings
/// - REST URLs
/// </summary>
/// <param name="storageConfig">
/// Storage configuration.
/// </param>
/// <param name="baseDirectory">
/// Base path for resolution.
/// </param>
private static void NormalizePath(
DataStorageConfig storageConfig,
string baseDirectory)
{
if (storageConfig == null)
return;
if (string.IsNullOrWhiteSpace(storageConfig.DataSource))
return;
// Database connection strings and URLs
// must never be treated as file paths.
if (storageConfig.Type == DataStorageType.LocalDatabase ||
storageConfig.Type == DataStorageType.RemoteDatabase ||
storageConfig.Type == DataStorageType.RestApi)
{
return;
}
if (Path.IsPathRooted(storageConfig.DataSource))
return;
storageConfig.DataSource =
Path.GetFullPath(
Path.Combine(
baseDirectory,
storageConfig.DataSource));
}
}
}
@@ -1,36 +0,0 @@
{
"_Comment": "GCI DataStorage configuration",
"DataStorageSection": {
"MeterLoginPasswords": {
"___Documentation___": {
"Description": "Reads login passwords for meters by PCB ID",
"Type": "Supported: LocalDatabase, RemoteDatabase, LocalCsv, LocalJson, RestApi",
"DataSource": "Database connection string",
"QueryTemplate": "QUERYPARAM is placeholder for runtime value. Example: WHERE [PcbId]=QUERYPARAM -> PCB ID provided during GetPasswordAsync()."
},
"Name": "MeterLoginPasswords",
"Type": "LocalDatabase",
"DataSource": "Server=(localdb)\\SensusLocalDB;Database=UnionTownCalibAndSkeleton;Integrated Security=True;",
"QueryTemplate": "SELECT [Password] FROM [dbo].[SkeletonKeys] WHERE [PcbId] = QUERYPARAM"
},
"PreAdjustmentCalibrationParams": {
"___Documentation___": {
"Description": "Reads pre-adjustment calibration parameters by meter size",
"Type": "Supported: LocalDatabase, RemoteDatabase, LocalCsv, LocalJson, RestApi",
"DataSource": "Database connection string",
"QueryTemplate": "QUERYPARAM is placeholder for runtime value. Example: WHERE [MeterSize]=QUERYPARAM -> meter size provided during ReadCalibrationParamsAsync()."
},
"Name": "PreAdjustmentCalibrationParams",
"Type": "LocalDatabase",
"DataSource": "Server=(localdb)\\SensusLocalDB;Database=UnionTownCalibAndSkeleton;Integrated Security=True;",
"QueryTemplate": "SELECT [ParameterName], [ParameterValue] FROM [dbo].[PreAdjustmentCalibrationParams] WHERE [MeterSize] = QUERYPARAM"
}
}
}
@@ -1,32 +0,0 @@
namespace GenesisCordonelInterface.Core.DataStorage.Config
{
/// <summary>
/// Root GCI configuration object loaded from gci_config.json.
///
/// This class represents the top-level configuration structure
/// and serves as an entry point for all configurable GCI features.
///
/// Example:
///
/// {
/// "DataStorage":
/// {
/// ...
/// }
/// }
/// </summary>
public class GciConfig
{
/// <summary>
/// Data storage configuration section.
///
/// Contains definitions for all configured readers and writers,
/// such as:
///
/// - MeterLoginPasswords
/// - PreAdjustmentCalibrationParams
/// - future storage providers
/// </summary>
public GciDataStorageConfig DataStorage { get; set; }
}
}
@@ -1,177 +0,0 @@
using System;
using System.IO;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common.Models;
using Newtonsoft.Json;
namespace GenesisCordonelInterface.Core.DataStorage.Config
{
/// <summary>
/// Loads GCI configuration from gci_config.json.
///
/// Responsibilities:
/// - Locate configuration file
/// - Deserialize JSON into strongly typed objects
/// - Normalize relative file paths
/// - Preserve database connection strings and REST URLs
///
/// Example:
///
/// Config/
/// gci_config.json
///
/// Data/
/// meter_passwords.csv
///
/// Relative paths:
/// Data\file.csv
///
/// become:
///
/// C:\App\bin\Debug\Data\file.csv
///
/// Database sources remain unchanged:
///
/// Server=(localdb)\MojaDB;Database=...
/// </summary>
public static class GciConfigLoader
{
/// <summary>
/// Loads default GCI configuration from:
///
/// Config\gci_config.json
/// </summary>
/// <returns>
/// Loaded GCI configuration.
/// </returns>
public static GciConfig LoadDefault()
{
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
string configPath = Path.Combine(
baseDirectory,
"Config",
"gci_config.json");
return Load(configPath, baseDirectory);
}
/// <summary>
/// Loads GCI configuration from specified file.
/// </summary>
/// <param name="configPath">
/// Path to configuration json file.
/// </param>
/// <param name="baseDirectory">
/// Base directory used for resolving relative paths.
/// </param>
/// <returns>
/// Loaded configuration object.
/// </returns>
public static GciConfig Load(
string configPath,
string baseDirectory = null)
{
if (string.IsNullOrWhiteSpace(configPath))
throw new ArgumentException(
"Config path must not be empty.",
nameof(configPath));
if (!File.Exists(configPath))
throw new FileNotFoundException(
"GCI config file was not found.",
configPath);
string json = File.ReadAllText(configPath);
GciConfig config =
JsonConvert.DeserializeObject<GciConfig>(json);
if (config == null)
throw new InvalidOperationException(
"GCI config could not be loaded.");
NormalizeDataStoragePaths(
config,
baseDirectory ?? Path.GetDirectoryName(configPath));
return config;
}
/// <summary>
/// Normalizes paths for all configured data storage entries.
///
/// Converts relative file paths into absolute paths.
/// Database connection strings remain untouched.
/// </summary>
/// <param name="config">
/// Loaded configuration object.
/// </param>
/// <param name="baseDirectory">
/// Base path used for relative resolution.
/// </param>
private static void NormalizeDataStoragePaths(
GciConfig config,
string baseDirectory)
{
if (config.DataStorage == null)
return;
NormalizePath(
config.DataStorage.MeterLoginPasswords,
baseDirectory);
NormalizePath(
config.DataStorage.PreAdjustmentCalibrationParams,
baseDirectory);
}
/// <summary>
/// Converts relative file paths into absolute paths.
///
/// Applies only to:
/// - LocalCsv
/// - RemoteCsv
/// - LocalJson
/// - RemoteJson
///
/// Does not modify:
/// - Database connection strings
/// - REST URLs
/// </summary>
/// <param name="storageConfig">
/// Storage configuration.
/// </param>
/// <param name="baseDirectory">
/// Base path for resolution.
/// </param>
private static void NormalizePath(
DataStorageConfig storageConfig,
string baseDirectory)
{
if (storageConfig == null)
return;
if (string.IsNullOrWhiteSpace(storageConfig.DataSource))
return;
// Database connection strings and URLs
// must never be treated as file paths.
if (storageConfig.Type == DataStorageType.LocalDatabase ||
storageConfig.Type == DataStorageType.RemoteDatabase ||
storageConfig.Type == DataStorageType.RestApi)
{
return;
}
if (Path.IsPathRooted(storageConfig.DataSource))
return;
storageConfig.DataSource =
Path.GetFullPath(
Path.Combine(
baseDirectory,
storageConfig.DataSource));
}
}
}
@@ -1,30 +0,0 @@
using GenesisCordonelInterface.Core.DataStorage.Reading.Common.Models;
namespace GenesisCordonelInterface.Core.DataStorage.Config
{
/// <summary>
/// Contains all configured GCI data storage sources.
///
/// Each property represents one logical use-case
/// and points to its storage configuration.
///
/// Example:
/// MeterLoginPasswords
/// -> SQL database
///
/// PreAdjustmentCalibrationParams
/// -> CSV file
/// </summary>
public class GciDataStorageConfig
{
/// <summary>
/// Configuration for meter login password lookup.
/// </summary>
public DataStorageConfig MeterLoginPasswords { get; set; }
/// <summary>
/// Configuration for pre-adjustment calibration data lookup.
/// </summary>
public DataStorageConfig PreAdjustmentCalibrationParams { get; set; }
}
}
@@ -1,49 +0,0 @@
namespace GenesisCordonelInterface.Core.DataStorage.Reading.Common.Contracts
{
/// <summary>
/// Defines common contract for all GCI data storage readers.
///
/// Implementations can read data from different storage types:
/// - SQL database
/// - CSV file
/// - JSON file
/// - REST API
///
/// Consumers should use this interface instead of concrete readers.
/// </summary>
public interface IDataStorageReader
{
/// <summary>
/// Reads data from configured storage using provided query.
/// </summary>
/// <param name="query">
/// Query object containing lookup parameters.
/// </param>
/// <returns>
/// Storage-specific result object.
/// </returns>
object GetData(Models.DataQuery query);
/// <summary>
/// Tests whether configured data source is accessible.
/// </summary>
/// <param name="enableDiagnostics">
/// Enables detailed diagnostic output.
/// </param>
/// <returns>
/// Diagnostic result of source test.
/// </returns>
Models.ReaderDiagnosticResult TestSource(bool enableDiagnostics);
/// <summary>
/// Tests whether configured query is valid for the data source.
/// </summary>
/// <param name="enableDiagnostics">
/// Enables detailed diagnostic output.
/// </param>
/// <returns>
/// Diagnostic result of query test.
/// </returns>
Models.ReaderDiagnosticResult TestQuery(bool enableDiagnostics);
}
}
@@ -1,94 +0,0 @@
using System;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common.Models;
using GenesisCordonelInterface.Core.DataStorage.Reading.Common.Contracts;
namespace GenesisCordonelInterface.Core.DataStorage.Reading.Common
{
/// <summary>
/// Factory responsible for creating appropriate
/// data storage reader implementations.
///
/// The reader type is selected according to:
///
/// DataStorageConfig.Type
///
/// Example:
///
/// LocalDatabase
/// -> DatabaseDataStorageReader
///
/// LocalCsv
/// -> CsvDataStorageReader
///
/// LocalJson
/// -> JsonDataStorageReader
///
/// RestApi
/// -> RestApiDataStorageReader
///
/// This factory hides implementation details from
/// higher layers and keeps consumers independent
/// of storage technology.
///
/// Trace:
///
/// MeterLoginPasswordReader
/// -> DataStorageReaderFactory.Create()
/// -> DatabaseDataStorageReader
/// -> CsvDataStorageReader
/// -> JsonDataStorageReader
/// -> RestApiDataStorageReader
/// </summary>
public static class DataStorageReaderFactory
{
/// <summary>
/// Creates appropriate reader implementation
/// according to storage configuration.
/// </summary>
/// <param name="config">
/// Data storage configuration loaded from gci_config.json.
/// </param>
/// <returns>
/// Configured storage reader implementation.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Configuration is null.
/// </exception>
/// <exception cref="NotSupportedException">
/// Unsupported storage type.
/// </exception>
public static IDataStorageReader Create(
DataStorageConfig config)
{
if (config == null)
throw new ArgumentNullException(nameof(config));
switch (config.Type)
{
case DataStorageType.RemoteDatabase:
case DataStorageType.LocalDatabase:
return new Providers.DatabaseDataStorageReader(config);
case DataStorageType.RemoteCsv:
case DataStorageType.LocalCsv:
return new Providers.CsvDataStorageReader(config);
case DataStorageType.RemoteJson:
case DataStorageType.LocalJson:
return new Providers.JsonDataStorageReader(config);
case DataStorageType.RestApi:
return new Providers.RestApiDataStorageReader(config);
default:
throw new NotSupportedException(
$"Unsupported DataStorageType: '{config.Type}'");
}
}
}
}
@@ -1,58 +0,0 @@
using System.Collections.Generic;
namespace GenesisCordonelInterface.Core.DataStorage.Reading.Common.Models
{
/// <summary>
/// Represents query input for data storage readers.
///
/// Query parameters are used as lookup values
/// during storage search operations.
///
/// A single parameter:
///
/// 231630279
///
/// executes one lookup.
///
/// Multiple parameters:
///
/// 231630279
/// 231630243
/// 231630148
///
/// can execute batch operations.
///
/// Example:
///
/// QueryTemplate:
///
/// SELECT [Password]
/// WHERE [PcbId]=QUERYPARAM
///
/// Query:
///
/// QueryParams:
/// 231630279
///
/// Result:
///
/// Password belonging to 231630279.
/// </summary>
public class DataQuery
{
/// <summary>
/// Collection of query values.
///
/// Single item:
///
/// QueryParams[0]
///
/// represents one lookup.
///
/// Multiple items may be processed
/// as batch requests.
/// </summary>
public List<string> QueryParams { get; }
= new List<string>();
}
}

Some files were not shown because too many files have changed in this diff Show More