Camera CJMS11 - support dialog multi pictures

This commit is contained in:
Michal Buzik 2026-07-16 12:19:27 +02:00
parent 69b607f963
commit f1bc71fb92
31 changed files with 11280 additions and 1034 deletions

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion("3.9.3069.8")] [assembly: AssemblyVersion("3.9.3134.0")]
[assembly: AssemblyFileVersion("3.9.3069.8")] [assembly: AssemblyFileVersion("3.9.3134.0")]

View File

@ -1427,6 +1427,15 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Delay between pictures.
/// </summary>
internal static string DelaySendImage {
get {
return ResourceManager.GetString("DelaySendImage", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Density. /// Looks up a localized string similar to Density.
/// </summary> /// </summary>
@ -2723,15 +2732,6 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to iPerl Communication in progress.
/// </summary>
internal static string iPerl_Communication_in_progress {
get {
return ResourceManager.GetString("iPerl_Communication_in_progress", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to ITS-27 calibration coefficients. /// Looks up a localized string similar to ITS-27 calibration coefficients.
/// </summary> /// </summary>
@ -3101,6 +3101,15 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Meter Communication in progress.
/// </summary>
internal static string Meter_Communication_in_progress {
get {
return ResourceManager.GetString("Meter_Communication_in_progress", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Sensors. /// Looks up a localized string similar to Sensors.
/// </summary> /// </summary>
@ -3839,6 +3848,15 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Pictures Count.
/// </summary>
internal static string PictureCouts {
get {
return ResourceManager.GetString("PictureCouts", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to PID. /// Looks up a localized string similar to PID.
/// </summary> /// </summary>
@ -4640,6 +4658,15 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Radio Communication failed.
/// </summary>
internal static string Radio_Communication_failed {
get {
return ResourceManager.GetString("Radio_Communication_failed", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Rate of change [%]. /// Looks up a localized string similar to Rate of change [%].
/// </summary> /// </summary>

View File

@ -1931,15 +1931,6 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to iPERL Komunikace probíhá.
/// </summary>
internal static string iPerl_Communication_in_progress {
get {
return ResourceManager.GetString("iPerl_Communication_in_progress", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Jazyk. /// Looks up a localized string similar to Jazyk.
/// </summary> /// </summary>
@ -2147,6 +2138,15 @@ namespace TBF.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Komunikace s vodemerem probíhá.
/// </summary>
internal static string Meter_Communication_in_progress {
get {
return ResourceManager.GetString("Meter_Communication_in_progress", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Testované typy měřičů. /// Looks up a localized string similar to Testované typy měřičů.
/// </summary> /// </summary>

View File

@ -1020,8 +1020,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve"> <data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Současně s předchozím krokem</value> <value>Současně s předchozím krokem</value>
</data> </data>
<data name="iPerl_Communication_in_progress" xml:space="preserve"> <data name="Meter_Communication_in_progress" xml:space="preserve">
<value>iPERL Komunikace probíhá</value> <value>Komunikace s vodemerem probíhá</value>
</data> </data>
<data name="Language" xml:space="preserve"> <data name="Language" xml:space="preserve">
<value>Jazyk</value> <value>Jazyk</value>

File diff suppressed because it is too large Load Diff

View File

@ -1023,8 +1023,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve"> <data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Prallel mit vorherigem Schritt</value> <value>Prallel mit vorherigem Schritt</value>
</data> </data>
<data name="iPerl_Communication_in_progress" xml:space="preserve"> <data name="Meter_Communication_in_progress" xml:space="preserve">
<value>iPerl Kommunikation läuft</value> <value>Meter Kommunikation läuft</value>
</data> </data>
<data name="Language" xml:space="preserve"> <data name="Language" xml:space="preserve">
<value>Sprache</value> <value>Sprache</value>

View File

@ -1017,8 +1017,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve"> <data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>simultaneo con il passo precedente</value> <value>simultaneo con il passo precedente</value>
</data> </data>
<data name="iPerl_Communication_in_progress" xml:space="preserve"> <data name="Meter_Communication_in_progress" xml:space="preserve">
<value>iPerl comunicazioni in corso</value> <value>Meter comunicazioni in corso</value>
</data> </data>
<data name="Language" xml:space="preserve"> <data name="Language" xml:space="preserve">
<value>lingua</value> <value>lingua</value>

View File

@ -1011,8 +1011,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve"> <data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Jednocześnie z poprzednim krokiem</value> <value>Jednocześnie z poprzednim krokiem</value>
</data> </data>
<data name="iPerl_Communication_in_progress" xml:space="preserve"> <data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Komunikacja z iPERL w toku</value> <value>Komunikacja z vodomera w toku</value>
</data> </data>
<data name="Language" xml:space="preserve"> <data name="Language" xml:space="preserve">
<value>Język</value> <value>Język</value>

View File

@ -543,6 +543,12 @@
<data name="PulsesPerLtr" xml:space="preserve"> <data name="PulsesPerLtr" xml:space="preserve">
<value>Pulses per liter</value> <value>Pulses per liter</value>
</data> </data>
<data name="DelaySendImage" xml:space="preserve">
<value>Delay between pictures</value>
</data>
<data name="PictureCouts" xml:space="preserve">
<value>Pictures Count</value>
</data>
<data name="Component" xml:space="preserve"> <data name="Component" xml:space="preserve">
<value>Component</value> <value>Component</value>
</data> </data>
@ -1042,8 +1048,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve"> <data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Simultaneous with previous step</value> <value>Simultaneous with previous step</value>
</data> </data>
<data name="iPerl_Communication_in_progress" xml:space="preserve"> <data name="Meter_Communication_in_progress" xml:space="preserve">
<value>iPerl Communication in progress</value> <value>Meter Communication in progress</value>
</data> </data>
<data name="Language" xml:space="preserve"> <data name="Language" xml:space="preserve">
<value>Language</value> <value>Language</value>
@ -1732,6 +1738,9 @@
<data name="RFID_communication_failed" xml:space="preserve"> <data name="RFID_communication_failed" xml:space="preserve">
<value>RFID communication failed</value> <value>RFID communication failed</value>
</data> </data>
<data name="Radio_Communication_failed" xml:space="preserve">
<value>Radio Communication failed</value>
</data>
<data name="Head_was_disabled_by_the_user" xml:space="preserve"> <data name="Head_was_disabled_by_the_user" xml:space="preserve">
<value>Disabled by user</value> <value>Disabled by user</value>
</data> </data>

View File

@ -1011,8 +1011,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve"> <data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Одновременно с предыдущим шагом</value> <value>Одновременно с предыдущим шагом</value>
</data> </data>
<data name="iPerl_Communication_in_progress" xml:space="preserve"> <data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Осуществляется связь с iPerl </value> <value>Осуществляется связь с водомером </value>
</data> </data>
<data name="Language" xml:space="preserve"> <data name="Language" xml:space="preserve">
<value>Язык</value> <value>Язык</value>

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using log4net; using log4net;
@ -70,6 +71,9 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
int lastWmNr1; int lastWmNr1;
Bitmap lastImage; /// non-zoomed image Bitmap lastImage; /// non-zoomed image
Bitmap zoomedImage; Bitmap zoomedImage;
private readonly List<string> currentImageGroup = new List<string>();//multiple pictures
private int currentImageGroupIndex;
private bool mouseOverPictureBox;
Thread imageProcessingThread; /// Thread to process images Thread imageProcessingThread; /// Thread to process images
public delegate void OcrTextObtainedDelegate(int ix, bool isEnd, string text); public delegate void OcrTextObtainedDelegate(int ix, bool isEnd, string text);
@ -96,6 +100,12 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
public TestStartEndForm() public TestStartEndForm()
{ {
InitializeComponent(); InitializeComponent();
KeyPreview = true;
pictureBox1.MouseWheel += pictureBox1_MouseWheel;
pictureBox1.MouseEnter += pictureBox1_MouseEnter;
pictureBox1.MouseLeave += pictureBox1_MouseLeave;
this.Icon = Properties.Resources.TBF_icon; this.Icon = Properties.Resources.TBF_icon;
@ -483,15 +493,46 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
startTextBoxes[i].TextChanged += new System.EventHandler(this.startTextBoxX_TextChanged); startTextBoxes[i].TextChanged += new System.EventHandler(this.startTextBoxX_TextChanged);
startTextBoxes[i].KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.startTextBoxX_KeyPress); startTextBoxes[i].KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.startTextBoxX_KeyPress);
startTextBoxes[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.startTextBoxX_MouseDown); startTextBoxes[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.startTextBoxX_MouseDown);
startTextBoxes[i].Enter += startTextBoxX_Enter;
} }
private void startTextBoxX_Enter(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null) { return; }
int physPos = PhysPos(textBox, startTextBoxes);
if (physPos >= 0)
{
LoadImage(sender, Tst.Start, physPos);
}
}
private void EndTextBox_EnableHanders(int i) private void EndTextBox_EnableHanders(int i)
{ {
endTextBoxes[i].AcceptsTabChanged += new System.EventHandler(this.endTextBoxX_AcceptsTabChanged); endTextBoxes[i].AcceptsTabChanged += new System.EventHandler(this.endTextBoxX_AcceptsTabChanged);
endTextBoxes[i].TextChanged += new System.EventHandler(this.endTextBoxX_TextChanged); endTextBoxes[i].TextChanged += new System.EventHandler(this.endTextBoxX_TextChanged);
endTextBoxes[i].KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.endTextBoxX_KeyPress); endTextBoxes[i].KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.endTextBoxX_KeyPress);
endTextBoxes[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.endTextBoxX_AcceptsTabChanged); endTextBoxes[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.endTextBoxX_AcceptsTabChanged);
endTextBoxes[i].Enter += endTextBoxX_Enter;
} }
private void endTextBoxX_Enter(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null) { return; }
int physPos = PhysPos(textBox, endTextBoxes);
if (physPos >= 0)
{
LoadImage(sender, Tst.End, physPos);
}
}
private void TestStartEndForm_FormClosed(object sender, FormClosedEventArgs e) private void TestStartEndForm_FormClosed(object sender, FormClosedEventArgs e)
{ {
@ -763,7 +804,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
TextBox clickedTextBox = sender as TextBox; TextBox clickedTextBox = sender as TextBox;
if (clickedTextBox != null) if (clickedTextBox != null)
{ {
var physPos = PhysPos(clickedTextBox, startTextBoxes); var physPos = PhysPos(clickedTextBox, endTextBoxes);//startTextBoxes);
if (physPos < 0) if (physPos < 0)
{ {
@ -1069,7 +1110,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
TextBox clickedTextBox = sender as TextBox; TextBox clickedTextBox = sender as TextBox;
if (clickedTextBox != null) if (clickedTextBox != null)
{ {
var physPos = PhysPos(clickedTextBox, startTextBoxes); var physPos = PhysPos(clickedTextBox, endTextBoxes);//startTextBoxes);
if (physPos < 0) if (physPos < 0)
{ {
@ -1134,65 +1175,479 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
/// </summary> /// </summary>
/// <param name="startOrEnd">Tst.Start or Tst.End</param> /// <param name="startOrEnd">Tst.Start or Tst.End</param>
/// <param name="physPos">0..23</param> /// <param name="physPos">0..23</param>
void LoadImage(object sender, Tst startOrEnd, int physPos) void LoadImage( object sender, Tst startOrEnd, int physPos)
{ {
int wmNr1b = phys2wm[physPos]; /// 0 means no WM if (physPos < 0 || physPos >= phys2wm.Length)
if (wmNr1b <= 0) return; {
return;
}
wmNr0b = wmNr1b - 1; int wmNr1b = phys2wm[physPos];
string imageFileName; // Hodnota 0 znamená, že na tejto fyzickej pozícii nie je vodomer.
if (startOrEnd == Tst.Start && startImages[wmNr0b] != null) if (wmNr1b <= 0)
imageFileName = startImages[wmNr0b]; {
else if (startOrEnd == Tst.End && endImages[wmNr0b] != null) return;
imageFileName = endImages[wmNr0b]; }
else
imageFileName = string.Empty;
if (imageFileName == lastImageName) wmNr0b = wmNr1b - 1;
{
return;
}
lastImageName = imageFileName; string imageFileName = GetBaseImageFileName(
lastWmNr1 = wmNr1b; startOrEnd,
wmNr0b);
if (string.IsNullOrEmpty(imageFileName) || !File.Exists(imageFileName)) lastWmNr1 = wmNr1b;
{
lastImage = null; if (string.IsNullOrWhiteSpace(imageFileName))
} {
else ClearImageGroup();
{ LoadImageFile(null);
using (Bitmap tempBmp = Image.FromFile(imageFileName) as Bitmap) return;
}
/*
* Ak používateľ zvolil iný vodomer alebo Start/End obrázok,
* vytvoríme novú skupinu:
*
* TestAdvance-1-start.bmp
* TestAdvance-1-start_img01_....bmp
* TestAdvance-1-start_img02_....bmp
*/
if (!string.Equals(
imageFileName,
lastImageName,
StringComparison.OrdinalIgnoreCase))
{
lastImageName = imageFileName;
LoadImageGroup(imageFileName);
// Pôvodný kompatibilný obrázok bude zobrazený ako prvý.
currentImageGroupIndex = 0;
}
else
{
/*
* Súbory mohli vzniknúť po prvom otvorení dialógu,
* preto skupinu pri opätovnom výbere obnovíme.
*/
RefreshCurrentImageGroup();
}
if (currentImageGroup.Count == 0)
{
LoadImageFile(null);
return;
}
currentImageGroupIndex = Math.Max(
0,
Math.Min(
currentImageGroupIndex,
currentImageGroup.Count - 1));
LoadImageFile(
currentImageGroup[currentImageGroupIndex]);
}
/// <summary>
/// base name of image file
/// </summary>
/// <param name="startOrEnd"></param>
/// <param name="waterMeterIndex"></param>
/// <returns></returns>
private string GetBaseImageFileName(
Tst startOrEnd,
int waterMeterIndex)
{
if (waterMeterIndex < 0 ||
waterMeterIndex >= WaterMetersCount)
{
return null;
}
if (startOrEnd == Tst.Start)
{
if (startImages == null ||
waterMeterIndex >= startImages.Length)
{ {
Rectangle rect; return null;
if (tempBmp.Height < tempBmp.Width) }
return startImages[waterMeterIndex];
}
if (startOrEnd == Tst.End)
{
if (endImages == null ||
waterMeterIndex >= endImages.Length)
{
return null;
}
return endImages[waterMeterIndex];
}
return null;
}
/// <summary>
/// load group of images
/// </summary>
/// <param name="baseImageFileName"></param>
private void LoadImageGroup(
string baseImageFileName)
{
currentImageGroup.Clear();
currentImageGroupIndex = 0;
if (string.IsNullOrWhiteSpace(baseImageFileName))
{
return;
}
string fullBaseFileName;
try
{
fullBaseFileName =
Path.GetFullPath(baseImageFileName);
}
catch (Exception exc)
{
log.Warn(
$"Cannot create image group from invalid path: " +
$"file='{baseImageFileName}', " +
$"error={exc.Message}");
return;
}
string directory =
Path.GetDirectoryName(fullBaseFileName);
string baseName =
Path.GetFileNameWithoutExtension(fullBaseFileName);
string extension =
Path.GetExtension(fullBaseFileName);
if (string.IsNullOrWhiteSpace(directory) ||
string.IsNullOrWhiteSpace(baseName))
{
return;
}
/*
* Pôvodný obrázok pridáme ako prvý.
*/
if (File.Exists(fullBaseFileName))
{
currentImageGroup.Add(fullBaseFileName);
}
if (!Directory.Exists(directory))
{
return;
}
string searchPattern =
$"{baseName}_img*{extension}";
try
{
List<string> timedImages =
Directory
.GetFiles(
directory,
searchPattern,
SearchOption.TopDirectoryOnly)
.OrderBy(GetTimedImageIndex)
.ThenBy(
fileName => fileName,
StringComparer.OrdinalIgnoreCase)
.ToList();
foreach (string timedImage in timedImages)
{
if (!currentImageGroup.Contains(
timedImage,
StringComparer.OrdinalIgnoreCase))
{ {
int hght = tempBmp.Height; currentImageGroup.Add(timedImage);
int leftMargin = (tempBmp.Width - hght) / 2;
rect = new Rectangle(leftMargin, 0, hght, hght);
}
else
{
int hght = tempBmp.Height;
int wdth = tempBmp.Width;
int margin = (hght - wdth) / 2;
rect = new Rectangle(0, margin, wdth, wdth);
}
//int hght = tempBmp.Height;
//int leftMargin = (tempBmp.Width - hght) / 2;
//lastImage = new Bitmap(tempBmp.Clone(new Rectangle(leftMargin, 0, hght, hght), tempBmp.PixelFormat));
lastImage = new Bitmap(tempBmp.Clone(rect, tempBmp.PixelFormat));
if (isZoomed[wmNr0b])
{
zoomedImage = MakeZoomedImage(lastImage, zoomCenterLoc[wmNr0b]);
} }
} }
}
ShowImage(); log.Debug(
} $"Image group loaded: " +
$"baseFile='{fullBaseFileName}', " +
$"searchPattern='{searchPattern}', " +
$"imagesCount={currentImageGroup.Count}");
}
catch (Exception exc)
{
log.Warn(
$"Cannot load image group: " +
$"baseFile='{fullBaseFileName}', " +
$"pattern='{searchPattern}', " +
$"error={exc.Message}");
}
}
/// <summary>
/// grouping by time
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private static int GetTimedImageIndex(
string fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return int.MaxValue;
}
string nameWithoutExtension =
Path.GetFileNameWithoutExtension(fileName);
Match match = Regex.Match(
nameWithoutExtension,
@"_img(?<index>\d+)_",
RegexOptions.IgnoreCase);
if (!match.Success)
{
return int.MaxValue;
}
int imageIndex;
return int.TryParse(
match.Groups["index"].Value,
out imageIndex)
? imageIndex
: int.MaxValue;
}
/// <summary>
/// refreshing current image group
/// </summary>
private void RefreshCurrentImageGroup()
{
if (string.IsNullOrWhiteSpace(lastImageName))
{
return;
}
string currentlySelectedFile =
currentImageGroupIndex >= 0 &&
currentImageGroupIndex < currentImageGroup.Count
? currentImageGroup[currentImageGroupIndex]
: null;
LoadImageGroup(lastImageName);
if (string.IsNullOrWhiteSpace(currentlySelectedFile))
{
return;
}
int restoredIndex =
currentImageGroup.FindIndex(
fileName =>
string.Equals(
fileName,
currentlySelectedFile,
StringComparison.OrdinalIgnoreCase));
if (restoredIndex >= 0)
{
currentImageGroupIndex = restoredIndex;
}
}
/// --- picture load ---
private void LoadImageFile(
string imageFileName)
{
DisposeLoadedImages();
if (string.IsNullOrWhiteSpace(imageFileName) ||
!File.Exists(imageFileName))
{
log.Debug(
$"Image cannot be displayed because the file does not exist: " +
$"file='{imageFileName}'");
ShowImage();
return;
}
try
{
using (var tempBmp =
new Bitmap(imageFileName))
{
Rectangle rect =
CreateSquareCropRectangle(tempBmp);
using (Bitmap croppedImage =
tempBmp.Clone(
rect,
tempBmp.PixelFormat))
{
lastImage =
new Bitmap(croppedImage);
}
}
if (isZoomed[wmNr0b])
{
zoomedImage =
MakeZoomedImage(
lastImage,
zoomCenterLoc[wmNr0b]);
}
log.Debug(
$"Image displayed from group: " +
$"waterMeter={lastWmNr1}, " +
$"groupIndex={currentImageGroupIndex + 1}/" +
$"{currentImageGroup.Count}, " +
$"file='{imageFileName}'");
}
catch (Exception exc)
{
log.Error(
$"Cannot load image: " +
$"file='{imageFileName}', " +
$"error={exc.Message}",
exc);
DisposeLoadedImages();
}
ShowImage();
}
/// --- block picture Crop help method ---
private static Rectangle CreateSquareCropRectangle( Bitmap bitmap)
{
int size = Math.Min( bitmap.Width, bitmap.Height);
int x = (bitmap.Width - size) / 2;
int y = (bitmap.Height - size) / 2;
return new Rectangle( x, y, size, size);
}
// --- block release old pictures ---
private void DisposeLoadedImages()
{
if (lastImage != null)
{
lastImage.Dispose();
lastImage = null;
}
if (zoomedImage != null)
{
zoomedImage.Dispose();
zoomedImage = null;
}
}
private void ClearImageGroup()
{
currentImageGroup.Clear();
currentImageGroupIndex = 0;
lastImageName = null;
}
// --- block picture exchange ---
private void ShowPreviousImageFromGroup()
{
ShowImageFromGroup(-1);
}
private void ShowNextImageFromGroup()
{
ShowImageFromGroup(1);
}
private void ShowImageFromGroup(
int direction)
{
if (direction == 0 ||
currentImageGroup.Count <= 1)
{
return;
}
int newIndex =
currentImageGroupIndex + direction;
/*
* Cyklické prepínanie:
*
* posledný -> prvý
* prvý -> posledný
*/
if (newIndex < 0)
{
newIndex =
currentImageGroup.Count - 1;
}
else if (newIndex >= currentImageGroup.Count)
{
newIndex = 0;
}
currentImageGroupIndex = newIndex;
LoadImageFile(
currentImageGroup[currentImageGroupIndex]);
}
// --- mouse events ---
private void pictureBox1_MouseEnter(
object sender,
EventArgs e)
{
mouseOverPictureBox = true;
/*
* PictureBox štandardne nemusí mať focus.
* Focus pomôže zachytiť klávesy aj koliesko.
*/
pictureBox1.Focus();
}
private void pictureBox1_MouseLeave(
object sender,
EventArgs e)
{
mouseOverPictureBox = false;
}
private void pictureBox1_MouseWheel(
object sender,
MouseEventArgs e)
{
if (!mouseOverPictureBox ||
currentImageGroup.Count <= 1)
{
return;
}
if (e.Delta > 0)
{
ShowPreviousImageFromGroup();
}
else if (e.Delta < 0)
{
ShowNextImageFromGroup();
}
}
/// <summary> /// <summary>
/// Left click = Zoom, Right click = Unzoom /// Left click = Zoom, Right click = Unzoom
@ -1276,7 +1731,9 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
{ {
if (lastImage == null) if (lastImage == null)
{ {
Image previousImage = pictureBox1.Image;
pictureBox1.Image = new Bitmap(TBF.Properties.Resources.Empty); pictureBox1.Image = new Bitmap(TBF.Properties.Resources.Empty);
previousImage?.Dispose();
return; return;
} }
@ -1312,10 +1769,108 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
Brush brush = (brightness > 160) ? darkBrush : lightBrush; Brush brush = (brightness > 160) ? darkBrush : lightBrush;
grph.DrawString(lastWmNr1.ToString(), font, brush, margin, margin); grph.DrawString(lastWmNr1.ToString(), font, brush, margin, margin);
DrawImageInfo(grph, tempBmp);
} }
Image oldPictureBoxImage = pictureBox1.Image;
pictureBox1.Image = tempBmp; pictureBox1.Image = tempBmp;
oldPictureBoxImage?.Dispose();
} }
private void DrawImageInfo( Graphics graphics, Bitmap bitmap)
{
if (graphics == null)
{
throw new ArgumentNullException(nameof(graphics));
}
if (bitmap == null)
{
throw new ArgumentNullException(nameof(bitmap));
}
string currentImageFileName = GetCurrentImageFileName();
if (string.IsNullOrWhiteSpace(currentImageFileName))
{
return;
}
string fileName = Path.GetFileName(currentImageFileName);
string displayText = fileName;
Match match = Regex.Match( fileName, @"_img(?<index>\d+)_(?<date>\d{8})_(?<time>\d{6})_(?<ms>\d{3})", RegexOptions.IgnoreCase);
if (match.Success)
{
string imageIndex = match.Groups["index"].Value;
string date = match.Groups["date"].Value;
string time = match.Groups["time"].Value;
string milliseconds = match.Groups["ms"].Value;
string formattedDate =
$"{date.Substring(6, 2)}." +
$"{date.Substring(4, 2)}." +
$"{date.Substring(0, 4)}";
string formattedTime =
$"{time.Substring(0, 2)}:" +
$"{time.Substring(2, 2)}:" +
$"{time.Substring(4, 2)}." +
milliseconds;
string baseFileName =
Regex.Replace(
fileName,
@"_img\d+_\d{8}_\d{6}_\d{3}",
string.Empty,
RegexOptions.IgnoreCase);
displayText =
$"{baseFileName} [img{imageIndex}]" +
Environment.NewLine +
$"{formattedDate} {formattedTime}";
}
using (Font font = new Font( "Arial", isZoomed[wmNr0b] ? 8 : 10, FontStyle.Bold))
{
SizeF textSize =
graphics.MeasureString(
displayText,
font);
float margin = 5;
float x = bitmap.Width - textSize.Width - margin;
float y = bitmap.Height - textSize.Height - margin;
graphics.DrawString( displayText, font, Brushes.Black, x + 1, y + 1);
graphics.DrawString( displayText, font, Brushes.White, x, y);
}
}
private string GetCurrentImageFileName()
{
if (currentImageGroup == null ||
currentImageGroup.Count == 0)
{
return lastImageName;
}
if (currentImageGroupIndex < 0 ||
currentImageGroupIndex >= currentImageGroup.Count)
{
return lastImageName;
}
return currentImageGroup[currentImageGroupIndex];
}
private void checkBoxEnableStartBox_CheckStateChanged(object sender, EventArgs e) private void checkBoxEnableStartBox_CheckStateChanged(object sender, EventArgs e)
@ -1345,5 +1900,35 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
} }
} }
} }
//Page Down/Up evenst
protected override bool ProcessCmdKey(
ref Message msg,
Keys keyData)
{
if (mouseOverPictureBox &&
currentImageGroup.Count > 1)
{
if (keyData == Keys.PageUp)
{
ShowPreviousImageFromGroup();
return true;
}
if (keyData == Keys.PageDown)
{
ShowNextImageFromGroup();
return true;
}
}
return base.ProcessCmdKey(
ref msg,
keyData);
}
} }
} }

View File

@ -4,7 +4,7 @@
/// * mark test method from smart family devices /// * mark test method from smart family devices
/// * (this Test method is used for devices that support smart reader) /// * (this Test method is used for devices that support smart reader)
/// </summary> /// </summary>
public interface ITestMethodSmart public interface ITestMethodSmart : ITestMethod
{ {
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TBF.Rig.Network.Camera.CJMS11
{
internal sealed class CameraLineReader
{
private readonly Stream stream;
private readonly byte[] receiveBuffer;
private int bufferStart;
private int bufferEnd;
public CameraLineReader(
Stream stream,
int bufferSize = 64 * 1024)
{
if (stream == null)
throw new ArgumentNullException(nameof(stream));
if (!stream.CanRead)
throw new ArgumentException(
"Stream must be readable.",
nameof(stream));
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException(
nameof(bufferSize));
this.stream = stream;
receiveBuffer = new byte[bufferSize];
}
public async Task<string> ReadLineAsync(
int timeoutMs,
CancellationToken cancellationToken)
{
if (timeoutMs <= 0)
throw new ArgumentOutOfRangeException(
nameof(timeoutMs));
using (var lineBuffer = new MemoryStream())
{
while (true)
{
int newLineIndex = FindNewLine();
if (newLineIndex >= 0)
{
int count = newLineIndex - bufferStart;
if (count > 0)
{
lineBuffer.Write(
receiveBuffer,
bufferStart,
count);
}
bufferStart = newLineIndex + 1;
return ConvertLineToString(lineBuffer);
}
if (bufferStart < bufferEnd)
{
lineBuffer.Write(
receiveBuffer,
bufferStart,
bufferEnd - bufferStart);
}
bufferStart = 0;
bufferEnd = 0;
int read = await ReadChunkAsync(
timeoutMs,
cancellationToken)
.ConfigureAwait(false);
if (read == 0)
{
throw new IOException(
"Camera connection was closed.");
}
bufferStart = 0;
bufferEnd = read;
}
}
}
private int FindNewLine()
{
for (int i = bufferStart; i < bufferEnd; i++)
{
if (receiveBuffer[i] == (byte)'\n')
return i;
}
return -1;
}
private async Task<int> ReadChunkAsync(
int timeoutMs,
CancellationToken cancellationToken)
{
using (var timeoutCts =
CancellationTokenSource.CreateLinkedTokenSource(
cancellationToken))
{
timeoutCts.CancelAfter(timeoutMs);
try
{
return await stream.ReadAsync(
receiveBuffer,
0,
receiveBuffer.Length,
timeoutCts.Token)
.ConfigureAwait(false);
}
catch (OperationCanceledException)
when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException(
$"Camera read timeout after {timeoutMs} ms.");
}
}
}
private static string ConvertLineToString(
MemoryStream lineBuffer)
{
int length = checked((int)lineBuffer.Length);
if (length == 0)
return string.Empty;
byte[] data = lineBuffer.GetBuffer();
if (data[length - 1] == (byte)'\r')
length--;
return Encoding.ASCII.GetString(
data,
0,
length);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
using System;
using TBF.Rig.Network.Camera.CJMS11.POJO; using TBF.Rig.Network.Camera.CJMS11.POJO;
namespace TBF.Rig.Network.Camera.CJMS11 namespace TBF.Rig.Network.Camera.CJMS11
@ -11,6 +12,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
private string orig_status; private string orig_status;
private string orig_command; private string orig_command;
private string orig_payload; private string orig_payload;
private DateTime timeStamp;
public POJO.MessageStatus Status public POJO.MessageStatus Status
{ {
@ -35,6 +37,12 @@ namespace TBF.Rig.Network.Camera.CJMS11
public string OrigCommand => orig_command; public string OrigCommand => orig_command;
public string OrigPayload => orig_payload; public string OrigPayload => orig_payload;
public DateTime TimeStamp
{
get => timeStamp;
set => timeStamp = value;
}
public JmsMessage(string status, string command, string payload) public JmsMessage(string status, string command, string payload)
{ {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using log4net; using log4net;
using Newtonsoft.Json;
using TBF.Rig.Network.Camera.CJMS11.POJO; using TBF.Rig.Network.Camera.CJMS11.POJO;
namespace TBF.Rig.Network.Camera.CJMS11 namespace TBF.Rig.Network.Camera.CJMS11
@ -44,6 +45,16 @@ namespace TBF.Rig.Network.Camera.CJMS11
if (message.Length < 1) return false; if (message.Length < 1) return false;
this.jmsMessage = JmsMessageFromString(message); this.jmsMessage = JmsMessageFromString(message);
try
{
CameraResponse response =
JsonConvert.DeserializeObject<CameraResponse>(jmsMessage.Payload);
jmsMessage.TimeStamp = response.timeStamp;
}catch(Exception e)
{
log.Debug("Error parsing message timestamp: " + e.Message);
}
return true; return true;
} }
@ -70,23 +81,39 @@ namespace TBF.Rig.Network.Camera.CJMS11
return null; return null;
} }
public static ParsedImage ImageParser(string payloadImage) public static ParsedImage ImageParser(
string payloadImage)
{ {
// Equivalent regex pattern const string prefix = "IMAGE:";
var imagePattern = new Regex(@"IMAGE:([A-Z0-9_]+):\s*(.*?)\s*~IMAGE_END", RegexOptions.Singleline); const string endMarker = "~IMAGE_END";
var match = imagePattern.Match(payloadImage); int prefixIndex = payloadImage.IndexOf( prefix, StringComparison.Ordinal);
if (match.Success)
{ if (prefixIndex < 0)
string encoding = match.Groups[1].Value; throw new ArgumentException( "IMAGE prefix was not found.");
string imageData = match.Groups[2].Value;
return new ParsedImage(ImageTypeEnum.GetCommandM(encoding), imageData); int encodingStart =
} prefixIndex + prefix.Length;
else
{ int encodingEnd =
throw new ArgumentException($"Payload does not match expected image format: {payloadImage}"); payloadImage.IndexOf(
} ':',
encodingStart);
if (encodingEnd < 0)
throw new ArgumentException(
"Image encoding separator was not found.");
int dataStart = encodingEnd + 1;
int dataEnd = payloadImage.IndexOf( endMarker, dataStart, StringComparison.Ordinal);
if (dataEnd < 0)
throw new ArgumentException( "IMAGE_END marker was not found.");
string encoding = payloadImage .Substring( encodingStart, encodingEnd - encodingStart) .Trim();
string imageData = payloadImage.Substring( dataStart,dataEnd - dataStart).Trim();
return new ParsedImage( ImageTypeEnum.GetCommandM(encoding), imageData);
} }
public override string ToString() public override string ToString()

View File

@ -0,0 +1,12 @@
using System;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class CameraResponse
{
public string message { get; set; }
public DateTime timeStamp { get; set; }
}
}

View File

@ -0,0 +1,37 @@
using Newtonsoft.Json;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class SendImagePayload
{
[JsonProperty("frameGap")]
public int FrameGap { get; set; }
[JsonProperty("frameTime")]
public string FrameTime { get; set; }
[JsonProperty("frameTimeMillis")]
public long FrameTimeMillis { get; set; }
[JsonProperty("pictureBase64")]
public string PictureBase64 { get; set; }
[JsonProperty("picturesComplete")]
public int PicturesComplete { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("taskId")]
public string TaskId { get; set; }
[JsonProperty("taskPath")]
public string TaskPath { get; set; }
[JsonProperty("taskTime")]
public string TaskTime { get; set; }
[JsonProperty("workerId")]
public int WorkerId { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using Newtonsoft.Json;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class SendImagesRequest
{
[JsonProperty("count")]
public int Count { get; set; }
[JsonProperty("delay")]
public int Delay { get; set; }
[JsonProperty("taskId")]
public string TaskId { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using Newtonsoft.Json;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class SendSummaryPayload
{
[JsonProperty("delay")]
public int Delay { get; set; }
[JsonProperty("pic_count")]
public int PictureCount { get; set; }
[JsonProperty("timeStamp")]
public string TimeStamp { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Drawing;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class TimedCameraImage
{
public int Index { get; set; }
public string TaskId { get; set; }
public DateTimeOffset? FrameTime { get; set; }
public long FrameTimeMillis { get; set; }
public int FrameGap { get; set; }
public Image Image { get; set; }
}
}

View File

@ -20,17 +20,36 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0]; public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; } public override XmlSerializer GetSerializer() { return Serializer; }
public double PulsesPerLtr; /// [l^-1] ///PulsePerMeter [l^-1]
public double PulsesPerLtr;
public override void InitializeAll() /// <summary>
{ /// delta time gap for send parameter
PulsesPerLtr = 1.0; /// </summary>
} /// <description>delta time for send parameter 500ms is minimum</description>
public int RoiDeltaTimeMs;
/// <summary>
/// count of picture for send > 1 / grabImage == 0|1 parameter - switch method
/// </summary>
/// <description>count of picture for send > 1 / grabImage == 0|1 parameter - switch method</description>
public int RoiPicCount;
string[] paramNames = new string[] string[] paramNames = new string[]
{ {
Strings.PulsesPerLtr, Strings.PulsesPerLtr,
Strings.PictureCouts,
Strings.DelaySendImage,
}; };
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
RoiPicCount = 1; //default value 1 => grab Image
RoiDeltaTimeMs = 500; //delta time for send parameter 500ms is minimum
}
public override string ParamName(int i) { return paramNames[i]; } public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; } public override int ParamsCount() { return paramNames.Length; }
@ -39,6 +58,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
switch (i) switch (i)
{ {
case 0: return PulsesPerLtr.ToString(); case 0: return PulsesPerLtr.ToString();
case 1: return RoiPicCount.ToString();
case 2: return RoiDeltaTimeMs.ToString();
default: return string.Empty; default: return string.Empty;
} }
} }
@ -49,6 +70,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
switch (i) switch (i)
{ {
case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None; case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 1: RoiPicCount = Int32.Parse(strValue); return CfgUpdateFlags.None;
case 2: RoiDeltaTimeMs = Int32.Parse(strValue); return CfgUpdateFlags.None;
default: return CfgUpdateFlags.None; default: return CfgUpdateFlags.None;
} }
} }
@ -59,11 +82,26 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
message = string.Empty; message = string.Empty;
double dummy; double dummy;
int dummyInt;
switch (i) switch (i)
{ {
case 0: case 0:
if (Utils.TryParseUDouble(strValue, out dummy)) return true; if (Utils.TryParseUDouble(strValue, out dummy)) return true;
break; break;
case 1:
if (!Int32.TryParse(strValue, out dummyInt) || (dummyInt < 0 || dummyInt > 50))
{
message = ParamName(i) + " is invalid. Param must be between 0 and 50!";
return false;
}
return true;
case 2:
if (!Int32.TryParse(strValue, out dummyInt) || (dummyInt < 500 || dummyInt < 5500))
{
message = ParamName(i) + " is invalid. Param must be between 500 and 5500!";
return false;
}
return true;
default: default:
message = "Invalid index"; message = "Invalid index";
return false; return false;
@ -76,6 +114,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
void CopyContentTo(ProcedureParams prms) void CopyContentTo(ProcedureParams prms)
{ {
prms.PulsesPerLtr = this.PulsesPerLtr; prms.PulsesPerLtr = this.PulsesPerLtr;
prms.RoiDeltaTimeMs = this.RoiDeltaTimeMs;
prms.RoiPicCount = this.RoiPicCount;
} }
public IParamsProvider Clone() public IParamsProvider Clone()

View File

@ -3,6 +3,7 @@
/// ///
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
using log4net; using log4net;
using Common; using Common;
@ -41,6 +42,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
get { return roiCfg.ProcParams.PulsesPerLtr; } get { return roiCfg.ProcParams.PulsesPerLtr; }
set { roiCfg.ProcParams.PulsesPerLtr = value; } set { roiCfg.ProcParams.PulsesPerLtr = value; }
} }
public int RoiDeltaTimeMs { get { return roiCfg.ProcParams.RoiDeltaTimeMs; } }
public int RoiPicCount { get { return roiCfg.ProcParams.RoiPicCount; } }
public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); } } public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); } }
public string QuantityUnits { get; set; } public string QuantityUnits { get; set; }
@ -123,26 +126,65 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
return GrabImageOp(imageFileName, roiCfg.BlackAndWhite, roiCfg.LowResolution, roiCfg.ImageRotation); return GrabImageOp(imageFileName, roiCfg.BlackAndWhite, roiCfg.LowResolution, roiCfg.ImageRotation);
} }
public IOperation GrabImageOp(string imageFileName, // Roi.cs
bool blackAndWhite, bool lowResolution, ImageRotation imageRotation) public IOperation GrabImageOp(
string imageFileName,
bool blackAndWhite,
bool lowResolution,
ImageRotation imageRotation)
{ {
if (NetCamera != null) if (NetCamera == null)
{ {
///TODO BUMI - implementing grabing multiple images
/// 1. Create a list of image file names
string[] imageNames = new string[roiCfg.ImageOpacity.Count];
for (int i = 0; i < imageNames.Length; i++)
{
imageNames[i] = imageFileName + string.Format("{0}_{1}",imageNames.Length, i);
}
/// 2. implement count of images to grab
/// 3. implement grabing multiple images
/// TODO: Implement support for sharing one camera by multiple ROI-s
return NetCamera.GrabImagesOp(new string[] { imageFileName }, blackAndWhite, lowResolution, imageRotation);
}
else
return null; return null;
}
int imageCount = Math.Max(1, RoiPicCount);
string[] imageNames = CreateImageFileNames(
imageFileName,
imageCount);
return NetCamera.GrabImagesOp(
imageNames,
blackAndWhite,
lowResolution,
imageRotation);
}
private static string[] CreateImageFileNames(
string originalFileName,
int imageCount)
{
if (imageCount <= 1)
{
return new[] { originalFileName };
}
string directory = Path.GetDirectoryName(originalFileName);
string baseName = Path.GetFileNameWithoutExtension(originalFileName);
string extension = Path.GetExtension(originalFileName);
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss_fff");
var result = new string[imageCount];
// Prvý obrázok zostáva kompatibilný s dialógom.
result[0] = originalFileName;
for (int i = 1; i < imageCount; i++)
{
string fileName = string.Format(
"{0}_{1}_{2:D2}{3}",
baseName,
timestamp,
i + 1,
extension);
result[i] = string.IsNullOrEmpty(directory)
? fileName
: Path.Combine(directory, fileName);
}
return result;
} }
public IValve GetValve() public IValve GetValve()

View File

@ -94,17 +94,24 @@ namespace TBF.Rig.Network.Telnet
public class PromptReceivedImagesEventArgs : EventArgs public class PromptReceivedImagesEventArgs : EventArgs
{ {
public Image image; /// server image. public int idxCamera;
public int idxCamera; /// camera index. public int idxImage;
public int idxImage; /// image index. public int imageCount;
public int imageCounts; /// number of images. public Image image;
public DateTimeOffset? frameTime;
public PromptReceivedImagesEventArgs(int idxCamera, Image image, int idxImage, int imageCounts)
public PromptReceivedImagesEventArgs(
int idxCamera,
int idxImage,
int imageCount,
Image image,
DateTimeOffset? frameTime)
{ {
this.image = image;
this.idxCamera = idxCamera; this.idxCamera = idxCamera;
this.idxImage = idxImage; this.idxImage = idxImage;
this.imageCounts = imageCounts; this.imageCount = imageCount;
this.image = image;
this.frameTime = frameTime;
} }
} }

View File

@ -366,7 +366,7 @@ namespace TBF.Rig.Sequences
Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams }); Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams });
//------------------------------------------------ //------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress); Bridge.OnActivity(this, Strings.Meter_Communication_in_progress);
//------------------------------------------------ //------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed bool stopPressed = false; /// true when STOP button pressed

View File

@ -48,6 +48,16 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection.Single
} }
else else
{ {
if (DebugLevel == DebugMode.Simulate &&
test.Name.ToLower().Contains("q3")
)
{
//Q3 Test - calibration data
return new FlyingStartMassCollectionSeq().Execute(test, repetNr, isLastRepetition,
testMethodCfg.TestParams.DelayedStart, null, null, DebugLevel);
}
/// DebugLevel == DebugMode.Simulate /// DebugLevel == DebugMode.Simulate
(new FlyingStartMassCollectionSeq()).MakeSimulatedTrivial(test, repetNr, test.Part); (new FlyingStartMassCollectionSeq()).MakeSimulatedTrivial(test, repetNr, test.Part);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetNr, Progress.Completed)); Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetNr, Progress.Completed));

View File

@ -150,9 +150,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvanceCollect
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).EndWMState = dataEntryCmpnt.WMEndState(i); (rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).EndWMState = dataEntryCmpnt.WMEndState(i);
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).BeginWMState = dataEntryCmpnt.WMStartState(i); (rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).BeginWMState = dataEntryCmpnt.WMStartState(i);
} }
if (rr is Rig.Network.Camera.RoiForFixedStart.Roi) if (rr is Rig.Network.Camera.RoiForFixedStart.Roi)
{ {
(rr as Rig.Network.Camera.RoiForFixedStart.Roi).EndWMState = dataEntryCmpnt.WMEndState(i); (rr as Rig.Network.Camera.RoiForFixedStart.Roi).EndWMState = dataEntryCmpnt.WMEndState(i);
@ -167,6 +165,16 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvanceCollect
dataEntryCmpnt.WMStartState(i); dataEntryCmpnt.WMStartState(i);
log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - BeginWMState [{0}], EndWMState [{1}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMStartState(i),dataEntryCmpnt.WMEndState(i)); log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - BeginWMState [{0}], EndWMState [{1}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMStartState(i),dataEntryCmpnt.WMEndState(i));
} }
//New camera CJMS11 - supplier Java Microservices, s.r.o
if (rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).EndWMState =
dataEntryCmpnt.WMEndState(i);
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).BeginWMState =
dataEntryCmpnt.WMStartState(i);
log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - BeginWMState [{0}], EndWMState [{1}] -> RoiForFixedStartCJMS11.Roi",dataEntryCmpnt.WMStartState(i),dataEntryCmpnt.WMEndState(i));
}
} }
} }

View File

@ -1038,11 +1038,13 @@
<Compile Include="Rig\Network\Camera\CJMS11\CameraCfgCtrl.designer.cs"> <Compile Include="Rig\Network\Camera\CJMS11\CameraCfgCtrl.designer.cs">
<DependentUpon>CameraCfgCtrl.cs</DependentUpon> <DependentUpon>CameraCfgCtrl.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Rig\Network\Camera\CJMS11\CameraLineReader.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\Factory.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\Factory.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\GrabImagesOp.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\GrabImagesOp.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\JmsMessage.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\JmsMessage.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\JmsPacket.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\JmsPacket.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\LiveStreamOp.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\LiveStreamOp.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CameraResponse.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandM.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandM.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandMEnum.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandMEnum.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ImageType.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\POJO\ImageType.cs" />
@ -1050,6 +1052,10 @@
<Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatus.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatus.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatusEnum.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatusEnum.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ParsedImage.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\POJO\ParsedImage.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\SendImagePayload.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\SendImagesRequest.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\SendSummaryPayload.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\TimedCameraImage.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\RoisAndResults.cs" /> <Compile Include="Rig\Network\Camera\CJMS11\RoisAndResults.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\TerminalDlg.cs"> <Compile Include="Rig\Network\Camera\CJMS11\TerminalDlg.cs">
<SubType>Form</SubType> <SubType>Form</SubType>

View File

@ -3,6 +3,7 @@
/// ///
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using log4net; using log4net;
using NHibernate; using NHibernate;
using Common; using Common;
@ -229,7 +230,26 @@ namespace TBF.UiBridge
public static void OnCameraUICmd(object sender, CameraUICmdEventArgs data) public static void OnCameraUICmd(object sender, CameraUICmdEventArgs data)
{ {
if (CameraUICmdHandler == null) return; if (CameraUICmdHandler == null) return;
try { CameraUICmdHandler(sender, data); } try
{
log.DebugFormat("CameraUICmdHandler: {0}", data.CameraUICmd);
foreach (EventHandler<CameraUICmdEventArgs> handler in CameraUICmdHandler.GetInvocationList())
{
var localHandler = handler;
Task.Run(() =>
{
try
{
localHandler(sender, data);
}
catch (Exception e)
{
log.Error("CameraUICmdHandler(...) failed", e);
}
});
}
}
catch (Exception e) { log.Error("CameraUICmdHandler(...) failed", e); } catch (Exception e) { log.Error("CameraUICmdHandler(...) failed", e); }
} }
public static event EventHandler<CameraUICmdEventArgs> CameraUICmdHandler; public static event EventHandler<CameraUICmdEventArgs> CameraUICmdHandler;

View File

@ -2,10 +2,13 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Threading.Tasks; using System.Threading.Tasks;
using Common;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using TBF.Rig.Generic; using TBF.Rig.Generic;
using TBF.Rig.Network.Camera.CJMS11; using TBF.Rig.Network.Camera.CJMS11;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.common;
using Factory = TBF.Rig.Network.Camera.CJMS11.Factory; using Factory = TBF.Rig.Network.Camera.CJMS11.Factory;
@ -17,25 +20,41 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
public class CameraTest public class CameraTest
{ {
private static string ipCamera1 = "192.168.0.170"; private static string ipCamera1 = "192.168.0.170";
private static string ipCamera2 = "192.168.0.169"; private static string ipCamera2 = "192.168.0.129";
public string IPCamera1 { get { return ipCamera1; } } public string IPCamera1 { get { return ipCamera1; } }
public string IPCamera2 { get { return ipCamera2; } } public string IPCamera2 { get { return ipCamera2; } }
private RoiCfg CreateTestRoiCfg()
{
var factory = new TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.Factory();
var roi = new RoiCfg("TestRoi", factory);
roi.BlackAndWhite = false;
roi.LowResolution = true;
roi.ImageRotation = ImageRotation.None;
roi.ImageFrame = Frame.StandardFrame();
return roi;
}
[TestMethod] [TestMethod]
public void Initialize() public void Initialize()
{ {
TBF.Rig.Network.Camera.CJMS11.Camera camera = GetCamera( IPCamera1); TBF.Rig.Network.Camera.CJMS11.Camera camera = GetCamera(IPCamera1);
camera.RoiConfiguration = CreateTestRoiCfg();
camera.Initialize(); camera.Initialize();
TBF.Rig.Network.Camera.CJMS11.Camera camera2 = GetCamera( IPCamera2); TBF.Rig.Network.Camera.CJMS11.Camera camera2 = GetCamera( IPCamera2);
camera2.RoiConfiguration = CreateTestRoiCfg();
camera2.Initialize(); camera2.Initialize();
TBF.Rig.Network.Camera.CJMS11.Camera camera11 = GetCamera( IPCamera1); // TBF.Rig.Network.Camera.CJMS11.Camera camera11 = GetCamera( IPCamera1);
camera11.Initialize(); // camera11.Initialize();
//
TBF.Rig.Network.Camera.CJMS11.Camera camera12 = GetCamera( IPCamera2); // TBF.Rig.Network.Camera.CJMS11.Camera camera12 = GetCamera( IPCamera2);
camera12.Initialize(); // camera12.Initialize();
} }
@ -57,25 +76,25 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
camera.Initialize(); camera.Initialize();
}); });
var task3 = Task.Run(() => // var task3 = Task.Run(() =>
{ // {
var camera = GetCamera(IPCamera2); // var camera = GetCamera(IPCamera2);
camera.Initialize(); // camera.Initialize();
}); // });
//
var task4 = Task.Run(() => // var task4 = Task.Run(() =>
{ // {
var camera = GetCamera(IPCamera1); // var camera = GetCamera(IPCamera1);
camera.Initialize(); // camera.Initialize();
}); // });
Task.WaitAll(task1, task2, task3, task4); // blocks until both finish Task.WaitAll(task1, task2/*, task3, task4*/); // blocks until both finish
// Optionally, add assertions or diagnostics // Optionally, add assertions or diagnostics
Assert.IsTrue(task1.IsCompleted); Assert.IsTrue(task1.IsCompleted);
Assert.IsTrue(task2.IsCompleted); Assert.IsTrue(task2.IsCompleted);
Assert.IsTrue(task3.IsCompleted); // Assert.IsTrue(task3.IsCompleted);
Assert.IsTrue(task4.IsCompleted); // Assert.IsTrue(task4.IsCompleted);
} }
@ -112,7 +131,7 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
var camera = GetCamera(IPCamera1); var camera = GetCamera(IPCamera1);
Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListener()); Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListenerAsynch());
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3)); var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3));
var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result; var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result;
if (completedAnswerTask == timeoutAnswerTask) if (completedAnswerTask == timeoutAnswerTask)
@ -129,35 +148,35 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
camera.Initialize(); camera.Initialize();
}); });
var task3 = Task.Run(() => // var task3 = Task.Run(() =>
{ // {
var camera = GetCamera(IPCamera2); // var camera = GetCamera(IPCamera2);
//
Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListener()); // Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListenerAsynch());
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3)); // var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3));
var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result; // var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result;
if (completedAnswerTask == timeoutAnswerTask) // if (completedAnswerTask == timeoutAnswerTask)
{ // {
Assert.Fail(); // Assert.Fail();
} // }
//
// //TODO BUMI enable check image
// //Assert.IsTrue(saveImageTask.Result != null);
// });
//
// var task4 = Task.Run(() =>
// {
// var camera = GetCamera(IPCamera1);
// camera.Initialize();
// });
//TODO BUMI enable check image await Task.WhenAll(task1, task2/*,task3, task4*/); // blocks until both finish
//Assert.IsTrue(saveImageTask.Result != null);
});
var task4 = Task.Run(() =>
{
var camera = GetCamera(IPCamera1);
camera.Initialize();
});
await Task.WhenAll(task1, task2,task3, task4); // blocks until both finish
// Optionally, add assertions or diagnostics // Optionally, add assertions or diagnostics
Assert.IsTrue(task1.IsCompleted); Assert.IsTrue(task1.IsCompleted);
Assert.IsTrue(task2.IsCompleted); Assert.IsTrue(task2.IsCompleted);
Assert.IsTrue(task3.IsCompleted); // Assert.IsTrue(task3.IsCompleted);
Assert.IsTrue(task4.IsCompleted); // Assert.IsTrue(task4.IsCompleted);
} }