Beginning of the Implementing multple cameras into the AiQ GUI

Features added:
- Onvif discoverable
- New Camera Type combo box
- Access has be changed to be more scalable and dynamic in preparation for more cameras
This commit is contained in:
2025-12-19 16:14:13 +00:00
parent 760987fa75
commit 7aba890514
18 changed files with 455 additions and 333 deletions

View File

@@ -65,12 +65,9 @@ namespace AiQ_GUI
this.Name = "AiQ GUI V" + GUIUpdate.GUIVerShort;
LblGUIVers.Text += GUIUpdate.GUIVerShort;
await UniDataTask; // Have to wait for expected GUI version to compare to.
Task<string[]> 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;
@@ -84,7 +81,7 @@ namespace AiQ_GUI
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
CbBxCameraModel.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
@@ -96,6 +93,20 @@ namespace AiQ_GUI
Flags.Start = false;
}
private async void CbBxCamType_SelectedIndexChanged(object sender, EventArgs e)
{
CbBxCameraModel.Items.Clear(); // REQUIRED
string camType = CbBxCamType.Text;
string[] models = await Task.Run(() => Access.ReadCamTypes(camType));
if (models != null && models.Length > 0)
CbBxCameraModel.Items.AddRange(models);
}
private void PopulateUIWithLDS(LocalDataStore lds)
{
CbBxUserName.Text = lds.User;
@@ -251,7 +262,7 @@ namespace AiQ_GUI
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
// Requests, deserialises and checks the diagnostics API is correct
@@ -693,7 +704,7 @@ namespace AiQ_GUI
{
// Update the serial number register with new cameras details
// Cam description is in model drop down 6 digit model num + 3 for " - "
string NewSerial = GoogleAPI.UpdateSpreadSheetPreTest(CameraAccessInfo.SpreadsheetID, Vers, CbBxCameraType.Text.Substring(9), CamOnTest.Model);
string NewSerial = GoogleAPI.UpdateSpreadSheetPreTest(CameraAccessInfo.SpreadsheetID, Vers, CbBxCameraModel.Text.Substring(9), CamOnTest.Model);
if (NewSerial.Contains("ERROR"))
{
@@ -731,10 +742,10 @@ namespace AiQ_GUI
private void BtnClose_Click(object sender, EventArgs e)
{
// Save user settings in LDS for next time if values are valid
if (CbBxUserName.Text.Length > 2 && CbBxCameraType.Text.Length > 6)
if (CbBxUserName.Text.Length > 2 && CbBxCameraModel.Text.Length > 6)
{
localDataStore.User = CbBxUserName.Text;
localDataStore.LastModel = CbBxCameraType.Text;
localDataStore.LastModel = CbBxCameraModel.Text;
LDS.SetLDS(localDataStore);
}
@@ -748,7 +759,7 @@ namespace AiQ_GUI
private void BtnRestart_Click(object sender, EventArgs e)
{
Helper.RestartApp(); // Restart abruptly don't worry about anything else going on
Helper.RestartApp(); // Restart abruptly don't worry about anything else going on
}
// ***** Allows moving GUI by grab and dragging *****
@@ -820,12 +831,6 @@ namespace AiQ_GUI
Flags.No = true;
}
private void CmBxCameraType_SelectedIndexChanged(object sender, EventArgs e)
{
CamOnTest.Model = CbBxCameraType.Text.Substring(0, 6); // Model on test is the first 6 characters of the textbox
Access.ReadModelRow(CamOnTest.Model); // Fill in all info about current model number
TestStartConditions();
}
private void CmBoBoxUserName_TextChanged(object sender, EventArgs e)
{
@@ -843,19 +848,23 @@ namespace AiQ_GUI
timerTypeIP.Enabled = false; // Stop this triggering again
CamOnTest.DevPass = TxBxOutput.Text = RhTxBxActions.Text = ""; // Blank password & Clear actions box as it is now a different camera
if (RegexCache.RegexIPPattern().IsMatch(CbBxFoundCams.Text)) // Check IP address is valid
string selectedText = CbBxFoundCams.Text.Trim();
string ipOnly = selectedText.Split(' ', StringSplitOptions.RemoveEmptyEntries)[0];
if (RegexCache.RegexIPPattern().IsMatch(ipOnly)) // Check IP address is valid
{
if (!await Network.PingIP(CbBxFoundCams.Text))
if (!await Network.PingIP(ipOnly))
{
CbBxFoundCams.BackColor = Color.Red;
return;
}
CamOnTest.IP = CbBxFoundCams.Text; // Set the IP address under test
CamOnTest.IP = ipOnly; //Always store clean IP
CbBxFoundCams.BackColor = BtnColour;
BtnSecret.Enabled = true;
Vers = await FlexiAPI.GetVersions(CamOnTest.IP);
Vers = await FlexiAPI.GetVersions(ipOnly);
// Wont be filled out before the pre test but needed for final test
if (RegexCache.SerialRegex().IsMatch(CamOnTest.Serial) && RegexCache.ModelRegex().IsMatch(CamOnTest.Model))
@@ -872,12 +881,12 @@ namespace AiQ_GUI
Lics.DisplayDevPassword(Vers, CamOnTest); // Generate and display secret for use later
string networkConfigText = await FlexiAPI.ProcessNetworkConfig(CamOnTest.IP);
string networkConfigText = await FlexiAPI.ProcessNetworkConfig(ipOnly);
BtnSet211.Text = string.IsNullOrEmpty(networkConfigText) ? "Set to 211" : networkConfigText;
ShowToolTip(BtnSecret); // Set dev password to Tooltip and clipboard
}
else if (CbBxFoundCams.Text.Contains("Found"))
else if (selectedText.Contains("Found"))
{
CbBxFoundCams.BackColor = BtnColour;
}
@@ -957,7 +966,7 @@ namespace AiQ_GUI
RhTxBxActions.SelectionColor = Color.LightGreen;
}
RhTxBxActions.AppendText(Mssg + Environment.NewLine);
RhTxBxActions.AppendText(Mssg + Environment.NewLine);
RhTxBxActions.SelectionStart = RhTxBxActions.Text.Length;
RhTxBxActions.SelectionColor = SystemColors.Control;
RhTxBxActions.ScrollToCaret();
@@ -976,7 +985,7 @@ namespace AiQ_GUI
if (await Network.PingIP("8.8.8.8")) // Ping to find if we are online
{
Flags.Offline = false; // Ping succeeded
CbBxCameraType.Enabled = true;
CbBxCameraModel.Enabled = true;
}
else
TSC = SetInvalid("Offline Mode, could not connect to the internet."); // Ping failed
@@ -993,7 +1002,7 @@ namespace AiQ_GUI
TSC = SetInvalid("Select Username.");
// Model number selected
if (CbBxCameraType.SelectedIndex == -1)
if (CbBxCameraModel.SelectedIndex == -1)
TSC = SetInvalid("Select Model number.");
// Settings IP addresses filled in
@@ -1494,15 +1503,19 @@ namespace AiQ_GUI
private void BtnOpenWebpage_Click(object sender, EventArgs e)
{
// Cut off anything after the first space (e.g. " - Onvif")
string ip = CamOnTest.IP.Split(' ')[0];
ProcessStartInfo psi = new()
{
FileName = $"http://{CamOnTest.IP}", // Just the URL
UseShellExecute = true // Lets the OS decide how to open it
FileName = $"http://{ip}",
UseShellExecute = true
};
Process.Start(psi);
}
private async void UploadWonwooSetOV_Click(object sender, EventArgs e)
{
await FlexiAPI.UploadWonwooSet(CbBxFoundCams.Text, false); // false = Colour
@@ -1543,7 +1556,7 @@ namespace AiQ_GUI
{
BtnPrintGB.Enabled = true;
if (CbBxCameraType.SelectedIndex != -1 && RegexCache.SerialRegex().IsMatch(TxBxSerialPrint.Text)) // Check model and serial are known
if (CbBxCameraModel.SelectedIndex != -1 && RegexCache.SerialRegex().IsMatch(TxBxSerialPrint.Text)) // Check model and serial are known
{
Printer.ZebraIP = localDataStore.ZebraIP;
BtnPrintAiQ.Enabled = true;
@@ -1739,8 +1752,18 @@ namespace AiQ_GUI
// PDF.CreateSoakTestReport(NewCam, "SoakTestRig", DateTime.Now, file);
// }
//}
var password = @"mavPA\$\$";
var psi = new ProcessStartInfo
{
FileName = @"C:\Program Files (x86)\Mobatek\MobaXterm\MobaXterm.exe",
Arguments = $@"-newtab -ssh {CamOnTest.IP} -user mav -pass ""{password}""",
UseShellExecute = true
};
Process.Start(psi);
stopWatchTest.Stop();
AddToActionsList("RunTime " + stopWatchTest.Elapsed.ToString(@"hh\:mm\:ss\.ff"), Level.LOG);
}