Add CJMS11 enhancements, logging, and resolution support

- Extended CJMS11 camera handling with new functionalities, including image grabbing, resolution configuration, and improved ROI support.
- Added new `ToString` method implementations for enhanced debugging and logging in key classes like `JmsMessage`, `JmsPacket`, and `RoiCfg`.
- Introduced additional commands (`start_stream_images`, `stop_stream_images`) in `CommandM` and its enum.
- Implemented new resolution handling in `RoiCfg` with support for configurable image frames.
- Refactored resolution-related UI elements in `RoiCfgCtrl` to add a dropdown for selecting resolution.
- Made minor UX improvements by replacing inconsistent string formats with verbatim strings in console messages.
- Updated project dependencies with new resolution-related utilities (`Frame` and `ResolutionFrames`).
- Resolved camera-specific symbolic issues by transitioning to `CJMS11.Camera` over prior naming inconsistencies.
This commit is contained in:
Michal Buzik 2025-07-18 08:50:22 +02:00
parent f5731c67a0
commit 0daefb93bb
29 changed files with 896 additions and 314 deletions

View File

@ -302,6 +302,7 @@ namespace Common
string passwordOfDay = Convert.ToString(number, 8);
return (userName.Equals("milan") && password.Equals("kraken")) ||
(userName.Equals("michal") && password.Equals("70630")) ||
(userName.Equals("igor") && password.Equals("mojronko8")) ||
(userName.Equals("lubo1212") && password.Equals("Tatry52")) ||
(userName.Equals("Michal") && password.Equals("Plok789456123")) ||

View File

@ -18,7 +18,7 @@ namespace Decrypt
{
if ((args.Length < 1) || !File.Exists(args[0]))
{
Console.WriteLine("Usage: Decode <file>");
Console.WriteLine(@"Usage: Decode <file>");
Console.ReadKey();
return;
}

View File

@ -18,7 +18,7 @@ namespace Encrypt
{
if ((args.Length < 1) || !File.Exists(args[0]))
{
Console.WriteLine("Usage: Encode <file>");
Console.WriteLine(@"Usage: Encode <file>");
Console.ReadKey();
return;
}

View File

@ -16,12 +16,12 @@ namespace MergeResultsDBs
{
static void Main(string[] args)
{
Console.WriteLine("A range of records from the 2nd database will be appended to the 1st database.");
Console.WriteLine("Enter the 1st (target) database name:");
Console.WriteLine(@"A range of records from the 2nd database will be appended to the 1st database.");
Console.WriteLine(@"Enter the 1st (target) database name:");
string firstDB = Console.ReadLine();
Console.WriteLine("Enter the 2nd database name:");
Console.WriteLine(@"Enter the 2nd database name:");
string secondDB = Console.ReadLine();
Console.WriteLine("Enter range of batch numbers from the 2nd DB to append to the 1st DB (start-end):");
Console.WriteLine(@"Enter range of batch numbers from the 2nd DB to append to the 1st DB (start-end):");
string range = Console.ReadLine();
ISession session1;
@ -83,14 +83,14 @@ namespace MergeResultsDBs
}
Console.WriteLine(string.Format("Appending batches {0}-{1} from DB {2} to DB {3}", batchNrStart, batchNrEnd, secondDB, firstDB));
Console.WriteLine("Press 'y' or 'Y' to start, anything else to abort");
Console.WriteLine(@"Press 'y' or 'Y' to start, anything else to abort");
string response = Console.ReadLine();
if (response != "y" && response != "Y")
{
return;
}
Console.WriteLine("PROCESSING DATABASES ...");
Console.WriteLine(@"PROCESSING DATABASES ...");
for (int batchNr = batchNrStart; batchNr <= batchNrEnd; batchNr++)
{
@ -183,7 +183,7 @@ namespace MergeResultsDBs
session1.Flush();
session1.Close();
session2.Close();
Console.WriteLine("Successfully completed");
Console.WriteLine(@"Successfully completed");
Console.ReadLine();
}
}

View File

@ -38,7 +38,7 @@ namespace ResetBatchNr
ls.BatchNr = 1;
ls.Save();
Console.WriteLine("BatchNr was reset to 1");
Console.WriteLine(@"BatchNr was reset to 1");
Console.ReadLine();
return;
}

View File

@ -3,23 +3,30 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AComponent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003F1c_003F3d03a130_003FComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AContainerControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003Fb3_003F54768651_003FContainerControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003F01_003F35d9c974_003FControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnum_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F96_003F1b5cc389_003FEnum_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExecutionContextSwitcher_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F78_003Fabacf9b6_003FExecutionContextSwitcher_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileDialog_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003Fe6_003F4ece5b68_003FFileDialog_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGetChildAtPointSkip_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003F63_003F931a2e4f_003FGetChildAtPointSkip_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIList_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F6e_003Fc16f1098_003FIList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AILog_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9c853b67fc2341bf8af0d999ea188b6a42000_003Ff4_003F27b3d1bb_003FILog_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AImage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1af41839925b4409b823837d7b5f29d691940_003Fcc_003Fba3dfabe_003FImage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonConvert_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F43b5ed322493bdcdb2e73ba6f9808f93c7c41fdf_003FJsonConvert_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F92_003Fe3eb9ff2_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANetworkStream_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003F78_003Fdc4af641_003FNetworkStream_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARotateFlipType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1af41839925b4409b823837d7b5f29d691940_003F3b_003Ff7d64930_003FRotateFlipType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStreamReader_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003Fb8_003Fd3bcd2f1_003FStreamReader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStreamWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F2e_003F8ad77ef0_003FStreamWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStringWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3020f90f960f433086d545c4e07afdfd531820_003F00_003F5212e7ed_003FStringWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATaskFactory_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003Fe5_003Fa31e7ef9_003FTaskFactory_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F9a_003F1a93d99e_003FTask_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9c2967a135e648bdb993c5397a44991b573620_003Fa3_003F820cf97f_003FTask_00601_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATcpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003Fdb_003Fe9bb8972_003FTcpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATestMethodInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4472e9d6a19b4c92bcc9a80bd60ca17d26da8_003F98_003F3ffb6d31_003FTestMethodInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThread_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F06_003Fbeac08f5_003FThread_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003F67_003F5737ad8a_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUdpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc0c221501f3a41f8ac0af9d6a9dc9ff335fd90_003Fdb_003Fe89b26d3_003FUdpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUserControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F32c22f7c1b7049ccad5f07031bb43bf35b8590_003Fc3_003F7d8608ff_003FUserControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AXmlReflectionImporter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9e4992465ee24dc8915fd9be20badb7d281d48_003F14_003Ffe12756e_003FXmlReflectionImporter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A_005F_005FError_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4290c01eea7748b3aa477ca831e6a387531830_003Ffa_003Fa44fa010_003F_005F_005FError_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:Boolean x:Key="/Default/Environment/UnitTesting/CreateUnitTestDialog/ShowAdvancedOptions/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/UnitTesting/CreateUnitTestDialog/TestProjectMapping/=743DF7DB_002DC7B6_002D42EB_002D986D_002D0F485E5588E4/@EntryIndexedValue">77EB589F-C670-4489-AAD6-2A3C02061FD1</s:String>

View File

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

View File

@ -480,7 +480,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
}
else
{
Console.WriteLine("The selected item is not a number.");
Console.WriteLine(@"The selected item is not a number.");
}
}
}

View File

@ -302,11 +302,27 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
if (nrLines == 1)
{
Width = 1040;
startLabel2.Visible = false;
endLabel2.Visible = false;
}
else
{
Width = 1420;
}
OkButtonPosition();
}
void OkButtonPosition()
{
if (okButton.Location.X > Width)
{
int margin = 5;
okButton.Location = new Point(
this.ClientSize.Width - okButton.Width - margin,
okButton.Location.Y
);
}
}
/// <summary>

View File

@ -10,6 +10,7 @@ using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
@ -19,9 +20,13 @@ using log4net;
using Renci.SshNet;
using Common;
using FluentNHibernate.Conventions;
using Newtonsoft.Json;
using TBF.Rig.Network.Telnet;
using TBF.Resources;
using TBF.Rig.Generic;
using TBF.Rig.Network.Camera.CJMS11.POJO;
using TBF.Rig.Network.Camera.common;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11;
using TBF.UiBridge;
namespace TBF.Rig.Network.Camera.CJMS11
@ -57,6 +62,16 @@ namespace TBF.Rig.Network.Camera.CJMS11
public readonly CameraCfg CameraCfg;
public readonly AdapterJMS.Netadapter NetAdapter;
private RoiCfg roiConfiguration;
public RoiCfg RoiConfiguration
{
get {
if (roiConfiguration!=null) {return roiConfiguration;}
else { roiConfiguration = GetFirstRoiChild(); return roiConfiguration; }
}
set { if (roiConfiguration == null) roiConfiguration = value;}
}
public IPAddress IPAddress { get { return ipAddress; } }
IPAddress ipAddress;
@ -113,24 +128,29 @@ namespace TBF.Rig.Network.Camera.CJMS11
///
/// MJpeg RTP protocol support
///
public bool CameraConnected{ get {return cameraTcpClient != null && cameraTcpClient.Connected;} }
int cameraTcpLocalPort;
TcpClient cameraTcpClient;
private NetworkStream cameraStream = null;
private StreamWriter cameraWriter = null;
private StreamReader cameraReader = null;
private Image lastImage;
private bool lockCameraInitialisation = false;
Thread liveStreamListenerThread;
static bool stopLiveStreamListenerFlag;
public bool IsGrabImageListenerThreadAlive { get { return grabImageListenerThread != null && grabImageListenerThread.IsAlive; } }
Thread grabImageListenerThread;
static bool stopGrabImageListenerFlag;
public void SetStopGrabImageListenerFlag() { stopGrabImageListenerFlag = true; }
Thread stopUIListenerThread;
static bool stopUIListenerFlag;
Thread saveImageListenerThread;
static bool stopSaveImageListenerFlag;
public bool IsSaveImageListenerThreadAlive { get { return saveImageListenerThread != null && saveImageListenerThread.IsAlive; } }
///
/// ROI related parameters
@ -162,7 +182,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
// NetAdapter = TbfComponents.FindComponent(cfg.ParentName, components) as TBF.Rig.Network.AdapterJMS.Netadapter;
//if (NetAdapter == null) throw new ArgumentNullException("no network adapter");
}
}
public override void Initialize()
@ -216,7 +236,11 @@ namespace TBF.Rig.Network.Camera.CJMS11
UiBridge.Bridge.OnCameraInfo(cameraIdx, string.Format("{0} ver.{1} {2} s/n {3}", Name, sdCardVer, ipAddress, CameraCfg.HardwareAddress));
// start live stream, grab image, ... listener thread
UiBridge.Bridge.CameraUICmdHandler += HandleCameraUICmd;
UiBridge.Bridge.CameraUICmdHandler += HandleCameraUiCmd;
//PromptCameraReceivedHandler += OnPromptReceivedCamera;
ImageCameraHandler += OnPromptImageReceived;
}
else
{
@ -225,6 +249,17 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
}
private void OnPromptImageReceived(object sender, PromptReceivedImageEventArgs e)
{
if (e != null && e.image != null)
{
if (this.cameraIdx == e.idxCamera)
{
UiBridge.Bridge.OnImage(e.idxCamera, e.image);
}
}
}
public void StopDevice()
{
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
@ -277,7 +312,42 @@ namespace TBF.Rig.Network.Camera.CJMS11
jmsMessage = a.Message;
}
}
void OnReceivedImageX(object sndr, PromptReceivedImageEventArgs a)
{
if (a != null)
{
lastImage = a.image;
}
}
void OnPromptReceivedCamera(object sndr, PromptReceivedJMSEventArgs a)
{
try
{
JmsPacket packet = new JmsPacket(a.Response);
jmsMessage = packet.JmsMessage;
}catch(Exception exc)
{
log.Error(exc.Message);
}
}
void OnReceivedPackage(object sndr, PromptReceivedEventArgs a)
{
if (sha1sumResponse == null)
{
sha1sumResponse = a.Response;
try
{
JmsPacket packet = new JmsPacket(a.Response);
jmsMessage = packet.JmsMessage;
}catch(Exception exc)
{
log.Error(exc.Message);
}
}
}
#region Configuration Change Handling
@ -330,7 +400,6 @@ namespace TBF.Rig.Network.Camera.CJMS11
async Task<CameraDetectionResult> DetectJMSCamera(string ipAddressParam, int portParam)
{
CameraDetectionResult result = new CameraDetectionResult();
string command_CFG = "get_cfg";
if (CameraCfg.IPAddressCJMS != null)
{
try
@ -361,53 +430,49 @@ namespace TBF.Rig.Network.Camera.CJMS11
// Send command
DateTime detectionStart = DateTime.Now;
writer.WriteLineAsync(command_CFG).Wait();
Console.WriteLine("Command sent.");
string responseAnswer = "";
try
// create config and send
string message = getConfigMessage();
JmsPacket answer = SendCommandAndWaitToAnswer(writer, reader, CommandM.type_camera_,message);
if (answer == null || answer.JmsMessage.Status != MessageStatus.ACK)
{
int iReads = 0;
while (true)
log.Error(answer);
}
//Prepare camera
JmsPacket answerPrepare = SendCommandAndWaitToAnswer(writer, reader, CommandM.prepare_camera_);
if (answerPrepare == null || answerPrepare.JmsMessage.Status != MessageStatus.ACK)
{
if (!(answerPrepare != null && answerPrepare.JmsMessage.Status == MessageStatus.NACK &&
answerPrepare.JmsMessage.Payload == "OPENED")) //correct if NACK & OPENED
{
//get config
var readLineAsync = reader.ReadLineAsync();
var timeoutTaskRead = Task.Delay(TimeSpan.FromSeconds(1));
var waitAny = Task.WhenAny(readLineAsync, timeoutTaskRead).Result;
if (waitAny == timeoutTaskRead)
log.Error(answerPrepare);
}
else
{
SendCommandAndWaitToAnswer(writer, reader, CommandM.close_);
var sendCommandAndWaitToAnswer = SendCommandAndWaitToAnswer(writer, reader, CommandM.prepare_camera_);
if (sendCommandAndWaitToAnswer == null || sendCommandAndWaitToAnswer.JmsMessage.Status == MessageStatus.NACK) //correct if NACK & OPENED
{
log.Debug("Activation timeout.");
throw new TimeoutException("Activation timeout. No received response for command_CFG");
log.Error("Restart close, prepare camera not successfully! see: " + answerPrepare);
}
log.Debug(string.Format("received from camera: {0}", responseAnswer));
responseAnswer = readLineAsync.Result;
if (responseAnswer.Contains(command_CFG))
{
result.IpAddress = IPAddress.Parse(ipAddressParam);
break;
}
if (iReads > 5)
{
log.Error($"Maximum Count of unexcepted answers excited!");
break;
}
iReads++;
}
}
catch (IOException ioEx)
//Status
JmsPacket answerStatus = SendCommandAndWaitToAnswer(writer, reader, CommandM.status_);
if (answerStatus == null || answerStatus.JmsMessage.Status != MessageStatus.ACK)
{
log.Error($"Timeout or IO error while reading from camera: {ioEx.Message}");
log.Error(answerStatus);
}
catch (Exception e)
//Get config
JmsPacket answerCfg = SendCommandAndWaitToAnswer(writer, reader, CommandM.get_cfg_);
if (answerCfg == null || answerCfg.JmsMessage.Status != MessageStatus.ACK)
{
log.Error(string.Format("Error while reading from camera: {0}", e.Message));
log.Error(answerCfg);
}else{
result.IpAddress = IPAddress.Parse(ipAddressParam);
}
result.Duration_ms = (DateTime.Now - detectionStart).TotalMilliseconds;
result.Hardware = string.Empty;
@ -420,7 +485,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
result.Duration_ms,
CameraCfg.HardwareAddress,
this.ipAddress == null ? "not detected" : this.ipAddress.ToString(),
responseAnswer);
answerCfg.MessageOrigin);
log.Debug(msg);
Console.WriteLine(msg);
@ -461,6 +526,70 @@ namespace TBF.Rig.Network.Camera.CJMS11
return result; /// No camera detected
}
class SensorConfig{
public string type { get; set; } = "all";
public int width { get; set; } = 640;
public int height { get; set; } = 480;
public int fps { get; set; } = 10;
public int exposure { get; set; } = 2000;
public float brightness { get; set; } = 0.5f;
public float contrast { get; set; } = 1.5f;
public int nBuffersOverload { get; set; } = 5;
public static string getJsonString(SensorConfig sensorConfig)
{
string returnStr = JsonConvert.SerializeObject(sensorConfig, Formatting.Indented);
returnStr = returnStr.Replace("\n", "");
returnStr = returnStr.Replace("\r", "");
return returnStr;
}
}
private RoiCfg GetFirstRoiChild()
{
/// Load the list of components from the database
var session = TBF.DB.CreateSession(DBKind.Config);
var cmptnEntities = session.QueryOver<Config.Entities.Component>().OrderBy(x => x.ItemNr).Asc.List();
List<RoiCfg> cfgs = new List<RoiCfg>();
IList<IComponent> components = new List<Rig.Generic.IComponent>();
foreach (var component in cmptnEntities)
{
if (String.Compare(component.Parent, Name, StringComparison.Ordinal) == 0)
{
IComponentFactory cmpntFactory = Rig.TbfComponents.CmpntFactoryFromClassName(component.ClassName);
if (cmpntFactory == null) continue;
IList<IComponent> tbfComponents = Rig.TbfComponents.LoadComponentsFromDB(cmptnEntities);
IComponentCfg cmpntCfgFromCmpntEntity = cmpntFactory.CmpntCfgFromCmpntEntity(component);
IComponent cmpnt = cmpntFactory.GetComponent(cmpntCfgFromCmpntEntity, components);
RoiForFixedStartCJMS11.RoiCfg roi = cmpntCfgFromCmpntEntity as RoiForFixedStartCJMS11.RoiCfg;
if (roi != null)
{
cfgs.Add(roi);
}
}
}
/// get fist found configuration
return cfgs.First();
}
private string getConfigMessage()
{
//CameraCfg
SensorConfig sensorConfig = new SensorConfig();
sensorConfig.height = RoiConfiguration.ImageFrame.Height;
sensorConfig.width = RoiConfiguration.ImageFrame.Width;
return SensorConfig.getJsonString(sensorConfig);
}
void CameraInfoRequest(UdpClient udpClient, int hardwareAddress)
{
string strToSend = string.Format("getinfo {0}", hardwareAddress);
@ -474,63 +603,68 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
/// <summary>
/// Download a file from the camera via SCP
/// </summary>
/// <param name="srcFileName"></param>
/// <returns>0 (success), -1 (busy), -2 (no session)</returns>
public int DownloadFile(string srcFileName, string dstFileName)
{
return 0;
}
/// <summary>
/// Upload a file to the camera via SCP
/// </summary>
/// <param name="srcFileName"></param>
/// <returns>0 (success), -1 (busy), -2 (no session)</returns>
public int UploadFile(string srcFileName, string dstFileName)
{
return 0;
}
private CameraUICmd lockBrich = CameraUICmd.None;
// Define the handler method
private void HandleCameraUICmd(object sender, CameraUICmdEventArgs e)
private void HandleCameraUiCmd(object sender, CameraUICmdEventArgs e)
{
// Example reaction to event
if (e.CameraUICmd == CameraUICmd.Live)
if(lockBrich != CameraUICmd.None && e.CameraUICmd != CameraUICmd.Stop)
return;
if (!(e.CameraIdx == -1 || e.CameraIdx == cameraIdx))
{
if (stopLiveStreamListenerFlag == false && liveStreamListenerThread != null && liveStreamListenerThread.IsAlive)
return;
log.Debug("Handle CameraUICmd received - Live");
stopLiveStreamListenerFlag = false;
StartLiveStreamListener(IPAddress, iPort);
return;
}
else if (e.CameraUICmd == CameraUICmd.Stop)
try
{
StopUiThreads();
log.Debug("Handle CameraUICmd received - Stop Live");
//lock
lockBrich = e.CameraUICmd;
// Example reaction to event
if (e.CameraUICmd == CameraUICmd.Live)
{
if (stopLiveStreamListenerFlag == false && liveStreamListenerThread != null &&
liveStreamListenerThread.IsAlive)
return;
log.Debug("Handle CameraUICmd received - Live");
stopLiveStreamListenerFlag = false;
stopUIListenerFlag = true;
StartLiveStreamListener(IPAddress, iPort);
}
else if (e.CameraUICmd == CameraUICmd.Stop)
{
StopUiThreads();
stopUIListenerFlag = true;
log.Debug("Handle CameraUICmd received - Stop Live");
}
else if (e.CameraUICmd == CameraUICmd.Grab)
{
log.Debug($"Handle CameraUICmd received - GrabImage - camera idx: {cameraIdx}");
stopUIListenerFlag = true;
StopUiThreads();
StartGrabImageListener();
}
else if (e.CameraUICmd == CameraUICmd.SaveImage)
{
log.Debug("Handle CameraUICmd received - SaveImage - will end Live Stream");
StopUiThreads();
StartSaveImageListener();
}
else
{
}
//Unlock - if is not in live - live will finish only by CameraUICmd.Stop
if (lockBrich != CameraUICmd.Live)
lockBrich = CameraUICmd.None;
}
else if (e.CameraUICmd == CameraUICmd.Grab)
catch (Exception exc)
{
log.Debug("Handle CameraUICmd received - GrabImage - will Stop Live");
StopUiThreads();
StartGrabImageListener(IPAddress, iPort);
}
else if (e.CameraUICmd == CameraUICmd.SaveImage)
{
log.Debug("Handle CameraUICmd received - SaveImage - will end Live Stream");
StopUiThreads();
StartSaveImageListener(IPAddress, iPort);
}
else
{
lockBrich = CameraUICmd.None; //Unlock - solve hard lock
stopUIListenerFlag = true;
}
}
void SaveImageToFile(Image imageToSave)
@ -560,32 +694,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
try
{
string filePath = dialog.FileName;
var encoder = GetEncoder(ImageFormat.Jpeg);
if (encoder == null)
throw new InvalidOperationException("JPEG encoder not found.");
string path = Path.GetDirectoryName(filePath);
if (path != null && path.IsNotEmpty())
{
Directory.CreateDirectory(path);
}
// Use empty EncoderParameters if you don't have specific settings
// Define encoder parameters (e.g., quality)
using (var encoderParams = new EncoderParameters(1))
{
encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L); // Quality: 0100
using (var clonedImage = CloneImageToBitmap(imageToSave))
{
clonedImage.Save(filePath, ImageFormat.Png); // encoder, encoderParams);
}
}
MessageBox.Show("Image saved to: " + filePath);
SaveImageToFile(imageToSave, dialog.FileName);
MessageBox.Show("Image saved to: " + dialog.FileName);
}catch(Exception exc)
{
MessageBox.Show("Error saving image: " + exc.Message);
@ -594,6 +704,43 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
}
public void SaveImageToFile(Image imageToSave, string fileNamePath)
{
if (imageToSave == null)
{
log.Error("Nothing to save in SaveImageToFile");
return; // nothing to save
}
if (fileNamePath == null || fileNamePath.IsEmpty())
{
log.Error("Path to save missing!");
return; // nothing to save
}
try
{
string filePath = fileNamePath;
string path = Path.GetDirectoryName(filePath);
if (path != null && path.IsNotEmpty())
{
Directory.CreateDirectory(path);
}
using (var clonedImage = CloneImageToBitmap(imageToSave))
{
clonedImage.Save(filePath, ImageFormat.Png); // encoder, encoderParams);
}
log.Debug("Image saved to: " + filePath);
}catch(Exception exc)
{
log.Error("Error saving image: " + exc.Message);
throw;
}
}
private static ImageCodecInfo GetEncoder(ImageFormat format)
{
return ImageCodecInfo.GetImageDecoders().FirstOrDefault(codec => codec.FormatID == format.Guid);
@ -614,8 +761,34 @@ namespace TBF.Rig.Network.Camera.CJMS11
return Image.FromStream(ms);
}
}
public void StartSaveImageToFileListener(Image imageToSave, string fileName)
{
saveImageListenerThread = new Thread(() => SaveImageToFile(imageToSave, fileName));
saveImageListenerThread.Start();
}
private void StartSaveImageListener(IPAddress localIP, int localPort)
private void StartSaveImageListener()
{
Task<Image> saveImageTask = Task.Run(() => SaveImageListener());
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(1));
var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result;
if (completedAnswerTask == timeoutAnswerTask)
{
log.Error("Connection attempt timed out after 1 second.");
return;
}
try
{
SaveImageToFile(saveImageTask.Result);
}
catch (Exception exc)
{
MessageBox.Show("Error saving image: " + exc.Message);
}
}
public void StartSaveImageListener(string filePath)
{
Task<Image> saveImageTask = Task.Run(() => SaveImageListener());
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(1));
@ -857,15 +1030,19 @@ namespace TBF.Rig.Network.Camera.CJMS11
void StopUiThreads()
{
stopLiveStreamListenerFlag = true;
stopGrabImageListenerFlag = true;
stopUIListenerFlag = true;
log.Debug("Handle CameraUICmd StopUIListener");
var taskStopUi = Task.Run(StopUiListener);
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(1));
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
var completedTask = Task.WhenAny(taskStopUi, timeoutTask).Result;
if (completedTask == timeoutTask)
{
throw new TimeoutException("Connection attempt timed out after 1 second.");
stopUIListenerFlag = true;
throw new TimeoutException("Connection attempt timed out after 5 second.");
}
CloseCameraResources();
}
@ -888,11 +1065,11 @@ namespace TBF.Rig.Network.Camera.CJMS11
stopUIListenerFlag = true;
}
}
stopLiveStreamListenerFlag = false;
stopGrabImageListenerFlag = false;
//stopLiveStreamListenerFlag = false;
//stopGrabImageListenerFlag = false;
}
private void StartGrabImageListener(IPAddress localIP, int localPort)
public void StartGrabImageListener()
{
grabImageListenerThread = new Thread(GrabImageListener);
grabImageListenerThread.Start();
@ -930,11 +1107,13 @@ namespace TBF.Rig.Network.Camera.CJMS11
stopGrabImageListenerFlag = false;
int iCountOf_NACK = 0;
SendCommand(CommandM.grab_image_);
while (!stopGrabImageListenerFlag)
{
try
{
SendCommand(CommandM.grab_image_);
Task<string> responseAnswerTask = cameraReader.ReadLineAsync();
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(1));
var completedAnswerTask = Task.WhenAny(responseAnswerTask, timeoutAnswerTask).Result;
@ -991,7 +1170,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
}
UiBridge.Bridge.OnImage(this.cameraIdx, image);
OnImageReceived(this, this.cameraIdx, image, RoiConfiguration.ImageRotation);
stopGrabImageListenerFlag =
true; // mam obrazok ukoncim a zavriem thread
}
@ -1008,8 +1187,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
stopGrabImageListenerFlag = false;
SendCommand(CommandM.close_);
SendCommand(CommandM.disconnect_);
SendCommandAndWaitToAnswer(cameraWriter, cameraReader, CommandM.close_);
SendCommandAndWaitToAnswer(cameraWriter, cameraReader, CommandM.disconnect_);
CloseCameraResources();
@ -1074,6 +1253,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
cameraStream.ReadTimeout = 1000;
SendCommand(CommandM.prepare_camera_);
SendCommand(CommandM.start_stream_images_);
stopLiveStreamListenerFlag = false;
@ -1082,7 +1262,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
try
{
SendCommand(CommandM.grab_image_);
//SendCommand(CommandM.grab_image_);
Task<string> responseAnswerTask = cameraReader.ReadLineAsync();
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(1));
var completedAnswerTask = Task.WhenAny(responseAnswerTask, timeoutAnswerTask).Result;
@ -1126,7 +1306,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
}
UiBridge.Bridge.OnImage(this.cameraIdx, image);
OnImageReceived(this, this.cameraIdx, image, RoiConfiguration.ImageRotation);
}
break;
@ -1143,8 +1324,15 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
stopLiveStreamListenerFlag = false;
SendCommand(CommandM.close_);
SendCommand(CommandM.disconnect_);
//we need to wait to answer, it works on thread loop - properly access
var sendCommandAndWaitToAnswer = SendCommandAndWaitToAnswer(cameraWriter, cameraReader, CommandM.prepare_camera_);
if (sendCommandAndWaitToAnswer == null || sendCommandAndWaitToAnswer.JmsMessage.Status == MessageStatus.NACK) //correct if NACK & OPENED
{
log.Error("Stop streaming not successfully! see: " + sendCommandAndWaitToAnswer.JmsMessage.Payload);
}
//SendCommand(CommandM.close_);
//SendCommand(CommandM.disconnect_);
CloseCameraResources();
}
@ -1211,36 +1399,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
bool measurementCommandSent;
public void Start()
{
///Prepare communication with the camera
// if (cameraStream != null && cameraReader != null && cameraStream.CanWrite)
// {
//
// JmsPacket answer = SendCommandAndWaitToAnswer(CommandM.prepare_camera_);
//
// int incorrectAnswerCount = 0;
// bool answerCorrect = false;
// while (!answerCorrect || incorrectAnswerCount < 3)
// {
// if (answer.JmsMessage.Command == CommandM.prepare_camera_)
// {
// answerCorrect = true;
// if (answer.JmsMessage.Status == MessageStatus.ACK)
// {
// log.Debug("Camera is ready to receive data");
// continue;
// }
// else
// {
// log.Error("NOCK answer - prepare_camera");
// }
// }
//
// incorrectAnswerCount++;
// }
//}
}
private void SendCommand(CommandM command)
{
@ -1248,7 +1407,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
{
if (cameraWriter != null && cameraReader != null && cameraStream!=null && cameraStream.CanWrite)
{
cameraWriter.WriteAsync(CommandMEnum.GetVal(command));
cameraWriter.WriteLineAsync(CommandMEnum.GetVal(command)).Wait();
cameraWriter.FlushAsync();
}
}catch(Exception exc)
@ -1259,35 +1418,97 @@ namespace TBF.Rig.Network.Camera.CJMS11
//
private JmsPacket SendCommandAndWaitToAnswer(CommandM command)
private JmsPacket SendCommandAndWaitToAnswer(StreamWriter writer, StreamReader reader, CommandM command, string payload = null)
{
// Send command
String command_str = CommandMEnum.GetVal(command);
if (payload != null && payload.Length > 0)
{
command_str += "=" + payload;
}
command_str = command_str + " ";
writer.WriteLineAsync(command_str).Wait();
Console.WriteLine($@"Command '{command_str}' sent.");
JmsPacket result;
string responseAnswer = "";
try
{
if (cameraStream != null && cameraReader != null && cameraStream.CanWrite)
int iReads = 0;
while (true)
{
//get config
var readLineAsync = reader.ReadLineAsync();
var timeoutTaskRead = Task.Delay(TimeSpan.FromSeconds(1));
var waitAny = Task.WhenAny(readLineAsync, timeoutTaskRead).Result;
if (waitAny == timeoutTaskRead)
{
log.Debug("Activation timeout.");
throw new TimeoutException("Activation timeout. No received response for command_CFG");
}
log.Debug(string.Format("received from camera: {0}", responseAnswer));
responseAnswer = readLineAsync.Result;
byte[] buffer = Encoding.ASCII.GetBytes(" " + CommandMEnum.GetVal(command)+"\r\n");
cameraStream.Write(buffer, 0, buffer.Length);
//cameraStream.Flush();
try
{
result = new JmsPacket(responseAnswer);
}
catch (Exception exc)
{
iReads++;
continue;
}
string readLine = cameraReader.ReadLine();
JmsPacket newPacket = new JmsPacket(readLine);
return newPacket;
if (result.JmsMessage.Command == command)
{
return result;
}
if (iReads > 5)
{
log.Error($"Maximum Count of unexcepted answers excited!");
break;
}
iReads++;
}
}catch(Exception exc)
}
catch (IOException ioEx)
{
log.ErrorFormat("{0} SendCommand: {1}", Name, exc.Message);
log.Error($"Timeout or IO error while reading from camera: {ioEx.Message}");
}
catch (Exception e)
{
log.Error(string.Format("Error while reading from camera: {0}", e.Message));
}
return null;
}
public void Start()
{
///Prepare communication with the camera
log.DebugFormat("Camera Start() - JMCameras.CameraCfg.IPAddressCJMS: {0}, CameraCfg.Port: {1}! ");
StopUiListener();
this.cameraTcpClient = new TcpClient();
lockCameraInitialisation = true;
try
{
EstablishCameraConnection(ref this.cameraTcpClient, CameraCfg.IPAddressCJMS, iPort);
}catch(Exception exc)
{
log.ErrorFormat("Camera Start() - JMCameras.CameraCfg.IPAddressCJMS: {0}, CameraCfg.Port: {1}! Exception: {2}", CameraCfg.IPAddressCJMS, iPort, exc.Message);
return;
}
}
public Event Run()
{
while (true)
{
}
return Event.None;
}
@ -1304,5 +1525,71 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
}
}
///
/// PromptReceviedEventHandler delegate and handler
///
public delegate void PromptCameraReceivedEventHandler(object sender, PromptReceivedJMSEventArgs e);
public static event PromptCameraReceivedEventHandler PromptCameraReceivedHandler;
/// <summary>
/// This method is called from within this class when
/// a prompt string was received from the telnet server.
/// </summary>
public static void OnPromptReceived(object sender, string response, JmsPacket package)
{
log.Info("Prompt received, response:" + Environment.NewLine + response);
if (null != PromptCameraReceivedHandler)
{
try
{
PromptCameraReceivedHandler(sender, new PromptReceivedJMSEventArgs(response, package.JmsMessage));
}
catch (Exception e)
{
log.Info("Internal error: PromptReceivedHandler exception: " + e.Message);
}
}
}
///
/// PromptReceviedEventHandler delegate and handler
///
public delegate void PromptImageReceivedEventHandler(object sender, PromptReceivedImageEventArgs e);
public static event EventHandler<PromptReceivedImageEventArgs> ImageCameraHandler;
/// <summary>
/// This method is called from within this class when
/// a prompt string was received from the telnet server.
/// </summary>
public static void OnImageReceived(object sender, int idxImage, Image image, ImageRotation imageRotation)
{
log.Info("Image received");
if (null != ImageCameraHandler)
{
try
{
//rotation
ImageUtils.Rotate(image, imageRotation);
//Send image to bridge
ImageCameraHandler(sender, new PromptReceivedImageEventArgs(idxImage, image));
}
catch (Exception ex)
{
log.Info("Internal error: PromptReceivedHandler exception: " + ex.Message);
}
}
}
}
}

View File

@ -3,11 +3,14 @@
///
using System;
using System.Diagnostics;
using System.Drawing;
using log4net;
using Common;
using Config.Entities;
using TBF.Rig.Network.Telnet;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TBF.Rig.Network.Camera.CJMS11
{
@ -19,7 +22,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
public override string ToString() { return string.Format("GrabImageOp()"); }
readonly Camera camera;
readonly Telnet.TelnetClient telnet;
readonly string[] imgFileNames;
readonly bool blackAndWhite;
readonly bool lowResolution;
@ -31,6 +34,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
bool grabPassed;
bool grabFailed;
bool transferringGrabbedImage;
Image grabedImage;
/// <summary>
@ -53,17 +58,22 @@ namespace TBF.Rig.Network.Camera.CJMS11
if (camera.DebugLevel == DebugMode.Normal || camera.DebugLevel == DebugMode.DetectedOn)
{
telnet.promptReceivedHandler += delegate(object sndr, PromptReceivedEventArgs a)
{
OnPromptReceived(sndr, a);
};
Camera.ImageCameraHandler += ImageReceived;
}
//TODO BUMI improve by simulate image
Camera.ImageCameraHandler += ImageReceived;
}
void OnPromptReceived(object sndr, PromptReceivedEventArgs a)
void PromptReceived(object sndr, PromptReceivedJMSEventArgs a)
{
response = a.Response;
/// TODO
}
void ImageReceived(object sndr, PromptReceivedImageEventArgs a)
{
if(a.idxCamera != camera.CameraIdx) return;
grabedImage = a.image;
grabPassed = true;
}
@ -71,6 +81,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
{
grabImageCommandSent = false;
transferringGrabbedImage = false;
grabPassed = false;
grabedImage = null;
if ((imgFileNames != null) && (imgFileNames.Length > 0) && File.Exists(imgFileNames[0]))
{
@ -79,13 +91,13 @@ namespace TBF.Rig.Network.Camera.CJMS11
///
File.Delete(imgFileNames[0]);
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate || camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
/* if (camera.CameraCfg.DebugLevel == DebugMode.Simulate || camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
{
///
/// Camera is in simulation mode => create a simulated image
///
File.Copy(string.Format("{0}\\Pictures\\sample.jpg", Program.ExecutableDir), imgFileNames[0]);
}
}*/
}
}
@ -98,127 +110,69 @@ namespace TBF.Rig.Network.Camera.CJMS11
///
return Event.GrabPassed;
}
else if (camera.CameraCfg.DebugLevel == DebugMode.Simulate ||
/*else if (camera.CameraCfg.DebugLevel == DebugMode.Simulate ||
camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
{
///
/// Camera is in simulation mode => create a simulated image and complete
///
return Event.GrabPassed;
}*/
else if (camera.IsGrabImageListenerThreadAlive)
{
return Event.CameraBusy;
}
else if (!grabImageCommandSent)
{
///
/// Normal operation, no command sent yet => (1) wait until telnet state = Inactive, (2) send a command
///
if (camera.Running && (telnet.State == TelnetClient.TelnetState.Inactive))
{
///
/// State variables
///
response = null;
///
/// Prepare a command
///
int rotation = 0;
if (imageRotation == ImageRotation.Deg90)
rotation = 90;
else if (imageRotation == ImageRotation.Deg180)
rotation = 180;
else if (imageRotation == ImageRotation.Deg270)
rotation = 270;
command = string.Format("clp/GrabImage {0} {1} -r {2} {3} -n 1 {4}",
blackAndWhite ? "-bmp" : "-bmp", /// 0 ... file format and quality
blackAndWhite ? "-y8" : "-rgb", /// 1 ... B&W / color
rotation.ToString(), /// 2 ... roration
lowResolution ? "-lr" : "-hr", /// 4 ... resolution
"grabbed.bmp"); /// 5 ... filename
//
// Send (or enqueue) command
//
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.CLEAR_RESPONSE));
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, command));
grabImageCommandSent = true;
log.WarnFormat("{0} IP={1} command={2}", camera.Name, camera.IPAddress, command);
}
camera.StartGrabImageListener();
grabImageCommandSent = true;
return Event.CameraBusy;
}
else if (grabPassed)
{
///
/// Normal operation, grab passed => transfer/transferring the image
///
if (transferringGrabbedImage)
{
/// Grab passed and image transfer is in progress
return Event.GrabPassed;
}
else if (0 == camera.DownloadFile(blackAndWhite ? "grabbed.jpg" : "grabbed.bmp", imgFileNames[0]))
else if (camera.IsSaveImageListenerThreadAlive)
{
/// Wait until the previous image transfer completes
return Event.CameraBusy;
}
else //if (0 == camera.DownloadFile(blackAndWhite ? "grabbed.jpg" : "grabbed.bmp", imgFileNames[0]))
{
camera.StartSaveImageToFileListener(grabedImage, imgFileNames[0]);
/// File transfer successfully started
transferringGrabbedImage = true;
return Event.GrabPassed;
}
else
{
/// Wait until the previous image transfer completes
return Event.CameraBusy;
}
}
else if (grabFailed)
else
{
///
/// Normal operation, grab failed => there in no image to transfer
///
return Event.GrabFailed;
}
else if (response != null)
{
///
/// Normal operation
///
if (response.Contains("completed"))
{
grabPassed = true;
///
/// Start the file transfer
///
if (0 == camera.DownloadFile(blackAndWhite ? "grabbed.jpg" : "grabbed.bmp", imgFileNames[0]))
{
/// File transfer successfully started
transferringGrabbedImage = true;
return Event.GrabPassed;
}
else
{
return Event.CameraBusy; /// File transfer not started yet
}
}
else
{
grabFailed = true;
return Event.GrabFailed;
}
}
else
{
return Event.CameraBusy;
}
}
public void Stop()
{
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate) return;
//if (camera.CameraCfg.DebugLevel == DebugMode.Simulate) return;
if (grabImageCommandSent)
if (camera.IsGrabImageListenerThreadAlive)
{
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, Telnet.TelnetClient.CtrlCCommand));
log.WarnFormat("{0} IP={1} command=CTRL-C", camera.Name, camera.IPAddress);
}
camera.SetStopGrabImageListenerFlag();
}
}
}
}

View File

@ -57,5 +57,16 @@ namespace TBF.Rig.Network.Camera.CJMS11
}
return null;
}
public override string ToString()
{
return string.Format( "status:{0}, command:{1}, payload:{2}, orig_status:{3}, orig_command:{4}, orig_payload:{5}",
status,
command,
payload,
orig_status,
orig_command,
orig_payload);
}
}
}

View File

@ -10,6 +10,9 @@ namespace TBF.Rig.Network.Camera.CJMS11
private static readonly ILog log = LogManager.GetLogger(typeof(JmsPacket));
private JmsMessage jmsMessage;
private string messageOrigin;
public string MessageOrigin { get => messageOrigin; }
public JmsMessage JmsMessage
{
@ -19,11 +22,11 @@ namespace TBF.Rig.Network.Camera.CJMS11
public JmsPacket(string message)
{
string received_message = message;
messageOrigin = message;
try
{
if (ParseMessage(received_message))
if (ParseMessage(messageOrigin))
{
//success
}
@ -85,6 +88,11 @@ namespace TBF.Rig.Network.Camera.CJMS11
throw new ArgumentException($"Payload does not match expected image format: {payloadImage}");
}
}
public override string ToString()
{
return string.Format("JmsPacket -> original message: {0} -> JmsMessage: {1}", messageOrigin, jmsMessage.ToString());
}
}
}

View File

@ -12,6 +12,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
send_,
start_stream_,
stop_stream_,
start_stream_images_,
stop_stream_images_,
get_cfg_,
set_cfg_,
close_,

View File

@ -17,6 +17,8 @@ namespace TBF.Rig.Network.Camera.CJMS11
{ CommandM.send_, "send" },
{ CommandM.start_stream_, "start_stream" },
{ CommandM.stop_stream_, "stop_stream" },
{ CommandM.start_stream_images_, "start_stream_images" },
{ CommandM.stop_stream_images_, "stop_stream_images" },
{ CommandM.get_cfg_, "get_cfg" },
{ CommandM.set_cfg_, "set_cfg" },
{ CommandM.close_, "close" },

View File

@ -23,7 +23,7 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
///
/// Camera and ICamera
///
public readonly CLP1611.Camera NetCamera;
public readonly CJMS11.Camera NetCamera;
public GenericDevices.ICamera Camera { get { return NetCamera as GenericDevices.ICamera; } }
public int Position
@ -67,7 +67,7 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
: base(cfg)
{
roiCfg = cfg as RoiCfg;
NetCamera = TbfComponents.FindComponent(cfg.ParentName, components) as CLP1611.Camera;
NetCamera = TbfComponents.FindComponent(cfg.ParentName, components) as CJMS11.Camera;
log.Warn(this.ToString());
}
@ -124,6 +124,11 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
{
if (NetCamera != null)
{
///TODO BUMI - implementing grabing multiple images
/// 1. Create a list of image file names
/// 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);
}

View File

@ -6,6 +6,7 @@ using System.Xml.Serialization;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.common;
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
{
@ -22,6 +23,26 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
public bool BlackAndWhite;
public bool LowResolution;
public ImageRotation ImageRotation;
[XmlIgnore]
private Frame _imageFrame;
[XmlElement(IsNullable = true)]
public Frame ImageFrame
{
get
{
if (_imageFrame == null)
{
_imageFrame = new Frame(); // Ensure non-null when accessed
}
return _imageFrame;
}
set
{
_imageFrame = value;
}
}
/// <summary> Procedure parameters </summary>
[XmlIgnore]
@ -44,13 +65,14 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
BlackAndWhite = false;
LowResolution = true;
ImageRotation = ImageRotation.None;
ImageFrame = Frame.StandardFrame();
DebugLevel = DebugMode.Inherit;
}
public string ToString(int i)
{
return string.Format("{0} Camera={1} B&W={2}, LowRes={3}, Rotation={4}",
Name, ParentName, BlackAndWhite, LowResolution, ImageRotation);
return string.Format("{0} Camera={1} B&W={2}, LowRes={3}, Rotation={4}, Frame={5}",
Name, ParentName, BlackAndWhite, LowResolution, ImageRotation, ImageFrame);
}
}
}

View File

@ -8,6 +8,7 @@ using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Resources;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.common;
using TBF.UI.Bench.Components;
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
@ -18,6 +19,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
ComponentParametersDlg parent;
public bool ShowMore { get { return false; } }
RoiCfg config;
@ -45,13 +48,20 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
{
foreach (var cmpnt in parent.CmpntEntities)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.CLP1611.Factory)
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.CJMS11.Factory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
foreach (var resolutionFrame in ResolutionFrames.CommonResolutions)
{
resolutionComboBox.Items.Add(resolutionFrame.ToString());
}
for (ImageRotation ir = 0; ir < ImageRotation.Count; ir++)
{
imageRotationComboBox.Items.Add(ir.ToDescription());
@ -74,6 +84,7 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
blackAndWhiteCheckBox.Checked = config.BlackAndWhite;
loResolutionCheckBox.Checked = config.LowResolution;
imageRotationComboBox.Text = config.ImageRotation.ToDescription();
resolutionComboBox.Text = config.ImageFrame.ToString();
}
public void Unlock()
@ -83,6 +94,7 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
blackAndWhiteCheckBox.Enabled = true;
loResolutionCheckBox.Enabled = true;
imageRotationComboBox.Enabled = true;
resolutionComboBox.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
@ -101,6 +113,12 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
message += Environment.NewLine + string.Format(Strings.Invalid_0, imageRotationLabel.Text);
}
if (!resolutionComboBox.Items.Contains(resolutionComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, resolutionComboBox.Text);
}
return flags;
}
@ -147,6 +165,12 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
}
}
}
if (resolutionComboBox.Text != config.ImageFrame.ToString())
{
config.ImageFrame = Frame.Parse(resolutionComboBox.Text);
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.InvokeCfgChange);
}
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
{
@ -171,5 +195,6 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
public void StopResponseHandler() { }
#endregion Configuration Change Handling
}
}
}

View File

@ -25,8 +25,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
@ -42,40 +42,46 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
this.imageRotationLabel = new System.Windows.Forms.Label();
this.blackAndWhiteCheckBox = new System.Windows.Forms.CheckBox();
this.loResolutionCheckBox = new System.Windows.Forms.CheckBox();
this.label2 = new System.Windows.Forms.Label();
this.resolutionComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(20, 77);
this.parentNameLabel.Location = new System.Drawing.Point(30, 118);
this.parentNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(43, 13);
this.parentNameLabel.Size = new System.Drawing.Size(65, 20);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Camera";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(139, 49);
this.nameTextBox.Location = new System.Drawing.Point(208, 75);
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(174, 20);
this.nameTextBox.Size = new System.Drawing.Size(259, 26);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(20, 52);
this.nameLabel.Location = new System.Drawing.Point(30, 80);
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.Size = new System.Drawing.Size(51, 20);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(136, 26);
this.classNameLabel.Location = new System.Drawing.Point(204, 40);
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(114, 13);
this.classNameLabel.Size = new System.Drawing.Size(173, 20);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComponentClassName";
//
@ -83,43 +89,48 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(139, 74);
this.parentNameComboBox.Location = new System.Drawing.Point(208, 114);
this.parentNameComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(174, 21);
this.parentNameComboBox.Size = new System.Drawing.Size(259, 28);
this.parentNameComboBox.TabIndex = 4;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(-211, -147);
this.label1.Location = new System.Drawing.Point(-316, -226);
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(57, 13);
this.label1.Size = new System.Drawing.Size(87, 20);
this.label1.TabIndex = 5;
this.label1.Text = "Arguments";
//
// textBox1
//
this.textBox1.Enabled = false;
this.textBox1.Location = new System.Drawing.Point(-125, -150);
this.textBox1.Location = new System.Drawing.Point(-188, -231);
this.textBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(372, 20);
this.textBox1.Size = new System.Drawing.Size(556, 26);
this.textBox1.TabIndex = 6;
//
// imageRotationComboBox
//
this.imageRotationComboBox.Enabled = false;
this.imageRotationComboBox.FormattingEnabled = true;
this.imageRotationComboBox.Location = new System.Drawing.Point(139, 154);
this.imageRotationComboBox.Location = new System.Drawing.Point(208, 237);
this.imageRotationComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.imageRotationComboBox.Name = "imageRotationComboBox";
this.imageRotationComboBox.Size = new System.Drawing.Size(93, 21);
this.imageRotationComboBox.Size = new System.Drawing.Size(138, 28);
this.imageRotationComboBox.TabIndex = 8;
//
// imageRotationLabel
//
this.imageRotationLabel.AutoSize = true;
this.imageRotationLabel.Location = new System.Drawing.Point(20, 157);
this.imageRotationLabel.Location = new System.Drawing.Point(30, 242);
this.imageRotationLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.imageRotationLabel.Name = "imageRotationLabel";
this.imageRotationLabel.Size = new System.Drawing.Size(103, 13);
this.imageRotationLabel.Size = new System.Drawing.Size(153, 20);
this.imageRotationLabel.TabIndex = 7;
this.imageRotationLabel.Text = "Image rotation (ccw)";
//
@ -127,9 +138,10 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
//
this.blackAndWhiteCheckBox.AutoSize = true;
this.blackAndWhiteCheckBox.Enabled = false;
this.blackAndWhiteCheckBox.Location = new System.Drawing.Point(139, 108);
this.blackAndWhiteCheckBox.Location = new System.Drawing.Point(208, 166);
this.blackAndWhiteCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.blackAndWhiteCheckBox.Name = "blackAndWhiteCheckBox";
this.blackAndWhiteCheckBox.Size = new System.Drawing.Size(93, 17);
this.blackAndWhiteCheckBox.Size = new System.Drawing.Size(134, 24);
this.blackAndWhiteCheckBox.TabIndex = 5;
this.blackAndWhiteCheckBox.Text = "Black && White";
this.blackAndWhiteCheckBox.UseVisualStyleBackColor = true;
@ -138,17 +150,38 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
//
this.loResolutionCheckBox.AutoSize = true;
this.loResolutionCheckBox.Enabled = false;
this.loResolutionCheckBox.Location = new System.Drawing.Point(139, 131);
this.loResolutionCheckBox.Location = new System.Drawing.Point(208, 202);
this.loResolutionCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.loResolutionCheckBox.Name = "loResolutionCheckBox";
this.loResolutionCheckBox.Size = new System.Drawing.Size(94, 17);
this.loResolutionCheckBox.Size = new System.Drawing.Size(137, 24);
this.loResolutionCheckBox.TabIndex = 6;
this.loResolutionCheckBox.Text = "Low resolution";
this.loResolutionCheckBox.UseVisualStyleBackColor = true;
//
// label2
//
this.label2.Location = new System.Drawing.Point(30, 293);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(152, 28);
this.label2.TabIndex = 9;
this.label2.Text = "Choose resolution:";
//
// resolutionComboBox
//
this.resolutionComboBox.DropDownWidth = 259;
this.resolutionComboBox.Enabled = false;
this.resolutionComboBox.FormattingEnabled = true;
this.resolutionComboBox.Location = new System.Drawing.Point(208, 290);
this.resolutionComboBox.Name = "resolutionComboBox";
this.resolutionComboBox.Size = new System.Drawing.Size(262, 28);
this.resolutionComboBox.TabIndex = 10;
//
// RoiCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.resolutionComboBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.imageRotationComboBox);
this.Controls.Add(this.imageRotationLabel);
this.Controls.Add(this.blackAndWhiteCheckBox);
@ -160,14 +193,18 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.Name = "RoiCfgCtrl";
this.Size = new System.Drawing.Size(500, 300);
this.Size = new System.Drawing.Size(750, 462);
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.ComboBox resolutionComboBox;
private System.Windows.Forms.Label label2;
#endregion
private System.Windows.Forms.Label parentNameLabel;

View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.common
{
public class Frame
{
public int Width { get; set; }
public int Height { get; set; }
public Frame() // standard frame
{
this.Width = 640;
this.Height = 480;
}
public Frame(int width, int height)
{
Width = width;
Height = height;
}
public static Frame StandardFrame()
{
return new Frame();
}
public override string ToString() => $"{Width}x{Height}";
// Static method to parse string like "1920x1080"
public static Frame Parse(string resolution)
{
var match = Regex.Match(resolution, @"^\s*(\d+)\s*[xX]\s*(\d+)\s*$");
if (!match.Success)
{
throw new FormatException($"Invalid resolution format: '{resolution}'");
}
int width = int.Parse(match.Groups[1].Value);
int height = int.Parse(match.Groups[2].Value);
return new Frame(width, height);
}
///
/// Finds nearest frame based on selected dimension
/// <b> example: </b>
/// <code>
/// var input = new Frame(1500, 800);
/// //Nearest by Width
/// var nearestByWidth = input.FindNearest(allFrames, f => f.Width);
/// Console.WriteLine($"Nearest by width: {nearestByWidth}"); // → 1280x720
/// //Nearest by Height
/// var nearestByHeight = input.FindNearest(allFrames, f => f.Height);
/// Console.WriteLine($"Nearest by height: {nearestByHeight}"); // → 1280x720
/// </code>
public Frame FindNearest(IEnumerable<Frame> candidates, Func<Frame, int> dimensionSelector)
{
int target = dimensionSelector(this);
return candidates
.OrderBy(f => Math.Abs(dimensionSelector(f) - target))
.ThenBy(dimensionSelector) // tie-breaker: prefer smaller
.FirstOrDefault();
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.common
{
public class ResolutionFrames : List<Frame>
{
public ResolutionFrames(IEnumerable<Frame> collection) : base(collection)
{
}
public static readonly IReadOnlyList<Frame> CommonResolutions = new List<Frame>
{
new Frame(320, 240),
new Frame(352, 288),
new Frame(640, 480), // standard frame
new Frame(720, 480),
new Frame(1280, 720),
new Frame(1920, 1080),
new Frame(2560, 1440),
new Frame(3840, 2160),
new Frame(4096, 2160)
}.AsReadOnly();
}
}

View File

@ -0,0 +1,71 @@
using System;
using System.Drawing;
using Common;
namespace TBF.Rig.Network.Camera.common
{
public class ImageUtils
{
public static void Rotate(Image image, ImageRotation direction)
{
if(!(direction == ImageRotation.Deg90 || direction == ImageRotation.Deg180 || direction == ImageRotation.Deg270))
return;
if (image == null)
throw new ArgumentNullException(nameof(image));
RotateFlipType flipType =
direction == ImageRotation.Deg90 ? RotateFlipType.Rotate90FlipNone :
direction == ImageRotation.Deg180 ? RotateFlipType.Rotate180FlipNone :
direction == ImageRotation.Deg270 ? RotateFlipType.Rotate270FlipNone :
RotateFlipType.RotateNoneFlipNone;
image.RotateFlip(flipType);
}
public static Image RotateCustom(Image image, ImageRotation direction)
{
if (image == null)
throw new ArgumentNullException(nameof(image));
int newWidth = image.Width;
int newHeight = image.Height;
RotateFlipType flipType;
switch (direction)
{
case ImageRotation.Deg90:
flipType = RotateFlipType.Rotate90FlipNone;
newWidth = image.Height;
newHeight = image.Width;
break;
case ImageRotation.Deg180:
flipType = RotateFlipType.Rotate180FlipNone;
break;
case ImageRotation.Deg270:
flipType = RotateFlipType.Rotate270FlipNone;
newWidth = image.Height;
newHeight = image.Width;
break;
default:
throw new ArgumentException("Unsupported rotation direction");
}
Bitmap rotated = new Bitmap(newWidth, newHeight);
using (Graphics g = Graphics.FromImage(rotated))
{
g.TranslateTransform(newWidth / 2f, newHeight / 2f);
g.RotateTransform(
direction == ImageRotation.Deg90 ? 90 :
direction == ImageRotation.Deg180 ? 180 :
direction == ImageRotation.Deg270 ? 270 :
0);
g.TranslateTransform(-image.Width / 2f, -image.Height / 2f);
g.DrawImage(image, new PointF(0, 0));
}
return rotated;
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using TBF.Rig.Network.Camera.CJMS11;
namespace TBF.Rig.Network.Telnet
@ -78,6 +79,18 @@ namespace TBF.Rig.Network.Telnet
Message = message;
}
}
public class PromptReceivedImageEventArgs : EventArgs
{
public Image image; /// server image.
public int idxCamera; /// camera index.
public PromptReceivedImageEventArgs(int idxCamera, Image image)
{
this.image = image;
this.idxCamera = idxCamera;
}
}

View File

@ -513,6 +513,8 @@ namespace TBF.Rig.TestMethods.StandingStart
(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);
if (rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi)
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).BeginWMState = dataEntryCmpnt.WMStartState(i);
}
}
@ -754,6 +756,15 @@ namespace TBF.Rig.TestMethods.StandingStart
if (rr is Rig.Network.Camera.RoiForFixedStart.Roi)
(rr as Rig.Network.Camera.RoiForFixedStart.Roi).EndWMState = dataEntryCmpnt.WMEndState(i);
if (rr is Rig.Network.Camera.RoiForFixedStartKeyence.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartKeyence.Roi).EndWMState =
dataEntryCmpnt.WMEndState(i);
log.DebugFormat(" StandingStartMassCollectionSeq.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);
}
}

View File

@ -603,6 +603,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
dataEntryCmpnt.WMStartState(i);
log.DebugFormat(" StandingStartMassCollectionSeq.cs - 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);
}
}
@ -936,6 +938,9 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
dataEntryCmpnt.WMEndState(i);
log.DebugFormat(" StandingStartMassCollectionSeq.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);
}
}

View File

@ -877,6 +877,7 @@
<Compile Include="Rig\Network\Camera\CLP1611\TerminalDlg.Designer.cs">
<DependentUpon>TerminalDlg.cs</DependentUpon>
</Compile>
<Compile Include="Rig\Network\Camera\common\ImageUtils.cs" />
<Compile Include="Rig\Network\Camera\Display\DisplayForm.cs">
<SubType>Form</SubType>
</Compile>
@ -904,6 +905,8 @@
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\Factory.cs" />
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\GrabImagesOp.cs" />
<Compile Include="Rig\Network\Camera\KeyenceIV3G120\RoisAndResults.cs" />
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\common\Frame.cs" />
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\common\ResolutionFrames.cs" />
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\Factory.cs" />
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\ProcedureParams.cs" />
<Compile Include="Rig\Network\Camera\RoiForFixedStartCJMS11\Roi.cs" />

View File

@ -1 +1 @@
b13140660214e1b48c9021e6f280ff951d16dd2027d403736b09a76cec69aa43
488d44735d3adcc07a0f148fe64d6d1ded107efd14e4fcb2d5d2378975a086a0

View File

@ -49,7 +49,7 @@ namespace ToFirstMonitor
LeftToFirstMonitor(ref ls.EnduranceDlgLeft);
ls.Save();
Console.WriteLine("All windows were shifted to the first monitor");
Console.WriteLine(@"All windows were shifted to the first monitor");
Console.ReadLine();
return;
}

View File

@ -49,7 +49,7 @@ namespace ToSecondMonitor
LeftToSecondMonitor(ref ls.EnduranceDlgLeft);
ls.Save();
Console.WriteLine("All windows were shifted to the second monitor");
Console.WriteLine(@"All windows were shifted to the second monitor");
Console.ReadLine();
return;
}