Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc8e82c0e8 | ||
|
|
1525bb7c1a | ||
|
|
2aeaf42325 | ||
|
|
bf4fb469da | ||
|
|
a20b0761fd | ||
|
|
3b9e8d754d | ||
|
|
fed3281525 | ||
|
|
c1d966d86a | ||
|
|
b2d2f8c13b | ||
|
|
4e5e3d63e1 | ||
|
|
25602fb914 | ||
|
|
602d0d5308 |
@@ -0,0 +1,19 @@
|
|||||||
|
<?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>
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<?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>
|
||||||
|
</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>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
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ú
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
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()
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
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")]
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <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
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <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", "4.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 ((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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
<?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.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: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" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</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" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?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>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="log4net" version="3.0.3" targetFramework="net472" />
|
||||||
|
</packages>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,410 @@
|
|||||||
|
///
|
||||||
|
/// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 842 B |
|
After Width: | Height: | Size: 768 B |
|
After Width: | Height: | Size: 746 B |
|
After Width: | Height: | Size: 894 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1018 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 667 B |
|
After Width: | Height: | Size: 667 B |
|
After Width: | Height: | Size: 661 B |
|
After Width: | Height: | Size: 661 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
@@ -98,6 +98,16 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Pictures\Clamping-XL-off.png" />
|
<Content Include="Pictures\Clamping-XL-off.png" />
|
||||||
<Content Include="Pictures\Clamping-XL-on.png" />
|
<Content Include="Pictures\Clamping-XL-on.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-L-open-dry.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-L-vacuum.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-M-open-dry.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-M-vacuum.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-S-open-dry.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-S-vacuum.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-XL-closed.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-XL-open-dry.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-XL-open.png" />
|
||||||
|
<Content Include="Pictures\ValveSw-XL-vacuum.png" />
|
||||||
<None Include="Pictures\Cover-XL-off.png" />
|
<None Include="Pictures\Cover-XL-off.png" />
|
||||||
<None Include="Pictures\Cover-XL-on.png" />
|
<None Include="Pictures\Cover-XL-on.png" />
|
||||||
<Content Include="Pictures\Div-L-sink-dry.png" />
|
<Content Include="Pictures\Div-L-sink-dry.png" />
|
||||||
@@ -191,6 +201,12 @@
|
|||||||
<Content Include="Pictures\Valve-XL-closed.png" />
|
<Content Include="Pictures\Valve-XL-closed.png" />
|
||||||
<Content Include="Pictures\Valve-XL-open-dry.png" />
|
<Content Include="Pictures\Valve-XL-open-dry.png" />
|
||||||
<Content Include="Pictures\Valve-XL-open.png" />
|
<Content Include="Pictures\Valve-XL-open.png" />
|
||||||
|
<None Include="Pictures\ValveSw-L-closed.png" />
|
||||||
|
<None Include="Pictures\ValveSw-L-open.png" />
|
||||||
|
<None Include="Pictures\ValveSw-M-closed.png" />
|
||||||
|
<None Include="Pictures\ValveSw-M-open.png" />
|
||||||
|
<None Include="Pictures\ValveSw-S-closed.png" />
|
||||||
|
<None Include="Pictures\ValveSw-S-open.png" />
|
||||||
<None Include="Pictures\WaterM-L.png" />
|
<None Include="Pictures\WaterM-L.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
|||||||
@@ -0,0 +1,234 @@
|
|||||||
|
using System.IO.MemoryMappedFiles;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SharedComponents
|
||||||
|
{
|
||||||
|
public class LiveLogCache
|
||||||
|
{
|
||||||
|
/*// Staticka instancia pre singleton
|
||||||
|
private static readonly LiveLogCache _instance = new LiveLogCache();
|
||||||
|
|
||||||
|
// Uzamykaci objekt pre bezpecny pristup z viacerych vlakien
|
||||||
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
|
// Zoznam na ukladanie logov
|
||||||
|
private readonly List<string> _logs = new List<string>();
|
||||||
|
|
||||||
|
// Udalost pre notifikaciu pri zmene logov
|
||||||
|
public event Action<string> LogAdded;
|
||||||
|
|
||||||
|
// Sukromny konstruktor (singleton pattern)
|
||||||
|
private LiveLogCache() { }
|
||||||
|
|
||||||
|
// Metoda na ziskanie poctu logov
|
||||||
|
public int GetCount()
|
||||||
|
{
|
||||||
|
return _logs.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Staticka metoda na ziskanie instancie
|
||||||
|
public static LiveLogCache Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verejna vlastnost na ziskanie logov
|
||||||
|
public IReadOnlyList<string> Logs
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _logs.AsReadOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metoda na pridanie logu
|
||||||
|
public void AddLog(string log)
|
||||||
|
{
|
||||||
|
// Ziskanie aktualneho casu v pozadovanom formate
|
||||||
|
string timeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:");
|
||||||
|
|
||||||
|
// Vytvorenie noveho logu s casovou peciatkou na zaciatku
|
||||||
|
string logWithTimeStamp = $"{timeStamp} {log}";
|
||||||
|
|
||||||
|
// Pridanie logu do zoznamu
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_logs.Add(logWithTimeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spustenie udalosti pre notifikaciu
|
||||||
|
LogAdded?.Invoke(logWithTimeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metoda na vycistenie logov
|
||||||
|
public void ClearLogs()
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_logs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volitelne: Spusti udalost, ak by sme chceli notifikovat aj o vymazani logov
|
||||||
|
LogAdded?.Invoke("Logs were cleared.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ziskanie vsetkych logov
|
||||||
|
public List<string> GetAllLogs()
|
||||||
|
{
|
||||||
|
return new List<string>(_logs); // Vratime kopiu logov
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ziskanie logov medzi urcitou poziciou (s upravenym indexovanim)
|
||||||
|
public List<string> GetLogs(int startIndex, int count)
|
||||||
|
{
|
||||||
|
// Zabezpeci, ze indexy nebudu mimo rozsahu
|
||||||
|
return _logs.Skip(startIndex).Take(count).ToList();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Zlepseny kod, ktory umoznuje pracu s MemoryMappedFile, namiesto len priestoru vo virtualnej pamati, navyse je tento subor velkostne obmedzeny na 1MB
|
||||||
|
|
||||||
|
// Staticka instancia pre singleton
|
||||||
|
private static readonly LiveLogCache _instance = new LiveLogCache(true);
|
||||||
|
|
||||||
|
// Uzamykaci objekt pre bezpecny pristup z viacerych vlakien
|
||||||
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
|
// Zoznam na ukladanie logov
|
||||||
|
private readonly List<string> _logs = new List<string>();
|
||||||
|
|
||||||
|
// Udalost pre notifikaciu pri zmene logov
|
||||||
|
public event Action<string> LogAdded;
|
||||||
|
|
||||||
|
// Memory-mapped file
|
||||||
|
private MemoryMappedFile _mmf;
|
||||||
|
private MemoryMappedViewAccessor _accessor;
|
||||||
|
private const int MaxLogSize = 1024 * 1024; // 1MB
|
||||||
|
|
||||||
|
// Sukromny konstruktor (singleton pattern)
|
||||||
|
private LiveLogCache(bool itsLogsCreator)
|
||||||
|
{
|
||||||
|
if (itsLogsCreator == true)
|
||||||
|
{
|
||||||
|
_mmf = MemoryMappedFile.CreateOrOpen("LiveLogCacheMMF", MaxLogSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_mmf = MemoryMappedFile.OpenExisting("LiveLogCacheMMF");
|
||||||
|
}
|
||||||
|
|
||||||
|
_accessor = _mmf.CreateViewAccessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metoda na ziskanie poctu logov
|
||||||
|
public int GetCount()
|
||||||
|
{
|
||||||
|
return _logs.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Staticka metoda na ziskanie instancie
|
||||||
|
public static LiveLogCache Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verejna vlastnost na ziskanie logov
|
||||||
|
public IReadOnlyList<string> Logs
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _logs.AsReadOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metoda na pridanie logu
|
||||||
|
public void AddLog(string log)
|
||||||
|
{
|
||||||
|
// Ziskanie aktualneho casu v pozadovanom formate
|
||||||
|
string timeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:");
|
||||||
|
|
||||||
|
// Vytvorenie noveho logu s casovou peciatkou na zaciatku
|
||||||
|
string logWithTimeStamp = $"{timeStamp} {log}";
|
||||||
|
|
||||||
|
// Pridanie logu do zoznamu
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_logs.Add(logWithTimeStamp);
|
||||||
|
WriteLogToMemoryMappedFile(logWithTimeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spustenie udalosti pre notifikaciu
|
||||||
|
LogAdded?.Invoke(logWithTimeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metoda na vycistenie logov
|
||||||
|
public void ClearLogs()
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_logs.Clear();
|
||||||
|
ClearMemoryMappedFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volitelne: Spusti udalost, ak by sme chceli notifikovat aj o vymazani logov
|
||||||
|
LogAdded?.Invoke("Logs were cleared.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ziskanie vsetkych logov
|
||||||
|
public List<string> GetAllLogs()
|
||||||
|
{
|
||||||
|
return new List<string>(_logs); // Vratime kopiu logov
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ziskanie logov medzi urcitou poziciou (s upravenym indexovanim)
|
||||||
|
public List<string> GetLogs(int startIndex, int count)
|
||||||
|
{
|
||||||
|
// Zabezpeci, ze indexy nebudu mimo rozsahu
|
||||||
|
return _logs.Skip(startIndex).Take(count).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metoda na naplnenie ListView
|
||||||
|
/*public void PopulateListView(ListView listView)
|
||||||
|
{
|
||||||
|
listView.Items.Clear();
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
foreach (var log in _logs)
|
||||||
|
{
|
||||||
|
listView.Items.Add(new ListView Item(log));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Write log to memory-mapped file
|
||||||
|
private void WriteLogToMemoryMappedFile(string log)
|
||||||
|
{
|
||||||
|
byte[] logBytes = Encoding.UTF8.GetBytes(log + Environment.NewLine);
|
||||||
|
_accessor.WriteArray(0, logBytes, 0, logBytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear memory-mapped file
|
||||||
|
private void ClearMemoryMappedFile()
|
||||||
|
{
|
||||||
|
byte[] emptyBytes = new byte[MaxLogSize];
|
||||||
|
_accessor.WriteArray(0, emptyBytes, 0, emptyBytes.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net472</TargetFramework>
|
||||||
|
<LangVersion>10.0</LangVersion>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
is_global = true
|
||||||
|
build_property.RootNamespace = SharedComponents
|
||||||
|
build_property.ProjectDir = C:\Users\micha\git\tbf\SharedComponents\
|
||||||
|
build_property.EnableComHosting =
|
||||||
|
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// <auto-generated/>
|
||||||
|
global using global::System;
|
||||||
|
global using global::System.Collections.Generic;
|
||||||
|
global using global::System.IO;
|
||||||
|
global using global::System.Linq;
|
||||||
|
global using global::System.Threading;
|
||||||
|
global using global::System.Threading.Tasks;
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\micha\.nuget\packages\</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.14.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="C:\Users\micha\.nuget\packages\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||||
@@ -76,7 +76,7 @@ namespace TBF.Boxes
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return string.Format(Format, Val * Factor);
|
return string.Format(string.Format("{{0:{0}}}", Format), Val * Factor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
///
|
///
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Common;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Dirichlet.Numerics;
|
using Dirichlet.Numerics;
|
||||||
using TBF.Boxes;
|
using TBF.Boxes;
|
||||||
@@ -273,6 +274,11 @@ namespace TBF.Rig.BuiltIn
|
|||||||
/// <summary>Start this operation</summary>
|
/// <summary>Start this operation</summary>
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
if (cb.DebugLevel == DebugMode.Simulate)
|
||||||
|
{
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
UInt128 changed = cb.SetValves(switchPoints[0].MasksOpen, switchPoints[0].MasksClose, StateMachine.LogicalFnValves);
|
UInt128 changed = cb.SetValves(switchPoints[0].MasksOpen, switchPoints[0].MasksClose, StateMachine.LogicalFnValves);
|
||||||
|
|
||||||
if (timeStamp != null && switchPoints[0].TimeSec == timeShift)
|
if (timeStamp != null && switchPoints[0].TimeSec == timeShift)
|
||||||
@@ -291,7 +297,12 @@ namespace TBF.Rig.BuiltIn
|
|||||||
/// </returns>
|
/// </returns>
|
||||||
public Event Run()
|
public Event Run()
|
||||||
{
|
{
|
||||||
if (nextIx >= switchPoints.Count)
|
if (cb.DebugLevel == DebugMode.Simulate)
|
||||||
|
{
|
||||||
|
return Event.ValvesSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextIx >= switchPoints.Count)
|
||||||
{
|
{
|
||||||
return (StateMachine.Time >= swStartTime + maxDelayTime + waitOnCBDelay) ? Event.ValvesSet : Event.ValvesBusy;
|
return (StateMachine.Time >= swStartTime + maxDelayTime + waitOnCBDelay) ? Event.ValvesSet : Event.ValvesBusy;
|
||||||
}
|
}
|
||||||
@@ -320,6 +331,11 @@ namespace TBF.Rig.BuiltIn
|
|||||||
/// <summary>Start this operation</summary>
|
/// <summary>Start this operation</summary>
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
|
if (cb.DebugLevel == DebugMode.Simulate)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (switchTime != null && startStopValveBitNr >= 16 && startStopValveBitNr <= 23 && cb is ControlBoard.Uni.UniCB)
|
if (switchTime != null && startStopValveBitNr >= 16 && startStopValveBitNr <= 23 && cb is ControlBoard.Uni.UniCB)
|
||||||
{
|
{
|
||||||
switchTime.Val = (cb as ControlBoard.Uni.UniCB).Data.ValveSwitchTime[startStopValveBitNr - 16];
|
switchTime.Val = (cb as ControlBoard.Uni.UniCB).Data.ValveSwitchTime[startStopValveBitNr - 16];
|
||||||
|
|||||||
@@ -539,12 +539,10 @@ namespace TBF.Rig.Sequences
|
|||||||
//---endnew2
|
//---endnew2
|
||||||
(outPath.Scale is IScale) ? (outPath.Scale as IScale).Mass : 0, /// collected water mass in kg
|
(outPath.Scale is IScale) ? (outPath.Scale as IScale).Mass : 0, /// collected water mass in kg
|
||||||
"VolMM",
|
"VolMM",
|
||||||
//---new2
|
AmbTemp, /// ambient temperature in degree C
|
||||||
AmbTemp.ToString(), /// ambient temperature in degree C
|
AmbHumi, /// ambient humidity in R%
|
||||||
AmbHumi.ToString(), /// ambient humidity in R%
|
AmbPress, /// ambient pressure in mbar (= 1 hPa)
|
||||||
AmbPress.ToString(), /// ambient pressure in mbar (= 1 hPa)
|
outPath.RegValve?.Position.ToString("F1")); /// regulation valve position in % (0=closed / 100=open)
|
||||||
//---endnew2
|
|
||||||
outPath.RegValve.Position.ToString("F1")); /// regulation valve position in % (0=closed / 100=open)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogProcessDataHeaderHeatMeters(ILog logger, string sectionName)
|
public void LogProcessDataHeaderHeatMeters(ILog logger, string sectionName)
|
||||||
|
|||||||
@@ -1505,23 +1505,25 @@ namespace TBF.Rig.Sequences
|
|||||||
tstRslt.DensityLine = Formulas.RealDensity();
|
tstRslt.DensityLine = Formulas.RealDensity();
|
||||||
tstRslt.DensityDiv = Formulas.RealDensity();
|
tstRslt.DensityDiv = Formulas.RealDensity();
|
||||||
|
|
||||||
|
double flowMeterLtrPerPulse = outPath.FlowMeter?.LtrPerPulse ?? 1;
|
||||||
|
|
||||||
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
|
||||||
tstRslt.StartTime = DateTime.Now;
|
tstRslt.StartTime = DateTime.Now;
|
||||||
tstRslt.EndTime = DateTime.Now + new TimeSpan(0, 0, 1);
|
tstRslt.EndTime = DateTime.Now + new TimeSpan(0, 0, 1);
|
||||||
tstRslt.FlowSetTime = 10;
|
tstRslt.FlowSetTime = 10;
|
||||||
tstRslt.TestTime = tstRslt.TargetTime();
|
tstRslt.TestTime = tstRslt.TargetTime();
|
||||||
tstRslt.PulsesMaster = (outPath.FlowMeter.LtrPerPulse > 1E-6) ? (1.0075 * tstRslt.TargetVolume() / outPath.FlowMeter.LtrPerPulse) : 1;
|
tstRslt.PulsesMaster = (flowMeterLtrPerPulse > 1E-6) ? (1.0075 * tstRslt.TargetVolume() / flowMeterLtrPerPulse) : 1;
|
||||||
tstRslt.MassStartRaw = 0;
|
tstRslt.MassStartRaw = 0;
|
||||||
tstRslt.MassStart = MeasurementCorrection.CorrectedValue(tstRslt.MassStartRaw, outPath.Scale.Corrections);
|
tstRslt.MassStart = MeasurementCorrection.CorrectedValue(tstRslt.MassStartRaw, outPath.Scale.Corrections);
|
||||||
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Formulas.RealDensity() / 1000.0f;
|
tstRslt.MassEndRaw = tstRslt.TargetVolume() * Formulas.RealDensity() / 1000.0f;
|
||||||
tstRslt.MassEnd = MeasurementCorrection.CorrectedValue(tstRslt.MassEndRaw, outPath.Scale.Corrections);
|
tstRslt.MassEnd = MeasurementCorrection.CorrectedValue(tstRslt.MassEndRaw, outPath.Scale.Corrections);
|
||||||
tstRslt.Flow = 3.6 * outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster / tstRslt.TestTime;
|
tstRslt.Flow = 3.6 * flowMeterLtrPerPulse * tstRslt.PulsesMaster / tstRslt.TestTime;
|
||||||
tstRslt.MassOfEvapWater = 0;
|
tstRslt.MassOfEvapWater = 0;
|
||||||
tstRslt.VolumeCTV = 1000 * tstRslt.Batch.Buoyancy * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.DensityLine; /// [l] commercially true volume
|
tstRslt.VolumeCTV = 1000 * tstRslt.Batch.Buoyancy * (tstRslt.MassEnd - tstRslt.MassStart) / tstRslt.DensityLine; /// [l] commercially true volume
|
||||||
tstRslt.VolumeMaster = outPath.FlowMeter.LtrPerPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
|
tstRslt.VolumeMaster = flowMeterLtrPerPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
|
||||||
tstRslt.ConstMasterRaw = outPath.FlowMeter.LtrPerPulse; /// Uncorrected master flowmeter coefficient
|
tstRslt.ConstMasterRaw = flowMeterLtrPerPulse; /// Uncorrected master flowmeter coefficient
|
||||||
tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean); /// Corrected master pulses per liter
|
tstRslt.ConstMasterCorr = outPath.FlowMeter?.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean) ?? 1; /// Corrected master pulses per liter
|
||||||
tstRslt.ConstMaster = (tstRslt.VolumeMaster == 0) ? tstRslt.ConstMasterCorr : (outPath.FlowMeter.LtrPerPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster);
|
tstRslt.ConstMaster = (tstRslt.VolumeMaster == 0) ? tstRslt.ConstMasterCorr : (flowMeterLtrPerPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster);
|
||||||
|
|
||||||
tstRslt.ErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV);
|
tstRslt.ErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV);
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,11 @@ namespace TBF.Rig.TestMethods.LeakTest
|
|||||||
Bridge.OnActivity(this, Strings.Setting_the_water_pressure);
|
Bridge.OnActivity(this, Strings.Setting_the_water_pressure);
|
||||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
|
|
||||||
|
//TODO BUMI - check this possition for sstart logging - when finish remove this comment
|
||||||
|
//--- log start process in this section
|
||||||
|
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
|
||||||
|
|
||||||
|
|
||||||
float pumpPower = test.PumpPower;
|
float pumpPower = test.PumpPower;
|
||||||
int startTime = StateMachine.Time;
|
int startTime = StateMachine.Time;
|
||||||
@@ -214,10 +219,14 @@ namespace TBF.Rig.TestMethods.LeakTest
|
|||||||
Bridge.OnActivity(this, Strings.Test_in_progress);
|
Bridge.OnActivity(this, Strings.Test_in_progress);
|
||||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
|
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
|
|
||||||
|
LogProcessDataHeader(processDataLogger, "Maximum water pressure set");
|
||||||
|
|
||||||
State.Create(string.Format("{0}({1}) : Maximum water pressure set", test.Method, test.Name))
|
State.Create(string.Format("{0}({1}) : Maximum water pressure set", test.Method, test.Name))
|
||||||
.AddOperation(checkUiOp)
|
.AddOperation(checkUiOp)
|
||||||
.AddOperations(readTempPressOps)
|
.AddOperations(readTempPressOps)
|
||||||
.AddOperation(new Operations.TimerOp(testParams.DurationPMax))
|
.AddOperation(new Operations.TimerOp(testParams.DurationPMax))
|
||||||
|
.AddOperation(processDataLoggingOp)
|
||||||
.EnterState();
|
.EnterState();
|
||||||
do {
|
do {
|
||||||
e = StateMachine.WaitRunDevsRunOps();
|
e = StateMachine.WaitRunDevsRunOps();
|
||||||
@@ -246,10 +255,14 @@ namespace TBF.Rig.TestMethods.LeakTest
|
|||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
Bridge.OnActivity(this, Strings.Measuring_the_weight);
|
Bridge.OnActivity(this, Strings.Measuring_the_weight);
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
LogProcessDataHeader(processDataLogger, "Measuring the start mass");
|
||||||
|
|
||||||
State.Create(string.Format("{0}({1}) : Measuring the start mass", test.Method, test.Name))
|
State.Create(string.Format("{0}({1}) : Measuring the start mass", test.Method, test.Name))
|
||||||
.AddOperation(checkUiOp)
|
.AddOperation(checkUiOp)
|
||||||
.AddOperations(readTempPressOps)
|
.AddOperations(readTempPressOps)
|
||||||
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
||||||
|
.AddOperation(processDataLoggingOp)
|
||||||
.EnterState();
|
.EnterState();
|
||||||
do {
|
do {
|
||||||
e = StateMachine.WaitRunDevsRunOps();
|
e = StateMachine.WaitRunDevsRunOps();
|
||||||
@@ -275,10 +288,14 @@ namespace TBF.Rig.TestMethods.LeakTest
|
|||||||
///------------------------------------------------
|
///------------------------------------------------
|
||||||
Bridge.OnActivity(this, Strings.Test_in_progress);
|
Bridge.OnActivity(this, Strings.Test_in_progress);
|
||||||
///------------------------------------------------
|
///------------------------------------------------
|
||||||
|
|
||||||
|
LogProcessDataHeader(processDataLogger, "Starting the test");
|
||||||
|
|
||||||
State.Create(string.Format("{0}({1}) : Starting the test", test.Method, test.Name))
|
State.Create(string.Format("{0}({1}) : Starting the test", test.Method, test.Name))
|
||||||
.AddOperation(checkUiOp)
|
.AddOperation(checkUiOp)
|
||||||
.AddOperations(readTempPressOps)
|
.AddOperations(readTempPressOps)
|
||||||
.AddOperation(new Operations.TimerOp(testParams.DurationLeak))
|
.AddOperation(new Operations.TimerOp(testParams.DurationLeak))
|
||||||
|
.AddOperation(processDataLoggingOp)
|
||||||
.EnterState();
|
.EnterState();
|
||||||
do {
|
do {
|
||||||
e = StateMachine.WaitRunDevsRunOps();
|
e = StateMachine.WaitRunDevsRunOps();
|
||||||
@@ -305,10 +322,14 @@ namespace TBF.Rig.TestMethods.LeakTest
|
|||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
Bridge.OnActivity(this, Strings.Measuring_the_weight);
|
Bridge.OnActivity(this, Strings.Measuring_the_weight);
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
LogProcessDataHeader(processDataLogger, " Measuring the end mass");
|
||||||
|
|
||||||
State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name))
|
State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name))
|
||||||
.AddOperation(checkUiOp)
|
.AddOperation(checkUiOp)
|
||||||
.AddOperations(readTempPressOps)
|
.AddOperations(readTempPressOps)
|
||||||
.AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
.AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
|
||||||
|
.AddOperation(processDataLoggingOp)
|
||||||
.EnterState();
|
.EnterState();
|
||||||
do {
|
do {
|
||||||
e = StateMachine.WaitRunDevsRunOps();
|
e = StateMachine.WaitRunDevsRunOps();
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ namespace TBF.Rig.TestMethods.PMaxTest
|
|||||||
Bridge.OnActivity(this, Strings.Setting_the_water_pressure);
|
Bridge.OnActivity(this, Strings.Setting_the_water_pressure);
|
||||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.FlowSetting));
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
|
|
||||||
float pumpPower = test.PumpPower;
|
float pumpPower = test.PumpPower;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@@ -175,11 +175,21 @@ namespace TBF.Rig.TestMethods.PMaxTest
|
|||||||
|
|
||||||
int startTime = StateMachine.Time;
|
int startTime = StateMachine.Time;
|
||||||
int endTime = startTime + testParams.DurationPMax;
|
int endTime = startTime + testParams.DurationPMax;
|
||||||
|
|
||||||
|
//TODO BUMI - check this possition for sstart logging - when finish remove this comment
|
||||||
|
//--- log start process in this section
|
||||||
|
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
|
||||||
|
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
Bridge.OnActivity(this, Strings.Test_in_progress);
|
Bridge.OnActivity(this, Strings.Test_in_progress);
|
||||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
|
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Progress.Test));
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
|
|
||||||
|
//TODO BUMI - check if is ok possition to start logging - at last remove comment
|
||||||
|
//--- log start process in this section
|
||||||
|
LogProcessDataHeader(processDataLogger, "Starting the test");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*//---new1
|
/*//---new1
|
||||||
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
|
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
|
||||||
@@ -194,10 +204,8 @@ namespace TBF.Rig.TestMethods.PMaxTest
|
|||||||
.AddOperation(checkUiOp)
|
.AddOperation(checkUiOp)
|
||||||
.AddOperations(readTempPressOps)
|
.AddOperations(readTempPressOps)
|
||||||
.AddOperation(new Operations.TimerOp(testParams.DurationPMax))
|
.AddOperation(new Operations.TimerOp(testParams.DurationPMax))
|
||||||
//---new1
|
.AddOperation(processDataLoggingOp)
|
||||||
.AddOperation(processDataLoggingOp)
|
.EnterState();
|
||||||
//---endNew1
|
|
||||||
.EnterState();
|
|
||||||
do {
|
do {
|
||||||
e = StateMachine.WaitRunDevsRunOps();
|
e = StateMachine.WaitRunDevsRunOps();
|
||||||
|
|
||||||
@@ -213,7 +221,8 @@ namespace TBF.Rig.TestMethods.PMaxTest
|
|||||||
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
|
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
|
||||||
}
|
}
|
||||||
while (e.Contains(Event.TimerBusy));
|
while (e.Contains(Event.TimerBusy));
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// PMaxTest completed
|
/// PMaxTest completed
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
using Config.Resources;
|
||||||
|
using log4net;
|
||||||
|
using Sensus.iPerl.RfidCom.Helper;
|
||||||
|
using Sensus.iPerl.RfidCom.Services;
|
||||||
|
using Sensus.iPerl.RfidCom.Structures;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using TBF.Rig.Hart.Common;
|
||||||
|
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
|
||||||
|
using static Sensus.iPerl.NfcHandler.MCI_Protocol;
|
||||||
|
|
||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||||
|
{
|
||||||
|
internal class OpticalHeadTest
|
||||||
|
{
|
||||||
|
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||||
|
|
||||||
|
internal static string OpenSealing(IperlHead iHead)
|
||||||
|
{
|
||||||
|
if (RfidCommands.OpenSealing($"COM{iHead.RfidComPortNr}")) return "OK";
|
||||||
|
return "Error Open Sealing";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ReadRequest_PCB(IperlHead iHead)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] pcb = null;
|
||||||
|
int readRetVal = iPerlCommunicationForm.ReadRequestPort(iHead, MessageID.Configuration, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.Configuration, 16, 5, out pcb);
|
||||||
|
if (readRetVal == 0)
|
||||||
|
{
|
||||||
|
return RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(BitConverter.ToString(pcb).Replace("-", string.Empty))).ToString();
|
||||||
|
}
|
||||||
|
rfidDataLogger.Error($"COM{iHead.RfidComPortNr}: ReadRequest_PCB ({MessageID.Configuration},16,5...) <- Error: {readRetVal}");
|
||||||
|
return "Error";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return (ex.Message.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string SetActiveMode(IperlHead iHead)
|
||||||
|
{
|
||||||
|
byte[] cmd = new byte[1] { (byte)Command.SetActiveMode };
|
||||||
|
if (0 == iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.Command, StructName.Command, 0, 1, cmd))
|
||||||
|
{
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "Error Set Active Mode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string SetTestMode(IperlHead iHead)
|
||||||
|
{
|
||||||
|
byte[] cmd = new byte[1] { (byte)Command.SetTestMode };
|
||||||
|
if (0 == iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.Command, StructName.Command, 0, 1, cmd))
|
||||||
|
{
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "Error Set Test Mode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if IPERL
|
||||||
|
internal static string TurnOffRadio(IperlHead iHead)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int retValue = iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.RadioPassthrough, StructName.RadioParams, 0x1898, 1, new byte[] { (byte)3 }); // WakeUpInterval
|
||||||
|
return 0 == retValue ? "OK" : "Error";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return (ex.Message.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string SetProductionMode(IperlHead iHead)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int retValue = iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.RadioPassthrough, StructName.RadioInfo, 0x1804, 1, new byte[] { (byte)1 }); // System Status
|
||||||
|
return 0 == retValue ? "OK" : "Error";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return (ex.Message.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string WriteRequestPort_u8_Customer_Text(IperlHead iHead)
|
||||||
|
{
|
||||||
|
string custText = "FF0123456789ABCDEF"; // Sample text to test write function
|
||||||
|
/*try
|
||||||
|
{
|
||||||
|
byte[] cmd = RfidHelper.HexStringToByteArray(custText);
|
||||||
|
if (0 == iPerlCommunicationForm.WriteRequestPort(iHead, MessageID.RadioPassthrough, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.RadioParams, 0x1899, 9, cmd))
|
||||||
|
{
|
||||||
|
RfidCommunicationService rfidCommunicationService = new RfidCommunicationService { ComPort = $"COM{iHead.RfidComPortNr}", WaitTimeAfterFailure = 2200, PassThroughWaitTime = 1500, MaxRetries = 3, TimeOut = 5000 };
|
||||||
|
//rfidCommunicationService.RfidWrite(Params.u8_Customer_Text, custText);
|
||||||
|
return rfidCommunicationService.RfidRead<string>(Params.u8_Customer_Text).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return (ex.Message.ToString());
|
||||||
|
}*/
|
||||||
|
return $"Error COM{iHead.RfidComPortNr}";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string SetRfidMode(IperlHead iHead)
|
||||||
|
{
|
||||||
|
iHead.SetRfidInterface();
|
||||||
|
iHead.SetCommunicationInterface(CommunicationInterface.RFID);
|
||||||
|
return ($"OK - {Strings.Program_restart_is_required_to_apply_some_settings}");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string SetNfcMode(IperlHead iHead)
|
||||||
|
{
|
||||||
|
iHead.SetNfcInterface();
|
||||||
|
iHead.SetCommunicationInterface(CommunicationInterface.NFC);
|
||||||
|
return ($"OK - {Strings.Program_restart_is_required_to_apply_some_settings}");
|
||||||
|
}
|
||||||
|
#endif /// IPERL
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2022 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using TBF.Resources;
|
||||||
|
|
||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication
|
||||||
|
{
|
||||||
|
public enum ConditionID
|
||||||
|
{
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
Count,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SequenceConditionOp : IOperation
|
||||||
|
{
|
||||||
|
public const string ConditionNameFmt = "iPERL communication milestone {0}";
|
||||||
|
|
||||||
|
ConditionID id;
|
||||||
|
TestMethod testMethodComponent;
|
||||||
|
|
||||||
|
public SequenceConditionOp(TestMethod testMethodComponent, ConditionID id)
|
||||||
|
{
|
||||||
|
this.testMethodComponent = testMethodComponent;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start() { }
|
||||||
|
|
||||||
|
public Event Run()
|
||||||
|
{
|
||||||
|
bool conditionMet = testMethodComponent.IperlCommMilestone[(int)id];
|
||||||
|
return conditionMet ? Event.ConditionMet : Event.ConditionNotMet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop() { }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format(ConditionNameFmt, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
|
||||||
|
{
|
||||||
|
partial class IperlHeadTestCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.optoTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||||
|
this.optoListBox = new System.Windows.Forms.ListBox();
|
||||||
|
this.rfidOutputListBox = new System.Windows.Forms.ListBox();
|
||||||
|
this.RfidTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.rfidCommandComboBox = new System.Windows.Forms.ComboBox();
|
||||||
|
this.commandTestButton = new System.Windows.Forms.Button();
|
||||||
|
this.optoTestGroupBox.SuspendLayout();
|
||||||
|
this.RfidTestGroupBox.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// optoTestGroupBox
|
||||||
|
//
|
||||||
|
this.optoTestGroupBox.Controls.Add(this.optoListBox);
|
||||||
|
this.optoTestGroupBox.Location = new System.Drawing.Point(5, 4);
|
||||||
|
this.optoTestGroupBox.Name = "optoTestGroupBox";
|
||||||
|
this.optoTestGroupBox.Size = new System.Drawing.Size(591, 161);
|
||||||
|
this.optoTestGroupBox.TabIndex = 2;
|
||||||
|
this.optoTestGroupBox.TabStop = false;
|
||||||
|
this.optoTestGroupBox.Text = "Opto-data";
|
||||||
|
//
|
||||||
|
// optoListBox
|
||||||
|
//
|
||||||
|
this.optoListBox.FormattingEnabled = true;
|
||||||
|
this.optoListBox.ItemHeight = 16;
|
||||||
|
this.optoListBox.Location = new System.Drawing.Point(7, 22);
|
||||||
|
this.optoListBox.Name = "optoListBox";
|
||||||
|
this.optoListBox.Size = new System.Drawing.Size(573, 132);
|
||||||
|
this.optoListBox.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// rfidOutputListBox
|
||||||
|
//
|
||||||
|
this.rfidOutputListBox.FormattingEnabled = true;
|
||||||
|
this.rfidOutputListBox.ItemHeight = 16;
|
||||||
|
this.rfidOutputListBox.Location = new System.Drawing.Point(5, 54);
|
||||||
|
this.rfidOutputListBox.Name = "rfidOutputListBox";
|
||||||
|
this.rfidOutputListBox.SelectionMode = System.Windows.Forms.SelectionMode.None;
|
||||||
|
this.rfidOutputListBox.Size = new System.Drawing.Size(575, 164);
|
||||||
|
this.rfidOutputListBox.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// RfidTestGroupBox
|
||||||
|
//
|
||||||
|
this.RfidTestGroupBox.Controls.Add(this.rfidOutputListBox);
|
||||||
|
this.RfidTestGroupBox.Controls.Add(this.label2);
|
||||||
|
this.RfidTestGroupBox.Controls.Add(this.rfidCommandComboBox);
|
||||||
|
this.RfidTestGroupBox.Controls.Add(this.commandTestButton);
|
||||||
|
this.RfidTestGroupBox.Location = new System.Drawing.Point(5, 171);
|
||||||
|
this.RfidTestGroupBox.Name = "RfidTestGroupBox";
|
||||||
|
this.RfidTestGroupBox.Size = new System.Drawing.Size(591, 224);
|
||||||
|
this.RfidTestGroupBox.TabIndex = 3;
|
||||||
|
this.RfidTestGroupBox.TabStop = false;
|
||||||
|
this.RfidTestGroupBox.Text = "RFID / NFC data";
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.AutoSize = true;
|
||||||
|
this.label2.Location = new System.Drawing.Point(2, 25);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(69, 16);
|
||||||
|
this.label2.TabIndex = 2;
|
||||||
|
this.label2.Text = "Command";
|
||||||
|
//
|
||||||
|
// rfidCommandComboBox
|
||||||
|
//
|
||||||
|
this.rfidCommandComboBox.FormattingEnabled = true;
|
||||||
|
this.rfidCommandComboBox.Location = new System.Drawing.Point(86, 19);
|
||||||
|
this.rfidCommandComboBox.Name = "rfidCommandComboBox";
|
||||||
|
this.rfidCommandComboBox.Size = new System.Drawing.Size(341, 24);
|
||||||
|
this.rfidCommandComboBox.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// commandTestButton
|
||||||
|
//
|
||||||
|
this.commandTestButton.Location = new System.Drawing.Point(449, 19);
|
||||||
|
this.commandTestButton.Name = "commandTestButton";
|
||||||
|
this.commandTestButton.Size = new System.Drawing.Size(126, 24);
|
||||||
|
this.commandTestButton.TabIndex = 0;
|
||||||
|
this.commandTestButton.Text = "Send command";
|
||||||
|
this.commandTestButton.UseVisualStyleBackColor = true;
|
||||||
|
this.commandTestButton.MouseClick += new System.Windows.Forms.MouseEventHandler(this.CommandTestButtonClick);
|
||||||
|
//
|
||||||
|
// IperlHeadTestCtrl
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.Controls.Add(this.optoTestGroupBox);
|
||||||
|
this.Controls.Add(this.RfidTestGroupBox);
|
||||||
|
this.Name = "IperlHeadTestCtrl";
|
||||||
|
this.Size = new System.Drawing.Size(611, 432);
|
||||||
|
this.Load += new System.EventHandler(this.UserControl_Load);
|
||||||
|
this.optoTestGroupBox.ResumeLayout(false);
|
||||||
|
this.RfidTestGroupBox.ResumeLayout(false);
|
||||||
|
this.RfidTestGroupBox.PerformLayout();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.GroupBox optoTestGroupBox;
|
||||||
|
private System.Windows.Forms.ListBox rfidOutputListBox;
|
||||||
|
private System.Windows.Forms.GroupBox RfidTestGroupBox;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.ComboBox rfidCommandComboBox;
|
||||||
|
private System.Windows.Forms.Button commandTestButton;
|
||||||
|
private System.Windows.Forms.ListBox optoListBox;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using TBF.Rig.Sequences;
|
||||||
|
|
||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
|
||||||
|
{
|
||||||
|
public partial class IperlHeadTestCtrl : UserControl
|
||||||
|
{
|
||||||
|
IperlHeadCfg config;
|
||||||
|
IperlHead iPerlHead;
|
||||||
|
Thread optoThread;
|
||||||
|
|
||||||
|
private bool stopWorkerThread;
|
||||||
|
public event EventHandler<OptoReceivedEventArgs> OptoReceivedHandler;
|
||||||
|
|
||||||
|
public IperlHeadTestCtrl(IperlHeadCfg config)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
InitializeComponent();
|
||||||
|
if (config == null) return;
|
||||||
|
|
||||||
|
iPerlCommunicationForm.cfg = new TestMethodCfg(null); // default values for iPerlCommunication
|
||||||
|
|
||||||
|
foreach(var head in ProcessData.IperlHeads)
|
||||||
|
{
|
||||||
|
if (head != null && head.Name == config.Name) { iPerlHead = head; }
|
||||||
|
}
|
||||||
|
|
||||||
|
rfidCommandComboBox.DisplayMember = "Name";
|
||||||
|
rfidCommandComboBox.ValueMember = "Value";
|
||||||
|
var items = new[]
|
||||||
|
{
|
||||||
|
new {Name = "Read PCB", Value = "ReadPCB" },
|
||||||
|
new {Name = "Set Test Mode", Value = "SetTestMode" },
|
||||||
|
new {Name = "Set Active Mode", Value = "SetActiveMode" },
|
||||||
|
#if DEBUG
|
||||||
|
new {Name = "Start Read Opto Data", Value = "ReadOptoData" },
|
||||||
|
new {Name = "Stop Read Opto Data", Value = "StopReadOptoData" },
|
||||||
|
#endif
|
||||||
|
new {Name = " ", Value = "" },
|
||||||
|
new {Name = "Reset NFC Head", Value = "ResetNfcHead" },
|
||||||
|
new {Name = "Set NFC Head Interface", Value = "SetNfcHead" },
|
||||||
|
new {Name = "Set RFID Head interface", Value = "SetRfidHead" }
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
// CTRL+ALT+double click - hidden poweruser menu
|
||||||
|
if (((Keyboard.ModifierKeys & Keys.Control) == Keys.Control) && ((Keyboard.ModifierKeys & Keys.Alt) == Keys.Alt) && Users.CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser)
|
||||||
|
{
|
||||||
|
Array.Resize(ref items, items.Length + 1);
|
||||||
|
items[items.Length - 1] = new { Name = "Kluc", Value = "Kluc" };
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
rfidCommandComboBox.DataSource = items;
|
||||||
|
|
||||||
|
stopWorkerThread = false;
|
||||||
|
|
||||||
|
OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
|
||||||
|
{
|
||||||
|
if (this.InvokeRequired)
|
||||||
|
this.Invoke((Delegate)new EventHandler<OptoReceivedEventArgs>(this.OnOptoReceived2), sndr, (object)args);
|
||||||
|
else
|
||||||
|
this.OnOptoReceived2(sndr, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnOptoReceived2(object sender, OptoReceivedEventArgs args)
|
||||||
|
{
|
||||||
|
optoListBox.Items.Insert(0,args.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CommandTestButtonClick(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
rfidOutputListBox.Items.Clear();
|
||||||
|
|
||||||
|
using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
|
||||||
|
{
|
||||||
|
ListItem rfidListItem = new ListItem();
|
||||||
|
rfidListItem.Attributes.Add("style", "font-weight:bold");
|
||||||
|
switch (rfidCommandComboBox.SelectedValue)
|
||||||
|
{
|
||||||
|
case "ReadPCB":
|
||||||
|
rfidListItem.Text = $"PCB: {OpticalHeadTest.ReadRequest_PCB(iPerlHead)}";
|
||||||
|
break;
|
||||||
|
case "SetTestMode":
|
||||||
|
rfidListItem.Text = OpticalHeadTest.SetTestMode(iPerlHead);
|
||||||
|
optoListBox.Items.Clear();
|
||||||
|
stopWorkerThread = false;
|
||||||
|
optoThread = new Thread(OptoWorker);
|
||||||
|
if (!optoThread.IsAlive)
|
||||||
|
{
|
||||||
|
iPerlHead.StartDataStreamProcessing(); // open opto port
|
||||||
|
optoThread.Start();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "SetActiveMode":
|
||||||
|
rfidListItem.Text = OpticalHeadTest.SetActiveMode(iPerlHead);
|
||||||
|
stopWorkerThread = true;
|
||||||
|
iPerlHead.StopDataStreamProcessing(); // close opto port
|
||||||
|
break;
|
||||||
|
case "ResetNfcHead":
|
||||||
|
iPerlHead.ResetNfcInterface();
|
||||||
|
break;
|
||||||
|
case "SetNfcHead":
|
||||||
|
iPerlHead.SetNfcInterface();
|
||||||
|
break;
|
||||||
|
case "SetRfidHead":
|
||||||
|
iPerlHead.SetRfidInterface();
|
||||||
|
break;
|
||||||
|
case "ReadOptoData":
|
||||||
|
optoListBox.Items.Clear();
|
||||||
|
stopWorkerThread = false;
|
||||||
|
optoThread = new Thread(OptoWorker);
|
||||||
|
if (optoThread.IsAlive)
|
||||||
|
{
|
||||||
|
stopWorkerThread = true;
|
||||||
|
iPerlHead.StopDataStreamProcessing(); // close opto port
|
||||||
|
}
|
||||||
|
if (!optoThread.IsAlive)
|
||||||
|
{
|
||||||
|
iPerlHead.StartDataStreamProcessing(); // open opto port
|
||||||
|
optoThread.Start();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "StopReadOptoData":
|
||||||
|
stopWorkerThread = true;
|
||||||
|
iPerlHead.StopDataStreamProcessing(); // close opto port
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rfidOutputListBox.Items.Add(rfidListItem);
|
||||||
|
rfidOutputListBox.Items.AddRange(logChecker.Messages.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OptoWorker()
|
||||||
|
{
|
||||||
|
while (!this.stopWorkerThread)
|
||||||
|
{
|
||||||
|
Thread.Sleep(250);
|
||||||
|
if (this.stopWorkerThread)
|
||||||
|
break;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string buffer = iPerlHead.ReadOptoData();
|
||||||
|
if (string.IsNullOrEmpty(buffer))
|
||||||
|
{
|
||||||
|
this.OnOptoReceived((object)this, new OptoReceivedEventArgs("."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
OnOptoReceived((object)this, new OptoReceivedEventArgs(buffer));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.OnOptoReceived((object)this, new OptoReceivedEventArgs(ex.Message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnOptoReceived(object sender, OptoReceivedEventArgs args)
|
||||||
|
{
|
||||||
|
if (this.OptoReceivedHandler == null)
|
||||||
|
return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.OptoReceivedHandler(sender, args);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
//OnHandleDestroyed(new EventArgs());
|
||||||
|
stopWorkerThread = true;
|
||||||
|
if (optoThread != null)
|
||||||
|
{
|
||||||
|
optoThread.Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,315 @@
|
|||||||
|
using log4net;
|
||||||
|
using Sensus.iPerl.NfcHandler;
|
||||||
|
using Sensus.iPerl.RfidCom.Exceptions;
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using static Sensus.iPerl.NfcHandler.MCI_Protocol;
|
||||||
|
|
||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
|
||||||
|
{
|
||||||
|
internal class NfcServices
|
||||||
|
{
|
||||||
|
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||||
|
internal static int ReadRequest(TestMethodCfg cfg, IperlHead iperlHead, MCI_Protocol.StructName structName, int offset, int length, out byte[] buffer)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
NfcDataHandler _nfcDataHandler = new NfcDataHandler();
|
||||||
|
MessageEventHandlers(_nfcDataHandler);
|
||||||
|
CR95HF_MessageEventHandlers(_nfcDataHandler._CR95HF_Reader);
|
||||||
|
ST25DV_MessageEventHandlers(_nfcDataHandler._ST25DV_Device);
|
||||||
|
MCI_MessageEventHandlers(_nfcDataHandler._MCI_Protocol);
|
||||||
|
NFCHeadConfig_MessageEventHandlers(_nfcDataHandler._NFCHead_Config);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} ReadRequest : {structName}, {offset}, {length}");
|
||||||
|
OpenConnection(_nfcDataHandler, cfg, iperlHead);
|
||||||
|
|
||||||
|
buffer = MciRead(_nfcDataHandler, cfg, structName, (ushort)offset, length);
|
||||||
|
_nfcDataHandler.RFProtocolOFF(); // turn off rf antenna due to possible interference
|
||||||
|
|
||||||
|
CloseComPort(_nfcDataHandler);
|
||||||
|
|
||||||
|
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} ReadRequest : {structName}, {offset}, {length} ; Response= {ByteArrayToHexString(buffer)} ; Error: {_nfcDataHandler.LastErrorMessage}");
|
||||||
|
|
||||||
|
if (_nfcDataHandler.LastErrorCode != 0)
|
||||||
|
{
|
||||||
|
throw new RfidValidationException(_nfcDataHandler.LastErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToInt32(_nfcDataHandler.LastErrorCode); //return 0;
|
||||||
|
}
|
||||||
|
catch (RfidValidationException)
|
||||||
|
{
|
||||||
|
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} ReadRequest Error: {ex.Message}");
|
||||||
|
buffer = new byte[length];
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer = new byte[length];
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int WriteRequest(TestMethodCfg cfg, IperlHead iperlHead, MCI_Protocol.StructName structName, int offset, int length, byte[] buffer)
|
||||||
|
{
|
||||||
|
NfcDataHandler _nfcDataHandler = new NfcDataHandler();
|
||||||
|
MessageEventHandlers(_nfcDataHandler);
|
||||||
|
CR95HF_MessageEventHandlers(_nfcDataHandler._CR95HF_Reader);
|
||||||
|
ST25DV_MessageEventHandlers(_nfcDataHandler._ST25DV_Device);
|
||||||
|
MCI_MessageEventHandlers(_nfcDataHandler._MCI_Protocol);
|
||||||
|
NFCHeadConfig_MessageEventHandlers(_nfcDataHandler._NFCHead_Config);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} WriteRequest : {structName}, {offset}, {length}, {ByteArrayToHexString(buffer)}");
|
||||||
|
OpenConnection(_nfcDataHandler, cfg, iperlHead);
|
||||||
|
|
||||||
|
MciWrite(_nfcDataHandler, cfg, structName, (ushort)offset, length, buffer);
|
||||||
|
_nfcDataHandler.RFProtocolOFF(); // turn off rf antenna due to possible interference
|
||||||
|
|
||||||
|
CloseComPort(_nfcDataHandler);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} WriteRequest Error: {ex.Message}");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OpenConnection(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, IperlHead iperlHead)
|
||||||
|
{
|
||||||
|
string comPort = $"COM{iperlHead.RfidComPortNr}";
|
||||||
|
int retryCount = 0 ;
|
||||||
|
Open:
|
||||||
|
nfcDataHandler.Close();
|
||||||
|
Thread.Sleep(100);
|
||||||
|
if (nfcDataHandler.OpenConnection(comPort, cfg.BaudRate, cfg.DataBits, cfg.ParityBit, cfg.StopBits))
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} Port Open");
|
||||||
|
|
||||||
|
if (nfcDataHandler.ConnectReader())
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} Reader connected");
|
||||||
|
if (!nfcDataHandler.ConnectDevice())
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} Error connect device.");
|
||||||
|
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||||
|
{
|
||||||
|
if (nfcDataHandler.Echo()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retryCount++;
|
||||||
|
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} Error connect reader. Reconnect comport {retryCount}");
|
||||||
|
if (retryCount < cfg.MaxCommRetries)
|
||||||
|
{
|
||||||
|
nfcDataHandler.Close();
|
||||||
|
iperlHead.ResetNfcInterface(); // reset NFC head via optoport - switch to RFID and back to NFC interface
|
||||||
|
goto Open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rfidDataLogger.Error($"Open NFC COM{iperlHead.RfidComPortNr} Port Failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CloseComPort(NfcDataHandler nfcDataHandler)
|
||||||
|
{
|
||||||
|
nfcDataHandler.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] MciRead(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, StructName structName, ushort offset, int length)
|
||||||
|
{
|
||||||
|
bool isReadValues = false;
|
||||||
|
int retryCount = 0;
|
||||||
|
Read:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
isReadValues = false;
|
||||||
|
long num1 = (long)length;
|
||||||
|
int timeoutMs = 4000;
|
||||||
|
byte payloadlength = Convert.ToByte(num1.ToString("X2"), 16);
|
||||||
|
if (nfcDataHandler.MCI_Read(structName, offset, payloadlength, timeoutMs))
|
||||||
|
{
|
||||||
|
byte[] lastData = nfcDataHandler.LastData;
|
||||||
|
if ((long)lastData.Length >= num1)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"COM: MciRead ({structName},{offset},{length}) = {ByteArrayToHexString(lastData)}");
|
||||||
|
return lastData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rfidDataLogger.Info($"COM: MciRead ({structName},{offset},{length}) = {ByteArrayToHexString(lastData)}");
|
||||||
|
}
|
||||||
|
else if (nfcDataHandler.LastErrorCode == (byte)0)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"MCI Error: Unidentified");
|
||||||
|
retryCount++;
|
||||||
|
if (retryCount < cfg.MaxCommRetries)
|
||||||
|
goto Read;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info("Last error message: " + nfcDataHandler.LastErrorMessage);
|
||||||
|
retryCount++;
|
||||||
|
if (retryCount < cfg.MaxCommRetries)
|
||||||
|
goto Read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error("MciRead Last error message: " + ex.Message);
|
||||||
|
retryCount++;
|
||||||
|
if (retryCount < cfg.MaxCommRetries)
|
||||||
|
goto Read;
|
||||||
|
}
|
||||||
|
return new byte[length];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MciWrite(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, MCI_Protocol.StructName structName, ushort offset, int length, byte[] payload)
|
||||||
|
{
|
||||||
|
int retryCount = 0;
|
||||||
|
Write:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long num1 = (long)length;
|
||||||
|
int timeoutMs = 4000;
|
||||||
|
byte payloadlength = Convert.ToByte(num1);
|
||||||
|
if ((int)payloadlength != payload.Length)
|
||||||
|
rfidDataLogger.Error("Insufficient Payload -- Payload lenth : " + (object)payload.Length);
|
||||||
|
else if (nfcDataHandler.MCI_Write(structName, offset, payloadlength, payload, timeoutMs))
|
||||||
|
{
|
||||||
|
// OK
|
||||||
|
}
|
||||||
|
else if (nfcDataHandler.LastErrorCode > (byte)0)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error("Last error message: " + nfcDataHandler.LastErrorMessage);
|
||||||
|
//int num2 = (int)MessageBox.Show(this._nfcDataHandler.LastErrorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error("MciWrite error message: " + ex.Message);
|
||||||
|
retryCount++;
|
||||||
|
if (retryCount < cfg.MaxCommRetries)
|
||||||
|
goto Write;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MciWriteCommand(NfcDataHandler nfcDataHandler, byte commandcode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ushort offset = 0;
|
||||||
|
int timeoutMs = 4000;
|
||||||
|
byte payloadlength = 1;
|
||||||
|
byte[] payload = new byte[1] { commandcode };
|
||||||
|
if (nfcDataHandler.MCI_Write(MCI_Protocol.StructName.Command, offset, payloadlength, payload, timeoutMs) || nfcDataHandler.LastErrorCode <= (byte)0)
|
||||||
|
return;
|
||||||
|
rfidDataLogger.Error("MciWriteCommand Last error message: " + nfcDataHandler.LastErrorMessage);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error("MciWriteCommand Last error message: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ByteArrayToHexString(byte[] data)
|
||||||
|
{
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
foreach (byte num in data)
|
||||||
|
stringBuilder.Append(num.ToString("X2"));
|
||||||
|
return stringBuilder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] BuildPayLoad(string strPayLoad, int length)
|
||||||
|
{
|
||||||
|
byte[] collection;
|
||||||
|
|
||||||
|
if (strPayLoad.Split(':').Length > 1)
|
||||||
|
{
|
||||||
|
uint timestamp = ConvertDateTimeToTimestamp(Convert.ToDateTime(DateTime.ParseExact(strPayLoad, "HH:mm:ss dd/MM/yyyy", (IFormatProvider)CultureInfo.InvariantCulture)));
|
||||||
|
byte[] bytes = BitConverter.GetBytes(timestamp);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
else if (strPayLoad.Split(',').Length > 1)
|
||||||
|
{
|
||||||
|
string[] strArray = strPayLoad.Split(',');
|
||||||
|
collection = new byte[strArray.Length];
|
||||||
|
for (int index3 = 0; index3 < strArray.Length; ++index3)
|
||||||
|
collection[index3] = Convert.ToByte(strArray[index3], 16);
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//int num = strPayLoad.Split(',').Length;
|
||||||
|
collection = HexStringToByteArray(strPayLoad.Substring(strPayLoad.Length - length * 2).ToUpper());
|
||||||
|
Array.Reverse((Array)collection);
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] HexStringToByteArray(string hexString)
|
||||||
|
{
|
||||||
|
int length = hexString.Length;
|
||||||
|
byte[] byteArray = new byte[length / 2];
|
||||||
|
for (int startIndex = 0; startIndex < length; startIndex += 2)
|
||||||
|
byteArray[startIndex / 2] = Convert.ToByte(hexString.Substring(startIndex, 2), 16);
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint ConvertDateTimeToTimestamp(DateTime datetime)
|
||||||
|
{
|
||||||
|
TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
|
||||||
|
return (uint)((datetime - new DateTime(2000, 1, 1, 0, 0, 0).ToLocalTime()).TotalSeconds + utcOffset.TotalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region EventHandlers
|
||||||
|
public static void MCI_MessageEventHandlers(MCI_Protocol e)
|
||||||
|
{
|
||||||
|
DelNfc_MCI_MessageHandler mciMessageHandler = new DelNfc_MCI_MessageHandler(OnHandler);
|
||||||
|
e.MessageEvent += mciMessageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ST25DV_MessageEventHandlers(ST25DV_Device e)
|
||||||
|
{
|
||||||
|
DelNfc_ST25DV_MessageHandler dvMessageHandler = new DelNfc_ST25DV_MessageHandler(OnHandler);
|
||||||
|
e.MessageEvent += dvMessageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CR95HF_MessageEventHandlers(CR95HF_Reader e)
|
||||||
|
{
|
||||||
|
DelNfc_CR95HF_MessageHandler hfMessageHandler = new DelNfc_CR95HF_MessageHandler(OnHandler);
|
||||||
|
e.MessageEvent += hfMessageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void NFCHeadConfig_MessageEventHandlers(NFCHeadConfig e)
|
||||||
|
{
|
||||||
|
DelNfc_NFCHeadConfig_MessageHandler configMessageHandler = new DelNfc_NFCHeadConfig_MessageHandler(OnHandler);
|
||||||
|
e.MessageEvent += configMessageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MessageEventHandlers(NfcDataHandler e)
|
||||||
|
{
|
||||||
|
DelNfcMessageHandler nfcMessageHandler = new DelNfcMessageHandler(OnHandler);
|
||||||
|
e.MessageEvent += nfcMessageHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnHandler(object sender, NfcMessageEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Message == null)
|
||||||
|
return;
|
||||||
|
string message = e.Message.Replace("\n", " ").Replace("\r", "");
|
||||||
|
rfidDataLogger.Debug(message);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
using Sensus.iPerl.RfidCom.Exceptions;
|
||||||
|
using Sensus.iPerl.RfidCom.Helper;
|
||||||
|
using Sensus.iPerl.RfidCom;
|
||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
|
||||||
|
{
|
||||||
|
internal class RfidServices
|
||||||
|
{
|
||||||
|
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm));
|
||||||
|
|
||||||
|
internal static int ReadRequest(TestMethodCfg cfg, IperlHead iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"{iperlHead.CommInterface} Start {i} reading: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},{offset}, {length}... timeout {cfg.CommTimeout})");
|
||||||
|
using (RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] response = writer.ReadRequest((byte)messageID, offset, length, cfg.CommTimeout);
|
||||||
|
string hexString = RfidHelper.ConvertByteArrayToHexString(response);
|
||||||
|
string swapHexString = RfidHelper.SwapHexcode(hexString);
|
||||||
|
string decString = RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(hexString)).ToString();
|
||||||
|
|
||||||
|
if (length > 10)
|
||||||
|
{
|
||||||
|
//if the result only contains "00"s we are working on the wrong COM port
|
||||||
|
// or the module just isn't connected
|
||||||
|
if (Regex.IsMatch(hexString, @"^(00)\1+$"))
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) <- Error: No RFID signal.");
|
||||||
|
throw new RfidValidationException("Error_Rfid_NoSignal");
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the result only contains "03"s the meter did not answer.
|
||||||
|
// Might be due to the module being positioned incorrectly.
|
||||||
|
if (Regex.IsMatch(hexString, @"^(03)\1+$"))
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) <- Error: No meter signal.");
|
||||||
|
throw new RfidValidationException("Error_Rfid_NoAnswerFromMeter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.ClosePort();
|
||||||
|
buffer = response;
|
||||||
|
rfidDataLogger.Info($"{iperlHead.Name} ({iperlHead.SerialNr}): ReadRequestPort(COM{iperlHead.RfidComPortNr},...) returned HEX: {hexString}; SwapHexCodeToDecimal: {decString}");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (RfidDataNotAvailableException)
|
||||||
|
{
|
||||||
|
if (/*RfidHelper.IsPassThrough(messageID)*/ messageID == MessageID.ASICRegisterReadTest || messageID == MessageID.RadioPassthrough)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Info($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) {(i > 0 ? "<- Error: Invalid Pass-Through data." : "<- Info: Wait for Pass-Through data.")}");
|
||||||
|
Thread.Sleep(cfg.PassThroughWaitTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (RfidValidationException)
|
||||||
|
{
|
||||||
|
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) {ex.Message}");
|
||||||
|
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rfidDataLogger.Error($"{iperlHead.CommInterface} reading failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...)");
|
||||||
|
log.Error($"{iperlHead.CommInterface} reading failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...)");
|
||||||
|
buffer = new byte[length];
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int WriteRequest(TestMethodCfg cfg, IperlHead iperlHead, MessageID messageID, int offset, int length, byte[] buffer)
|
||||||
|
{
|
||||||
|
RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}");
|
||||||
|
string payload = RfidHelper.ConvertByteArrayToHexString(buffer);
|
||||||
|
|
||||||
|
for (var i = 0; i < cfg.MaxCommRetries; i++)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"{iperlHead.CommInterface} Start {i} writting: COM{iperlHead.RfidComPortNr}: WriteRequest ({messageID},{offset}, {length}, {payload}... timeout {cfg.CommTimeout})");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (writer.ClosePort()) writer.OpenPort();
|
||||||
|
writer.WriteRequest((byte)messageID, offset, length, buffer, cfg.CommTimeout, false);
|
||||||
|
writer.ClosePort();
|
||||||
|
rfidDataLogger.InfoFormat($"{iperlHead.Name}({iperlHead.SerialNr},COM{iperlHead.RfidComPortNr}): WriteRequestPort({messageID}, {offset}, {length}, {payload})");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (messageID == MessageID.RadioPassthrough || messageID == MessageID.ASICRegisterReadTest)
|
||||||
|
{
|
||||||
|
Thread.Sleep(1500);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: Error: {ex.Message}");
|
||||||
|
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||||
|
if (i > 1)
|
||||||
|
{
|
||||||
|
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: Reopen the com port.");
|
||||||
|
writer.ClosePort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.ClosePort();
|
||||||
|
rfidDataLogger.Error($"RFID writing failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: WriteRequestPort ({messageID},...) {System.Text.Encoding.UTF8.GetString(buffer)}");
|
||||||
|
log.Error($"RFID writing failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: WriteRequestPort ({messageID},...) {System.Text.Encoding.UTF8.GetString(buffer)}");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
|
||||||
|
{
|
||||||
|
internal class SimulationServices
|
||||||
|
{
|
||||||
|
const int Q2CorrFactorsAddr = 0x1878;
|
||||||
|
|
||||||
|
internal static int ReadRequest(TestMethodCfg cfg, IperlHead iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||||
|
{
|
||||||
|
byte[] configurationBuffer = new byte[ConfigStruct.Length] { 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
byte[] calibrationBuffer = new byte[CalibrationStructV4.Length] { 3, 0, 150, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 150, 10 };
|
||||||
|
buffer = new byte[length];
|
||||||
|
|
||||||
|
if (messageID == MessageID.Configuration)
|
||||||
|
{
|
||||||
|
Array.Copy(GetPCB(iperlHead), 0, configurationBuffer, 16, 5); // set PCB Number according to iPerlHead configuration
|
||||||
|
Array.Copy(configurationBuffer,offset,buffer,0,length);
|
||||||
|
}
|
||||||
|
else if (messageID == MessageID.Calibration)
|
||||||
|
{
|
||||||
|
Array.Copy(calibrationBuffer, offset, buffer, 0, length);
|
||||||
|
}
|
||||||
|
else if ((messageID == MessageID.MetrologyMemory) && (offset == Q2CorrFactorsAddr) && (length == 2))
|
||||||
|
{
|
||||||
|
buffer = new byte[2] { 0, 0 };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer = new byte[length];
|
||||||
|
}
|
||||||
|
|
||||||
|
return iperlHead.Name.Equals("iPerl13") ? 2 : 0; /// Simulates an error on position 13
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int WriteRequest(TestMethodCfg cfg, IperlHead iperlHead, MessageID messageID, int offset, int length, byte[] buffer)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Array GetPCB(IperlHead iperlHead)
|
||||||
|
{
|
||||||
|
string pcbStr = iperlHead.RfidComPortNr.ToString().PadRight(10,'0') + iperlHead.Position.ToString("D2");
|
||||||
|
long decVal = Convert.ToInt64(pcbStr);
|
||||||
|
string nHexStr = decVal.ToString("X4");
|
||||||
|
|
||||||
|
string hexStr = "";
|
||||||
|
for (int a = nHexStr.Length; a >= 1; a = a - 2)
|
||||||
|
{
|
||||||
|
hexStr = hexStr + nHexStr.Substring(a - 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Enumerable.Range(0, hexStr.Length)
|
||||||
|
.Where(x => x % 2 == 0)
|
||||||
|
.Select(x => Convert.ToByte(hexStr.Substring(x, 2), 16))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using log4net;
|
||||||
|
using TBF.Rig.ControlBoard.Uni;
|
||||||
|
using TBF.Rig.GenericDevices;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public class ChangeRegValvePositionOp : IOperation
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(ChangeRegValvePositionOp));
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("ChangeRegValvePositionOp({0},{1}s)", regV.Name, timePulseSec.ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set by the constructor
|
||||||
|
readonly UniCB uniCB;
|
||||||
|
readonly RegValve regV;
|
||||||
|
readonly int regulValveNr;
|
||||||
|
readonly double timePulseSec;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow.
|
||||||
|
/// Events: FlowSet, FlowTimeOut
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cb">Control board device</param>
|
||||||
|
/// <param name="rv">Regulation valve component</param>
|
||||||
|
/// <param name="posLoPct">Lower limit of the position to be achieved</param>
|
||||||
|
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
|
||||||
|
/// <param name="timeout">Timeout in sec. for setting the flow</param>
|
||||||
|
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||||
|
public ChangeRegValvePositionOp(UniCB uniCB, RegValve regV, double timePulseSec)
|
||||||
|
{
|
||||||
|
this.uniCB = uniCB;
|
||||||
|
if (this.uniCB == null) throw new ArgumentNullException("ctrlBoard");
|
||||||
|
|
||||||
|
this.regV = regV as RegValve;
|
||||||
|
if (this.regV == null) throw new ArgumentNullException("regValve is null or not Uni");
|
||||||
|
regulValveNr = this.regV.Idx1;
|
||||||
|
|
||||||
|
this.timePulseSec = timePulseSec;
|
||||||
|
|
||||||
|
log.Debug(this.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Start this operation</summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
uniCB.RegVlvIncrMove(false, regulValveNr, timePulseSec, this.regV.RegulationMinStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Run this operation</summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Event.SetFlowDone
|
||||||
|
/// </returns>
|
||||||
|
public Event Run()
|
||||||
|
{
|
||||||
|
return Event.PositionReached;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Stop this operation</summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using TBF.Rig.Generic;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public class Factory : IComponentFactory
|
||||||
|
{
|
||||||
|
public string ClassName { get { return GetType().Namespace.Substring(12); } }
|
||||||
|
public override string ToString() { return ClassName; }
|
||||||
|
|
||||||
|
public IComponent DummyComponent() { return new RegValve(); }
|
||||||
|
|
||||||
|
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new RegValve(cfg, components); }
|
||||||
|
|
||||||
|
public IComponentCfg DefaultConfig() { return new RegValveCfg("VR", this); }
|
||||||
|
|
||||||
|
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||||
|
{
|
||||||
|
return ComponentCfgBase.CreateFromDbEntity(RegValveCfg.Serializer, component, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
static class Handlers
|
||||||
|
{
|
||||||
|
static readonly ILog log = LogManager.GetLogger(typeof(Handlers));
|
||||||
|
|
||||||
|
static Handlers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called from the state machine when a procedure is selected and UI needs to be updated.
|
||||||
|
/// </summary>
|
||||||
|
public static void OnAdcChanged(object sender, CmdResponseArgs data)
|
||||||
|
{
|
||||||
|
if (AdcChangedHandler == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AdcChangedHandler(sender, data);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.Error("AdcChangedHandler(...) failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static event EventHandler<CmdResponseArgs> AdcChangedHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using log4net;
|
||||||
|
using SchematicDrawing;
|
||||||
|
using TBF.Rig.ControlBoard.Uni;
|
||||||
|
using TBF.Boxes;
|
||||||
|
using SharedComponents;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public class RegValve : ComponentBase, Generic.IDevice, GenericDevices.IRegValve, IDrawingItCmpntWithSetpoint
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(RegValve));
|
||||||
|
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||||
|
|
||||||
|
public readonly RegValveCfg regValveCfg;
|
||||||
|
public IDrawingItem DrawingItem { get { return regValveCfg as IDrawingItem; } }
|
||||||
|
|
||||||
|
IDictionary<double, double> dict;
|
||||||
|
public IDictionary<double, double> Dict { get { return dict; } }
|
||||||
|
|
||||||
|
public readonly UniCB UniCB;
|
||||||
|
|
||||||
|
public ValveCategory Category { get { return regValveCfg.Category; } }
|
||||||
|
public int Idx1 { get { return regValveCfg.Idx1; } } /// 1 .. 8
|
||||||
|
public int DacValueClosed { get { return regValveCfg.AdcValueClosed; } } /// 0 .. 1023
|
||||||
|
public int DacValueOpen { get { return regValveCfg.AdcValueOpen; } } /// 0 .. 1023
|
||||||
|
public int StableTime { get { return regValveCfg.StableTime; } } /// 0=200ms, step=50ms, max. 1500ms (max.26)
|
||||||
|
public int FlowStableSec { get { return regValveCfg.FlowStableSec; } } /// 0 .. 60 sec
|
||||||
|
public bool StoredPositionReuse { get { return regValveCfg.StoredPositionReuse; } }
|
||||||
|
public int RegulationMinStep { get { return regValveCfg.RegulationMinStep; } } /// low regulation saturation time ...0=0, 1=50, 2=100, 3=150, 4=200, 5=250, 6=300 [ms]
|
||||||
|
///
|
||||||
|
public bool IsCoax { get { return false; } }
|
||||||
|
|
||||||
|
public RegValveState RegValveState
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (UniCB.Data.RegVStatus[Idx1 - 1])
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0: return ControlBoard.Uni.RegValveState.Idle;
|
||||||
|
case 2: return ControlBoard.Uni.RegValveState.PwOrFreqRegul;
|
||||||
|
case 3: return ControlBoard.Uni.RegValveState.DacValueRegul;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Position 0.0 .. 100.0 in %
|
||||||
|
public double Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int denominator = DacValueOpen - DacValueClosed;
|
||||||
|
if (denominator == 0) denominator = 1;
|
||||||
|
return 100.0 * Convert.ToDouble(Math.Max(0, Math.Min(denominator, (int)UniCB.AnalogInput(adcChannel) - DacValueClosed)))
|
||||||
|
/ Convert.ToDouble(denominator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///
|
||||||
|
public double SetpointVal
|
||||||
|
{
|
||||||
|
get { return Position; }
|
||||||
|
set { TargetRegValvePosition = value; }
|
||||||
|
}
|
||||||
|
///
|
||||||
|
public void IncreaseSetpoint()
|
||||||
|
{
|
||||||
|
IncrementalMovement(true, 0.5);
|
||||||
|
}
|
||||||
|
///
|
||||||
|
public void DecreaseSetpoint()
|
||||||
|
{
|
||||||
|
IncrementalMovement(true, -0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int adcChannel;
|
||||||
|
public double TargetRegValvePosition;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Incremental movement of the regulation valve.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">Time in seconds, positive value opens the reg. valve</param>
|
||||||
|
public void IncrementalMovement(bool isFromUI, double time)
|
||||||
|
{
|
||||||
|
UniCB.RegVlvIncrMove(isFromUI, Idx1, time, RegulationMinStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move a regulation valve to specfied position
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rvId">Reg. valve ID</param>
|
||||||
|
/// <param name="position">Reg. valve position (0 .. 1.0)</param>
|
||||||
|
public void MoveToPosition(bool isFromUI, double posPctLo, double posPctHi = -1)
|
||||||
|
{
|
||||||
|
int adcDiff = Math.Abs(regValveCfg.AdcValueOpen - regValveCfg.AdcValueClosed);
|
||||||
|
int adcLower = Math.Min(regValveCfg.AdcValueOpen, regValveCfg.AdcValueClosed);
|
||||||
|
|
||||||
|
int targetAdcValLo = Math.Max(0, Convert.ToInt32(Math.Round((posPctLo * adcDiff / 100.0) + adcLower)));
|
||||||
|
int targetAdcValHi = (posPctHi < 0) ? -1 : Math.Min(1023, Convert.ToInt32(Math.Round((posPctHi * adcDiff / 100.0) + adcLower)));
|
||||||
|
|
||||||
|
UniCB.RegVlvMoveToPos(isFromUI, Idx1, targetAdcValLo, targetAdcValHi, RegulationMinStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Configuration Change Handling
|
||||||
|
|
||||||
|
public static void OnCfgChange(object sender, CfgChangeArgs args)
|
||||||
|
{
|
||||||
|
if (CfgChangeHandler == null) return;
|
||||||
|
try { CfgChangeHandler(sender, args); }
|
||||||
|
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
|
||||||
|
|
||||||
|
public override void StartChangeHandler()
|
||||||
|
{
|
||||||
|
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
|
||||||
|
{
|
||||||
|
RegValveCfg tmpcfg = args.Cfg as RegValveCfg;
|
||||||
|
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
|
||||||
|
{
|
||||||
|
if (args.Command == CfgChangeCmd.CfgChange)
|
||||||
|
{
|
||||||
|
regValveCfg.StableTimeMs = tmpcfg.StableTimeMs;
|
||||||
|
regValveCfg.FlowStableSec = tmpcfg.FlowStableSec;
|
||||||
|
regValveCfg.RegulationMinStep = tmpcfg.RegulationMinStep;
|
||||||
|
}
|
||||||
|
else if (args.Command == CfgChangeCmd.RVOpenStep)
|
||||||
|
{
|
||||||
|
IncrementalMovement(true, 0.5); /// true = command is comming from the UI
|
||||||
|
}
|
||||||
|
else if (args.Command == CfgChangeCmd.RVCloseStep)
|
||||||
|
{
|
||||||
|
IncrementalMovement(true, -0.5); /// true = command is comming from the UI
|
||||||
|
}
|
||||||
|
else if (args.Command == CfgChangeCmd.GetAdc1 || args.Command == CfgChangeCmd.GetAdc2)
|
||||||
|
{
|
||||||
|
short adcValue = UniCB.AnalogInput(adcChannel);
|
||||||
|
RegValveCfgCtrl.OnCmdResponse(this, new CmdResponseArgs(args.Command, Idx1, adcValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Configuration Change Handling
|
||||||
|
|
||||||
|
|
||||||
|
public RegValve() { }
|
||||||
|
|
||||||
|
public RegValve(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||||
|
: base(cfg)
|
||||||
|
{
|
||||||
|
regValveCfg = cfg as RegValveCfg;
|
||||||
|
|
||||||
|
this.UniCB = TbfComponents.FindComponent(cfg.ParentName, components) as UniCB;
|
||||||
|
if (this.UniCB == null) throw new Exception(string.Format("Cannot find {0} (a parent of {1})", cfg.ParentName, Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
adcChannel = regValveCfg.Idx1 - 1;
|
||||||
|
this.dict = new Dictionary<double, double>();
|
||||||
|
|
||||||
|
TBF.UiBridge.Bridge.SetpointChangeHandler += delegate(object sndr, TBF.UiBridge.SetpointChangeArgs args)
|
||||||
|
{
|
||||||
|
if (args.Name == Name)
|
||||||
|
{
|
||||||
|
if (args.Increase) IncreaseSetpoint(); else DecreaseSetpoint();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// IDevice interface implementation
|
||||||
|
///
|
||||||
|
public void RunDeviceBefore()
|
||||||
|
{
|
||||||
|
Int16 adcValue = UniCB.AnalogInput(adcChannel);
|
||||||
|
Handlers.OnAdcChanged(this, new CmdResponseArgs(CfgChangeCmd.GetAdc, Idx1, adcValue));
|
||||||
|
}
|
||||||
|
public void RunDeviceAfter() { }
|
||||||
|
public void StopDevice() { }
|
||||||
|
public void StopDevice2() { }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Operation to set the water flow within tolerances
|
||||||
|
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flowMeter">Flowmeter component</param>
|
||||||
|
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
|
||||||
|
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
|
||||||
|
/// <param name="pidCoef">PID coefficient (float)</param>
|
||||||
|
/// <param name="measuredFlow">Measured flow [m3/h]</param>
|
||||||
|
/// <param name="timeout">Timeout in [s]</param>
|
||||||
|
/// <returns>SetFlowOp instance</returns>
|
||||||
|
public IOperation SetFlowOp(GenericDevices.IFlowMeter flowMeter, double requiredFlowLo, double requiredFlowHi, DoubleBox measuredFlow, int timeout, int delay)
|
||||||
|
{
|
||||||
|
return new SetFlowOp(UniCB, this, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Operation to set the water flow within tolerances. Leave the measurement running.
|
||||||
|
/// Events: Event.None, Event.FlowReached, Event.FlowTimeOut
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flowMeter">Flowmeter component</param>
|
||||||
|
/// <param name="requiredFlowLo">Lower limit of the required flow [m3/h]</param>
|
||||||
|
/// <param name="requiredFlowHi">Higher limit of the required flow [m3/h]</param>
|
||||||
|
/// <param name="measuredFlow">Measured flow [m3/h]</param>
|
||||||
|
/// <param name="timeout">Timeout in [s]</param>
|
||||||
|
/// <returns>SetFlowOp instance</returns>
|
||||||
|
public IOperation SetFlowAndMeasureOp(GenericDevices.IFlowMeter flowMeter, double requiredFlowLo, double requiredFlowHi,
|
||||||
|
DoubleBox measuredFlow, int timeout, float filterConstant)
|
||||||
|
{
|
||||||
|
return new SetFlowOp(UniCB, this, flowMeter, requiredFlowLo, requiredFlowHi, measuredFlow, timeout, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Operation to set the regulation valve to a required position
|
||||||
|
/// Events: Event.None
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flowLo">Lower limit of the required valve position in [%]</param>
|
||||||
|
/// <param name="flowLo">Higher limit of the required valve position in [%]</param>
|
||||||
|
/// <returns>SetPositionOp instance</returns>
|
||||||
|
public IOperation SetRegValvePositionOp(double pctLo, double pctHi, int timeoutMs)
|
||||||
|
{
|
||||||
|
return new SetRegValvePositionOp(UniCB, this, pctLo, pctHi, timeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IOperation ChangeRegValvePositionOp(double timePulseSec)
|
||||||
|
{
|
||||||
|
return new ChangeRegValvePositionOp(UniCB, this, timePulseSec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Config.Entities;
|
||||||
|
using SchematicDrawing;
|
||||||
|
using TBF.Rig.Generic;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public class RegValveCfg : ComponentCfgBase, IChildComponentCfg, IDrawingItemWithSetpoint
|
||||||
|
{
|
||||||
|
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RegValveCfg) })[0];
|
||||||
|
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||||
|
|
||||||
|
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||||
|
{
|
||||||
|
return new RegValveCfgCtrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Serialized parameters
|
||||||
|
///
|
||||||
|
public int Idx1; /// 1..8
|
||||||
|
public ValveCategory Category; /// Feeding, Output or All
|
||||||
|
public int AdcValueClosed; /// 0..1023
|
||||||
|
public int AdcValueOpen; /// 0..1023
|
||||||
|
public int StableTimeMs; /// 200..1500 ms, step is 50 ms
|
||||||
|
public int FlowStableSec; /// 0..60 sec
|
||||||
|
public bool StoredPositionReuse; /// true = store and re-use previous regulation valve positions
|
||||||
|
public int RegulationMinStep { get; set; } /// low regulation saturation time ...0=0, 1=50, 2=100, 3=150, 4=200, 5=250, 6=300 [ms]
|
||||||
|
public string SetpFormat { get; set; }
|
||||||
|
public Common.Unit SetpUnit { get; set; }
|
||||||
|
|
||||||
|
/// Schematic drawing info
|
||||||
|
public Shape Shape { get; set; }
|
||||||
|
public int X { get; set; }
|
||||||
|
public int Y { get; set; }
|
||||||
|
public Sz Sz { get; set; }
|
||||||
|
public Orient Orient { get; set; }
|
||||||
|
public bool Flip { get; set; }
|
||||||
|
public int LblX { get; set; }
|
||||||
|
public int LblY { get; set; }
|
||||||
|
public Orient LblOrient { get; set; }
|
||||||
|
public int SetpX { get; set; }
|
||||||
|
public int SetpY { get; set; }
|
||||||
|
public Orient SetpOrient { get; set; }
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public IList<GNode> GNodes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.
|
||||||
|
/// </summary>
|
||||||
|
public int StableTime { get { return (StableTimeMs - 200) / 50; } }
|
||||||
|
|
||||||
|
/// Private parameterless constructor invoked by all other (public) constructors
|
||||||
|
RegValveCfg()
|
||||||
|
{
|
||||||
|
GNodes = new List<GNode>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegValveCfg(string name, IComponentFactory factory)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
Shape = Shape.RegV;
|
||||||
|
Sz = Sz.M;
|
||||||
|
SetpFormat = "{0:F0} %";
|
||||||
|
SetpUnit = Common.Unit.Pct;
|
||||||
|
|
||||||
|
Name = name;
|
||||||
|
Factory = factory;
|
||||||
|
ParentName = "UniCB";
|
||||||
|
Category = ValveCategory.Output;
|
||||||
|
Idx1 = 1;
|
||||||
|
AdcValueClosed = 100;
|
||||||
|
AdcValueOpen = 500;
|
||||||
|
StableTimeMs = 500;
|
||||||
|
FlowStableSec = 5;
|
||||||
|
StoredPositionReuse = false;
|
||||||
|
RegulationMinStep = 0;
|
||||||
|
|
||||||
|
LblX = 38;
|
||||||
|
SetpX = 38;
|
||||||
|
SetpY = 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public string ToString(int i)
|
||||||
|
{
|
||||||
|
return string.Format("Name={0} ({1}), Idx1={2}, Cat.={3}, ADC-Closed={4}, ADC-Open={5}, StabTm={6}ms, FlowStable={7}s, PosReuse={8}",
|
||||||
|
Name,
|
||||||
|
(string.IsNullOrEmpty(ParentName) ? "-" : ParentName),
|
||||||
|
Idx1,
|
||||||
|
Category,
|
||||||
|
AdcValueClosed,
|
||||||
|
AdcValueOpen,
|
||||||
|
StableTimeMs,
|
||||||
|
FlowStableSec,
|
||||||
|
StoredPositionReuse,
|
||||||
|
RegulationMinStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,394 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using log4net;
|
||||||
|
using Common;
|
||||||
|
using Config.Entities;
|
||||||
|
using TBF.Rig.Generic;
|
||||||
|
using TBF.UI.Bench.Components;
|
||||||
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public partial class RegValveCfgCtrl : UserControl, IComponentCfgCtrl
|
||||||
|
{
|
||||||
|
static readonly ILog log = LogManager.GetLogger(typeof(RegValveCfgCtrl));
|
||||||
|
|
||||||
|
ComponentParametersDlg parent;
|
||||||
|
|
||||||
|
public bool ShowMore { get { return true; } }
|
||||||
|
|
||||||
|
RegValveCfg config;
|
||||||
|
public IComponentCfg Config
|
||||||
|
{
|
||||||
|
get { return config as IComponentCfg; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
config = value as RegValveCfg;
|
||||||
|
Redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegValveCfgCtrl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegulationValveCfgCtrl_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
parent = ParentForm as ComponentParametersDlg;
|
||||||
|
if (parent == null) return;
|
||||||
|
|
||||||
|
if (parent.CmpntEntities != null)
|
||||||
|
{
|
||||||
|
foreach (var c in parent.CmpntEntities.Where(x => x.ClassName == "ControlBoard.Uni"))
|
||||||
|
{
|
||||||
|
parentNameComboBox.Items.Add(c.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryComboBox.Items.Add(ValveCategory.Feeding.ToString());
|
||||||
|
categoryComboBox.Items.Add(ValveCategory.Output.ToString());
|
||||||
|
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
adc1 = config.AdcValueClosed;
|
||||||
|
pct1 = 0;
|
||||||
|
adc2 = config.AdcValueOpen;
|
||||||
|
pct2 = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Common.Unit units = 0; units < global::Common.Unit.Count; units++)
|
||||||
|
{
|
||||||
|
if (global::Common.Units.IsQuantity(units, Quantity.Error))
|
||||||
|
{
|
||||||
|
unitsComboBox.Items.Add(units.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regulMinStepsComboBox.Items.Add("0");
|
||||||
|
regulMinStepsComboBox.Items.Add("50");
|
||||||
|
regulMinStepsComboBox.Items.Add("100");
|
||||||
|
regulMinStepsComboBox.Items.Add("150");
|
||||||
|
regulMinStepsComboBox.Items.Add("200");
|
||||||
|
regulMinStepsComboBox.Items.Add("250");
|
||||||
|
regulMinStepsComboBox.Items.Add("300");
|
||||||
|
|
||||||
|
Redraw();
|
||||||
|
StartResponseHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Closing()
|
||||||
|
{
|
||||||
|
StopResponseHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Redraw()
|
||||||
|
{
|
||||||
|
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||||
|
|
||||||
|
classNameLabel.Text = config.Factory.ClassName;
|
||||||
|
nameTextBox.Text = config.Name;
|
||||||
|
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
|
||||||
|
categoryComboBox.Text = config.Category.ToString();
|
||||||
|
positionTextBox.Text = config.Idx1.ToString();
|
||||||
|
adcClosedTextBox.Text = config.AdcValueClosed.ToString();
|
||||||
|
adcOpenTextBox.Text = config.AdcValueOpen.ToString();
|
||||||
|
stableTimeTextBox.Text = config.StableTimeMs.ToString();
|
||||||
|
flowStableSecTextBox.Text = config.FlowStableSec.ToString();
|
||||||
|
storedPosReuseCheckBox.Checked = config.StoredPositionReuse;
|
||||||
|
formatTextBox.Text = config.SetpFormat;
|
||||||
|
unitsComboBox.Text = config.SetpUnit.ToString();
|
||||||
|
regulMinStepsComboBox.Text = (config.RegulationMinStep * 50).ToString();
|
||||||
|
|
||||||
|
adcTextBox1.Text = adc1.ToString();
|
||||||
|
adcTextBox2.Text = adc2.ToString();
|
||||||
|
pctTextBox1.Text = pct1.ToString();
|
||||||
|
pctTextBox2.Text = pct2.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unlock()
|
||||||
|
{
|
||||||
|
nameTextBox.Enabled = true;
|
||||||
|
parentNameComboBox.Enabled = true;
|
||||||
|
categoryComboBox.Enabled = true;
|
||||||
|
positionTextBox.Enabled = true;
|
||||||
|
adcClosedTextBox.Enabled = true;
|
||||||
|
adcOpenTextBox.Enabled = true;
|
||||||
|
stableTimeTextBox.Enabled = true;
|
||||||
|
flowStableSecTextBox.Enabled = true;
|
||||||
|
storedPosReuseCheckBox.Enabled = true;
|
||||||
|
formatTextBox.Enabled = true;
|
||||||
|
unitsComboBox.Enabled = true;
|
||||||
|
regulMinStepsComboBox.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||||
|
{
|
||||||
|
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "Invalid 'Parent Name'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!categoryComboBox.Text.Equals(ValveCategory.Feeding.ToString()) &&
|
||||||
|
!categoryComboBox.Text.Equals(ValveCategory.Output.ToString()))
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "Invalid 'Category'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 1 || dummy > 8)
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "'Position' should be between 1 and 8";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(adcClosedTextBox.Text, out dummy) || dummy < 0 || dummy > 1023)
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "'ADC when Closed' should be between 0 and 1023";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(adcOpenTextBox.Text, out dummy) || dummy < 0 || dummy > 1023)
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "'ADC when Open' should be between 0 and 1023";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(stableTimeTextBox.Text, out dummy) || dummy < 200 || dummy > 1500 || (dummy % 50) != 0)
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "'Stable time' should be between 200 and 1500 ms in 50 ms steps";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(flowStableSecTextBox.Text, out dummy) || dummy < 0 || dummy > 60)
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "'Flow stable' should be between 0 and 60 sec";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unitsComboBox.Items.Contains(unitsComboBox.Text))
|
||||||
|
{
|
||||||
|
flags |= CfgUpdateFlags.Error;
|
||||||
|
message += Environment.NewLine + "Invalid 'Units'";
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CfgUpdateFlags UpdateCfg()
|
||||||
|
{
|
||||||
|
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||||
|
|
||||||
|
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||||
|
///
|
||||||
|
if (!config.Name.Equals(nameTextBox.Text))
|
||||||
|
{
|
||||||
|
config.Name = nameTextBox.Text;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
string parentname = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
|
||||||
|
if (!config.ParentName.Equals(parentname))
|
||||||
|
{
|
||||||
|
config.ParentName = parentname;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValveCategory newCategory;
|
||||||
|
if (categoryComboBox.Text.Equals(ValveCategory.Feeding.ToString())) newCategory = ValveCategory.Feeding;
|
||||||
|
else if (categoryComboBox.Text.Equals(ValveCategory.Output.ToString())) newCategory = ValveCategory.Output;
|
||||||
|
else newCategory = ValveCategory.None;
|
||||||
|
if (newCategory != config.Category)
|
||||||
|
{
|
||||||
|
config.Category = newCategory;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp = int.Parse(positionTextBox.Text);
|
||||||
|
if (config.Idx1 != tmp)
|
||||||
|
{
|
||||||
|
config.Idx1 = tmp;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = int.Parse(adcClosedTextBox.Text);
|
||||||
|
if (config.AdcValueClosed != tmp)
|
||||||
|
{
|
||||||
|
config.AdcValueClosed = tmp;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = int.Parse(adcOpenTextBox.Text);
|
||||||
|
if (config.AdcValueOpen != tmp)
|
||||||
|
{
|
||||||
|
config.AdcValueOpen = tmp;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = int.Parse(stableTimeTextBox.Text);
|
||||||
|
if (config.StableTimeMs != tmp)
|
||||||
|
{
|
||||||
|
config.StableTimeMs = tmp;
|
||||||
|
flags |= CfgUpdateFlags.AnyChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = int.Parse(flowStableSecTextBox.Text);
|
||||||
|
if (config.FlowStableSec != tmp)
|
||||||
|
{
|
||||||
|
config.FlowStableSec = tmp;
|
||||||
|
flags |= CfgUpdateFlags.AnyChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = regulMinStepsComboBox.SelectedIndex;
|
||||||
|
if (config.RegulationMinStep != tmp)
|
||||||
|
{
|
||||||
|
config.RegulationMinStep = tmp;
|
||||||
|
flags |= CfgUpdateFlags.AnyChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool btmp = storedPosReuseCheckBox.Checked;
|
||||||
|
if (config.StoredPositionReuse != btmp)
|
||||||
|
{
|
||||||
|
config.StoredPositionReuse = btmp;
|
||||||
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & CfgUpdateFlags.AnyChange) != 0)
|
||||||
|
{
|
||||||
|
RegValve.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
config.SetpFormat = formatTextBox.Text;
|
||||||
|
config.SetpUnit = global::Common.Unit.None;
|
||||||
|
for (Common.Unit units = 0; units < global::Common.Unit.Count; units++)
|
||||||
|
{
|
||||||
|
if (unitsComboBox.Text == units.ToString())
|
||||||
|
{
|
||||||
|
config.SetpUnit = units;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
int adc1;
|
||||||
|
int pct1;
|
||||||
|
|
||||||
|
int adc2;
|
||||||
|
int pct2;
|
||||||
|
|
||||||
|
private void openButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RegValve.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.RVOpenStep, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RegValve.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.RVCloseStep, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
private void getButton1_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RegValve.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.GetAdc1, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getButton2_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RegValve.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.GetAdc2, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
int tmpPct1;
|
||||||
|
int tmpPct2;
|
||||||
|
if ((int.TryParse(pctTextBox1.Text, out tmpPct1) && (tmpPct1 >= 0) && (tmpPct1 <= 100)) &&
|
||||||
|
(int.TryParse(pctTextBox2.Text, out tmpPct2) && (tmpPct2 >= 0) && (tmpPct2 <= 100)))
|
||||||
|
{
|
||||||
|
pct1 = tmpPct1;
|
||||||
|
pct2 = tmpPct2;
|
||||||
|
UpdateValveOpenClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateValveOpenClose()
|
||||||
|
{
|
||||||
|
if ((adc1 == adc2) || (pct1 == pct2)) return;
|
||||||
|
|
||||||
|
double factor = (float)(adc2 - adc1) / (float)(pct2 - pct1);
|
||||||
|
int adcClosed = (int)((float)(0 - pct1) * factor + (float)adc1 + 0.5f);
|
||||||
|
int adcOpen = (int)((float)(100 - pct1) * factor + (float)adc1 + 0.5f);
|
||||||
|
|
||||||
|
if ((adcClosed >= 0) && (adcOpen >= 0))
|
||||||
|
{
|
||||||
|
adcClosedTextBox.Text = adcClosed.ToString();
|
||||||
|
adcOpenTextBox.Text = adcOpen.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void regulMinStepsComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (regulMinStepsComboBox.SelectedItem != null)
|
||||||
|
{
|
||||||
|
//config.RegulationMinStep = regulMinStepsComboBox.SelectedIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#region Configuration Change Handling
|
||||||
|
|
||||||
|
public static void OnCmdResponse(object sender, CmdResponseArgs args)
|
||||||
|
{
|
||||||
|
if (CmdResponseHandler == null) return;
|
||||||
|
try { CmdResponseHandler(sender, args); }
|
||||||
|
catch (Exception e) { log.Error("CmdResponseHandler(...) failed", e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static event EventHandler<CmdResponseArgs> CmdResponseHandler;
|
||||||
|
|
||||||
|
public void StartResponseHandler()
|
||||||
|
{
|
||||||
|
Handlers.AdcChangedHandler += delegate(object sndr, CmdResponseArgs args)
|
||||||
|
{
|
||||||
|
if (InvokeRequired) { Invoke(new EventHandler<CmdResponseArgs>(OnAdcChanged), sndr, args); }
|
||||||
|
else OnAdcChanged(sndr, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
CmdResponseHandler += delegate(object sender, CmdResponseArgs args)
|
||||||
|
{
|
||||||
|
if (args.Command == CfgChangeCmd.GetAdc1)
|
||||||
|
{
|
||||||
|
adc1 = args.Response;
|
||||||
|
adcTextBox1.Text = adc1.ToString();
|
||||||
|
}
|
||||||
|
else if (args.Command == CfgChangeCmd.GetAdc2)
|
||||||
|
{
|
||||||
|
adc2 = args.Response;
|
||||||
|
adcTextBox2.Text = adc2.ToString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopResponseHandler()
|
||||||
|
{
|
||||||
|
CmdResponseHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAdcChanged(object sender, CmdResponseArgs data)
|
||||||
|
{
|
||||||
|
if (data.Command == CfgChangeCmd.GetAdc && data.Id == config.Idx1)
|
||||||
|
{
|
||||||
|
adcTextBox.Text = data.Response.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Configuration Change Handling
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,581 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Metering Systems
|
||||||
|
///
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
partial class RegValveCfgCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.positionTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.positionLabel = new System.Windows.Forms.Label();
|
||||||
|
this.parentNameLabel = new System.Windows.Forms.Label();
|
||||||
|
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.nameLabel = new System.Windows.Forms.Label();
|
||||||
|
this.classNameLabel = new System.Windows.Forms.Label();
|
||||||
|
this.adcClosedLabel = new System.Windows.Forms.Label();
|
||||||
|
this.adcClosedTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.adcOpenTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.adcOpenLabel = new System.Windows.Forms.Label();
|
||||||
|
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
|
||||||
|
this.storedPosReuseCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
|
this.stableTimeTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.stableTimeLabel = new System.Windows.Forms.Label();
|
||||||
|
this.flowStableSecTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.flowStableSecLabel = new System.Windows.Forms.Label();
|
||||||
|
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.setButton1 = new System.Windows.Forms.Button();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.ADC = new System.Windows.Forms.Label();
|
||||||
|
this.getButton1 = new System.Windows.Forms.Button();
|
||||||
|
this.pctTextBox1 = new System.Windows.Forms.TextBox();
|
||||||
|
this.adcTextBox1 = new System.Windows.Forms.TextBox();
|
||||||
|
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.setButton2 = new System.Windows.Forms.Button();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.getButton2 = new System.Windows.Forms.Button();
|
||||||
|
this.pctTextBox2 = new System.Windows.Forms.TextBox();
|
||||||
|
this.adcTextBox2 = new System.Windows.Forms.TextBox();
|
||||||
|
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.closeButton = new System.Windows.Forms.Button();
|
||||||
|
this.openButton = new System.Windows.Forms.Button();
|
||||||
|
this.adcTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
|
this.categoryComboBox = new System.Windows.Forms.ComboBox();
|
||||||
|
this.categoryLabel = new System.Windows.Forms.Label();
|
||||||
|
this.unitsComboBox = new System.Windows.Forms.ComboBox();
|
||||||
|
this.unitsLabel = new System.Windows.Forms.Label();
|
||||||
|
this.formatTextBox = new System.Windows.Forms.TextBox();
|
||||||
|
this.formatLabel = new System.Windows.Forms.Label();
|
||||||
|
this.label5 = new System.Windows.Forms.Label();
|
||||||
|
this.regulMinStepsComboBox = new System.Windows.Forms.ComboBox();
|
||||||
|
this.groupBox1.SuspendLayout();
|
||||||
|
this.groupBox2.SuspendLayout();
|
||||||
|
this.groupBox3.SuspendLayout();
|
||||||
|
this.groupBox4.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// positionTextBox
|
||||||
|
//
|
||||||
|
this.positionTextBox.Enabled = false;
|
||||||
|
this.positionTextBox.Location = new System.Drawing.Point(138, 114);
|
||||||
|
this.positionTextBox.Name = "positionTextBox";
|
||||||
|
this.positionTextBox.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.positionTextBox.TabIndex = 8;
|
||||||
|
//
|
||||||
|
// positionLabel
|
||||||
|
//
|
||||||
|
this.positionLabel.AutoSize = true;
|
||||||
|
this.positionLabel.Location = new System.Drawing.Point(28, 117);
|
||||||
|
this.positionLabel.Name = "positionLabel";
|
||||||
|
this.positionLabel.Size = new System.Drawing.Size(18, 13);
|
||||||
|
this.positionLabel.TabIndex = 7;
|
||||||
|
this.positionLabel.Text = "ID";
|
||||||
|
//
|
||||||
|
// parentNameLabel
|
||||||
|
//
|
||||||
|
this.parentNameLabel.AutoSize = true;
|
||||||
|
this.parentNameLabel.Location = new System.Drawing.Point(28, 68);
|
||||||
|
this.parentNameLabel.Name = "parentNameLabel";
|
||||||
|
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
|
||||||
|
this.parentNameLabel.TabIndex = 3;
|
||||||
|
this.parentNameLabel.Text = "Parent Name";
|
||||||
|
//
|
||||||
|
// nameTextBox
|
||||||
|
//
|
||||||
|
this.nameTextBox.Enabled = false;
|
||||||
|
this.nameTextBox.Location = new System.Drawing.Point(138, 41);
|
||||||
|
this.nameTextBox.Name = "nameTextBox";
|
||||||
|
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
|
||||||
|
this.nameTextBox.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// nameLabel
|
||||||
|
//
|
||||||
|
this.nameLabel.AutoSize = true;
|
||||||
|
this.nameLabel.Location = new System.Drawing.Point(28, 44);
|
||||||
|
this.nameLabel.Name = "nameLabel";
|
||||||
|
this.nameLabel.Size = new System.Drawing.Size(35, 13);
|
||||||
|
this.nameLabel.TabIndex = 1;
|
||||||
|
this.nameLabel.Text = "Name";
|
||||||
|
//
|
||||||
|
// classNameLabel
|
||||||
|
//
|
||||||
|
this.classNameLabel.AutoSize = true;
|
||||||
|
this.classNameLabel.Location = new System.Drawing.Point(135, 14);
|
||||||
|
this.classNameLabel.Name = "classNameLabel";
|
||||||
|
this.classNameLabel.Size = new System.Drawing.Size(89, 13);
|
||||||
|
this.classNameLabel.TabIndex = 0;
|
||||||
|
this.classNameLabel.Text = "ComponentName";
|
||||||
|
//
|
||||||
|
// adcClosedLabel
|
||||||
|
//
|
||||||
|
this.adcClosedLabel.AutoSize = true;
|
||||||
|
this.adcClosedLabel.Location = new System.Drawing.Point(28, 141);
|
||||||
|
this.adcClosedLabel.Name = "adcClosedLabel";
|
||||||
|
this.adcClosedLabel.Size = new System.Drawing.Size(93, 13);
|
||||||
|
this.adcClosedLabel.TabIndex = 9;
|
||||||
|
this.adcClosedLabel.Text = "ADC when Closed";
|
||||||
|
//
|
||||||
|
// adcClosedTextBox
|
||||||
|
//
|
||||||
|
this.adcClosedTextBox.Enabled = false;
|
||||||
|
this.adcClosedTextBox.Location = new System.Drawing.Point(138, 138);
|
||||||
|
this.adcClosedTextBox.Name = "adcClosedTextBox";
|
||||||
|
this.adcClosedTextBox.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.adcClosedTextBox.TabIndex = 10;
|
||||||
|
//
|
||||||
|
// adcOpenTextBox
|
||||||
|
//
|
||||||
|
this.adcOpenTextBox.Enabled = false;
|
||||||
|
this.adcOpenTextBox.Location = new System.Drawing.Point(138, 162);
|
||||||
|
this.adcOpenTextBox.Name = "adcOpenTextBox";
|
||||||
|
this.adcOpenTextBox.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.adcOpenTextBox.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// adcOpenLabel
|
||||||
|
//
|
||||||
|
this.adcOpenLabel.AutoSize = true;
|
||||||
|
this.adcOpenLabel.Location = new System.Drawing.Point(28, 165);
|
||||||
|
this.adcOpenLabel.Name = "adcOpenLabel";
|
||||||
|
this.adcOpenLabel.Size = new System.Drawing.Size(87, 13);
|
||||||
|
this.adcOpenLabel.TabIndex = 11;
|
||||||
|
this.adcOpenLabel.Text = "ADC when Open";
|
||||||
|
//
|
||||||
|
// parentNameComboBox
|
||||||
|
//
|
||||||
|
this.parentNameComboBox.Enabled = false;
|
||||||
|
this.parentNameComboBox.FormattingEnabled = true;
|
||||||
|
this.parentNameComboBox.Location = new System.Drawing.Point(138, 65);
|
||||||
|
this.parentNameComboBox.Name = "parentNameComboBox";
|
||||||
|
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
|
||||||
|
this.parentNameComboBox.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// storedPosReuseCheckBox
|
||||||
|
//
|
||||||
|
this.storedPosReuseCheckBox.AutoSize = true;
|
||||||
|
this.storedPosReuseCheckBox.Enabled = false;
|
||||||
|
this.storedPosReuseCheckBox.Location = new System.Drawing.Point(31, 262);
|
||||||
|
this.storedPosReuseCheckBox.Name = "storedPosReuseCheckBox";
|
||||||
|
this.storedPosReuseCheckBox.Size = new System.Drawing.Size(162, 17);
|
||||||
|
this.storedPosReuseCheckBox.TabIndex = 17;
|
||||||
|
this.storedPosReuseCheckBox.Text = "Enable stored position re-use";
|
||||||
|
this.storedPosReuseCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// stableTimeTextBox
|
||||||
|
//
|
||||||
|
this.stableTimeTextBox.Enabled = false;
|
||||||
|
this.stableTimeTextBox.Location = new System.Drawing.Point(138, 186);
|
||||||
|
this.stableTimeTextBox.Name = "stableTimeTextBox";
|
||||||
|
this.stableTimeTextBox.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.stableTimeTextBox.TabIndex = 14;
|
||||||
|
//
|
||||||
|
// stableTimeLabel
|
||||||
|
//
|
||||||
|
this.stableTimeLabel.AutoSize = true;
|
||||||
|
this.stableTimeLabel.Location = new System.Drawing.Point(28, 189);
|
||||||
|
this.stableTimeLabel.Name = "stableTimeLabel";
|
||||||
|
this.stableTimeLabel.Size = new System.Drawing.Size(81, 13);
|
||||||
|
this.stableTimeLabel.TabIndex = 13;
|
||||||
|
this.stableTimeLabel.Text = "Stable time [ms]";
|
||||||
|
//
|
||||||
|
// flowStableSecTextBox
|
||||||
|
//
|
||||||
|
this.flowStableSecTextBox.Enabled = false;
|
||||||
|
this.flowStableSecTextBox.Location = new System.Drawing.Point(138, 210);
|
||||||
|
this.flowStableSecTextBox.Name = "flowStableSecTextBox";
|
||||||
|
this.flowStableSecTextBox.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.flowStableSecTextBox.TabIndex = 16;
|
||||||
|
//
|
||||||
|
// flowStableSecLabel
|
||||||
|
//
|
||||||
|
this.flowStableSecLabel.AutoSize = true;
|
||||||
|
this.flowStableSecLabel.Location = new System.Drawing.Point(28, 213);
|
||||||
|
this.flowStableSecLabel.Name = "flowStableSecLabel";
|
||||||
|
this.flowStableSecLabel.Size = new System.Drawing.Size(74, 13);
|
||||||
|
this.flowStableSecLabel.TabIndex = 15;
|
||||||
|
this.flowStableSecLabel.Text = "Flow stable [s]";
|
||||||
|
//
|
||||||
|
// groupBox1
|
||||||
|
//
|
||||||
|
this.groupBox1.Controls.Add(this.setButton1);
|
||||||
|
this.groupBox1.Controls.Add(this.label1);
|
||||||
|
this.groupBox1.Controls.Add(this.ADC);
|
||||||
|
this.groupBox1.Controls.Add(this.getButton1);
|
||||||
|
this.groupBox1.Controls.Add(this.pctTextBox1);
|
||||||
|
this.groupBox1.Controls.Add(this.adcTextBox1);
|
||||||
|
this.groupBox1.Location = new System.Drawing.Point(10, 398);
|
||||||
|
this.groupBox1.Name = "groupBox1";
|
||||||
|
this.groupBox1.Size = new System.Drawing.Size(280, 59);
|
||||||
|
this.groupBox1.TabIndex = 19;
|
||||||
|
this.groupBox1.TabStop = false;
|
||||||
|
this.groupBox1.Text = "Measured value 1";
|
||||||
|
//
|
||||||
|
// setButton1
|
||||||
|
//
|
||||||
|
this.setButton1.Location = new System.Drawing.Point(229, 17);
|
||||||
|
this.setButton1.Name = "setButton1";
|
||||||
|
this.setButton1.Size = new System.Drawing.Size(38, 33);
|
||||||
|
this.setButton1.TabIndex = 5;
|
||||||
|
this.setButton1.Text = "Set";
|
||||||
|
this.setButton1.UseVisualStyleBackColor = true;
|
||||||
|
this.setButton1.Click += new System.EventHandler(this.setButton_Click);
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.Location = new System.Drawing.Point(209, 28);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(15, 13);
|
||||||
|
this.label1.TabIndex = 4;
|
||||||
|
this.label1.Text = "%";
|
||||||
|
//
|
||||||
|
// ADC
|
||||||
|
//
|
||||||
|
this.ADC.AutoSize = true;
|
||||||
|
this.ADC.Location = new System.Drawing.Point(11, 28);
|
||||||
|
this.ADC.Name = "ADC";
|
||||||
|
this.ADC.Size = new System.Drawing.Size(32, 13);
|
||||||
|
this.ADC.TabIndex = 3;
|
||||||
|
this.ADC.Text = "ADC:";
|
||||||
|
//
|
||||||
|
// getButton1
|
||||||
|
//
|
||||||
|
this.getButton1.Location = new System.Drawing.Point(101, 18);
|
||||||
|
this.getButton1.Name = "getButton1";
|
||||||
|
this.getButton1.Size = new System.Drawing.Size(38, 33);
|
||||||
|
this.getButton1.TabIndex = 2;
|
||||||
|
this.getButton1.Text = "Get";
|
||||||
|
this.getButton1.UseVisualStyleBackColor = true;
|
||||||
|
this.getButton1.Click += new System.EventHandler(this.getButton1_Click);
|
||||||
|
//
|
||||||
|
// pctTextBox1
|
||||||
|
//
|
||||||
|
this.pctTextBox1.Location = new System.Drawing.Point(160, 24);
|
||||||
|
this.pctTextBox1.Name = "pctTextBox1";
|
||||||
|
this.pctTextBox1.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.pctTextBox1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// adcTextBox1
|
||||||
|
//
|
||||||
|
this.adcTextBox1.Location = new System.Drawing.Point(47, 24);
|
||||||
|
this.adcTextBox1.Name = "adcTextBox1";
|
||||||
|
this.adcTextBox1.Size = new System.Drawing.Size(44, 20);
|
||||||
|
this.adcTextBox1.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// groupBox2
|
||||||
|
//
|
||||||
|
this.groupBox2.Controls.Add(this.setButton2);
|
||||||
|
this.groupBox2.Controls.Add(this.label2);
|
||||||
|
this.groupBox2.Controls.Add(this.label3);
|
||||||
|
this.groupBox2.Controls.Add(this.getButton2);
|
||||||
|
this.groupBox2.Controls.Add(this.pctTextBox2);
|
||||||
|
this.groupBox2.Controls.Add(this.adcTextBox2);
|
||||||
|
this.groupBox2.Location = new System.Drawing.Point(10, 462);
|
||||||
|
this.groupBox2.Name = "groupBox2";
|
||||||
|
this.groupBox2.Size = new System.Drawing.Size(280, 59);
|
||||||
|
this.groupBox2.TabIndex = 20;
|
||||||
|
this.groupBox2.TabStop = false;
|
||||||
|
this.groupBox2.Text = "Measured value 2";
|
||||||
|
//
|
||||||
|
// setButton2
|
||||||
|
//
|
||||||
|
this.setButton2.Location = new System.Drawing.Point(229, 17);
|
||||||
|
this.setButton2.Name = "setButton2";
|
||||||
|
this.setButton2.Size = new System.Drawing.Size(38, 33);
|
||||||
|
this.setButton2.TabIndex = 5;
|
||||||
|
this.setButton2.Text = "Set";
|
||||||
|
this.setButton2.UseVisualStyleBackColor = true;
|
||||||
|
this.setButton2.Click += new System.EventHandler(this.setButton_Click);
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.AutoSize = true;
|
||||||
|
this.label2.Location = new System.Drawing.Point(209, 28);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(15, 13);
|
||||||
|
this.label2.TabIndex = 4;
|
||||||
|
this.label2.Text = "%";
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.AutoSize = true;
|
||||||
|
this.label3.Location = new System.Drawing.Point(11, 27);
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(32, 13);
|
||||||
|
this.label3.TabIndex = 3;
|
||||||
|
this.label3.Text = "ADC:";
|
||||||
|
//
|
||||||
|
// getButton2
|
||||||
|
//
|
||||||
|
this.getButton2.Location = new System.Drawing.Point(101, 18);
|
||||||
|
this.getButton2.Name = "getButton2";
|
||||||
|
this.getButton2.Size = new System.Drawing.Size(38, 33);
|
||||||
|
this.getButton2.TabIndex = 2;
|
||||||
|
this.getButton2.Text = "Get";
|
||||||
|
this.getButton2.UseVisualStyleBackColor = true;
|
||||||
|
this.getButton2.Click += new System.EventHandler(this.getButton2_Click);
|
||||||
|
//
|
||||||
|
// pctTextBox2
|
||||||
|
//
|
||||||
|
this.pctTextBox2.Location = new System.Drawing.Point(160, 24);
|
||||||
|
this.pctTextBox2.Name = "pctTextBox2";
|
||||||
|
this.pctTextBox2.Size = new System.Drawing.Size(46, 20);
|
||||||
|
this.pctTextBox2.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// adcTextBox2
|
||||||
|
//
|
||||||
|
this.adcTextBox2.Location = new System.Drawing.Point(47, 24);
|
||||||
|
this.adcTextBox2.Name = "adcTextBox2";
|
||||||
|
this.adcTextBox2.Size = new System.Drawing.Size(44, 20);
|
||||||
|
this.adcTextBox2.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// groupBox3
|
||||||
|
//
|
||||||
|
this.groupBox3.Controls.Add(this.closeButton);
|
||||||
|
this.groupBox3.Controls.Add(this.openButton);
|
||||||
|
this.groupBox3.Location = new System.Drawing.Point(10, 527);
|
||||||
|
this.groupBox3.Name = "groupBox3";
|
||||||
|
this.groupBox3.Size = new System.Drawing.Size(280, 60);
|
||||||
|
this.groupBox3.TabIndex = 21;
|
||||||
|
this.groupBox3.TabStop = false;
|
||||||
|
this.groupBox3.Text = "Regulation valve";
|
||||||
|
//
|
||||||
|
// closeButton
|
||||||
|
//
|
||||||
|
this.closeButton.Location = new System.Drawing.Point(14, 19);
|
||||||
|
this.closeButton.Name = "closeButton";
|
||||||
|
this.closeButton.Size = new System.Drawing.Size(107, 28);
|
||||||
|
this.closeButton.TabIndex = 1;
|
||||||
|
this.closeButton.Text = "Close";
|
||||||
|
this.closeButton.UseVisualStyleBackColor = true;
|
||||||
|
this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
|
||||||
|
//
|
||||||
|
// openButton
|
||||||
|
//
|
||||||
|
this.openButton.Location = new System.Drawing.Point(160, 19);
|
||||||
|
this.openButton.Name = "openButton";
|
||||||
|
this.openButton.Size = new System.Drawing.Size(107, 28);
|
||||||
|
this.openButton.TabIndex = 0;
|
||||||
|
this.openButton.Text = "Open";
|
||||||
|
this.openButton.UseVisualStyleBackColor = true;
|
||||||
|
this.openButton.Click += new System.EventHandler(this.openButton_Click);
|
||||||
|
//
|
||||||
|
// adcTextBox
|
||||||
|
//
|
||||||
|
this.adcTextBox.Location = new System.Drawing.Point(47, 14);
|
||||||
|
this.adcTextBox.Name = "adcTextBox";
|
||||||
|
this.adcTextBox.Size = new System.Drawing.Size(44, 20);
|
||||||
|
this.adcTextBox.TabIndex = 21;
|
||||||
|
//
|
||||||
|
// groupBox4
|
||||||
|
//
|
||||||
|
this.groupBox4.Controls.Add(this.label4);
|
||||||
|
this.groupBox4.Controls.Add(this.adcTextBox);
|
||||||
|
this.groupBox4.Location = new System.Drawing.Point(10, 352);
|
||||||
|
this.groupBox4.Name = "groupBox4";
|
||||||
|
this.groupBox4.Size = new System.Drawing.Size(279, 40);
|
||||||
|
this.groupBox4.TabIndex = 22;
|
||||||
|
this.groupBox4.TabStop = false;
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
this.label4.AutoSize = true;
|
||||||
|
this.label4.Location = new System.Drawing.Point(11, 17);
|
||||||
|
this.label4.Name = "label4";
|
||||||
|
this.label4.Size = new System.Drawing.Size(32, 13);
|
||||||
|
this.label4.TabIndex = 22;
|
||||||
|
this.label4.Text = "ADC:";
|
||||||
|
//
|
||||||
|
// categoryComboBox
|
||||||
|
//
|
||||||
|
this.categoryComboBox.Enabled = false;
|
||||||
|
this.categoryComboBox.FormattingEnabled = true;
|
||||||
|
this.categoryComboBox.Location = new System.Drawing.Point(138, 90);
|
||||||
|
this.categoryComboBox.Name = "categoryComboBox";
|
||||||
|
this.categoryComboBox.Size = new System.Drawing.Size(130, 21);
|
||||||
|
this.categoryComboBox.TabIndex = 6;
|
||||||
|
//
|
||||||
|
// categoryLabel
|
||||||
|
//
|
||||||
|
this.categoryLabel.AutoSize = true;
|
||||||
|
this.categoryLabel.Location = new System.Drawing.Point(28, 93);
|
||||||
|
this.categoryLabel.Name = "categoryLabel";
|
||||||
|
this.categoryLabel.Size = new System.Drawing.Size(49, 13);
|
||||||
|
this.categoryLabel.TabIndex = 5;
|
||||||
|
this.categoryLabel.Text = "Category";
|
||||||
|
//
|
||||||
|
// unitsComboBox
|
||||||
|
//
|
||||||
|
this.unitsComboBox.Enabled = false;
|
||||||
|
this.unitsComboBox.FormattingEnabled = true;
|
||||||
|
this.unitsComboBox.Location = new System.Drawing.Point(138, 309);
|
||||||
|
this.unitsComboBox.Name = "unitsComboBox";
|
||||||
|
this.unitsComboBox.Size = new System.Drawing.Size(80, 21);
|
||||||
|
this.unitsComboBox.TabIndex = 32;
|
||||||
|
//
|
||||||
|
// unitsLabel
|
||||||
|
//
|
||||||
|
this.unitsLabel.AutoSize = true;
|
||||||
|
this.unitsLabel.Location = new System.Drawing.Point(28, 312);
|
||||||
|
this.unitsLabel.Name = "unitsLabel";
|
||||||
|
this.unitsLabel.Size = new System.Drawing.Size(78, 13);
|
||||||
|
this.unitsLabel.TabIndex = 31;
|
||||||
|
this.unitsLabel.Text = "Unit of setpoint";
|
||||||
|
//
|
||||||
|
// formatTextBox
|
||||||
|
//
|
||||||
|
this.formatTextBox.Enabled = false;
|
||||||
|
this.formatTextBox.Location = new System.Drawing.Point(138, 285);
|
||||||
|
this.formatTextBox.Name = "formatTextBox";
|
||||||
|
this.formatTextBox.Size = new System.Drawing.Size(130, 20);
|
||||||
|
this.formatTextBox.TabIndex = 30;
|
||||||
|
//
|
||||||
|
// formatLabel
|
||||||
|
//
|
||||||
|
this.formatLabel.AutoSize = true;
|
||||||
|
this.formatLabel.Location = new System.Drawing.Point(28, 288);
|
||||||
|
this.formatLabel.Name = "formatLabel";
|
||||||
|
this.formatLabel.Size = new System.Drawing.Size(78, 13);
|
||||||
|
this.formatLabel.TabIndex = 29;
|
||||||
|
this.formatLabel.Text = "Setpoint format";
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
this.label5.AutoSize = true;
|
||||||
|
this.label5.Location = new System.Drawing.Point(28, 239);
|
||||||
|
this.label5.Name = "label5";
|
||||||
|
this.label5.Size = new System.Drawing.Size(110, 13);
|
||||||
|
this.label5.TabIndex = 33;
|
||||||
|
this.label5.Text = "Regul. min. steps [ms]";
|
||||||
|
//
|
||||||
|
// regulMinStepsComboBox
|
||||||
|
//
|
||||||
|
this.regulMinStepsComboBox.Enabled = false;
|
||||||
|
this.regulMinStepsComboBox.FormattingEnabled = true;
|
||||||
|
this.regulMinStepsComboBox.Location = new System.Drawing.Point(138, 236);
|
||||||
|
this.regulMinStepsComboBox.Name = "regulMinStepsComboBox";
|
||||||
|
this.regulMinStepsComboBox.Size = new System.Drawing.Size(80, 21);
|
||||||
|
this.regulMinStepsComboBox.TabIndex = 34;
|
||||||
|
this.regulMinStepsComboBox.SelectedIndexChanged += new System.EventHandler(this.regulMinStepsComboBox_SelectedIndexChanged);
|
||||||
|
//
|
||||||
|
// RegValveCfgCtrl
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.Controls.Add(this.regulMinStepsComboBox);
|
||||||
|
this.Controls.Add(this.label5);
|
||||||
|
this.Controls.Add(this.unitsComboBox);
|
||||||
|
this.Controls.Add(this.unitsLabel);
|
||||||
|
this.Controls.Add(this.formatTextBox);
|
||||||
|
this.Controls.Add(this.formatLabel);
|
||||||
|
this.Controls.Add(this.categoryComboBox);
|
||||||
|
this.Controls.Add(this.categoryLabel);
|
||||||
|
this.Controls.Add(this.groupBox4);
|
||||||
|
this.Controls.Add(this.groupBox3);
|
||||||
|
this.Controls.Add(this.groupBox2);
|
||||||
|
this.Controls.Add(this.groupBox1);
|
||||||
|
this.Controls.Add(this.flowStableSecTextBox);
|
||||||
|
this.Controls.Add(this.flowStableSecLabel);
|
||||||
|
this.Controls.Add(this.stableTimeTextBox);
|
||||||
|
this.Controls.Add(this.stableTimeLabel);
|
||||||
|
this.Controls.Add(this.storedPosReuseCheckBox);
|
||||||
|
this.Controls.Add(this.parentNameComboBox);
|
||||||
|
this.Controls.Add(this.adcOpenTextBox);
|
||||||
|
this.Controls.Add(this.adcOpenLabel);
|
||||||
|
this.Controls.Add(this.adcClosedTextBox);
|
||||||
|
this.Controls.Add(this.adcClosedLabel);
|
||||||
|
this.Controls.Add(this.positionTextBox);
|
||||||
|
this.Controls.Add(this.positionLabel);
|
||||||
|
this.Controls.Add(this.parentNameLabel);
|
||||||
|
this.Controls.Add(this.nameTextBox);
|
||||||
|
this.Controls.Add(this.nameLabel);
|
||||||
|
this.Controls.Add(this.classNameLabel);
|
||||||
|
this.Name = "RegValveCfgCtrl";
|
||||||
|
this.Size = new System.Drawing.Size(300, 700);
|
||||||
|
this.Load += new System.EventHandler(this.RegulationValveCfgCtrl_Load);
|
||||||
|
this.groupBox1.ResumeLayout(false);
|
||||||
|
this.groupBox1.PerformLayout();
|
||||||
|
this.groupBox2.ResumeLayout(false);
|
||||||
|
this.groupBox2.PerformLayout();
|
||||||
|
this.groupBox3.ResumeLayout(false);
|
||||||
|
this.groupBox4.ResumeLayout(false);
|
||||||
|
this.groupBox4.PerformLayout();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.TextBox positionTextBox;
|
||||||
|
private System.Windows.Forms.Label positionLabel;
|
||||||
|
private System.Windows.Forms.Label parentNameLabel;
|
||||||
|
private System.Windows.Forms.TextBox nameTextBox;
|
||||||
|
private System.Windows.Forms.Label nameLabel;
|
||||||
|
private System.Windows.Forms.Label classNameLabel;
|
||||||
|
private System.Windows.Forms.Label adcClosedLabel;
|
||||||
|
private System.Windows.Forms.TextBox adcClosedTextBox;
|
||||||
|
private System.Windows.Forms.TextBox adcOpenTextBox;
|
||||||
|
private System.Windows.Forms.Label adcOpenLabel;
|
||||||
|
private System.Windows.Forms.ComboBox parentNameComboBox;
|
||||||
|
private System.Windows.Forms.CheckBox storedPosReuseCheckBox;
|
||||||
|
private System.Windows.Forms.TextBox stableTimeTextBox;
|
||||||
|
private System.Windows.Forms.Label stableTimeLabel;
|
||||||
|
private System.Windows.Forms.TextBox flowStableSecTextBox;
|
||||||
|
private System.Windows.Forms.Label flowStableSecLabel;
|
||||||
|
private System.Windows.Forms.GroupBox groupBox1;
|
||||||
|
private System.Windows.Forms.Button setButton1;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.Label ADC;
|
||||||
|
private System.Windows.Forms.Button getButton1;
|
||||||
|
private System.Windows.Forms.TextBox pctTextBox1;
|
||||||
|
private System.Windows.Forms.TextBox adcTextBox1;
|
||||||
|
private System.Windows.Forms.GroupBox groupBox2;
|
||||||
|
private System.Windows.Forms.Button setButton2;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.Button getButton2;
|
||||||
|
private System.Windows.Forms.TextBox pctTextBox2;
|
||||||
|
private System.Windows.Forms.TextBox adcTextBox2;
|
||||||
|
private System.Windows.Forms.GroupBox groupBox3;
|
||||||
|
private System.Windows.Forms.Button closeButton;
|
||||||
|
private System.Windows.Forms.Button openButton;
|
||||||
|
private System.Windows.Forms.TextBox adcTextBox;
|
||||||
|
private System.Windows.Forms.GroupBox groupBox4;
|
||||||
|
private System.Windows.Forms.Label label4;
|
||||||
|
private System.Windows.Forms.ComboBox categoryComboBox;
|
||||||
|
private System.Windows.Forms.Label categoryLabel;
|
||||||
|
private System.Windows.Forms.ComboBox unitsComboBox;
|
||||||
|
private System.Windows.Forms.Label unitsLabel;
|
||||||
|
private System.Windows.Forms.TextBox formatTextBox;
|
||||||
|
private System.Windows.Forms.Label formatLabel;
|
||||||
|
private System.Windows.Forms.Label label5;
|
||||||
|
private System.Windows.Forms.ComboBox regulMinStepsComboBox;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Common;
|
||||||
|
using log4net;
|
||||||
|
using Config.Entities;
|
||||||
|
using TBF.Rig.ControlBoard.Uni;
|
||||||
|
using TBF.Rig.GenericDevices;
|
||||||
|
using TBF.Boxes;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public class SetFlowOp : IOperation
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp));
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2})", regV.Name, shrinkedTgtFlowLo, shrinkedTgtFlowHi);
|
||||||
|
}
|
||||||
|
|
||||||
|
public const double RqrdFlowRangeRatio = 0.5;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set by the constructor
|
||||||
|
///
|
||||||
|
readonly UniCB uniCB;
|
||||||
|
readonly RegValve regV;
|
||||||
|
readonly IFlowMeter flowMeter;
|
||||||
|
readonly double shrinkedTgtFlowLo;
|
||||||
|
readonly double shrinkedTgtFlowHi;
|
||||||
|
readonly double targetFlowAve;
|
||||||
|
readonly int timeout;
|
||||||
|
readonly int delay;
|
||||||
|
readonly bool leaveFlowControlRunning;
|
||||||
|
|
||||||
|
readonly double maximalFlow;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Internal state of this operation
|
||||||
|
///
|
||||||
|
enum OpState
|
||||||
|
{
|
||||||
|
Idle = 0,
|
||||||
|
ValveMoveToPosition1, /// Wait 1 takt
|
||||||
|
ValveMoveToPosition2, /// This is actual move to position
|
||||||
|
ValveMoveToPosition3, /// Wait 1 takt
|
||||||
|
SettingPosition,
|
||||||
|
Wait4FlowMsrmntAndSendRVMove, /// Wait until the flow measurement starts, then issue reg. valve move command
|
||||||
|
SettingFlow, /// Measure the flow and verify whether it is within limits sufficiently long time
|
||||||
|
FlowReached,
|
||||||
|
SendCommandAgain,
|
||||||
|
}
|
||||||
|
OpState opState;
|
||||||
|
|
||||||
|
double currentReqFlowLo;
|
||||||
|
double currentReqFlowHi;
|
||||||
|
double targetPositionLo;
|
||||||
|
double targetPositionHi;
|
||||||
|
|
||||||
|
int setFlowTime;
|
||||||
|
int expireTime;
|
||||||
|
DoubleBox msrdFlow;
|
||||||
|
int isFlowOkDuration;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow. Conditionally leave the measurement running.
|
||||||
|
/// Events: FlowSet, FlowTimeOut
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uniCB">Control board device</param>
|
||||||
|
/// <param name="regValve">Regulation valve component</param>
|
||||||
|
/// <param name="flowMeter">Flowmeter component</param>
|
||||||
|
/// <param name="qFrom">Lower limit of the flow to be achieved in [m3/h]</param>
|
||||||
|
/// <param name="qTo">Upper limit of the flow to be achieved in [m3/h]</param>
|
||||||
|
/// <param name="msrdFlow">DoubleBox for measured flow</param>
|
||||||
|
/// <param name="timeout">Timeout for the flow setting in [s]</param>
|
||||||
|
/// <param name="delay">Flow setting starts after this delay in [s]</param>
|
||||||
|
/// <param name="leaveFlowControlRunning">true = Leave the measurement running after op. stop</param>
|
||||||
|
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||||
|
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox msrdFlow,
|
||||||
|
int timeout, int delay, bool leaveFlowControlRunning)
|
||||||
|
{
|
||||||
|
this.uniCB = uniCB;
|
||||||
|
if (this.uniCB == null) throw new ArgumentNullException("Control board is null or not Uni");
|
||||||
|
|
||||||
|
this.regV = regValve as RegValve;
|
||||||
|
if (this.regV == null) throw new ArgumentNullException(string.Format("{0} is not Uni.RegValve", regValve.Name));
|
||||||
|
|
||||||
|
this.flowMeter = flowMeter;
|
||||||
|
if (this.flowMeter == null) throw new ArgumentNullException("flowMeter");
|
||||||
|
|
||||||
|
maximalFlow = flowMeter.NominalFlow * 1.25;
|
||||||
|
|
||||||
|
double rqrdFlowLoBeforeCorr = qFrom - MeasurementCorrection.GetCorrection(qFrom, flowMeter.Corrections);
|
||||||
|
double rqrdFlowHiBeforeCorr = qTo - MeasurementCorrection.GetCorrection(qTo, flowMeter.Corrections);
|
||||||
|
targetFlowAve = (rqrdFlowLoBeforeCorr + rqrdFlowHiBeforeCorr) / 2;
|
||||||
|
shrinkedTgtFlowLo = (RqrdFlowRangeRatio * rqrdFlowLoBeforeCorr)
|
||||||
|
+ ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the lower limit 15% of the range up
|
||||||
|
shrinkedTgtFlowHi = (RqrdFlowRangeRatio * rqrdFlowHiBeforeCorr)
|
||||||
|
+ ((1 - RqrdFlowRangeRatio) * targetFlowAve); /// Move the upper limit 15% of the range down
|
||||||
|
|
||||||
|
this.msrdFlow = msrdFlow;
|
||||||
|
this.timeout = timeout;
|
||||||
|
this.delay = delay;
|
||||||
|
this.leaveFlowControlRunning = leaveFlowControlRunning;
|
||||||
|
|
||||||
|
log.Debug(this.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow - Do not leave the measurement running.
|
||||||
|
/// Events: FlowSet
|
||||||
|
/// </summary>
|
||||||
|
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox flowbox, int timeout, int delay)
|
||||||
|
: this(uniCB, regValve, flowMeter, qFrom, qTo, flowbox, timeout, delay, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow - Do not leave the measurement running.
|
||||||
|
/// Events: FlowSet
|
||||||
|
/// </summary>
|
||||||
|
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox flowbox, int timeout)
|
||||||
|
: this(uniCB, regValve, flowMeter, qFrom, qTo, flowbox, timeout, 0, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow - No timeout.
|
||||||
|
/// Events: FlowSet
|
||||||
|
/// </summary>
|
||||||
|
public SetFlowOp(UniCB uniCB, IRegValve regValve, IFlowMeter flowMeter, double qFrom, double qTo, DoubleBox flowbox)
|
||||||
|
: this(uniCB, regValve, flowMeter, qFrom, qTo, flowbox, int.MaxValue, 0, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch target position limits from the dictionary or return false
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="avgReqFlow">Average of the flow targer range (input)</param>
|
||||||
|
/// <param name="positionLo">Target valve position low limit (output)</param>
|
||||||
|
/// <param name="positionHi">Target valve position high limit (output)</param>
|
||||||
|
/// <returns>true when positions for the target flow are stored in the memory, otherwise return false</returns>
|
||||||
|
bool FetchTargetPosition(double avgReqFlow, out double positionLo, out double positionHi)
|
||||||
|
{
|
||||||
|
double targetPosition;
|
||||||
|
if (regV.Dict.TryGetValue(avgReqFlow, out targetPosition))
|
||||||
|
{
|
||||||
|
positionLo = Math.Max(targetPosition * 0.95, 0.0);
|
||||||
|
positionHi = Math.Min(targetPosition * 1.05, 100.0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
positionLo = 0;
|
||||||
|
positionHi = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreTargetPosition(double avgReqFlow, double actPosition)
|
||||||
|
{
|
||||||
|
if (!regV.Dict.ContainsKey(targetFlowAve))
|
||||||
|
{
|
||||||
|
regV.Dict.Add(new KeyValuePair<double, double>(avgReqFlow, actPosition));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Start this operation</summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
|
||||||
|
regV.Idx1, flowMeter.Idx1, currentReqFlowLo, currentReqFlowHi);
|
||||||
|
|
||||||
|
/// Store the current time, etc.
|
||||||
|
setFlowTime = StateMachine.Time + delay;
|
||||||
|
expireTime = StateMachine.Time + timeout;
|
||||||
|
if (expireTime < 0) expireTime = int.MaxValue;
|
||||||
|
|
||||||
|
isFlowOkDuration = 0;
|
||||||
|
|
||||||
|
/// Start the flow measurement
|
||||||
|
uniCB.MeasureFlow(false, flowMeter.Idx1);
|
||||||
|
|
||||||
|
opState = OpState.Wait4FlowMsrmntAndSendRVMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Run this operation
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Event.OpArgumentError
|
||||||
|
/// Event.Starting
|
||||||
|
/// Event.Busy
|
||||||
|
/// Event.FlowReached
|
||||||
|
/// Event.RegulValveTimeOut
|
||||||
|
/// </returns>
|
||||||
|
public Event Run()
|
||||||
|
{
|
||||||
|
log.DebugFormat("Op.Run() opState={0}", opState);
|
||||||
|
|
||||||
|
if (StateMachine.Time > expireTime) return Event.RegulValveTimeOut;
|
||||||
|
|
||||||
|
if (opState == OpState.Wait4FlowMsrmntAndSendRVMove)
|
||||||
|
{
|
||||||
|
if (flowMeter.DebugLevel == DebugMode.Simulate) return Event.FlowReached;
|
||||||
|
|
||||||
|
if (!flowMeter.MsrmntAvailable) return Event.Starting;
|
||||||
|
|
||||||
|
double flow1 = flowMeter.ReadFlow();
|
||||||
|
|
||||||
|
/// Set the targer flow/frequency range
|
||||||
|
currentReqFlowLo = shrinkedTgtFlowLo; /// Default lower limit
|
||||||
|
currentReqFlowHi = shrinkedTgtFlowHi; /// Default upper limit
|
||||||
|
//if (flow1 >= targetFlowAve) currentReqFlowHi = targetFlowAve; /// Decrease upper limit
|
||||||
|
//if (flow1 <= targetFlowAve) currentReqFlowLo = targetFlowAve; /// Increase lower limit
|
||||||
|
|
||||||
|
if ((currentReqFlowLo >= currentReqFlowHi) || (currentReqFlowLo > maximalFlow) || (currentReqFlowHi <= 0))
|
||||||
|
{
|
||||||
|
return Event.OpArgumentError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StateMachine.Time > setFlowTime)
|
||||||
|
{
|
||||||
|
uniCB.SetFlow(false, regV.Idx1, flowMeter.NominalFreq * currentReqFlowLo / flowMeter.NominalFlow,
|
||||||
|
flowMeter.NominalFreq * currentReqFlowHi / flowMeter.NominalFlow);
|
||||||
|
|
||||||
|
log.InfoFormat("Run(): rv#={0} TARGET: flowLo={1} flowHi={2}", regV.Idx1, currentReqFlowLo, currentReqFlowHi);
|
||||||
|
|
||||||
|
opState = OpState.SettingFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Event.Starting;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opState == OpState.ValveMoveToPosition1)
|
||||||
|
{
|
||||||
|
opState = OpState.ValveMoveToPosition2;
|
||||||
|
return Event.Starting;
|
||||||
|
}
|
||||||
|
else if (opState == OpState.ValveMoveToPosition2) /// Move to position
|
||||||
|
{
|
||||||
|
/// Issues the appropriate ValveMove(...) command
|
||||||
|
regV.MoveToPosition(false, targetPositionLo, targetPositionHi);
|
||||||
|
|
||||||
|
opState = OpState.SettingPosition;
|
||||||
|
return Event.Starting;
|
||||||
|
}
|
||||||
|
else if (opState == OpState.ValveMoveToPosition3)
|
||||||
|
{
|
||||||
|
opState = OpState.SettingPosition;
|
||||||
|
return Event.Starting;
|
||||||
|
}
|
||||||
|
else if (opState == OpState.SettingPosition)
|
||||||
|
{
|
||||||
|
/// Repeated untill position is reached
|
||||||
|
double rvPosition = regV.Position;
|
||||||
|
if ((targetPositionLo <= rvPosition) && (rvPosition <= targetPositionHi))
|
||||||
|
{
|
||||||
|
opState = OpState.Wait4FlowMsrmntAndSendRVMove;
|
||||||
|
}
|
||||||
|
return Event.Starting;
|
||||||
|
}
|
||||||
|
else if (opState == OpState.SettingFlow)
|
||||||
|
{
|
||||||
|
/// Regulation valve is setting flow to the required value
|
||||||
|
///
|
||||||
|
double frequency = flowMeter.ReadFrequency();
|
||||||
|
double flow = flowMeter.ReadFlow();
|
||||||
|
if (msrdFlow != null && flow != 0) msrdFlow.Val = flow;
|
||||||
|
|
||||||
|
if (currentReqFlowLo <= flow && flow <= currentReqFlowHi)
|
||||||
|
{
|
||||||
|
isFlowOkDuration++; /// Increment the flow within range duration
|
||||||
|
|
||||||
|
if (isFlowOkDuration >= regV.FlowStableSec)
|
||||||
|
{
|
||||||
|
/// Flow is within range for sufficiently long time
|
||||||
|
if (regV.StoredPositionReuse)
|
||||||
|
{
|
||||||
|
double rvPosition = regV.Position; /// Read the current position
|
||||||
|
double storedPosition;
|
||||||
|
if (regV.Dict.TryGetValue(targetFlowAve, out storedPosition))
|
||||||
|
{
|
||||||
|
/// update the stored valve position
|
||||||
|
StoreTargetPosition(targetFlowAve, (rvPosition + storedPosition) / 2.0);
|
||||||
|
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% stored={3} <--- Updating a stored position",
|
||||||
|
regV.Idx1, targetFlowAve, rvPosition.ToString("F1"), storedPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// store the valve position
|
||||||
|
StoreTargetPosition(targetFlowAve, rvPosition);
|
||||||
|
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% <--- Storing a new position",
|
||||||
|
regV.Idx1, targetFlowAve, rvPosition.ToString("F1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, currentReqFlowLo, currentReqFlowHi);
|
||||||
|
|
||||||
|
opState = OpState.FlowReached;
|
||||||
|
return Event.FlowReached;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, FLOW_OK_TIMER={3}s)", flow, currentReqFlowLo, currentReqFlowHi, isFlowOkDuration);
|
||||||
|
return Event.Busy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// Flow is out of range
|
||||||
|
isFlowOkDuration = 0;
|
||||||
|
|
||||||
|
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2})", flow, currentReqFlowLo, currentReqFlowHi);
|
||||||
|
return Event.Busy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /// opState == OpState.FlowReached
|
||||||
|
{
|
||||||
|
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flowMeter.ReadFlow(), currentReqFlowLo, currentReqFlowHi);
|
||||||
|
return Event.FlowReached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Stop this operation</summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
if (!leaveFlowControlRunning)
|
||||||
|
{
|
||||||
|
uniCB.StopFlowControl(false, regV.Idx1); /// Stop the flow measurement
|
||||||
|
}
|
||||||
|
|
||||||
|
opState = OpState.Idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2021-2022 Sensus Slovensko a.s.
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using log4net;
|
||||||
|
using TBF.Rig.ControlBoard.Uni;
|
||||||
|
using TBF.Rig.GenericDevices;
|
||||||
|
|
||||||
|
namespace TBF.Rig.Uni.RegValveLowRegulTimeSaturation
|
||||||
|
{
|
||||||
|
public class SetRegValvePositionOp : IOperation
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(SetRegValvePositionOp));
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("SetRegValvePositionOp({0},{1},{2})", regV.Name, posLoPct, posHiPct);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Internal states of this operation
|
||||||
|
///
|
||||||
|
enum OpState
|
||||||
|
{
|
||||||
|
Idle = 0,
|
||||||
|
MoveToPosition, /// Send commend to move to position
|
||||||
|
CheckState, /// Check RV state by reading statos word
|
||||||
|
MovingToPosition, /// Command passed OK, RV is moving to a position
|
||||||
|
}
|
||||||
|
OpState opState;
|
||||||
|
|
||||||
|
/// Set by the constructor
|
||||||
|
readonly UniCB uniCB;
|
||||||
|
readonly RegValve regV;
|
||||||
|
readonly int regValveNr;
|
||||||
|
readonly double posLoPct;
|
||||||
|
readonly double posHiPct;
|
||||||
|
readonly int timeout;
|
||||||
|
|
||||||
|
/// Process values
|
||||||
|
int expireTime;
|
||||||
|
bool positionReached;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow.
|
||||||
|
/// Events: FlowSet, FlowTimeOut
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uniCB">Control board device</param>
|
||||||
|
/// <param name="_regulValve">Regulation valve component</param>
|
||||||
|
/// <param name="posLoPct">Lower limit of the position to be achieved</param>
|
||||||
|
/// <param name="posHiPct">Upper limit of the position to be achieved</param>
|
||||||
|
/// <param name="timeout">Timeout in sec. for setting the flow</param>
|
||||||
|
/// <remarks>Only Elde.Valve flow are used, other flow on the lists are ignored</remarks>
|
||||||
|
public SetRegValvePositionOp(UniCB uniCB, RegValve regV, double posLoPct, double posHiPct, int timeout)
|
||||||
|
{
|
||||||
|
this.uniCB = uniCB;
|
||||||
|
if (this.uniCB == null) throw new ArgumentNullException("ctrlBoard");
|
||||||
|
|
||||||
|
this.regV = regV as RegValve;
|
||||||
|
if (this.regV == null) throw new ArgumentNullException("regValve is null or not Uni");
|
||||||
|
this.regValveNr = this.regV.Idx1;
|
||||||
|
|
||||||
|
this.posLoPct = posLoPct;
|
||||||
|
this.posHiPct = posHiPct;
|
||||||
|
this.timeout = timeout;
|
||||||
|
|
||||||
|
log.Debug(this.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set required water flow - no timeout.
|
||||||
|
/// Events: FlowSet
|
||||||
|
/// </summary>
|
||||||
|
public SetRegValvePositionOp(UniCB cBoard, RegValve regValve, float posLoPct, float posHiPct)
|
||||||
|
: this(cBoard, regValve, posLoPct, posHiPct, int.MaxValue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Start this operation</summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
positionReached = false;
|
||||||
|
expireTime = StateMachine.Time + timeout;
|
||||||
|
log.InfoFormat("Start(): {0} reqPosLo={1}%, reqPosHi={2}%", regV.Name, posLoPct.ToString("F1"), posHiPct.ToString("F1"));
|
||||||
|
opState = OpState.MoveToPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Run this operation
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Event.None . . . . . . . busy adjusting position
|
||||||
|
/// Event.PositionReached . . position reached
|
||||||
|
/// Event.OpArgumentError . . invalid required position
|
||||||
|
/// </returns>
|
||||||
|
public Event Run()
|
||||||
|
{
|
||||||
|
if (opState == OpState.MoveToPosition)
|
||||||
|
{
|
||||||
|
if (posLoPct >= posHiPct || posLoPct > 100.0 || posHiPct < 0)
|
||||||
|
{
|
||||||
|
return Event.OpArgumentError;
|
||||||
|
}
|
||||||
|
|
||||||
|
regV.MoveToPosition(false, posLoPct, posHiPct);
|
||||||
|
opState = OpState.CheckState;
|
||||||
|
log.WarnFormat("Run(): RV#={0}, state={1}, MoveToPosition(false, {2:D1}, {3:D1}) issued", regValveNr, opState, posLoPct, posHiPct);
|
||||||
|
return Event.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (positionReached) return Event.PositionReached;
|
||||||
|
|
||||||
|
double positionPct = regV.Position;
|
||||||
|
log.WarnFormat("Run(): RV#={0}, state={1}, pos={2}%", regValveNr, opState, positionPct.ToString("F1"));
|
||||||
|
|
||||||
|
if (opState == OpState.CheckState)
|
||||||
|
{
|
||||||
|
if (posLoPct <= positionPct && positionPct <= posHiPct)
|
||||||
|
{
|
||||||
|
positionReached = true;
|
||||||
|
return Event.PositionReached;
|
||||||
|
}
|
||||||
|
else if (regV.RegValveState != RegValveState.DacValueRegul)
|
||||||
|
{
|
||||||
|
opState = OpState.MoveToPosition; /// Resend move command again in the next run
|
||||||
|
return Event.None;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opState = OpState.MovingToPosition;
|
||||||
|
return Event.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (StateMachine.Time > expireTime)
|
||||||
|
{
|
||||||
|
return Event.RegulValveTimeOut;
|
||||||
|
}
|
||||||
|
else if (opState == OpState.MovingToPosition)
|
||||||
|
{
|
||||||
|
if (posLoPct <= positionPct && positionPct <= posHiPct)
|
||||||
|
{
|
||||||
|
positionReached = true;
|
||||||
|
return Event.PositionReached;
|
||||||
|
}
|
||||||
|
return Event.None;
|
||||||
|
}
|
||||||
|
return Event.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Stop this operation</summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace TBF.Tools
|
||||||
|
{
|
||||||
|
public class ByteFormatter : IFormatProvider, ICustomFormatter
|
||||||
|
{
|
||||||
|
public ByteFormatter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetFormat(Type formatType)
|
||||||
|
{
|
||||||
|
if (formatType == typeof(ICustomFormatter))
|
||||||
|
return this;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Format(string fmt, object arg, IFormatProvider formatProvider)
|
||||||
|
{
|
||||||
|
if (arg.GetType() != typeof(byte))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return HandleOtherFormats(fmt, arg);
|
||||||
|
}
|
||||||
|
catch (FormatException e)
|
||||||
|
{
|
||||||
|
throw new FormatException(String.Format("The format of '{0}' is invalid.", fmt), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Convert one byte to string
|
||||||
|
///
|
||||||
|
byte b = (byte)arg;
|
||||||
|
if ((32 <= b) && (b <= 127)) return "'" + ((char)b).ToString() + "'";
|
||||||
|
if ((char)b == '\r') return "'\\r'";
|
||||||
|
if ((char)b == '\n') return "'\\n'";
|
||||||
|
if ((char)b == '\t') return "'\\t'";
|
||||||
|
if (b == 17) return "XON";
|
||||||
|
if (b == 19) return "XOFF";
|
||||||
|
if (b == 26) return "Ctrl-Z";
|
||||||
|
return b.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string HandleOtherFormats(string format, object arg)
|
||||||
|
{
|
||||||
|
if (arg is IFormattable)
|
||||||
|
return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
|
||||||
|
else if (arg != null)
|
||||||
|
return arg.ToString();
|
||||||
|
else
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||||
|
///
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
|
||||||
|
namespace TBF.Tools
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The class use the WinApi GetPrivateProfileSectionNames,
|
||||||
|
/// GetPrivateProfileSection, GetPrivateProfileString, WritePrivateProfileString
|
||||||
|
/// and present easy methods to work from a NET point of view.
|
||||||
|
/// Usage:
|
||||||
|
/// IniUtil ini = new IniUtil(@"C:\program files (x86)\myapp\myapp.ini");
|
||||||
|
/// string country = ini.GetValue("Carrier","Country","NoCountry");
|
||||||
|
/// </summary>
|
||||||
|
public class IniUtil
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern int GetPrivateProfileSectionNames(byte[] lpszReturnBuffer, int nSize, string lpFileName);
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern int GetPrivateProfileSection(string lpAppName, byte[] lpReturnedString, int nSize, string lpFileName);
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern int GetPrivateProfileString(string lpApplicationName, string lpKeyName, string lpDefault, byte[] lpReturnedString, int nSize, string lpFileName);
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern bool WritePrivateProfileString(string lpApplicationName, string lpKeyName, string lpString, string lpFileName);
|
||||||
|
|
||||||
|
private const int VALUE_BUFFER = 511;
|
||||||
|
private const int SECTION_BUFFER = (1024 * 16);
|
||||||
|
private string m_sIniFile;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// .ctor with INI file name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">Fullpath to the INI file</param>
|
||||||
|
public IniUtil(string fileName)
|
||||||
|
{
|
||||||
|
m_sIniFile = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the value for a specific key in a section
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="section">Section containing the key to write to</param>
|
||||||
|
/// <param name="key">Key to insert/update</param>
|
||||||
|
/// <param name="keyvalue">Value for the key</param>
|
||||||
|
/// <returns>True if OK</returns>
|
||||||
|
public bool SetValue(string section, string key, string keyvalue)
|
||||||
|
{
|
||||||
|
return WritePrivateProfileString(section, key, keyvalue, m_sIniFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value of the specidied key in the specified section,
|
||||||
|
/// If the key doesn't exists returns the default value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="section">Section containing the key to read from</param>
|
||||||
|
/// <param name="key">Required key</param>
|
||||||
|
/// <param name="ifMissing">Value to return in case the key is missing</param>
|
||||||
|
/// <returns>string value of the key or missing value</returns>
|
||||||
|
public string GetValue(string section, string key, string ifMissing)
|
||||||
|
{
|
||||||
|
byte[] by = new byte[VALUE_BUFFER];
|
||||||
|
int n = GetPrivateProfileString(section, key, ifMissing, by, VALUE_BUFFER, m_sIniFile);
|
||||||
|
string s = Encoding.ASCII.GetString(by);
|
||||||
|
return s.Substring(0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the NameValueCollection for every key in the section
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="section">Section name</param>
|
||||||
|
/// <returns>NameValueCollection with nake=Key and value=value</returns>
|
||||||
|
public NameValueCollection GetSectionKeysvalues(string section)
|
||||||
|
{
|
||||||
|
NameValueCollection n = new NameValueCollection();
|
||||||
|
if(section.Length > 0)
|
||||||
|
{
|
||||||
|
byte[] by = new byte[SECTION_BUFFER];
|
||||||
|
int x = GetPrivateProfileSection(section, by, SECTION_BUFFER, m_sIniFile);
|
||||||
|
if(x > 0) x--;
|
||||||
|
string keysvalues = Encoding.ASCII.GetString(by, 0, x);
|
||||||
|
string[] temp = keysvalues.Split('\0');
|
||||||
|
foreach(string s in temp)
|
||||||
|
{
|
||||||
|
string[] t = s.Split('=');
|
||||||
|
n.Add(t[0], t[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the names of all sections in .INI
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>string array with all the key names</returns>
|
||||||
|
public string[] GetSectionNames()
|
||||||
|
{
|
||||||
|
byte[] by = new byte[SECTION_BUFFER];
|
||||||
|
int x = GetPrivateProfileSectionNames(by, SECTION_BUFFER, m_sIniFile);
|
||||||
|
if(x > 0) x--;
|
||||||
|
string keys = Encoding.ASCII.GetString(by, 0, x);
|
||||||
|
return keys.Split('\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using log4net.Appender;
|
||||||
|
using log4net.Core;
|
||||||
|
using log4net.Repository.Hierarchy;
|
||||||
|
using log4net;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace TBF.Tools
|
||||||
|
{
|
||||||
|
public class LogChecker : IDisposable
|
||||||
|
{
|
||||||
|
readonly Logger _logger;
|
||||||
|
readonly Level _previousLevel;
|
||||||
|
readonly MemoryAppender _appender = new MemoryAppender();
|
||||||
|
|
||||||
|
public LogChecker(string logName, Level levelToCheck)
|
||||||
|
{
|
||||||
|
_logger = (Logger)LogManager.GetLogger(logName).Logger;
|
||||||
|
_logger.AddAppender(_appender);
|
||||||
|
_previousLevel = _logger.Level;
|
||||||
|
_logger.Level = levelToCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Messages
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new List<log4net.Core.LoggingEvent>(_appender.GetEvents())
|
||||||
|
.ConvertAll(x => x.RenderedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_logger.Level = _previousLevel;
|
||||||
|
_logger.RemoveAppender(_appender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example of use
|
||||||
|
//
|
||||||
|
// using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
|
||||||
|
// {
|
||||||
|
// Execute query using NHibernate
|
||||||
|
// ....
|
||||||
|
//
|
||||||
|
// MessageBox.Show(String.Join(Environment.NewLine,logChecker.Messages));
|
||||||
|
// }
|
||||||
|
//
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
///
|
||||||
|
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||||
|
///
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace TBF.Tools
|
||||||
|
{
|
||||||
|
public static class XmlTools
|
||||||
|
{
|
||||||
|
public static string ToXmlString<T>(this T input)
|
||||||
|
{
|
||||||
|
using (var writer = new StringWriter())
|
||||||
|
{
|
||||||
|
input.ToXml(writer);
|
||||||
|
return writer.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ToXml<T>(this T objectToSerialize, Stream stream)
|
||||||
|
{
|
||||||
|
new XmlSerializer(typeof(T)).Serialize(stream, objectToSerialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ToXml<T>(this T objectToSerialize, StringWriter writer)
|
||||||
|
{
|
||||||
|
new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
///
|
///
|
||||||
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
|
||||||
///
|
///
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Web.UI;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using log4net;
|
using log4net;
|
||||||
using NHibernate;
|
using NHibernate;
|
||||||
@@ -13,27 +15,31 @@ using Config.Entities;
|
|||||||
using TBF.Rig;
|
using TBF.Rig;
|
||||||
using TBF.Rig.Generic;
|
using TBF.Rig.Generic;
|
||||||
using TBF.Resources;
|
using TBF.Resources;
|
||||||
|
using TBF.Rig.GenericDevices;
|
||||||
|
using TBF.Rig.WaterMeters.WaterMeter;
|
||||||
using TBF.UI.Shared;
|
using TBF.UI.Shared;
|
||||||
|
|
||||||
namespace TBF.UI.Bench.Components
|
namespace TBF.UI.Bench.Components
|
||||||
{
|
{
|
||||||
public partial class ComponentsManagerDlg : Form, IParentOfListViewEx
|
public partial class ComponentsManagerDlg : Form, IParentOfListViewEx
|
||||||
{
|
{
|
||||||
static readonly ILog log = LogManager.GetLogger(typeof(ComponentsManagerDlg));
|
static readonly ILog log = LogManager.GetLogger(typeof(ComponentsManagerDlg));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of components (=component configuration instances)
|
/// List of components (=component configuration instances)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IList<Component> cmpntEntities;
|
IList<Component> cmpntEntities;
|
||||||
|
|
||||||
IList<Component> toBeDeletedEntities;
|
IList<Component> toBeDeletedEntities;
|
||||||
|
|
||||||
ISession session;
|
ISession session;
|
||||||
|
|
||||||
SelectComponentClassDlg selectComponentTypeDlg; /// Constructed once, the selection is kept between dialog usages
|
SelectComponentClassDlg selectComponentTypeDlg;
|
||||||
|
|
||||||
CfgUpdateFlags flags; /// Or-ed from particular Flags from ComponentParametersDlg
|
/// Constructed once, the selection is kept between dialog usages
|
||||||
|
CfgUpdateFlags flags;
|
||||||
|
|
||||||
|
/// Or-ed from particular Flags from ComponentParametersDlg
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ListViewEx columns
|
/// ListViewEx columns
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -50,27 +56,29 @@ namespace TBF.UI.Bench.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
MySortOrder sortOrder = MySortOrder.Ascending;
|
MySortOrder sortOrder = MySortOrder.Ascending;
|
||||||
int sortColumn = -1; /// 0-based index of column to be used for sorting
|
int sortColumn = -1;
|
||||||
|
|
||||||
/// Editors used by listViewEx
|
/// 0-based index of column to be used for sorting
|
||||||
|
/// Editors used by listViewEx
|
||||||
ComboBox debugCB;
|
ComboBox debugCB;
|
||||||
|
|
||||||
ComboBox logCB;
|
ComboBox logCB;
|
||||||
|
|
||||||
bool unlocked;
|
bool unlocked;
|
||||||
|
|
||||||
public ComponentsManagerDlg()
|
public ComponentsManagerDlg()
|
||||||
{
|
{
|
||||||
toBeDeletedEntities = new List<Component>();
|
toBeDeletedEntities = new List<Component>();
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
flags = CfgUpdateFlags.None;
|
flags = CfgUpdateFlags.None;
|
||||||
|
|
||||||
selectComponentTypeDlg = new SelectComponentClassDlg();
|
selectComponentTypeDlg = new SelectComponentClassDlg();
|
||||||
|
|
||||||
/// SharedDlgButtons configuration
|
/// SharedDlgButtons configuration
|
||||||
sharedButtons.ParentForm = this;
|
sharedButtons.ParentForm = this;
|
||||||
sharedButtons.RequiredGroupMembership = new GID[] { GID.Metrologists };
|
sharedButtons.RequiredGroupMembership = new GID[] { GID.Metrologists };
|
||||||
|
|
||||||
sharedButtons.OptionalButtons = SharedButtons.Buttons.Add |
|
sharedButtons.OptionalButtons = SharedButtons.Buttons.Add |
|
||||||
SharedButtons.Buttons.Remove |
|
SharedButtons.Buttons.Remove |
|
||||||
@@ -81,34 +89,35 @@ namespace TBF.UI.Bench.Components
|
|||||||
SharedButtons.Buttons.Export |
|
SharedButtons.Buttons.Export |
|
||||||
SharedButtons.Buttons.Import;
|
SharedButtons.Buttons.Import;
|
||||||
sharedButtons.Unlocked += Unlocked;
|
sharedButtons.Unlocked += Unlocked;
|
||||||
sharedButtons.OKClicked += okButton_Click;
|
sharedButtons.OKClicked += okButton_Click;
|
||||||
sharedButtons.CancelClicked += cancelButton_Click;
|
sharedButtons.CancelClicked += cancelButton_Click;
|
||||||
sharedButtons.AddClicked += addButton_Click;
|
sharedButtons.AddClicked += addButton_Click;
|
||||||
sharedButtons.RemoveClicked += removeButton_Click;
|
sharedButtons.RemoveClicked += removeButton_Click;
|
||||||
sharedButtons.UpClicked += upButton_Click;
|
sharedButtons.UpClicked += upButton_Click;
|
||||||
sharedButtons.DownClicked += downButton_Click;
|
sharedButtons.DownClicked += downButton_Click;
|
||||||
sharedButtons.EditClicked += editButton_Click;
|
sharedButtons.EditClicked += editButton_Click;
|
||||||
sharedButtons.CopyClicked += copyButton_Click;
|
sharedButtons.CopyClicked += copyButton_Click;
|
||||||
sharedButtons.ExportClicked += exportButton_Click;
|
sharedButtons.ExportClicked += exportButton_Click;
|
||||||
sharedButtons.ImportClicked += importButton_Click;
|
sharedButtons.ImportClicked += importButton_Click;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComponentsManagerDlg_Load(object sender, EventArgs e)
|
private void ComponentsManagerDlg_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
LoadFormPosition();
|
LoadFormPosition();
|
||||||
|
|
||||||
Text = Strings.Test_Bench_Components_Configuration;
|
Text = Strings.Test_Bench_Components_Configuration;
|
||||||
LocalSettings ls = Program.LocalSettings;
|
LocalSettings ls = Program.LocalSettings;
|
||||||
listViewEx.Columns.Add(Strings.Nr, (ls.ComponentsColumnCount > 0) ? ls.ComponentsColumnWidths[0] : 40);
|
listViewEx.Columns.Add(Strings.Nr, (ls.ComponentsColumnCount > 0) ? ls.ComponentsColumnWidths[0] : 40);
|
||||||
listViewEx.Columns.Add(Strings.Name, (ls.ComponentsColumnCount > 1) ? ls.ComponentsColumnWidths[1] : 80);
|
listViewEx.Columns.Add(Strings.Name, (ls.ComponentsColumnCount > 1) ? ls.ComponentsColumnWidths[1] : 80);
|
||||||
listViewEx.Columns.Add(Strings.Type, (ls.ComponentsColumnCount > 2) ? ls.ComponentsColumnWidths[2] : 120);
|
listViewEx.Columns.Add(Strings.Type, (ls.ComponentsColumnCount > 2) ? ls.ComponentsColumnWidths[2] : 120);
|
||||||
listViewEx.Columns.Add(Strings.Parent, (ls.ComponentsColumnCount > 3) ? ls.ComponentsColumnWidths[3] : 55);
|
listViewEx.Columns.Add(Strings.Parent, (ls.ComponentsColumnCount > 3) ? ls.ComponentsColumnWidths[3] : 55);
|
||||||
listViewEx.Columns.Add(Strings.Mode, (ls.ComponentsColumnCount > 4) ? ls.ComponentsColumnWidths[4] : 55);
|
listViewEx.Columns.Add(Strings.Mode, (ls.ComponentsColumnCount > 4) ? ls.ComponentsColumnWidths[4] : 55);
|
||||||
listViewEx.Columns.Add(Strings.Logging, (ls.ComponentsColumnCount > 5) ? ls.ComponentsColumnWidths[5] : 55);
|
listViewEx.Columns.Add(Strings.Logging, (ls.ComponentsColumnCount > 5) ? ls.ComponentsColumnWidths[5] : 55);
|
||||||
listViewEx.Columns.Add(Strings.Parameters, (ls.ComponentsColumnCount > 6) ? ls.ComponentsColumnWidths[6] : 600);
|
listViewEx.Columns.Add(Strings.Parameters,
|
||||||
|
(ls.ComponentsColumnCount > 6) ? ls.ComponentsColumnWidths[6] : 600);
|
||||||
listViewEx.HeaderStyle = ColumnHeaderStyle.Clickable;
|
listViewEx.HeaderStyle = ColumnHeaderStyle.Clickable;
|
||||||
|
|
||||||
debugCB = new ComboBox();
|
debugCB = new ComboBox();
|
||||||
for (DebugMode level = 0; level < DebugMode.Count; level++) debugCB.Items.Add(level.ToDescription());
|
for (DebugMode level = 0; level < DebugMode.Count; level++) debugCB.Items.Add(level.ToDescription());
|
||||||
splitContainer.Panel1.Controls.Add(debugCB);
|
splitContainer.Panel1.Controls.Add(debugCB);
|
||||||
|
|
||||||
@@ -119,23 +128,23 @@ namespace TBF.UI.Bench.Components
|
|||||||
listViewEx.SubItemClicked += new SubItemEventHandler(listViewEx_SubItemClicked);
|
listViewEx.SubItemClicked += new SubItemEventHandler(listViewEx_SubItemClicked);
|
||||||
listViewEx.SubItemEndEditing += new SubItemEndEditingEventHandler(listViewEx_SubItemEndEditing);
|
listViewEx.SubItemEndEditing += new SubItemEndEditingEventHandler(listViewEx_SubItemEndEditing);
|
||||||
|
|
||||||
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
|
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
|
||||||
|
|
||||||
session = TBF.DB.CreateSession(DBKind.Config);
|
session = TBF.DB.CreateSession(DBKind.Config);
|
||||||
cmpntEntities = session.QueryOver<Component>()
|
cmpntEntities = session.QueryOver<Component>()
|
||||||
.OrderBy(x => x.ItemNr).Asc
|
.OrderBy(x => x.ItemNr).Asc
|
||||||
.List<Component>();
|
.List<Component>();
|
||||||
|
|
||||||
RedrawAll();
|
RedrawAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void listViewEx_SubItemClicked(object sender, SubItemEventArgs e)
|
void listViewEx_SubItemClicked(object sender, SubItemEventArgs e)
|
||||||
{
|
{
|
||||||
if (unlocked && e.SubItem == (int)Column.DebugMode)
|
if (unlocked && e.SubItem == (int)Column.DebugMode)
|
||||||
{
|
{
|
||||||
listViewEx.StartEditing(debugCB, e.Item, e.SubItem);
|
listViewEx.StartEditing(debugCB, e.Item, e.SubItem);
|
||||||
}
|
}
|
||||||
else if (unlocked && e.SubItem == (int)Column.Logging)
|
else if (unlocked && e.SubItem == (int)Column.Logging)
|
||||||
{
|
{
|
||||||
listViewEx.StartEditing(logCB, e.Item, e.SubItem);
|
listViewEx.StartEditing(logCB, e.Item, e.SubItem);
|
||||||
}
|
}
|
||||||
@@ -146,7 +155,7 @@ namespace TBF.UI.Bench.Components
|
|||||||
if (!unlocked || ((e.SubItem != (int)Column.DebugMode) && (e.SubItem != (int)Column.Logging))) return;
|
if (!unlocked || ((e.SubItem != (int)Column.DebugMode) && (e.SubItem != (int)Column.Logging))) return;
|
||||||
|
|
||||||
if (DialogResult.Yes == MessageBox.Show(Strings.Do_you_want_to_copy_this_value_to_all_cells_below_this_cell,
|
if (DialogResult.Yes == MessageBox.Show(Strings.Do_you_want_to_copy_this_value_to_all_cells_below_this_cell,
|
||||||
Strings.Confirmation, MessageBoxButtons.YesNo, MessageBoxIcon.Question))
|
Strings.Confirmation, MessageBoxButtons.YesNo, MessageBoxIcon.Question))
|
||||||
{
|
{
|
||||||
int columnNr = e.SubItem;
|
int columnNr = e.SubItem;
|
||||||
string value = null;
|
string value = null;
|
||||||
@@ -204,10 +213,11 @@ namespace TBF.UI.Bench.Components
|
|||||||
if (debugCB.Text.Equals(level.ToDescription()))
|
if (debugCB.Text.Equals(level.ToDescription()))
|
||||||
{
|
{
|
||||||
cmpnt.DebugMode = level;
|
cmpnt.DebugMode = level;
|
||||||
flags |= CfgUpdateFlags.RestartRqrd;
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.DisplayText = cmpnt.DebugMode.ToString();
|
e.DisplayText = cmpnt.DebugMode.ToString();
|
||||||
}
|
}
|
||||||
else if (e.SubItem == (int)Column.Logging)
|
else if (e.SubItem == (int)Column.Logging)
|
||||||
@@ -217,35 +227,36 @@ namespace TBF.UI.Bench.Components
|
|||||||
if (logCB.Text.Equals(level.ToDescription()))
|
if (logCB.Text.Equals(level.ToDescription()))
|
||||||
{
|
{
|
||||||
cmpnt.LogLevel = level;
|
cmpnt.LogLevel = level;
|
||||||
flags |= CfgUpdateFlags.RestartRqrd;
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.DisplayText = cmpnt.LogLevel.ToString();
|
e.DisplayText = cmpnt.LogLevel.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Unlocked(object sender, EventArgs e)
|
private void Unlocked(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
unlocked = true;
|
unlocked = true;
|
||||||
|
|
||||||
if (listViewEx.SelectedItems.Count == 1)
|
if (listViewEx.SelectedItems.Count == 1)
|
||||||
{
|
{
|
||||||
int ix = listViewEx.SelectedIndices[0];
|
int ix = listViewEx.SelectedIndices[0];
|
||||||
Focus();
|
Focus();
|
||||||
listViewEx.Items[ix].Selected = true;
|
listViewEx.Items[ix].Selected = true;
|
||||||
listViewEx.Items[ix].EnsureVisible();
|
listViewEx.Items[ix].EnsureVisible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedrawAll()
|
void RedrawAll()
|
||||||
{
|
{
|
||||||
listViewEx.Items.Clear();
|
listViewEx.Items.Clear();
|
||||||
foreach (var cmpnt in cmpntEntities) DrawOne(cmpnt);
|
foreach (var cmpnt in cmpntEntities) DrawOne(cmpnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawOne(Component cmpnt)
|
void DrawOne(Component cmpnt)
|
||||||
{
|
{
|
||||||
ListViewItem lvi = new ListViewItem(cmpnt.ItemNr.ToString());
|
ListViewItem lvi = new ListViewItem(cmpnt.ItemNr.ToString());
|
||||||
lvi.Tag = cmpnt;
|
lvi.Tag = cmpnt;
|
||||||
lvi.SubItems.Add(cmpnt.Name);
|
lvi.SubItems.Add(cmpnt.Name);
|
||||||
@@ -254,18 +265,17 @@ namespace TBF.UI.Bench.Components
|
|||||||
|
|
||||||
IComponentCfg cmpCfg = TbfComponents.CmpntCfgFromCmpntEntity(cmpnt);
|
IComponentCfg cmpCfg = TbfComponents.CmpntCfgFromCmpntEntity(cmpnt);
|
||||||
if (cmpCfg != null)
|
if (cmpCfg != null)
|
||||||
{
|
{
|
||||||
lvi.SubItems.Add(cmpCfg.DebugLevel.ToDescription());
|
lvi.SubItems.Add(cmpCfg.DebugLevel.ToDescription());
|
||||||
lvi.SubItems.Add(cmpCfg.LogLevel.ToDescription());
|
lvi.SubItems.Add(cmpCfg.LogLevel.ToDescription());
|
||||||
lvi.SubItems.Add(cmpCfg.ToString(-1));
|
lvi.SubItems.Add(cmpCfg.ToString(-1));
|
||||||
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
lvi.SubItems.Add("---");
|
||||||
lvi.SubItems.Add("---");
|
lvi.SubItems.Add("---");
|
||||||
lvi.SubItems.Add("---");
|
lvi.SubItems.Add("Not a component");
|
||||||
lvi.SubItems.Add("Not a component");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
listViewEx.Items.Add(lvi);
|
listViewEx.Items.Add(lvi);
|
||||||
}
|
}
|
||||||
@@ -304,10 +314,10 @@ namespace TBF.UI.Bench.Components
|
|||||||
private void LoadFormPosition()
|
private void LoadFormPosition()
|
||||||
{
|
{
|
||||||
LocalSettings ls = Program.LocalSettings;
|
LocalSettings ls = Program.LocalSettings;
|
||||||
Width = (ls.ComponentsDlgWidth > 0) ? ls.ComponentsDlgWidth : 850;
|
Width = (ls.ComponentsDlgWidth > 0) ? ls.ComponentsDlgWidth : 850;
|
||||||
Height = (ls.ComponentsDlgHeight > 0) ? ls.ComponentsDlgHeight : 500;
|
Height = (ls.ComponentsDlgHeight > 0) ? ls.ComponentsDlgHeight : 500;
|
||||||
Left = (ls.ComponentsDlgLeft != 0) ? ls.ComponentsDlgLeft : 200;
|
Left = (ls.ComponentsDlgLeft != 0) ? ls.ComponentsDlgLeft : 200;
|
||||||
Top = (ls.ComponentsDlgTop != 0) ? ls.ComponentsDlgTop : 100;
|
Top = (ls.ComponentsDlgTop != 0) ? ls.ComponentsDlgTop : 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -334,7 +344,11 @@ namespace TBF.UI.Bench.Components
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < (int)Column.ColumnsCount; i++)
|
for (int i = 0; i < (int)Column.ColumnsCount; i++)
|
||||||
{
|
{
|
||||||
if (listViewEx.Columns[i].Width != ls.ComponentsColumnWidths[i]) { anyColumnDiffers = true; break; }
|
if (listViewEx.Columns[i].Width != ls.ComponentsColumnWidths[i])
|
||||||
|
{
|
||||||
|
anyColumnDiffers = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,84 +380,149 @@ namespace TBF.UI.Bench.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// OK
|
/// OK
|
||||||
///
|
///
|
||||||
private void okButton_Click(object sender, EventArgs e)
|
private void okButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
|
ValidateComponents();
|
||||||
{
|
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
|
||||||
|
{
|
||||||
SaveDBChanges(session);
|
SaveDBChanges(session);
|
||||||
flags = CfgUpdateFlags.None; /// Changes saved
|
flags = CfgUpdateFlags.None; /// Changes saved
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveUISettings();
|
SaveUISettings();
|
||||||
|
|
||||||
DialogResult = DialogResult.OK;
|
DialogResult = DialogResult.OK;
|
||||||
Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel
|
private void ValidateComponents()
|
||||||
private void cancelButton_Click(object sender, EventArgs e)
|
{
|
||||||
{
|
Boolean invalid = false;
|
||||||
|
string validationMessage = "";
|
||||||
|
//validation cycle
|
||||||
|
invalid = !ValidateMetersBatchCount(out validationMessage);
|
||||||
|
|
||||||
|
if (invalid)
|
||||||
|
{
|
||||||
|
MessageBox.Show(validationMessage, Strings.Warning, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean ValidateMetersBatchCount(out string message)
|
||||||
|
{
|
||||||
|
bool invalid = false;
|
||||||
|
|
||||||
|
TBF.Rig.DataContainer.BenchInfo.ComponentCfg benchInfo = null;
|
||||||
|
int waterMetersCount = 0;
|
||||||
|
int iWaterMeterComponentCount = 0;
|
||||||
|
foreach (Component component in cmpntEntities)
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string className = (string.IsNullOrEmpty(component.ClassName) ? string.Empty : component.ClassName);
|
||||||
|
if (className == "DataContainer.BenchInfo")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cfg = new TBF.Rig.DataContainer.BenchInfo.Factory().CmpntCfgFromCmpntEntity(component)
|
||||||
|
as TBF.Rig.DataContainer.BenchInfo.ComponentCfg;
|
||||||
|
|
||||||
|
waterMetersCount = cfg.WaterMetersCount;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.Error("Finding of DataContainer.BenchInfo data unsuccessfully!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (className == "WaterMeter")
|
||||||
|
{
|
||||||
|
iWaterMeterComponentCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
invalid = (waterMetersCount != iWaterMeterComponentCount);
|
||||||
|
|
||||||
|
|
||||||
|
if (invalid)
|
||||||
|
{
|
||||||
|
message = "The count of water meters on the bench does not match the count of their components!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
message = "";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel
|
||||||
|
private void cancelButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
SaveUISettings();
|
SaveUISettings();
|
||||||
|
|
||||||
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
|
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
|
||||||
{
|
{
|
||||||
DialogResult dr = MessageBox.Show(Strings.Changes_will_be_lost_Do_you_want_to_proceed,
|
DialogResult dr = MessageBox.Show(Strings.Changes_will_be_lost_Do_you_want_to_proceed,
|
||||||
Strings.Warning,
|
Strings.Warning,
|
||||||
MessageBoxButtons.YesNo,
|
MessageBoxButtons.YesNo,
|
||||||
MessageBoxIcon.Question);
|
MessageBoxIcon.Question);
|
||||||
if (dr != DialogResult.Yes) return;
|
if (dr != DialogResult.Yes) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = CfgUpdateFlags.None; /// Abandoning changes confirmed
|
flags = CfgUpdateFlags.None; /// Abandoning changes confirmed
|
||||||
|
|
||||||
DialogResult = DialogResult.Cancel;
|
DialogResult = DialogResult.Cancel;
|
||||||
Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new component
|
/// Add a new component
|
||||||
private void addButton_Click(object sender, EventArgs e)
|
private void addButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
selectComponentTypeDlg.SelectedScriptName = null;
|
selectComponentTypeDlg.SelectedScriptName = null;
|
||||||
DialogResult dialogRslt = selectComponentTypeDlg.ShowDialog();
|
DialogResult dialogRslt = selectComponentTypeDlg.ShowDialog();
|
||||||
if (dialogRslt != DialogResult.OK) return;
|
if (dialogRslt != DialogResult.OK) return;
|
||||||
|
|
||||||
IComponentFactory factory = selectComponentTypeDlg.SlctdCmpntFactory;
|
IComponentFactory factory = selectComponentTypeDlg.SlctdCmpntFactory;
|
||||||
IComponentCfg cfg = factory.DefaultConfig();
|
IComponentCfg cfg = factory.DefaultConfig();
|
||||||
if (selectComponentTypeDlg.SelectedScriptName == null)
|
if (selectComponentTypeDlg.SelectedScriptName == null)
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
/// Create a single component of the selected type
|
/// Create a single component of the selected type
|
||||||
///
|
///
|
||||||
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
||||||
cfgControl.Config = cfg;
|
cfgControl.Config = cfg;
|
||||||
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
cfgControl.Config.ItemNr =
|
||||||
|
(cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
||||||
|
|
||||||
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
||||||
cfgForm.CmpntEntities = cmpntEntities;
|
cfgForm.CmpntEntities = cmpntEntities;
|
||||||
cfgForm.ComponentCfgCtrl = cfgControl;
|
cfgForm.ComponentCfgCtrl = cfgControl;
|
||||||
cfgForm.UnlockAfterStart = true;
|
cfgForm.UnlockAfterStart = true;
|
||||||
dialogRslt = cfgForm.ShowDialog();
|
dialogRslt = cfgForm.ShowDialog();
|
||||||
if (dialogRslt != DialogResult.OK) return;
|
if (dialogRslt != DialogResult.OK) return;
|
||||||
|
|
||||||
flags |= CfgUpdateFlags.RestartRqrd;
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
AddOne(cfgForm.Config.CreateDbEntity());
|
AddOne(cfgForm.Config.CreateDbEntity());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
/// Create more components, read their names and other properties from a file
|
/// Create more components, read their names and other properties from a file
|
||||||
///
|
///
|
||||||
using (TextReader reader = new StreamReader(selectComponentTypeDlg.SelectedScriptName))
|
using (TextReader reader = new StreamReader(selectComponentTypeDlg.SelectedScriptName))
|
||||||
{
|
{
|
||||||
int zeroBasedIdx = 0;
|
int zeroBasedIdx = 0;
|
||||||
string line = reader.ReadLine();
|
string line = reader.ReadLine();
|
||||||
while (line != null)
|
while (line != null)
|
||||||
{
|
{
|
||||||
line.Trim();
|
line.Trim();
|
||||||
if (line.Length > 0)
|
if (line.Length > 0)
|
||||||
{
|
{
|
||||||
string[] words = line.Split(new char[] { ' ', '\t' });
|
string[] words = line.Split(new char[] { ' ', '\t' });
|
||||||
@@ -451,83 +530,85 @@ namespace TBF.UI.Bench.Components
|
|||||||
if (UpdateCfg(ref cfg, words, ref zeroBasedIdx))
|
if (UpdateCfg(ref cfg, words, ref zeroBasedIdx))
|
||||||
{
|
{
|
||||||
flags |= CfgUpdateFlags.RestartRqrd;
|
flags |= CfgUpdateFlags.RestartRqrd;
|
||||||
cfg.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
cfg.ItemNr = (cmpntEntities.Count > 0)
|
||||||
|
? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1)
|
||||||
|
: 1;
|
||||||
AddOne(cfg.CreateDbEntity());
|
AddOne(cfg.CreateDbEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
zeroBasedIdx++;
|
zeroBasedIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = reader.ReadLine();
|
line = reader.ReadLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddOne(Component cmpnt)
|
void AddOne(Component cmpnt)
|
||||||
{
|
{
|
||||||
cmpntEntities.Add(cmpnt);
|
cmpntEntities.Add(cmpnt);
|
||||||
DrawOne(cmpnt);
|
DrawOne(cmpnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete the component
|
/// Delete the component
|
||||||
private void removeButton_Click(object sender, EventArgs e)
|
private void removeButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listViewEx.SelectedIndices.Count != 1) return;
|
if (listViewEx.SelectedIndices.Count != 1) return;
|
||||||
int ix = listViewEx.SelectedIndices[0];
|
int ix = listViewEx.SelectedIndices[0];
|
||||||
if (ix < 0) return;
|
if (ix < 0) return;
|
||||||
|
|
||||||
Component selectedCmpnt = (Component)listViewEx.Items[ix].Tag;
|
Component selectedCmpnt = (Component)listViewEx.Items[ix].Tag;
|
||||||
if (selectedCmpnt.Id != 0) toBeDeletedEntities.Add(selectedCmpnt);
|
if (selectedCmpnt.Id != 0) toBeDeletedEntities.Add(selectedCmpnt);
|
||||||
cmpntEntities.Remove(selectedCmpnt);
|
cmpntEntities.Remove(selectedCmpnt);
|
||||||
|
|
||||||
flags |= CfgUpdateFlags.AnyChange;
|
flags |= CfgUpdateFlags.AnyChange;
|
||||||
|
|
||||||
RedrawAll();
|
RedrawAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DoubleClick -> Edit the component
|
/// DoubleClick -> Edit the component
|
||||||
private void listViewEx_MouseDoubleClick(object sender, MouseEventArgs e)
|
private void listViewEx_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
editButton_Click(sender, e);
|
editButton_Click(sender, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Edit a component
|
/// Edit a component
|
||||||
private void editButton_Click(object sender, EventArgs e)
|
private void editButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listViewEx.SelectedIndices.Count != 1) return;
|
if (listViewEx.SelectedIndices.Count != 1) return;
|
||||||
ListViewItem lvi = listViewEx.SelectedItems[0];
|
ListViewItem lvi = listViewEx.SelectedItems[0];
|
||||||
Component component = lvi.Tag as Component;
|
Component component = lvi.Tag as Component;
|
||||||
if (component == null) return;
|
if (component == null) return;
|
||||||
|
|
||||||
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity(component);
|
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity(component);
|
||||||
if (cfg != null)
|
if (cfg != null)
|
||||||
{
|
{
|
||||||
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this, component.Id);
|
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this, component.Id);
|
||||||
cfgForm.CmpntEntities = cmpntEntities;
|
cfgForm.CmpntEntities = cmpntEntities;
|
||||||
cfgForm.ComponentCfgCtrl = cfg.GetControl(cmpntEntities);
|
cfgForm.ComponentCfgCtrl = cfg.GetControl(cmpntEntities);
|
||||||
cfgForm.ComponentCfgCtrl.Config = cfg;
|
cfgForm.ComponentCfgCtrl.Config = cfg;
|
||||||
DialogResult dr = cfgForm.ShowDialog();
|
DialogResult dr = cfgForm.ShowDialog();
|
||||||
if (dr != DialogResult.OK) return;
|
if (dr != DialogResult.OK) return;
|
||||||
|
|
||||||
flags |= cfgForm.Flags;
|
flags |= cfgForm.Flags;
|
||||||
|
|
||||||
sharedButtons.UnlockButtons(); /// Unlock this dialog buttons as changes were enabled
|
sharedButtons.UnlockButtons(); /// Unlock this dialog buttons as changes were enabled
|
||||||
unlocked = true; /// in the ComponentParametersDlg.
|
unlocked = true; /// in the ComponentParametersDlg.
|
||||||
|
|
||||||
Component modified = cfgForm.Config.CreateDbEntity();
|
Component modified = cfgForm.Config.CreateDbEntity();
|
||||||
Component original = (Component)lvi.Tag;
|
Component original = (Component)lvi.Tag;
|
||||||
|
|
||||||
original.Name = modified.Name;
|
original.Name = modified.Name;
|
||||||
original.ClassName = modified.ClassName;
|
original.ClassName = modified.ClassName;
|
||||||
original.Parent = modified.Parent;
|
original.Parent = modified.Parent;
|
||||||
original.DebugMode = modified.DebugMode;
|
original.DebugMode = modified.DebugMode;
|
||||||
original.LogLevel = modified.LogLevel;
|
original.LogLevel = modified.LogLevel;
|
||||||
original.Parameters = modified.Parameters;
|
original.Parameters = modified.Parameters;
|
||||||
|
|
||||||
RedrawAll();
|
RedrawAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy a component
|
/// Copy a component
|
||||||
private void copyButton_Click(object sender, EventArgs e)
|
private void copyButton_Click(object sender, EventArgs e)
|
||||||
@@ -535,7 +616,7 @@ namespace TBF.UI.Bench.Components
|
|||||||
if (listViewEx.SelectedIndices.Count != 1) return;
|
if (listViewEx.SelectedIndices.Count != 1) return;
|
||||||
ListViewItem lvi = listViewEx.SelectedItems[0];
|
ListViewItem lvi = listViewEx.SelectedItems[0];
|
||||||
|
|
||||||
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity((Component)lvi.Tag);
|
IComponentCfg cfg = TbfComponents.CmpntCfgFromCmpntEntity((Component)lvi.Tag);
|
||||||
if (cfg != null)
|
if (cfg != null)
|
||||||
{
|
{
|
||||||
cfg.Name += Strings.New_name_copy;
|
cfg.Name += Strings.New_name_copy;
|
||||||
@@ -543,7 +624,9 @@ namespace TBF.UI.Bench.Components
|
|||||||
{
|
{
|
||||||
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
||||||
cfgControl.Config = cfg;
|
cfgControl.Config = cfg;
|
||||||
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0)
|
||||||
|
? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1)
|
||||||
|
: 1;
|
||||||
|
|
||||||
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
||||||
cfgForm.CmpntEntities = cmpntEntities;
|
cfgForm.CmpntEntities = cmpntEntities;
|
||||||
@@ -588,7 +671,8 @@ namespace TBF.UI.Bench.Components
|
|||||||
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
IComponentCfgCtrl cfgControl = cfg.GetControl(cmpntEntities);
|
||||||
cfgControl.Config = cfg;
|
cfgControl.Config = cfg;
|
||||||
cfgControl.Config.Name = cfgControl.Config.Name + " imported";
|
cfgControl.Config.Name = cfgControl.Config.Name + " imported";
|
||||||
cfgControl.Config.ItemNr = (cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
cfgControl.Config.ItemNr =
|
||||||
|
(cmpntEntities.Count > 0) ? (cmpntEntities[cmpntEntities.Count - 1].ItemNr + 1) : 1;
|
||||||
|
|
||||||
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
ComponentParametersDlg cfgForm = new ComponentParametersDlg(this);
|
||||||
cfgForm.CmpntEntities = cmpntEntities;
|
cfgForm.CmpntEntities = cmpntEntities;
|
||||||
@@ -601,88 +685,90 @@ namespace TBF.UI.Bench.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void upButton_Click(object sender, EventArgs e)
|
private void upButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listViewEx.SelectedIndices.Count != 1) return;
|
if (listViewEx.SelectedIndices.Count != 1) return;
|
||||||
int ix = listViewEx.SelectedIndices[0];
|
int ix = listViewEx.SelectedIndices[0];
|
||||||
if (ix < 1) return;
|
if (ix < 1) return;
|
||||||
|
|
||||||
Component item1 = (Component)(listViewEx.Items[ix - 1].Tag);
|
Component item1 = (Component)(listViewEx.Items[ix - 1].Tag);
|
||||||
Component item2 = (Component)(listViewEx.Items[ix].Tag);
|
Component item2 = (Component)(listViewEx.Items[ix].Tag);
|
||||||
(item1 as IHasItemNr).ItemNr++;
|
(item1 as IHasItemNr).ItemNr++;
|
||||||
(item2 as IHasItemNr).ItemNr--;
|
(item2 as IHasItemNr).ItemNr--;
|
||||||
cmpntEntities.RemoveAt(ix);
|
cmpntEntities.RemoveAt(ix);
|
||||||
cmpntEntities.Insert(ix - 1, item2);
|
cmpntEntities.Insert(ix - 1, item2);
|
||||||
|
|
||||||
flags |= CfgUpdateFlags.AnyChange;
|
flags |= CfgUpdateFlags.AnyChange;
|
||||||
|
|
||||||
RedrawAll();
|
RedrawAll();
|
||||||
|
|
||||||
Focus();
|
Focus();
|
||||||
listViewEx.Items[ix - 1].Selected = true;
|
listViewEx.Items[ix - 1].Selected = true;
|
||||||
listViewEx.Items[ix - 1].EnsureVisible();
|
listViewEx.Items[ix - 1].EnsureVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downButton_Click(object sender, EventArgs e)
|
private void downButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listViewEx.SelectedIndices.Count != 1) return;
|
if (listViewEx.SelectedIndices.Count != 1) return;
|
||||||
int ix = listViewEx.SelectedIndices[0];
|
int ix = listViewEx.SelectedIndices[0];
|
||||||
if (ix >= listViewEx.Items.Count - 1) return;
|
if (ix >= listViewEx.Items.Count - 1) return;
|
||||||
|
|
||||||
Component item1 = (Component)(listViewEx.Items[ix].Tag);
|
Component item1 = (Component)(listViewEx.Items[ix].Tag);
|
||||||
Component item2 = (Component)(listViewEx.Items[ix + 1].Tag);
|
Component item2 = (Component)(listViewEx.Items[ix + 1].Tag);
|
||||||
(item1 as IHasItemNr).ItemNr++;
|
(item1 as IHasItemNr).ItemNr++;
|
||||||
(item2 as IHasItemNr).ItemNr--;
|
(item2 as IHasItemNr).ItemNr--;
|
||||||
cmpntEntities.RemoveAt(ix + 1);
|
cmpntEntities.RemoveAt(ix + 1);
|
||||||
cmpntEntities.Insert(ix, item2);
|
cmpntEntities.Insert(ix, item2);
|
||||||
|
|
||||||
flags |= CfgUpdateFlags.AnyChange;
|
flags |= CfgUpdateFlags.AnyChange;
|
||||||
|
|
||||||
RedrawAll();
|
RedrawAll();
|
||||||
|
|
||||||
Focus();
|
Focus();
|
||||||
listViewEx.Items[ix + 1].Selected = true;
|
listViewEx.Items[ix + 1].Selected = true;
|
||||||
listViewEx.Items[ix + 1].EnsureVisible();
|
listViewEx.Items[ix + 1].EnsureVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void componentsListView_SelectedIndexChanged(object sender, EventArgs e)
|
private void componentsListView_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listViewEx.SelectedIndices.Count == 1)
|
if (listViewEx.SelectedIndices.Count == 1)
|
||||||
{
|
{
|
||||||
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
|
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
|
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Edit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateButtonStates(SharedButtons.SelectedItemPos selectedItemPos)
|
public void UpdateButtonStates(SharedButtons.SelectedItemPos selectedItemPos)
|
||||||
{
|
{
|
||||||
if (selectedItemPos == SharedButtons.SelectedItemPos.None)
|
if (selectedItemPos == SharedButtons.SelectedItemPos.None)
|
||||||
{
|
{
|
||||||
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
|
sharedButtons.DisableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up |
|
||||||
}
|
SharedButtons.Buttons.Down);
|
||||||
else if (selectedItemPos == SharedButtons.SelectedItemPos.First)
|
}
|
||||||
{
|
else if (selectedItemPos == SharedButtons.SelectedItemPos.First)
|
||||||
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Down);
|
{
|
||||||
sharedButtons.DisableButtons(SharedButtons.Buttons.Up);
|
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Down);
|
||||||
}
|
sharedButtons.DisableButtons(SharedButtons.Buttons.Up);
|
||||||
else if (selectedItemPos == SharedButtons.SelectedItemPos.Last)
|
}
|
||||||
{
|
else if (selectedItemPos == SharedButtons.SelectedItemPos.Last)
|
||||||
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up);
|
{
|
||||||
sharedButtons.DisableButtons(SharedButtons.Buttons.Down);
|
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up);
|
||||||
}
|
sharedButtons.DisableButtons(SharedButtons.Buttons.Down);
|
||||||
else if (selectedItemPos == SharedButtons.SelectedItemPos.FirstAndLast)
|
}
|
||||||
{
|
else if (selectedItemPos == SharedButtons.SelectedItemPos.FirstAndLast)
|
||||||
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove);
|
{
|
||||||
sharedButtons.DisableButtons(SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
|
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove);
|
||||||
}
|
sharedButtons.DisableButtons(SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up | SharedButtons.Buttons.Down);
|
{
|
||||||
}
|
sharedButtons.EnableButtons(SharedButtons.Buttons.Remove | SharedButtons.Buttons.Up |
|
||||||
}
|
SharedButtons.Buttons.Down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ComponentsManagerDlg_FormClosing(object sender, FormClosingEventArgs e)
|
private void ComponentsManagerDlg_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -691,9 +777,9 @@ namespace TBF.UI.Bench.Components
|
|||||||
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
|
if ((flags & CfgUpdateFlags.AnyChange) != 0 || (flags & CfgUpdateFlags.RestartRqrd) != 0)
|
||||||
{
|
{
|
||||||
DialogResult dr = MessageBox.Show(Strings.Do_you_want_to_save_changes,
|
DialogResult dr = MessageBox.Show(Strings.Do_you_want_to_save_changes,
|
||||||
Strings.Warning,
|
Strings.Warning,
|
||||||
MessageBoxButtons.YesNo,
|
MessageBoxButtons.YesNo,
|
||||||
MessageBoxIcon.Question);
|
MessageBoxIcon.Question);
|
||||||
if (dr == DialogResult.Yes)
|
if (dr == DialogResult.Yes)
|
||||||
{
|
{
|
||||||
SaveDBChanges(session);
|
SaveDBChanges(session);
|
||||||
@@ -702,7 +788,7 @@ namespace TBF.UI.Bench.Components
|
|||||||
|
|
||||||
if (CurrentUser.Restore(this)) Program.MainWnd.UpdateUser();
|
if (CurrentUser.Restore(this)) Program.MainWnd.UpdateUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates component configuration from a script file
|
/// Updates component configuration from a script file
|
||||||
@@ -713,7 +799,7 @@ namespace TBF.UI.Bench.Components
|
|||||||
/// <returns>true = udated component configuration should be saved, new component should be created</returns>
|
/// <returns>true = udated component configuration should be saved, new component should be created</returns>
|
||||||
bool UpdateCfg(ref IComponentCfg cfg, string[] words, ref int zeroBasedIdx)
|
bool UpdateCfg(ref IComponentCfg cfg, string[] words, ref int zeroBasedIdx)
|
||||||
{
|
{
|
||||||
string name = words[words.Length - 1]; /// The last word is the component name
|
string name = words[words.Length - 1]; /// The last word is the component name
|
||||||
cfg.Name = name.Replace("#", (zeroBasedIdx + 1).ToString());
|
cfg.Name = name.Replace("#", (zeroBasedIdx + 1).ToString());
|
||||||
|
|
||||||
if (cfg is Rig.BuiltIn.Valve.ValveCfg)
|
if (cfg is Rig.BuiltIn.Valve.ValveCfg)
|
||||||
@@ -760,9 +846,9 @@ namespace TBF.UI.Bench.Components
|
|||||||
}
|
}
|
||||||
else if (cfg is Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg)
|
else if (cfg is Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg)
|
||||||
{
|
{
|
||||||
(cfg as IChildComponentCfg).ParentName = "CB";
|
(cfg as IChildComponentCfg).ParentName = "CB";
|
||||||
(cfg as Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg).ModbusAddress = (byte)(zeroBasedIdx + 1);
|
(cfg as Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg).ModbusAddress = (byte)(zeroBasedIdx + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (cfg is Rig.RegisterReaders.PulsesFromUniCB.RRCfg)
|
else if (cfg is Rig.RegisterReaders.PulsesFromUniCB.RRCfg)
|
||||||
{
|
{
|
||||||
@@ -818,4 +904,4 @@ namespace TBF.UI.Bench.Components
|
|||||||
listViewEx.Sort();
|
listViewEx.Sort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1181,6 +1181,10 @@ namespace TBF.UI.Process
|
|||||||
|
|
||||||
if (args.TestRslt != null)
|
if (args.TestRslt != null)
|
||||||
{
|
{
|
||||||
|
if (ProcessData.BatchRslts.Batch.WaterMeters.Count < wmsCount)
|
||||||
|
{
|
||||||
|
throw new Exception("Water Meter components cout is smaller as Bench Info water meter count!");
|
||||||
|
}
|
||||||
for (int i = 0; i < wmsCount; i++)
|
for (int i = 0; i < wmsCount; i++)
|
||||||
{
|
{
|
||||||
var wm = ProcessData.BatchRslts.Batch.WaterMeters[i];
|
var wm = ProcessData.BatchRslts.Batch.WaterMeters[i];
|
||||||
|
|||||||
@@ -0,0 +1,240 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace TBF.UI.Shared
|
||||||
|
{
|
||||||
|
public class SuggestComboBox : ComboBox
|
||||||
|
{
|
||||||
|
#region fields and properties
|
||||||
|
|
||||||
|
private readonly ListBox _suggLb = new ListBox { Visible = false, TabStop = false };
|
||||||
|
private readonly BindingList<string> _suggBindingList = new BindingList<string>();
|
||||||
|
private Expression<Func<ObjectCollection, IEnumerable<string>>> _propertySelector;
|
||||||
|
private Func<ObjectCollection, IEnumerable<string>> _propertySelectorCompiled;
|
||||||
|
private Expression<Func<string, string, bool>> _filterRule;
|
||||||
|
private Func<string, bool> _filterRuleCompiled;
|
||||||
|
private Expression<Func<string, string>> _suggestListOrderRule;
|
||||||
|
private Func<string, string> _suggestListOrderRuleCompiled;
|
||||||
|
|
||||||
|
public int SuggestBoxHeight
|
||||||
|
{
|
||||||
|
get { return _suggLb.Height; }
|
||||||
|
set { if (value > 0) _suggLb.Height = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the item-type of the ComboBox is not string,
|
||||||
|
/// you can set here which property should be used
|
||||||
|
/// </summary>
|
||||||
|
public Expression<Func<ObjectCollection, IEnumerable<string>>> PropertySelector
|
||||||
|
{
|
||||||
|
get { return _propertySelector; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null) return;
|
||||||
|
_propertySelector = value;
|
||||||
|
_propertySelectorCompiled = value.Compile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// Lambda-Expression to determine the suggested items
|
||||||
|
/// (as Expression here because simple lamda (func) is not serializable)
|
||||||
|
/// <para>default: case-insensitive contains search</para>
|
||||||
|
/// <para>1st string: list item</para>
|
||||||
|
/// <para>2nd string: typed text</para>
|
||||||
|
///</summary>
|
||||||
|
public Expression<Func<string, string, bool>> FilterRule
|
||||||
|
{
|
||||||
|
get { return _filterRule; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null) return;
|
||||||
|
_filterRule = value;
|
||||||
|
_filterRuleCompiled = item => value.Compile()(item, Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>
|
||||||
|
/// Lambda-Expression to order the suggested items
|
||||||
|
/// (as Expression here because simple lamda (func) is not serializable)
|
||||||
|
/// <para>default: alphabetic ordering</para>
|
||||||
|
///</summary>
|
||||||
|
public Expression<Func<string, string>> SuggestListOrderRule
|
||||||
|
{
|
||||||
|
get { return _suggestListOrderRule; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null) return;
|
||||||
|
_suggestListOrderRule = value;
|
||||||
|
_suggestListOrderRuleCompiled = value.Compile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ctor
|
||||||
|
/// </summary>
|
||||||
|
public SuggestComboBox()
|
||||||
|
{
|
||||||
|
// set the standard rules:
|
||||||
|
_filterRuleCompiled = s => s.ToLower().Contains(Text.Trim().ToLower());
|
||||||
|
_suggestListOrderRuleCompiled = s => s;
|
||||||
|
_propertySelectorCompiled = collection => collection.Cast<string>();
|
||||||
|
|
||||||
|
_suggLb.DataSource = _suggBindingList;
|
||||||
|
_suggLb.Click += SuggLbOnClick;
|
||||||
|
|
||||||
|
ParentChanged += OnParentChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// the magic happens here ;-)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
protected override void OnTextChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnTextChanged(e);
|
||||||
|
|
||||||
|
if (!Focused) return;
|
||||||
|
|
||||||
|
_suggBindingList.Clear();
|
||||||
|
_suggBindingList.RaiseListChangedEvents = false;
|
||||||
|
_propertySelectorCompiled(Items)
|
||||||
|
.Where(_filterRuleCompiled)
|
||||||
|
.OrderBy(_suggestListOrderRuleCompiled)
|
||||||
|
.ToList()
|
||||||
|
.ForEach(_suggBindingList.Add);
|
||||||
|
_suggBindingList.RaiseListChangedEvents = true;
|
||||||
|
_suggBindingList.ResetBindings();
|
||||||
|
|
||||||
|
_suggLb.Visible = _suggBindingList.Any();
|
||||||
|
|
||||||
|
if (_suggBindingList.Count == 1 &&
|
||||||
|
_suggBindingList.Single().Length == Text.Trim().Length)
|
||||||
|
{
|
||||||
|
Text = _suggBindingList.Single();
|
||||||
|
Select(0, Text.Length);
|
||||||
|
_suggLb.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region size and position of suggest box
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// suggest-ListBox is added to parent control
|
||||||
|
/// (in ctor parent isn't already assigned)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnParentChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Parent.Controls.Add(_suggLb);
|
||||||
|
Parent.Controls.SetChildIndex(_suggLb, 0);
|
||||||
|
_suggLb.Top = Top + Height - 3;
|
||||||
|
_suggLb.Left = Left + 3;
|
||||||
|
_suggLb.Width = Width - 20;
|
||||||
|
_suggLb.Font = new Font("Segoe UI", 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnLocationChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnLocationChanged(e);
|
||||||
|
_suggLb.Top = Top + Height + 0;
|
||||||
|
_suggLb.Left = Left + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSizeChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnSizeChanged(e);
|
||||||
|
_suggLb.Width = Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region visibility of suggest box
|
||||||
|
|
||||||
|
protected override void OnLostFocus(EventArgs e)
|
||||||
|
{
|
||||||
|
// _suggLb can only getting focused by clicking (because TabStop is off)
|
||||||
|
// --> click-eventhandler 'SuggLbOnClick' is called
|
||||||
|
if (!_suggLb.Focused)
|
||||||
|
HideSuggBox();
|
||||||
|
base.OnLostFocus(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SuggLbOnClick(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
|
Text = _suggLb.Text;
|
||||||
|
Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HideSuggBox()
|
||||||
|
{
|
||||||
|
_suggLb.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDropDown(EventArgs e)
|
||||||
|
{
|
||||||
|
HideSuggBox();
|
||||||
|
base.OnDropDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region keystroke events
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// if the suggest-ListBox is visible some keystrokes
|
||||||
|
/// should behave in a custom way
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_suggLb.Visible)
|
||||||
|
{
|
||||||
|
base.OnPreviewKeyDown(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (e.KeyCode)
|
||||||
|
{
|
||||||
|
case Keys.Down:
|
||||||
|
if (_suggLb.SelectedIndex < _suggBindingList.Count - 1)
|
||||||
|
_suggLb.SelectedIndex++;
|
||||||
|
return;
|
||||||
|
case Keys.Up:
|
||||||
|
if (_suggLb.SelectedIndex > 0)
|
||||||
|
_suggLb.SelectedIndex--;
|
||||||
|
return;
|
||||||
|
case Keys.Enter:
|
||||||
|
Text = _suggLb.Text;
|
||||||
|
Select(0, Text.Length);
|
||||||
|
_suggLb.Visible = false;
|
||||||
|
return;
|
||||||
|
case Keys.Escape:
|
||||||
|
HideSuggBox();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnPreviewKeyDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Keys[] KeysToHandle = new[] { Keys.Down, Keys.Up, Keys.Enter, Keys.Escape };
|
||||||
|
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||||
|
{
|
||||||
|
// the keysstrokes of our interest should not be processed be base class:
|
||||||
|
if (_suggLb.Visible && KeysToHandle.Contains(keyData))
|
||||||
|
return true;
|
||||||
|
return base.ProcessCmdKey(ref msg, keyData);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,12 +38,20 @@
|
|||||||
<conversionPattern value="%date %-5level %logger - %message%newline" />
|
<conversionPattern value="%date %-5level %logger - %message%newline" />
|
||||||
</layout>
|
</layout>
|
||||||
</appender>
|
</appender>
|
||||||
|
<appender name="LogCache" type="AppDiagnostic.LogCacheAppender">
|
||||||
|
<layout type="log4net.Layout.PatternLayout">
|
||||||
|
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
<!-- Set root logger -->
|
<!-- Set root logger -->
|
||||||
<root>
|
<root>
|
||||||
<level value="WARN" />
|
<level value="WARN" />
|
||||||
</root>
|
</root>
|
||||||
|
<root>
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="MemoryAppender" />
|
||||||
|
</root>
|
||||||
|
|
||||||
<!-- Set process loggers -->
|
<!-- Set process loggers -->
|
||||||
<logger name="AllResults"><level value="INFO" /><appender-ref ref="AllResults" /></logger>
|
<logger name="AllResults"><level value="INFO" /><appender-ref ref="AllResults" /></logger>
|
||||||
|
|||||||