using Newtonsoft.Json; using System.ComponentModel; using System.Diagnostics; using System.Reflection; namespace AiQ_GUI { public partial class MainForm : Form { // Classes LocalDataStore localDataStore = new(); Diags DiagsAPI = new(); VaxtorLic VaxtorLicResp = new(); Versions Vers = new(); readonly Camera CamOnTest = new(); SSHData sshData = new(); private List soakCameraList = []; private List soakCtsList = []; private List soakTasks = []; // Colours public static readonly Color BtnColour = Color.FromArgb(70, 65, 80); public static readonly Color TxBxColour = Color.FromArgb(53, 51, 64); [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public static MainForm? Instance { get; private set; } public MainForm() { InitializeComponent(); Instance = this; } private async void AiQGUI_Load(object sender, EventArgs e) { Stopwatch stopwatch = Stopwatch.StartNew(); Task? closeProcessesTask = Windows.CloseProcesses(); // Fire and forget closing other apps Windows.UpdateFirewall(); Task UniDataTask = Task.Run(() => Access.ReadUniData()); // Get universal data 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 if (await Network.PingIP("8.8.8.8")) // Ping to check if we're online { if (!GoogleAPI.Setup()) AddToActionsList("Cannot setup Google API"); } else { Flags.Offline = true; BtnStartTest.Text = "Offline Mode"; } GUIUpdate.GUIVerShort = await guiVerTask; // Guess the GUI version will be first to finish this.Name = "AiQ GUI V" + GUIUpdate.GUIVerShort; LblGUIVers.Text += GUIUpdate.GUIVerShort; await UniDataTask; // Have to wait for expected GUI version to compare to. Task modelListTask = Task.Run(() => Access.ReadCamTypes());// Get all model numbers GUIUpdate.UpdateGUI(); // Check if a GUI update is available string[] ArrayOfModels = await modelListTask; if (ArrayOfModels != null) // Returns null if no models found or file doesn't exists CbBxCameraType.Items.AddRange(await modelListTask); // Fill in the model number drop down // Load local data store localDataStore = await LDSWAIT; Logging.LogMessage("Opening GUI"); // Done after LDS to make sure directory exists. if (localDataStore == null) { AddToActionsList("Could not deserialise LDS.json please help!"); return; } Task CheckHWOnline = PingCheck(); // Async check all hardware is online PopulateUIWithLDS(localDataStore); // Update fields that depend on LDS CbBxCameraType.Text = localDataStore.LastModel; // Set last model that was tested into combobox BtnSave.BackColor = BtnSave.Enabled ? Color.ForestGreen : BtnSave.BackColor; // Sets the colour of the save button depending on if it is enabled. BtnRefreshUnix_Click(sender, e); // Reset timestamp if (RegexCache.FlexiVerRegex().IsMatch(UniversalData.ExpFlexiVer)) // Update Flexi version from universal data TxBxFlexiVer.Text = UniversalData.ExpFlexiVer; await CheckHWOnline; Flags.Start = false; stopwatch.Stop(); Debug.WriteLine("RunTime " + stopwatch.Elapsed.ToString(@"hh\:mm\:ss\.ff")); } private void PopulateUIWithLDS(LocalDataStore lds) { CbBxUserName.Text = lds.User; TxBxPsuIP.Text = PSU.PSUIP = lds.PSUIP; TxBxEzIP.Text = Ez.PoEPowerIP = lds.EzIP; TxBxZebraIP.Text = Printer.ZebraIP = lds.ZebraIP; TxBxTestTubeIP.Text = TestTube.TTPiPicoIP = lds.TestTubeIP; CbBxShutter.SelectedIndex = lds.Shutter; CbBxIris.SelectedIndex = lds.Iris; CbBxGain.SelectedIndex = lds.Gain; if (lds.User == "Bradley") BtnTest.Visible = true; TxBxCheckValid(TxBxPsuIP); // Set save button color if valid } private async void MainForm_Shown(object sender, EventArgs e) // Done on show as all UI elements are loaded in properly for find cams to use { BtnFindCams_Click(sender, e); CheckPrintCapable(); // Check if the print buttons can be enabled TestStartConditions(); await Task.Delay(1000); // Delay for UI to catch up if (LblPSUPing.ForeColor == Color.ForestGreen) // Check state of PSU if it is connected. Task.Run(() => PSU.DisplayState(PSU.PSUIP)); } // ***** Test buttons ***** private async void BtnStartTest_Click(object sender, EventArgs e) { // Show user test has started BtnStartTest.BackColor = Color.Orange; BtnStartTest.Text = "Test underway"; BtnPreTest.Enabled = BtnStartTest.Enabled = false; // Disable buttons to stop user rnning multiple tests at the same time. Logging.LogMessage("Final Test Started"); if (LblTestTubePing.Text == "❌") // No test tube so test like an IQ { string LEDreply = await FlexiAPI.APIHTTPLED(CamOnTest.IP, LEDPOWER.SAFE); // Set LED's to safe (0x0E) to help with eye safety and trim check. if (!LEDreply.Contains("Power levels set successfully")) AddToActionsList($"LED level could not be set: {LEDreply}"); } else if (!await TestTube.CheckInTestTube(CamOnTest.IP)) // Sets LED's to medium power after checking it is in the test tube await TestFailed(BtnStartTest, "Camera not in test tube"); Task VisCheck = Helper.VisualCheck(BtnStartTest); if (!await FlexiAPI.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)) Helper.RestartApp(); await Task.Delay(1000); // Without sleep it kept failing the factory reset as camera modules were not ready yet await CameraModules.FactoryResetModules(CamOnTest.IP); // Reset both modules and double check string VISCAReply = await FlexiAPI.APIHTTPVISCA(CamOnTest.IP, "8101043903FF", true); // Manual mode to be able to manipulate the SIG settings. if (VISCAReply != "9041FF9051FF") AddToActionsList("Couldn't set to manual mode"); await CameraModules.SetSIG(CbBxShutter, CbBxIris, CbBxGain, CamOnTest.IP); // Set SIG according to the drop downs in settings for a good picture ready for image check await ImageProcessing.ImageCheck(PicBxOV, PicBxIRF2, PicBxIRF16, LblIRImageF2, LblIRImageF16, CamOnTest); // Populates the picture boxes and checks iris changes await VisCheck; // Before changing UI elements wait for user to finish Visual check TabImagesandSettings.SelectedIndex = 2; // Swaps to the images tab this.Refresh(); // Show user things are happening by displaying images taken // 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 // 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 Helper.DCPowerCheck(LblDC); // If the camera is DC powered check it is within limits if (CameraAccessInfo.HardwareExtras.Contains("4G")) // If it is a router camera then test the router. { LblRouter.Visible = true; if (Router.CheckRouter(Router.GetRouterInfo())) LblRouter.Text += "OK"; else LblRouter.Text += "Error with router"; } await Wait; // Finished to 5s wait await SetTrim(); // Auto trims the cameras, some plates should have been captured in the meantime if (!await FlexiAPI.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. await CameraModules.FactoryResetModules(CamOnTest.IP); // Reset both modules and double check if (LblTestTubePing.Text == "❌") // Set LED's to MID in prep for diagnostics API { string LEDreply = await FlexiAPI.APIHTTPLED(CamOnTest.IP, LEDPOWER.MID); // Set LED's to medium (0x30) if (!LEDreply.Contains("Power levels set successfully")) AddToActionsList($"LED level could not be set: {LEDreply}"); } DateTime PCTime = DateTime.Now; // Grab PC time as close to the API as possible to pass onto PDF later await CheckDiagsAPIPt1(); // Requests, deserialises and checks the diagnostics API is correct await CheckDiagsAPIPt2(); // For only final test parts // Check module has gone to default config CameraModules.CheckCamModule(DiagsAPI.IRmodule, LblIRModule); // IR CameraModules.CheckCamModule(DiagsAPI.OVmodule, LblOVModule); // OV // Check voltage and current are OK. LED.CheckLEDs(DiagsAPI.LedVoltage, LblLEDV, "V", CameraAccessInfo.LED_V); // Voltage LED.CheckLEDs(DiagsAPI.LedCurrent, LblLEDI, "mA", CameraAccessInfo.LED_I); // Current this.Refresh(); // Make sure all labels are updated before checking them // If there are any actions identified then fail the test. // If any labels are red then fail. Only labels in panel so can foreach on labels not controls if (RhTxBxActions.Text.Length > 2 || PnlLbls.Controls.OfType