FIX CAMERA - Improve error handling, modularize image processing functions for CJMS11 cameras, and enhance multi-image support in TestStartEndForm.

This commit is contained in:
Michal Buzik 2026-07-21 14:50:59 +02:00
parent c1ee29cd06
commit 2fa212e6ff
6 changed files with 597 additions and 249 deletions

View File

@ -4,8 +4,8 @@
using System;
using System.Collections.Generic;
using log4net;
using Common;
using TBF.Rig.GenericDevices;
using System.Linq;
namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
{
@ -38,32 +38,21 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
public string[] StartImages
{
get { return startImages; }
set
{
/*if (entryFormCfg.DebugLevel == DebugMode.Simulate )
{
startImages = new string[] { "C:\\TBF\\Images\\Test\\Image1.jpg", "C:\\TBF\\Images\\Test\\Image2.jpg",
"C:\\TBF\\Images\\Test\\Image3.jpg", "C:\\TBF\\Images\\Test\\Image4.jpg", "C:\\TBF\\Images\\Test\\Image5.jpg",
"C:\\TBF\\Images\\Test\\Image1.jpg", "C:\\TBF\\Images\\Test\\Image2.jpg", "C:\\TBF\\Images\\Test\\Image3.jpg",
"C:\\TBF\\Images\\Test\\Image4.jpg", "C:\\TBF\\Images\\Test\\Image5.jpg", "C:\\TBF\\Images\\Test\\Image1.jpg",
"C:\\TBF\\Images\\Test\\Image2.jpg", "C:\\TBF\\Images\\Test\\Image3.jpg", "C:\\TBF\\Images\\Test\\Image4.jpg",
"C:\\TBF\\Images\\Test\\Image5.jpg", "C:\\TBF\\Images\\Test\\Image1.jpg", "C:\\TBF\\Images\\Test\\Image2.jpg",
"C:\\TBF\\Images\\Test\\Image3.jpg", "C:\\TBF\\Images\\Test\\Image4.jpg", "C:\\TBF\\Images\\Test\\Image5.jpg" };
}
else*/
{
startImages = value;
}
}
set { startImages = value; }
}
string[] startImages;
public string[] EndImages
{
get { return endImages; }
set { endImages = value; }
}
string[] startImages;
string[] endImages;
private readonly List<string>[] startImageLists = new List<string>[TBF.Data.WMsCount];
private readonly List<string>[] endImageLists = new List<string>[TBF.Data.WMsCount];
public bool SaveImages
{
@ -152,16 +141,27 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
entryFormCfg = cfg as EntryFormCfg;
}
public override void Initialize()
{
disabled = new bool[TBF.Data.WMsCount];
wmStartState = new double[TBF.Data.WMsCount];
wmStartStateStr = new string[TBF.Data.WMsCount];
wmEndState = new double[TBF.Data.WMsCount];
wmCycleEndState = new string[TBF.Data.WMsCount];
currentOp = CurrentOp.None;
log.FatalFormat("{0} initialized: {1}", Name, this);
}
public override void Initialize()
{
disabled = new bool[TBF.Data.WMsCount];
wmStartState = new double[TBF.Data.WMsCount];
wmStartStateStr = new string[TBF.Data.WMsCount];
wmEndState = new double[TBF.Data.WMsCount];
wmCycleEndState = new string[TBF.Data.WMsCount];
startImages = new string[TBF.Data.WMsCount];
endImages = new string[TBF.Data.WMsCount];
currentOp = CurrentOp.None;
for (int i = 0; i < TBF.Data.WMsCount; i++)
{
startImageLists[i] = new List<string>();
endImageLists[i] = new List<string>();
}
log.FatalFormat("{0} initialized: {1}", Name, this);
}
/// <returns>Reference to the operation</returns>
@ -202,15 +202,19 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
/// <param name="errLimLo"></param>
/// <param name="errLimHi"></param>
/// <returns></returns>
public IOperation ShowTestCollectFormOp(IRegReader[] regReaders, double volumeRef, double errLimLo,
public IOperation ShowTestCollectFormOp(
IRegReader[] regReaders,
double volumeRef,
double errLimLo,
double errLimHi)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
currentOp = CurrentOp.TestBothStates;
this.regReaders = regReaders;
this.refVolume = refVolume;
this.refVolume = volumeRef; // = refVolume;
this.errLimLo = errLimLo;
this.errLimHi = errLimHi;
return this;
}
@ -255,21 +259,38 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
void OpenTestStartStatesDlg(EntryForm myRef)
{
log.Debug("-- OpenTestStartStatesDlg --");
string ocrMessage;
var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage);
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, ocr, ocrMessage, myRef.OcrStream,
startImages, disabled);
log.DebugFormat( "Before TestStartEndForm: TBF.Data.WMsCount={0}, regReaders.Length={1}, startImages.Length={2}, disabled.Length={3}",
TBF.Data.WMsCount,
myRef.regReaders == null ? -1 : myRef.regReaders.Length,
startImages == null ? -1 : startImages.Length,
disabled == null ? -1 : disabled.Length);
if (startImages != null)
{
for (int i = 0; i < startImages.Length; i++)
{
log.DebugFormat( "startImages[{0}]='{1}'", i, startImages[i]);
}
}
string ocrMessage;
var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage);
myRef.modelessDlg = new TestStartEndForm( TBF.Data.WMsCount, myRef.regReaders, ocr, ocrMessage, myRef.OcrStream, startImages, disabled);
modelessDlg.Show();
}
///
void OpenTestEndStatesDlg(EntryForm myRef)
{
log.Debug("-- OpenTestEndStatesDlg --");
log.Warn("-- OpenTestEndStatesDlg ENTER --");
string ocrMessage;
var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage);
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, ocr, ocrMessage, myRef.OcrStream,
startImages, wmStartState, wmStartStateStr, endImages, disabled,
refVolume, errLimLo, errLimHi);
log.Warn("-- OpenTestEndStatesDlg SHOW --");
modelessDlg.Show();
}
@ -340,6 +361,12 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
/// <summary>Start this operation</summary>
public void Start()
{
log.WarnFormat( "EntryForm.Start: currentOp={0}, modelessDlg={1}, resultSaved={2}",
currentOp,
modelessDlg == null ? "<null>" : modelessDlg.GetType().FullName,
resultSaved);
resultSaved = false;
switch (currentOp)
{
@ -383,95 +410,80 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
/// <returns>Event.ResultsPrinted</returns>
public Event Run()
{
log.WarnFormat( "EntryForm.Run: currentOp={0}, modelessDlg={1}, completed={2}, resultSaved={3}",
currentOp,
modelessDlg == null ? "<null>" : modelessDlg.GetType().FullName,
modelessDlg is IHasCompleted && ((IHasCompleted)modelessDlg).Completed,
resultSaved);
if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed)
{
return Event.ModelessFormIsOpen;
}
if (!resultSaved) /// This is to save the result only once
if (!resultSaved)
{
if ((!entryFormCfg.EnterSerialNrsAtTheEnd && currentOp == CurrentOp.ShowFormAtCycleBeginning) ||
(entryFormCfg.EnterSerialNrsAtTheEnd && currentOp == CurrentOp.ShowFormAtCycleEnd))
try
{
CycleBeginningForm dlg = (modelessDlg as CycleBeginningForm);
if (dlg != null)
if ((!entryFormCfg.EnterSerialNrsAtTheEnd && currentOp == CurrentOp.ShowFormAtCycleBeginning) ||
(entryFormCfg.EnterSerialNrsAtTheEnd && currentOp == CurrentOp.ShowFormAtCycleEnd))
{
for (int i = 0; i < Math.Min(dlg.WaterMetersCount, waterMeters.Count); i++)
{
if (waterMeters[i] != null)
{
waterMeters[i].Disabled = disabled[i] = dlg.Disabled[i];
waterMeters[i].SerialNr = dlg.SNText[i];
if (!entryFormCfg.HideOrder && dlg.PurchaseOrder != null) waterMeters[i].PurchaseOrder = dlg.PurchaseOrder;
}
}
}
}
else if (currentOp == CurrentOp.ShowFormAtCycleEnd)
{
if (modelessDlg is CycleEndForm)
{
CycleEndForm dlg = (modelessDlg as CycleEndForm);
int count = waterMeters.Count;
if ((dlg != null) && (count > dlg.WaterMetersCount)) count = dlg.WaterMetersCount;
CycleBeginningForm dlg = modelessDlg as CycleBeginningForm;
for (int i = 0; i < count; i++)
if (dlg != null)
{
if (waterMeters[i] != null)
for (int i = 0; i < Math.Min( dlg.WaterMetersCount, waterMeters.Count); i++)
{
/// In case entryFormCfg.ShowCycleEndForm == false dlg would be null, values would be string.Empty
wmCycleEndState[i] = waterMeters[i].EndState = (dlg != null) ? dlg.EndStateText[i] : string.Empty;
if (waterMeters[i] != null)
{
waterMeters[i].Disabled = disabled[i] = dlg.Disabled[i];
waterMeters[i].SerialNr = dlg.SNText[i];
if (!entryFormCfg.HideOrder && dlg.PurchaseOrder != null)
{
waterMeters[i].PurchaseOrder = dlg.PurchaseOrder;
}
}
}
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestStartStates)
{
/// Fixed start/stop: test start
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
if (dlg != null)
{
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestEndStates)
{
/// Fixed start/stop: test end
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
if (dlg != null)
{
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
wmEndState[i] = dlg.WMEndState[i];
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestBothStates)
{
/// Fixed start/stop: test end
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
if (dlg != null)
{
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
wmEndState[i] = dlg.WMEndState[i];
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.DeferredTestEval)
{
/// Fixed start/stop: deferred test evaluation
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
if (dlg != null)
else if (currentOp == CurrentOp.ShowFormAtCycleEnd)
{
CycleEndForm dlg = modelessDlg as CycleEndForm;
if (dlg != null)
{
int count = waterMeters.Count;
if (count > dlg.WaterMetersCount)
{
count = dlg.WaterMetersCount;
}
for (int i = 0; i < count; i++)
{
if (waterMeters[i] != null)
{
wmCycleEndState[i] = waterMeters[i].EndState = dlg.EndStateText[i];
}
}
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestStartStates)
{
TestStartEndForm dlg = modelessDlg as TestStartEndForm;
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestEndStates)
{
TestStartEndForm dlg = modelessDlg as TestStartEndForm;
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
@ -479,12 +491,39 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
wmEndState[i] = dlg.WMEndState[i];
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestBothStates)
{
TestStartEndForm dlg = modelessDlg as TestStartEndForm;
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
wmEndState[i] = dlg.WMEndState[i];
}
}
else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.DeferredTestEval)
{
TestStartEndForm dlg = modelessDlg as TestStartEndForm;
for (int i = 0; i < dlg.WaterMetersCount; i++)
{
wmStartState[i] = dlg.WMStartState[i];
wmStartStateStr[i] = dlg.WMStartStateStr[i];
wmEndState[i] = dlg.WMEndState[i];
}
}
resultSaved = true;
}
finally
{
log.DebugFormat( "EntryForm operation completed: currentOp={0}", currentOp);
modelessDlg = null;
currentOp = CurrentOp.None;
}
resultSaved = true;
modelessDlg = null;
}
return Event.ModelessFormClosed; /// Form closed
return Event.ModelessFormClosed;
}
/// <summary>Stop this operation</summary>
@ -497,5 +536,31 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
}
currentOp = CurrentOp.None;
}
public void AddImages(string[] newStartImages, string[] newEndImages)
{
for (int i = 0; i < TBF.Data.WMsCount; i++)
{
if (newStartImages != null &&
i < newStartImages.Length &&
!string.IsNullOrEmpty(newStartImages[i]) &&
System.IO.File.Exists(newStartImages[i]) &&
!startImageLists[i].Any( image => string.Equals( image, newStartImages[i], StringComparison.OrdinalIgnoreCase)))
{
startImageLists[i].Add(newStartImages[i]);
}
if (newEndImages != null &&
i < newEndImages.Length &&
!string.IsNullOrEmpty(newEndImages[i]) &&
System.IO.File.Exists(newEndImages[i]) &&
!endImageLists[i].Any( image => string.Equals( image, newEndImages[i], StringComparison.OrdinalIgnoreCase)))
{
endImageLists[i].Add(newEndImages[i]);
}
}
}
}
}

View File

@ -179,7 +179,15 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
if (startImages == null || startImages.Length != WaterMetersCount)
{
throw new Exception("Invalid 'startImages' argument");
throw new Exception(
string.Format(
"Invalid 'startImages' argument. startImages.Length={0}, " +
"WaterMetersCount={1}, requestedWaterMetersCount={2}, " +
"regReaders.Length={3}",
startImages == null ? -1 : startImages.Length,
WaterMetersCount,
waterMetersCount,
regReaders == null ? -1 : regReaders.Length));
}
this.endImages = new string[WaterMetersCount];
@ -721,12 +729,12 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
private void previousButton_Click(object sender, EventArgs e)
{
ShowPreviousImageFromGroup();
}
private void nextButton_Click(object sender, EventArgs e)
{
ShowNextImageFromGroup();
}
@ -1142,8 +1150,8 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
private void endTextBox20_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 19); }
private void endTextBox21_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 20); }
private void endTextBox22_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 21); }
private void endTextBox24_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 22); }
private void endTextBox23_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 23); }
private void endTextBox24_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 23); }
private void endTextBox23_AcceptsTabChanged(object sender, EventArgs e) { LoadImage(sender, Tst.End, 22); }
private void endTextBox1_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 0); }
private void endTextBox2_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 1); }
private void endTextBox3_MouseDown(object sender, MouseEventArgs e) { LoadImage(sender, Tst.End, 2); }
@ -1290,77 +1298,92 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
return null;
}
/// <summary>
/// load group of images
/// </summary>
/// <param name="baseImageFileName"></param>
private void LoadImageGroup(
string baseImageFileName)
private void LoadImageGroup(string baseImageFileName)
{
currentImageGroup.Clear();
currentImageGroupIndex = 0;
if (string.IsNullOrWhiteSpace(baseImageFileName))
{
UpdateImageSwitchControls();
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}");
/*
* Vstup môže byť napríklad:
*
* C:\Tbf\Images\1667\1\Advance_(1_3)-start.bmp
*
* Preview však musí používať výhradne:
*
* C:\Tbf\Images\Temp\1667\1\Advance_(1_3)-start.bmp
* C:\Tbf\Images\Temp\1667\1\Advance_(1_3)-start_img02_....bmp
* C:\Tbf\Images\Temp\1667\1\Advance_(1_3)-start_img03_....bmp
*/
string tempBaseFileName =
GetTempImageFileName(baseImageFileName);
return;
}
if (string.IsNullOrWhiteSpace(tempBaseFileName))
{
log.WarnFormat(
"Cannot determine Temp image path from '{0}'.",
baseImageFileName);
string directory =
Path.GetDirectoryName(fullBaseFileName);
UpdateImageSwitchControls();
return;
}
string baseName =
Path.GetFileNameWithoutExtension(fullBaseFileName);
string tempDirectory =
Path.GetDirectoryName(tempBaseFileName);
string extension =
Path.GetExtension(fullBaseFileName);
string baseName =
Path.GetFileNameWithoutExtension(tempBaseFileName);
if (string.IsNullOrWhiteSpace(directory) ||
string.IsNullOrWhiteSpace(baseName))
{
return;
}
string extension =
Path.GetExtension(tempBaseFileName);
/*
* Pôvodný obrázok pridáme ako prvý.
*/
if (File.Exists(fullBaseFileName))
{
currentImageGroup.Add(fullBaseFileName);
}
if (string.IsNullOrWhiteSpace(tempDirectory) ||
string.IsNullOrWhiteSpace(baseName) ||
!Directory.Exists(tempDirectory))
{
log.DebugFormat(
"Temp image directory does not exist: '{0}'.",
tempDirectory);
if (!Directory.Exists(directory))
{
return;
}
UpdateImageSwitchControls();
return;
}
string searchPattern =
$"{baseName}_img*{extension}";
/*
* Prvý obrázok:
*
* Advance_(1_3)-start.bmp
*/
AddImageToCurrentGroup(tempBaseFileName);
/*
* Ďalšie obrázky:
*
* Advance_(1_3)-start_img02_20260720_094019_248.bmp
* Advance_(1_3)-start_img03_20260720_094019_847.bmp
*/
string timedPattern = string.Format(
"{0}_img*{1}",
baseName,
extension);
try
{
List<string> timedImages =
Directory
.GetFiles(
directory,
searchPattern,
tempDirectory,
timedPattern,
SearchOption.TopDirectoryOnly)
.OrderBy(GetTimedImageIndex)
.ThenBy(
@ -1370,29 +1393,255 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
foreach (string timedImage in timedImages)
{
if (!currentImageGroup.Contains(
timedImage,
StringComparer.OrdinalIgnoreCase))
{
currentImageGroup.Add(timedImage);
}
AddImageToCurrentGroup(timedImage);
}
log.Debug(
$"Image group loaded: " +
$"baseFile='{fullBaseFileName}', " +
$"searchPattern='{searchPattern}', " +
$"imagesCount={currentImageGroup.Count}");
UpdateImageSwitchControls();
log.DebugFormat(
"Temp image group loaded: input='{0}', tempBase='{1}', " +
"pattern='{2}', count={3}, files=[{4}]",
baseImageFileName,
tempBaseFileName,
timedPattern,
currentImageGroup.Count,
string.Join(
", ",
currentImageGroup.Select(Path.GetFileName)));
}
catch (Exception exc)
{
log.Warn(
$"Cannot load image group: " +
$"baseFile='{fullBaseFileName}', " +
$"pattern='{searchPattern}', " +
$"error={exc.Message}");
log.WarnFormat(
"Cannot load Temp image group: input='{0}', error={1}",
baseImageFileName,
exc.Message);
currentImageGroup.Clear();
currentImageGroupIndex = 0;
UpdateImageSwitchControls();
}
}
private static string GetTempImageFileName(
string imageFileName)
{
if (string.IsNullOrWhiteSpace(imageFileName))
{
return null;
}
string fullPath;
try
{
fullPath = Path.GetFullPath(imageFileName);
}
catch
{
return null;
}
const string tempRoot =
@"C:\Tbf\Images\Temp";
const string imagesRoot =
@"C:\Tbf\Images";
/*
* Súbor smeruje do Temp.
*/
if (fullPath.StartsWith(
tempRoot + Path.DirectorySeparatorChar,
StringComparison.OrdinalIgnoreCase))
{
return fullPath;
}
/*
* C:\Tbf\Images\1667\1\file.bmp
*
* zmeníme na:
*
* C:\Tbf\Images\Temp\1667\1\file.bmp
*/
if (fullPath.StartsWith(
imagesRoot + Path.DirectorySeparatorChar,
StringComparison.OrdinalIgnoreCase))
{
string relativePath =
fullPath.Substring(
imagesRoot.Length + 1);
return Path.Combine(
tempRoot,
relativePath);
}
/*
* Neznáma cesta zachováme iba časť od čísla batchu,
* ak cesta obsahuje adresár Temp.
*/
int tempIndex = fullPath.IndexOf(
@"\Temp\",
StringComparison.OrdinalIgnoreCase);
if (tempIndex >= 0)
{
string relativePath =
fullPath.Substring(
tempIndex + @"\Temp\".Length);
return Path.Combine(
tempRoot,
relativePath);
}
return null;
}
private static int GetRepetitionIndex(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return int.MaxValue;
}
Match match = Regex.Match(Path.GetFileNameWithoutExtension(fileName), @"\((?<repetition>\d+)_\d+\)",
RegexOptions.IgnoreCase);
int repetition;
return match.Success && int.TryParse(match.Groups["repetition"].Value, out repetition)
? repetition
: int.MaxValue;
}
private void AddImageToCurrentGroup(
string imageFileName)
{
if (string.IsNullOrWhiteSpace(imageFileName) ||
!File.Exists(imageFileName))
{
return;
}
bool alreadyAdded =
currentImageGroup.Any(
existingFile =>
string.Equals(
existingFile,
imageFileName,
StringComparison.OrdinalIgnoreCase));
if (!alreadyAdded)
{
currentImageGroup.Add(imageFileName);
}
}
private void UpdateImageSwitchControls()
{
bool canSwitch =
currentImageGroup.Count > 1;
//previousButton.Enabled = canSwitch;
//nextButton.Enabled = canSwitch;
// previousButton.Visible = canSwitch;
// nextButton.Visible = canSwitch;
}
private void AddTimedImagesToCurrentGroup(string baseImageFileName)
{
if (string.IsNullOrWhiteSpace(baseImageFileName))
{
return;
}
string directory = Path.GetDirectoryName(baseImageFileName);
string baseName = Path.GetFileNameWithoutExtension(baseImageFileName);
string extension = Path.GetExtension(baseImageFileName);
if (string.IsNullOrWhiteSpace(directory) ||
string.IsNullOrWhiteSpace(baseName) ||
!Directory.Exists(directory))
{
return;
}
string searchPattern = string.Format(
"{0}_img*{1}",
baseName,
extension);
List<string> timedImages =
Directory
.GetFiles(
directory,
searchPattern,
SearchOption.TopDirectoryOnly)
.OrderBy(GetTimedImageIndex)
.ThenBy(
fileName => fileName,
StringComparer.OrdinalIgnoreCase)
.ToList();
foreach (string timedImage in timedImages)
{
AddImageToCurrentGroup(timedImage);
}
}
private void AddTimedImagesFromDirectory( string directory, string searchPattern)
{
if (string.IsNullOrWhiteSpace(directory) ||
string.IsNullOrWhiteSpace(searchPattern) ||
!Directory.Exists(directory))
{
return;
}
List<string> timedImages = Directory .GetFiles( directory, searchPattern, SearchOption.TopDirectoryOnly)
.OrderBy(GetTimedImageIndex)
.ThenBy(
fileName => fileName,
StringComparer.OrdinalIgnoreCase)
.ToList();
foreach (string timedImage in timedImages)
{
AddImageToCurrentGroup(timedImage);
}
}
private static string GetCorrespondingTempImageDirectory( string directory)
{
if (string.IsNullOrWhiteSpace(directory))
{
return null;
}
const string normalImagesPart = @"\Tbf\Images\";
const string tempImagesPart = @"\Tbf\Images\Temp\";
/*
* Ak sme v Temp adresári, nič nemeníme.
*/
if (directory.IndexOf( tempImagesPart, StringComparison.OrdinalIgnoreCase) >= 0)
{
return directory;
}
int imagesIndex = directory.IndexOf( normalImagesPart, StringComparison.OrdinalIgnoreCase);
if (imagesIndex < 0)
{
return null;
}
return directory.Substring( 0, imagesIndex) + tempImagesPart + directory.Substring( imagesIndex + normalImagesPart.Length);
}
/// <summary>
/// grouping by time
/// </summary>
@ -1576,20 +1825,35 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
int direction)
{
if (direction == 0 ||
currentImageGroup.Count <= 1)
currentImageGroup.Count == 0)
{
return;
}
int newIndex =
currentImageGroupIndex + direction;
/*
* Cyklické prepínanie:
*
* posledný -> prvý
* prvý -> posledný
* Pred prepnutím odstránime súbory, ktoré medzitým
* prestali existovať.
*/
currentImageGroup.RemoveAll( fileName => !File.Exists(fileName));
if (currentImageGroup.Count == 0)
{
currentImageGroupIndex = 0;
UpdateImageSwitchControls();
LoadImageFile(null);
return;
}
if (currentImageGroup.Count == 1)
{
currentImageGroupIndex = 0;
UpdateImageSwitchControls();
LoadImageFile(currentImageGroup[0]);
return;
}
int newIndex = currentImageGroupIndex + direction;
if (newIndex < 0)
{
newIndex =
@ -1602,10 +1866,10 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
currentImageGroupIndex = newIndex;
LoadImageFile(
currentImageGroup[currentImageGroupIndex]);
}
LoadImageFile( currentImageGroup[currentImageGroupIndex]);
UpdateImageSwitchControls();
}
// --- mouse events ---

View File

@ -2385,33 +2385,26 @@ namespace TBF.Rig.Network.Camera.CJMS11
try
{
log.Debug(
$"Live stream waiting for camera lock: " +
$"cameraIdx={cameraIdx}");
log.Debug( $"Live stream waiting for camera lock: cameraIdx={cameraIdx}");
await cameraOperationLock
.WaitAsync(ct)
.ConfigureAwait(false);
await cameraOperationLock .WaitAsync(ct) .ConfigureAwait(false);
lockAcquired = true;
log.Debug(
$"Live stream acquired camera lock: " +
$"cameraIdx={cameraIdx}");
log.Debug( $"Live stream acquired camera lock: cameraIdx={cameraIdx}");
client = await ConnectCameraAsync(
timeoutMs: 3000,
ct: ct,
maxAttempts: 3,
retryDelayMs: 300)
.ConfigureAwait(false);
timeoutMs: 3000,
ct: ct,
maxAttempts: 3,
retryDelayMs: 300)
.ConfigureAwait(false);
stream = client.GetStream();
reader = new CameraLineReader( stream, 64 * 1024);
JmsPacket prepare =
await SendCommandAndWaitToAnswerAsync(
JmsPacket prepare = await SendCommandAndWaitToAnswerAsync(
stream,
reader,
CommandM.prepare_camera_,
@ -2425,10 +2418,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
prepare.JmsMessage != null &&
prepare.JmsMessage.Status ==
MessageStatus.NACK &&
!string.IsNullOrEmpty(
prepare.JmsMessage.Payload) &&
prepare.JmsMessage.Payload.Contains(
"OPENED");
!string.IsNullOrEmpty( prepare.JmsMessage.Payload) &&
prepare.JmsMessage.Payload.Contains( "OPENED");
bool prepared =
prepare != null &&
@ -2447,8 +2438,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
log.Debug( $"Camera already opened for live stream: cameraIdx={cameraIdx}");
}
JmsPacket start =
await SendCommandAndWaitToAnswerAsync(
JmsPacket start = await SendCommandAndWaitToAnswerAsync(
stream,
reader,
CommandM.start_stream_images_,
@ -2469,30 +2459,39 @@ namespace TBF.Rig.Network.Camera.CJMS11
while (!ct.IsCancellationRequested)
{
string response =
await reader.ReadLineAsync(
10000,
ct)
.ConfigureAwait(false);
string response = await reader.ReadLineAsync( 10000, ct).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(response))
continue;
JmsPacket packet =
new JmsPacket(response);
if (packet.JmsMessage == null)
continue;
if (packet.JmsMessage.Command !=
CommandM.grab_image_)
{
log.Debug( $"Unexpected packet during live stream: cameraIdx={cameraIdx}, command={packet.JmsMessage.Command}");
continue;
}
if (packet.JmsMessage.Status !=
MessageStatus.ACK)
JmsPacket packet = new JmsPacket(response);
if (packet.JmsMessage == null)
{
continue;
}
/*
* Server môže po spustení streamu poslať ešte jeden
* oneskorený alebo duplicitný ACK start_stream_images.
* Nie je to chyba streamu.
*/
if (packet.JmsMessage.Command == CommandM.start_stream_images_)
{
log.Debug( $"Ignoring delayed start stream response: cameraIdx={cameraIdx}");
continue;
}
if (packet.JmsMessage.Command != CommandM.grab_image_)
{
log.Debug( $"Unexpected packet during live stream: cameraIdx={cameraIdx}, " +
$"command={packet.JmsMessage.Command}");
continue;
}
if (packet.JmsMessage.Status != MessageStatus.ACK)
{
log.Warn( $"Live frame returned NACK: cameraIdx={cameraIdx}, payload={packet.JmsMessage.Payload}");
continue;
@ -2508,17 +2507,13 @@ namespace TBF.Rig.Network.Camera.CJMS11
Image image = parsed.Image;
if (image == null)
{
continue;
}
DrawOverlay(image);
OnImageReceived(
this,
cameraIdx,
image,
RoiConfiguration.ImageRotation,
0,
1);
OnImageReceived( this, cameraIdx, image, RoiConfiguration.ImageRotation, 0, 1);
}
}
catch (OperationCanceledException)
@ -2527,15 +2522,18 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
catch (TimeoutException exc)
{
log.Error( $"Live stream timeout: cameraIdx={cameraIdx}, IP={CameraCfg.IPAddressCJMS}, error={exc.Message}");
}
catch (SocketException exc)
{
log.Error( $"Live stream socket error: cameraIdx={cameraIdx}, IP={CameraCfg.IPAddressCJMS}, socketError={exc.SocketErrorCode}, " +
$"error={exc.Message}");
log.Error( $"Live stream socket error: cameraIdx={cameraIdx}, IP={CameraCfg.IPAddressCJMS}, " +
$"socketError={exc.SocketErrorCode}, error={exc.Message}");
}
catch (Exception exc)
{
log.Error( $"Live stream exception: cameraIdx={cameraIdx}, error={exc.Message}", exc);
UiBridge.Bridge.OnImage( cameraIdx, null);
}
@ -2607,6 +2605,14 @@ namespace TBF.Rig.Network.Camera.CJMS11
cameraOperationLock.Release();
}
/*
* Dôležité:
* ak stream skončí timeoutom, socket chybou alebo výnimkou,
* UI musí povoliť nový pokus o spustenie.
*/
stopLiveStreamListenerFlag = true;
lockBrich = CameraUICmd.None;
log.Debug( $"Live stream finished: cameraIdx={cameraIdx}");
}
}

View File

@ -137,6 +137,12 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
{
return null;
}
if (NetCamera.CameraCfg.DebugLevel != DebugMode.Simulate && NetCamera.IPAddress == null)
{
log.WarnFormat( "Skipping GrabImageOp for ROI '{0}': camera '{1}' was not detected.", Name, NetCamera.Name);
return null;
}
int imageCount = Math.Max(1, RoiPicCount);

View File

@ -609,10 +609,14 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
(rr as Rig.Network.Camera.RoiForFixedStart.Roi).BeginWMState = dataEntryCmpnt.WMStartState(i);
if (rr is Rig.Network.Camera.RoiForFixedStartKeyence.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).BeginWMState =
dataEntryCmpnt.WMStartState(i);
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).BeginWMState = dataEntryCmpnt.WMStartState(i);
log.DebugFormat("BeginWMState [{0}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMStartState(i));
}
if (rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).BeginWMState = dataEntryCmpnt.WMStartState(i);
log.DebugFormat("BeginWMState [{0}] -> RoiForFixedStartCJMS11.Roi",dataEntryCmpnt.WMStartState(i));
}
}
}
@ -916,7 +920,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.TestInProgress/*Event.ModelessFormClosed*/));
while (!e.Contains(Event.TestInProgress/*Event.ModelessFormClosed*/) && !e.Contains(Event.TestCompleted));
if (heatMetersTestParams != null)
@ -954,6 +958,13 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
dataEntryCmpnt.WMEndState(i);
log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - EndWMState [{0}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMEndState(i));
}
if (rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).EndWMState =
dataEntryCmpnt.WMEndState(i);
log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - EndWMState [{0}] -> RoiForFixedStartCJMS11.Roi",dataEntryCmpnt.WMEndState(i));
}
}
}

View File

@ -159,20 +159,16 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvanceCollect
if (rr is Rig.Network.Camera.RoiForFixedStartKeyence.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).EndWMState =
dataEntryCmpnt.WMEndState(i);
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).BeginWMState =
dataEntryCmpnt.WMStartState(i);
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).EndWMState = dataEntryCmpnt.WMEndState(i);
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).BeginWMState = dataEntryCmpnt.WMStartState(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);
(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));
}
}