From 4c624d7e29b8036dc67b5ae9ba18343147bdf95b Mon Sep 17 00:00:00 2001 From: Bradley Relyea Date: Tue, 2 Dec 2025 11:02:24 +0000 Subject: [PATCH] V4.6 --- AiQ_GUI.cs | 19 +++++++++++-------- AiQ_GUI_NET_Test.csproj | 14 +++++++------- Camera/CameraModules.cs | 32 ++++++++++++++++++++++++++++++-- Camera/FlexiAPI.cs | 36 +++++++++++++----------------------- Logging.cs | 2 +- Soak/Selenium.cs | 4 +--- Soak/SoakTest.cs | 14 +++++++++++++- 7 files changed, 76 insertions(+), 45 deletions(-) diff --git a/AiQ_GUI.cs b/AiQ_GUI.cs index b1dce52..95d0015 100644 --- a/AiQ_GUI.cs +++ b/AiQ_GUI.cs @@ -47,7 +47,7 @@ namespace AiQ_GUI Task LDSWAIT = Task.Run(() => LDS.GetLDS()); // Get and deserialise LDS.json Task guiVerTask = Task.Run(() => GUIUpdate.FindGUIVersion()); // Get GUI Version - Network.Initialize("admin", "admin"); // Initialise HTTP client + Network.Initialize("admin", "admin"); // Initialise HTTP client with basic auth creds. if (await Network.PingIP("8.8.8.8")) // Ping to check if we're online { @@ -145,10 +145,10 @@ namespace AiQ_GUI Task VisCheck = Helper.VisualCheck(BtnStartTest); - if (!await FlexiAPI.ZoomModules("1F40", CamOnTest.IP)) // Zoom to 8000 (1F40h) at the same time. + if (!await CameraModules.ZoomModules("1F40", CamOnTest.IP)) // Zoom to 8000 (1F40h) at the same time. await TestFailed(BtnStartTest, "Could not zoom modules to 8000"); - if (!await FlexiAPI.SetZoomLockOn(CamOnTest.IP)) + if (!await CameraModules.SetZoomLockOn(CamOnTest.IP)) Helper.RestartApp(); await Task.Delay(1000); // Without sleep it kept failing the factory reset as camera modules were not ready yet @@ -169,6 +169,9 @@ namespace AiQ_GUI // TODO - Force expire sighting. Task Wait = Task.Delay(5000); // Wait for 5 seconds to allow the camera to zoom in, set settings and capture some plates before auto trim + if (CameraAccessInfo.HardwareExtras.Contains("GPS")) // Check GPS if the hardware has it + await FlexiAPI.GPSFix(CamOnTest.IP); + // While waiting do the SSH tasks. sshData = SSH.CollectSSHData(CamOnTest.IP); // SSH into camera to get Vaxtor packages, filesystem size and if tailscale is installed. await SSH.CheckFSSize(CamOnTest.IP, LblFilesystemSize, sshData); // Check Filesystem size is between 100GB & 150GB @@ -188,7 +191,7 @@ namespace AiQ_GUI await Wait; // Finished to 5s wait await FlexiAPI.SetTrim(CamOnTest.IP, LblTestTubePing.Text); // Auto trims the cameras, some plates should have been captured in the meantime - if (!await FlexiAPI.ZoomModules("0000", CamOnTest.IP)) // Zoom to full wide + if (!await CameraModules.ZoomModules("0000", CamOnTest.IP)) // Zoom to full wide await TestFailed(BtnStartTest, "Could not zoom modules to full wide"); await Task.Delay(1000); // Wait to be sure cameras are zoomed out. @@ -235,7 +238,7 @@ namespace AiQ_GUI BtnPreTest.Enabled = BtnStartTest.Enabled = false; // Disable buttons to stop user rnning multiple tests at the same time. Logging.LogMessage("Pre Test Started"); - if (!await FlexiAPI.SetZoomLockOn(CamOnTest.IP)) + if (!await CameraModules.SetZoomLockOn(CamOnTest.IP)) Helper.RestartApp(); string LEDreply = await FlexiAPI.APIHTTPLED(CamOnTest.IP, LEDPOWER.MID); // Set LED's to medium (0x30) @@ -1465,7 +1468,7 @@ namespace AiQ_GUI private async void BtnZoomWide_Click(object sender, EventArgs e) { - if (await FlexiAPI.ZoomModules("0000", CamOnTest.IP)) + if (await CameraModules.ZoomModules("0000", CamOnTest.IP)) BtnZoomWide.BackColor = Color.Green; else BtnZoomWide.BackColor = Color.Red; @@ -1475,7 +1478,7 @@ namespace AiQ_GUI private async void BtnZoom8000_Click(object sender, EventArgs e) { - if (await FlexiAPI.ZoomModules("1F40", CamOnTest.IP)) + if (await CameraModules.ZoomModules("1F40", CamOnTest.IP)) BtnZoom8000.BackColor = Color.Green; else BtnZoom8000.BackColor = Color.Red; @@ -1579,7 +1582,7 @@ namespace AiQ_GUI CancellationTokenSource cts = new(); soakCtsList.Add(cts); - soakTasks.Add(SoakTest.StartSoak(SCL, SCL.CheckBox, cts.Token)); + soakTasks.Add(SoakTest.StartSoak(SCL, cts)); await Task.Delay(10000); } } diff --git a/AiQ_GUI_NET_Test.csproj b/AiQ_GUI_NET_Test.csproj index 4aa24f2..058f3d1 100644 --- a/AiQ_GUI_NET_Test.csproj +++ b/AiQ_GUI_NET_Test.csproj @@ -2,7 +2,7 @@ WinExe - net9.0-windows7.0 + net10.0-windows7.0 enable true enable @@ -16,7 +16,7 @@ AiQ GUI MAV Systems Ltd AiQ GUI - 4.5.0 + 4.6.0 A GUI to control and test the AiQ MAV Systems Ltd 2025 MAV - Plain - Blue.png @@ -26,6 +26,7 @@ False true False + AiQ_GUI.Program @@ -54,14 +55,13 @@ - - - + + - + - + diff --git a/Camera/CameraModules.cs b/Camera/CameraModules.cs index 176fc3e..2962e44 100644 --- a/Camera/CameraModules.cs +++ b/Camera/CameraModules.cs @@ -28,10 +28,10 @@ namespace AiQ_GUI MainForm.Instance.AddToActionsList($"{CamMod.firmwareVer} or {UniversalData.WonwooFirmware} could not be converted to a double"); } - if (CamOnTest.RMANum > 0 && LessTanOrEqualTo) + if (CamOnTest.RMANum > 0 && !LessTanOrEqualTo) errMssg += $"Firmware: {CamMod.firmwareVer} should be less than or equal to {UniversalData.WonwooFirmware} for RMA {CamOnTest.RMANum}"; - else if ((CamOnTest.RMANum == 0 || CamOnTest.RMANum == -1) && CamMod.firmwareVer != UniversalData.WonwooFirmware) + else if (CamOnTest.RMANum < 1 && CamMod.firmwareVer != UniversalData.WonwooFirmware) errMssg += $"Firmware: {CamMod.firmwareVer} should be {UniversalData.WonwooFirmware} "; if (CamMod.expMode != 0) // Auto 0=0x00 @@ -107,5 +107,33 @@ namespace AiQ_GUI // Build the final VISCA command string using the input characters split as p and q return $"8101044{command}00000{hex[0]}0{hex[1]}FF"; } + + public static async Task SetZoomLockOn(string IP) + { + // Set Zoomlock on and if it fails ask user to set it manually + if (!(await FlexiAPI.APIHTTPRequest("/api/zoomLock?enable=true", IP)).Contains("Zoom lock enabled.") + && !await MainForm.Instance.DisplayQuestion("Could not set zoomlock on" + Environment.NewLine + "Set Zoomlock to on then click YES. Click NO to restart.")) + { + return false; + } + + return true; + } + + public static async Task ZoomModules(string VISCAInput, string IPAddress) + { + // Populate the VISCA command with the four zoom characters + string VISCA = $"810104470{VISCAInput[0]}0{VISCAInput[1]}0{VISCAInput[2]}0{VISCAInput[3]}FF"; + + Task TS1 = FlexiAPI.APIHTTPVISCA(IPAddress, VISCA, true); + Task TS2 = FlexiAPI.APIHTTPVISCA(IPAddress, VISCA, false); + await Task.WhenAll(TS1, TS2); + + const string ExpReply = "9041FF9051FF"; + if (TS1.Result == ExpReply && TS1.Result == ExpReply) + return true; + + return false; + } } } \ No newline at end of file diff --git a/Camera/FlexiAPI.cs b/Camera/FlexiAPI.cs index db39ab2..54d944d 100644 --- a/Camera/FlexiAPI.cs +++ b/Camera/FlexiAPI.cs @@ -192,32 +192,16 @@ namespace AiQ_GUI } } - public static async Task SetZoomLockOn(string IP) + public static async Task GPSFix(string IPAddress) { - // Set Zoomlock on and if it fails ask user to set it manually - if (!(await APIHTTPRequest("/api/zoomLock?enable=true", IP)).Contains("Zoom lock enabled.") - && !await MainForm.Instance.DisplayQuestion("Could not set zoomlock on" + Environment.NewLine + "Set Zoomlock to on then click YES. Click NO to restart.")) + string sysstatus = await APIHTTPRequest("/sysstatus", IPAddress, 5); + SysStatus status = JsonConvert.DeserializeObject(sysstatus); + + if (status.gpsState == 0 || status.gpsPresent == "Not Fitted") { - return false; + MainForm.Instance.AddToActionsList($"GPS not present in camera. State: {status.gpsState} & Status: {status.gpsPresent}"); + return; } - - return true; - } - - public static async Task ZoomModules(string VISCAInput, string IPAddress) - { - // Populate the VISCA command with the four zoom characters - string VISCA = $"810104470{VISCAInput[0]}0{VISCAInput[1]}0{VISCAInput[2]}0{VISCAInput[3]}FF"; - - Task TS1 = APIHTTPVISCA(IPAddress, VISCA, true); - Task TS2 = APIHTTPVISCA(IPAddress, VISCA, false); - await Task.WhenAll(TS1, TS2); - - const string ExpReply = "9041FF9051FF"; - if (TS1.Result == ExpReply && TS1.Result == ExpReply) - return true; - - return false; } public static async Task SetTrim(string IPAddress, string LblTxt, int RetryCount = 0) // Sets trim by getting plate postion as metric @@ -557,6 +541,12 @@ namespace AiQ_GUI public int colourY { get; set; } } + public class SysStatus + { + public int gpsState { get; set; } = 0; + public string gpsPresent { get; set; } = string.Empty; + } + public class NetworkConfig { public Property propDHCP { get; set; } = new Property(); diff --git a/Logging.cs b/Logging.cs index 3d371d4..dfda213 100644 --- a/Logging.cs +++ b/Logging.cs @@ -41,7 +41,7 @@ } catch (Exception ex) { - MainForm.Instance.AddToActionsList($"Error logging message: {ex.Message}"); + MessageBox.Show($"Error logging message: {ex.Message}"); } } } diff --git a/Soak/Selenium.cs b/Soak/Selenium.cs index aef7084..5a91bf9 100644 --- a/Soak/Selenium.cs +++ b/Soak/Selenium.cs @@ -106,8 +106,6 @@ namespace AiQ_GUI // Initialises and opens a ChromeDriver with specific options public static ChromeDriver OpenDriver() { - string tempProfile = null; - try { ChromeOptions options = new(); @@ -121,7 +119,7 @@ namespace AiQ_GUI "--disable-features=BrowserAddPersonFeature,InterestFeedContentSuggestions"); // Use a unique temporary profile to avoid conflicts - tempProfile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + string tempProfile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); options.AddArguments($"--user-data-dir={tempProfile}"); // manual driver path diff --git a/Soak/SoakTest.cs b/Soak/SoakTest.cs index 5d8e36c..fdcdec5 100644 --- a/Soak/SoakTest.cs +++ b/Soak/SoakTest.cs @@ -7,8 +7,9 @@ namespace AiQ_GUI internal class SoakTest { // Main soak test loop: Randomise dropdowns, run luminance test every hour, power cycle at 7am - public static async Task StartSoak(Camera CamInfo, CheckBox CkBx, CancellationToken token) + public static async Task StartSoak(Camera CamInfo, CancellationTokenSource CTS) { + CancellationToken token = CTS.Token; if (CamInfo.Serial == "N/A") CamInfo.Serial = "UNKNOWN"; // If serial is not set, set it to UNKNOWN. Cannot have N/A in file names. @@ -18,6 +19,7 @@ namespace AiQ_GUI try { driver = Selenium.OpenDriver(); + Logging.LogMessage("----- Soak test started -----", SoakLogFile); await Task.Delay(1000); // Small delay to ensure driver is ready // Keep retrying until connected or cancelled @@ -58,6 +60,16 @@ namespace AiQ_GUI while (!token.IsCancellationRequested) { + try + { + string TheString = "Selenium string: " + driver.Manage().Window.Size; // Fails out if Window doesn't exist. + } + catch + { + CTS.Cancel(); + continue; + } + int currentHour = DateTime.Now.Hour; // At 7am, power cycle the camera