From 0daefb93bbe11afc2d306165c31a80636bd2de6a Mon Sep 17 00:00:00 2001 From: Michal Buzik Date: Fri, 18 Jul 2025 08:50:22 +0200 Subject: [PATCH] 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. --- Common/Utils.cs | 1 + Decrypt/Program.cs | 2 +- Encrypt/Program.cs | 2 +- MergeResultsDBs/Program.cs | 14 +- ResetBatchNr/Program.cs | 2 +- TBF.sln.DotSettings.user | 7 + TBF/Properties/AssemblyInfo.cs | 4 +- .../CycleBeginningForm.cs | 2 +- .../TestStartEndForm.cs | 16 + TBF/Rig/Network/Camera/CJMS11/Camera.cs | 635 +++++++++++++----- TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs | 132 ++-- TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs | 11 + TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs | 12 +- .../Network/Camera/CJMS11/POJO/CommandM.cs | 2 + .../Camera/CJMS11/POJO/CommandMEnum.cs | 2 + .../Camera/RoiForFixedStartCJMS11/Roi.cs | 9 +- .../Camera/RoiForFixedStartCJMS11/RoiCfg.cs | 26 +- .../RoiForFixedStartCJMS11/RoiCfgCtrl.cs | 29 +- .../RoiCfgCtrl.designer.cs | 91 ++- .../RoiForFixedStartCJMS11/common/Frame.cs | 70 ++ .../common/ResolutionFrames.cs | 32 + TBF/Rig/Network/Camera/common/ImageUtils.cs | 71 ++ TBF/Rig/Network/Telnet/EventArgsClasses.cs | 13 + .../StandingStart/StandingStartSeq.cs | 11 + .../StandingStartMassCollectionSeq.cs | 5 + TBF/TBF.csproj | 3 + .../TBFTests.csproj.CoreCompileInputs.cache | 2 +- ToFirstMonitor/Program.cs | 2 +- ToSecondMonitor/Program.cs | 2 +- 29 files changed, 896 insertions(+), 314 deletions(-) create mode 100644 TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/Frame.cs create mode 100644 TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/ResolutionFrames.cs create mode 100644 TBF/Rig/Network/Camera/common/ImageUtils.cs diff --git a/Common/Utils.cs b/Common/Utils.cs index 5581666e1..9aa8fc4e1 100644 --- a/Common/Utils.cs +++ b/Common/Utils.cs @@ -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")) || diff --git a/Decrypt/Program.cs b/Decrypt/Program.cs index 135921ce0..4798cc1e6 100644 --- a/Decrypt/Program.cs +++ b/Decrypt/Program.cs @@ -18,7 +18,7 @@ namespace Decrypt { if ((args.Length < 1) || !File.Exists(args[0])) { - Console.WriteLine("Usage: Decode "); + Console.WriteLine(@"Usage: Decode "); Console.ReadKey(); return; } diff --git a/Encrypt/Program.cs b/Encrypt/Program.cs index 753ce201c..20901e63e 100644 --- a/Encrypt/Program.cs +++ b/Encrypt/Program.cs @@ -18,7 +18,7 @@ namespace Encrypt { if ((args.Length < 1) || !File.Exists(args[0])) { - Console.WriteLine("Usage: Encode "); + Console.WriteLine(@"Usage: Encode "); Console.ReadKey(); return; } diff --git a/MergeResultsDBs/Program.cs b/MergeResultsDBs/Program.cs index 04d6e621e..ef0543baa 100644 --- a/MergeResultsDBs/Program.cs +++ b/MergeResultsDBs/Program.cs @@ -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(); } } diff --git a/ResetBatchNr/Program.cs b/ResetBatchNr/Program.cs index 93ab1c991..c690487bb 100644 --- a/ResetBatchNr/Program.cs +++ b/ResetBatchNr/Program.cs @@ -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; } diff --git a/TBF.sln.DotSettings.user b/TBF.sln.DotSettings.user index b9f914b45..146971552 100644 --- a/TBF.sln.DotSettings.user +++ b/TBF.sln.DotSettings.user @@ -3,23 +3,30 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded True 77EB589F-C670-4489-AAD6-2A3C02061FD1 diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 82b21bf67..44b429717 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -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")] diff --git a/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/CycleBeginningForm.cs b/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/CycleBeginningForm.cs index 24d6d2157..a9030f22e 100644 --- a/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/CycleBeginningForm.cs +++ b/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/CycleBeginningForm.cs @@ -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."); } } } diff --git a/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/TestStartEndForm.cs b/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/TestStartEndForm.cs index e1edd16a4..4e2472d0c 100644 --- a/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/TestStartEndForm.cs +++ b/TBF/Rig/DataEntry/StandartCameraPurchaseOrder/TestStartEndForm.cs @@ -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 + ); + } } /// diff --git a/TBF/Rig/Network/Camera/CJMS11/Camera.cs b/TBF/Rig/Network/Camera/CJMS11/Camera.cs index 784f51c15..52979b2ba 100644 --- a/TBF/Rig/Network/Camera/CJMS11/Camera.cs +++ b/TBF/Rig/Network/Camera/CJMS11/Camera.cs @@ -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 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().OrderBy(x => x.ItemNr).Asc.List(); + + + List cfgs = new List(); + IList components = new List(); + 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 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 } - - - /// - /// Download a file from the camera via SCP - /// - /// - /// 0 (success), -1 (busy), -2 (no session) - public int DownloadFile(string srcFileName, string dstFileName) - { - - return 0; - } - - /// - /// Upload a file to the camera via SCP - /// - /// - /// 0 (success), -1 (busy), -2 (no session) - 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: 0–100 - - 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 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 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 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 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; + + /// + /// This method is called from within this class when + /// a prompt string was received from the telnet server. + /// + 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 ImageCameraHandler; + + /// + /// This method is called from within this class when + /// a prompt string was received from the telnet server. + /// + 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); + } + } + } + + + + + } } diff --git a/TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs b/TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs index 8f3dea93c..c562bd624 100644 --- a/TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs +++ b/TBF/Rig/Network/Camera/CJMS11/GrabImagesOp.cs @@ -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; /// @@ -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(); + } } } } diff --git a/TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs b/TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs index 2ac5a28d2..6bccf0ad7 100644 --- a/TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs +++ b/TBF/Rig/Network/Camera/CJMS11/JmsMessage.cs @@ -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); + } } } \ No newline at end of file diff --git a/TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs b/TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs index 74d6cea51..2cfccee07 100644 --- a/TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs +++ b/TBF/Rig/Network/Camera/CJMS11/JmsPacket.cs @@ -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()); + } } } \ No newline at end of file diff --git a/TBF/Rig/Network/Camera/CJMS11/POJO/CommandM.cs b/TBF/Rig/Network/Camera/CJMS11/POJO/CommandM.cs index 578db4280..fdc1dc83e 100644 --- a/TBF/Rig/Network/Camera/CJMS11/POJO/CommandM.cs +++ b/TBF/Rig/Network/Camera/CJMS11/POJO/CommandM.cs @@ -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_, diff --git a/TBF/Rig/Network/Camera/CJMS11/POJO/CommandMEnum.cs b/TBF/Rig/Network/Camera/CJMS11/POJO/CommandMEnum.cs index f17f7aed2..25de4a621 100644 --- a/TBF/Rig/Network/Camera/CJMS11/POJO/CommandMEnum.cs +++ b/TBF/Rig/Network/Camera/CJMS11/POJO/CommandMEnum.cs @@ -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" }, diff --git a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Roi.cs b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Roi.cs index f69318cd2..03b4f92c3 100644 --- a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Roi.cs +++ b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/Roi.cs @@ -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); } diff --git a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfg.cs b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfg.cs index ba6e10961..04e5d33ce 100644 --- a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfg.cs +++ b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfg.cs @@ -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; + } + } /// Procedure parameters [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); } } } diff --git a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.cs b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.cs index 2b47af0f4..1ea9d8b65 100644 --- a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.cs +++ b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.cs @@ -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 - } + + } } diff --git a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.designer.cs b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.designer.cs index d0bb56573..d5dc22cd2 100644 --- a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.designer.cs +++ b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/RoiCfgCtrl.designer.cs @@ -25,8 +25,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11 #region Component Designer generated code - /// - /// Required method for Designer support - do not modify + /// + /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// 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; diff --git a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/Frame.cs b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/Frame.cs new file mode 100644 index 000000000..e31600c3e --- /dev/null +++ b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/Frame.cs @@ -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 + /// example: + /// + /// 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 + /// + + public Frame FindNearest(IEnumerable candidates, Func dimensionSelector) + { + int target = dimensionSelector(this); + return candidates + .OrderBy(f => Math.Abs(dimensionSelector(f) - target)) + .ThenBy(dimensionSelector) // tie-breaker: prefer smaller + .FirstOrDefault(); + } + } +} \ No newline at end of file diff --git a/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/ResolutionFrames.cs b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/ResolutionFrames.cs new file mode 100644 index 000000000..1fb0e8216 --- /dev/null +++ b/TBF/Rig/Network/Camera/RoiForFixedStartCJMS11/common/ResolutionFrames.cs @@ -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 + { + + public ResolutionFrames(IEnumerable collection) : base(collection) + { + } + + public static readonly IReadOnlyList CommonResolutions = new List + { + 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(); + + + + + } +} \ No newline at end of file diff --git a/TBF/Rig/Network/Camera/common/ImageUtils.cs b/TBF/Rig/Network/Camera/common/ImageUtils.cs new file mode 100644 index 000000000..fc99e4acc --- /dev/null +++ b/TBF/Rig/Network/Camera/common/ImageUtils.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/TBF/Rig/Network/Telnet/EventArgsClasses.cs b/TBF/Rig/Network/Telnet/EventArgsClasses.cs index 6f3d701d6..9573af4d3 100644 --- a/TBF/Rig/Network/Telnet/EventArgsClasses.cs +++ b/TBF/Rig/Network/Telnet/EventArgsClasses.cs @@ -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; + } + } diff --git a/TBF/Rig/TestMethods/StandingStart/StandingStartSeq.cs b/TBF/Rig/TestMethods/StandingStart/StandingStartSeq.cs index 51535e1ee..daf65692d 100644 --- a/TBF/Rig/TestMethods/StandingStart/StandingStartSeq.cs +++ b/TBF/Rig/TestMethods/StandingStart/StandingStartSeq.cs @@ -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); } } diff --git a/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs b/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs index 742e39037..98f842583 100644 --- a/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs +++ b/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs @@ -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); + } } diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj index 7b0ddfdf6..7fd0aef96 100644 --- a/TBF/TBF.csproj +++ b/TBF/TBF.csproj @@ -877,6 +877,7 @@ TerminalDlg.cs + Form @@ -904,6 +905,8 @@ + + diff --git a/TBFTests/obj/Release/TBFTests.csproj.CoreCompileInputs.cache b/TBFTests/obj/Release/TBFTests.csproj.CoreCompileInputs.cache index adf024ac9..62670bdd9 100644 --- a/TBFTests/obj/Release/TBFTests.csproj.CoreCompileInputs.cache +++ b/TBFTests/obj/Release/TBFTests.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -b13140660214e1b48c9021e6f280ff951d16dd2027d403736b09a76cec69aa43 +488d44735d3adcc07a0f148fe64d6d1ded107efd14e4fcb2d5d2378975a086a0 diff --git a/ToFirstMonitor/Program.cs b/ToFirstMonitor/Program.cs index 24489ae84..f22fee11c 100644 --- a/ToFirstMonitor/Program.cs +++ b/ToFirstMonitor/Program.cs @@ -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; } diff --git a/ToSecondMonitor/Program.cs b/ToSecondMonitor/Program.cs index c9132fa24..326a8350e 100644 --- a/ToSecondMonitor/Program.cs +++ b/ToSecondMonitor/Program.cs @@ -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; }