V3.14
This commit is contained in:
240
AiQ_GUI.cs
240
AiQ_GUI.cs
@@ -183,7 +183,7 @@ namespace AiQ_GUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
await Wait; // Finished to 5s wait
|
await Wait; // Finished to 5s wait
|
||||||
await SetTrim(); // Auto trims the cameras, some plates should have been captured in the meantime
|
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 FlexiAPI.ZoomModules("0000", CamOnTest.IP)) // Zoom to full wide
|
||||||
await TestFailed(BtnStartTest, "Could not zoom modules to full wide");
|
await TestFailed(BtnStartTest, "Could not zoom modules to full wide");
|
||||||
@@ -686,81 +686,6 @@ namespace AiQ_GUI
|
|||||||
Printer.PrintSerialLbl(CamOnTest.Model, NewSerial, CameraAccessInfo.Processor); // Print model/serial label
|
Printer.PrintSerialLbl(CamOnTest.Model, NewSerial, CameraAccessInfo.Processor); // Print model/serial label
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SetTrim(int RetryCount = 0) // Sets trim by getting plate postion as metric
|
|
||||||
{
|
|
||||||
Trim trim;
|
|
||||||
string trimData = await FlexiAPI.APIHTTPRequest("/SightingCreator-plate-positions", CamOnTest.IP, 5); // Get plate positions
|
|
||||||
|
|
||||||
try // Deserialise the JSON
|
|
||||||
{
|
|
||||||
Logging.LogMessage("Trim Data: " + trimData);
|
|
||||||
trim = JsonConvert.DeserializeObject<Trim>(trimData);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
await TestFailed(BtnStartTest, "Error reading JSON - " + trimData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check no value is -1 (no plate found) or if the positions are identical (one plate found). If it is then try again 3 times
|
|
||||||
if (new[] { trim.infraredX, trim.infraredY, trim.colourX, trim.colourY }.Any(value => value == -1)
|
|
||||||
|| (trim.infraredX == trim.colourX && trim.infraredY == trim.colourY))
|
|
||||||
{
|
|
||||||
if (RetryCount >= 3)
|
|
||||||
{
|
|
||||||
await DisplayOK("Please align trim in webpage then click OK."); // Awaited till OK has been clicked
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(5000); // Give 5 second delay for it to see a plate
|
|
||||||
await SetTrim(RetryCount++);
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 105;
|
|
||||||
|
|
||||||
if (LblTestTubePing.Text == "❌") // Test tube not connected so do the 2.7m check.
|
|
||||||
offset = 98;
|
|
||||||
|
|
||||||
// Horizontal distance offset for 2.7m compared to 30m is 98 pixels. This was empirically found from testing in the car park
|
|
||||||
// Colour camera is to the right of the infrared so it gets the offset.
|
|
||||||
// Using similar triangles going from 2.7m -> 0.65m which is the length of the test tube (Also exactly 1/4 length).
|
|
||||||
// 98 * (29.35/27.3) = 105.35 pixels
|
|
||||||
int OverviewX = trim.colourX + offset;
|
|
||||||
|
|
||||||
if (OverviewX > 1920) // If adding on the offset has pushed it out of limits then remove 0.1
|
|
||||||
{
|
|
||||||
if (OverviewX < 2120 && trim.infraredX > 400) // Within enough of a limit to automatically do it
|
|
||||||
{
|
|
||||||
OverviewX -= 200;
|
|
||||||
trim.infraredX -= 200;
|
|
||||||
}
|
|
||||||
else // Ask user to centre the plate in the field of view
|
|
||||||
{
|
|
||||||
await DisplayOK("Please centralise plate in view THEN press OK"); // Awaited till OK has been clicked
|
|
||||||
|
|
||||||
if (RetryCount >= 3)
|
|
||||||
{
|
|
||||||
await DisplayOK("Please align trim in webpage then click OK."); // Awaited till OK has been clicked
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await Task.Delay(5000); // Give 5 second delay for it to see a plate
|
|
||||||
await SetTrim(RetryCount++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compensated trim values, therefore should be close to 0,0 with limits of ±5% of 1920 and 1080 respectivly being ±96 and ±54
|
|
||||||
int TrimX = trim.infraredX - OverviewX;
|
|
||||||
int TrimY = trim.infraredY - trim.colourY;
|
|
||||||
|
|
||||||
// Update trim values
|
|
||||||
string[,] Trim_JSON = { { "propInterCameraOffsetX", Convert.ToString(TrimX) }, { "propInterCameraOffsetY", Convert.ToString(TrimY) } };
|
|
||||||
string TrimResp = await FlexiAPI.HTTP_Update("SightingCreator", CamOnTest.IP, Trim_JSON);
|
|
||||||
AddToActionsList(TrimResp, false);
|
|
||||||
|
|
||||||
if (!TrimResp.Contains($"\"propInterCameraOffsetX\": {{\"value\": \"{Convert.ToString(TrimX)}\", \"datatype\": \"int\"}}, \"propInterCameraOffsetY\": {{\"value\": \"{Convert.ToString(TrimY)}\", \"datatype\": \"int\"}},"))
|
|
||||||
AddToActionsList("Could not set camera trim");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***** Top right buttons *****
|
// ***** Top right buttons *****
|
||||||
private void BtnClose_Click(object sender, EventArgs e)
|
private void BtnClose_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -800,7 +725,8 @@ namespace AiQ_GUI
|
|||||||
private async void BtnFindCams_Click(object sender, EventArgs e)
|
private async void BtnFindCams_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
CbBxFoundCams.Text = "Searching";
|
CbBxFoundCams.Text = "Searching";
|
||||||
BtnFindCams.Enabled = BtnSetAll211.Enabled = BtnSoak.Enabled = BtnSet211.Enabled = BtnSetGodMode.Enabled = BtnUploadBlob.Enabled = SetGodModeAll.Enabled = false;
|
BtnFindCams.Enabled = BtnSetAll211.Enabled = BtnSoak.Enabled = BtnSet211.Enabled = BtnSetGodMode.Enabled = BtnUploadBlob.Enabled = SetGodModeAll.Enabled = BtnFactoryDefault.Enabled = false;
|
||||||
|
BtnSetGodMode.BackColor = BtnUploadBlob.BackColor = BtnFactoryDefault.BackColor = BtnSetAll211.BackColor = BtnColour;
|
||||||
CbBxFoundCams.Items.Clear();
|
CbBxFoundCams.Items.Clear();
|
||||||
soakCameraList.Clear();
|
soakCameraList.Clear();
|
||||||
|
|
||||||
@@ -838,7 +764,7 @@ namespace AiQ_GUI
|
|||||||
|
|
||||||
int cameraCount = CbBxFoundCams.Items.Count;
|
int cameraCount = CbBxFoundCams.Items.Count;
|
||||||
CbBxFoundCams.Text = cameraCount > 0 ? $"{cameraCount} Camera{(cameraCount == 1 ? "" : "s")} Found" : "No Cameras Found";
|
CbBxFoundCams.Text = cameraCount > 0 ? $"{cameraCount} Camera{(cameraCount == 1 ? "" : "s")} Found" : "No Cameras Found";
|
||||||
BtnFindCams.Enabled = BtnSetAll211.Enabled = SetGodModeAll.Enabled = BtnSoak.Enabled = BtnUploadBlob.Enabled = true;
|
BtnFindCams.Enabled = BtnSetAll211.Enabled = SetGodModeAll.Enabled = BtnSoak.Enabled = BtnUploadBlob.Enabled = BtnFactoryDefault.Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnYes_Click(object sender, EventArgs e)
|
private void BtnYes_Click(object sender, EventArgs e)
|
||||||
@@ -947,6 +873,7 @@ namespace AiQ_GUI
|
|||||||
|
|
||||||
private async void BtnSetGodMode_Click(object sender, EventArgs e)
|
private async void BtnSetGodMode_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
BtnSetGodMode.BackColor = BtnColour;
|
||||||
bool isGodModeCurrentlyOn = BtnSetGodMode.Text.Contains("On");
|
bool isGodModeCurrentlyOn = BtnSetGodMode.Text.Contains("On");
|
||||||
string newGodModeValue = isGodModeCurrentlyOn ? "true" : "false";
|
string newGodModeValue = isGodModeCurrentlyOn ? "true" : "false";
|
||||||
string[,] GOD_JSON = { { "propGodMode", newGodModeValue } };
|
string[,] GOD_JSON = { { "propGodMode", newGodModeValue } };
|
||||||
@@ -954,13 +881,8 @@ namespace AiQ_GUI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await FlexiAPI.HTTP_Update("Internal Config", CamOnTest.IP, GOD_JSON);
|
await FlexiAPI.HTTP_Update("Internal Config", CamOnTest.IP, GOD_JSON);
|
||||||
|
|
||||||
BtnSetGodMode.Text = newGodModeValue == "true" ? "Set God Mode Off" : "Set God Mode On";
|
BtnSetGodMode.Text = newGodModeValue == "true" ? "Set God Mode Off" : "Set God Mode On";
|
||||||
|
|
||||||
Color originalColor = BtnSetGodMode.BackColor;
|
|
||||||
BtnSetGodMode.BackColor = Color.Green;
|
BtnSetGodMode.BackColor = Color.Green;
|
||||||
await Task.Delay(500);
|
|
||||||
BtnSetGodMode.BackColor = originalColor;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -1663,6 +1585,7 @@ namespace AiQ_GUI
|
|||||||
|
|
||||||
private async void BtnUploadBlob_Click(object sender, EventArgs e)
|
private async void BtnUploadBlob_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
BtnUploadBlob.BackColor = BtnColour;
|
||||||
const string networkFolderPath = @"G:\Shared drives\MAV Production\MAV_146_AiQ_Mk2\Flexi";
|
const string networkFolderPath = @"G:\Shared drives\MAV Production\MAV_146_AiQ_Mk2\Flexi";
|
||||||
string fileToUpload = null;
|
string fileToUpload = null;
|
||||||
|
|
||||||
@@ -1716,10 +1639,13 @@ namespace AiQ_GUI
|
|||||||
AddToActionsList($"Upload result for {cam.IP}: {result}", false);
|
AddToActionsList($"Upload result for {cam.IP}: {result}", false);
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
}
|
}
|
||||||
|
BtnUploadBlob.BackColor = Color.Green;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void BtnFactoryDefault_Click(object sender, EventArgs e)
|
private async void BtnFactoryDefault_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
BtnFactoryDefault.BackColor = BtnColour;
|
||||||
|
|
||||||
foreach (Camera SCL in soakCameraList) // Reset all cameras that were being soaked to default module settings
|
foreach (Camera SCL in soakCameraList) // Reset all cameras that were being soaked to default module settings
|
||||||
{
|
{
|
||||||
if (!SCL.IsChecked)
|
if (!SCL.IsChecked)
|
||||||
@@ -1728,116 +1654,70 @@ namespace AiQ_GUI
|
|||||||
Network.Initialize("developer", SCL.DevPass); // Ensure network is initialized to the right camera, cannot be done in soak test finally becuase of this.
|
Network.Initialize("developer", SCL.DevPass); // Ensure network is initialized to the right camera, cannot be done in soak test finally becuase of this.
|
||||||
await CameraModules.FactoryResetModules(SCL.IP);
|
await CameraModules.FactoryResetModules(SCL.IP);
|
||||||
}
|
}
|
||||||
|
BtnFactoryDefault.BackColor = Color.Green;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SwitchTest(string TestingType)
|
// Constants
|
||||||
|
const double RealPlateWidthMeters = 0.52; // UK standard plate width
|
||||||
|
const double FocalLengthPixels = (50 * 1280) / 14.111224; // focal mm * pixel width / sensor width for IQ
|
||||||
|
// const double FocalLengthPixels = (50 * 1920) / 6.95; // focal mm * pixel width / sensor width for AiQ
|
||||||
|
const double FrameRate = 25.0; // Frames per second
|
||||||
|
|
||||||
|
public class FrameData
|
||||||
{
|
{
|
||||||
object sender = new();
|
public long FrameID;
|
||||||
EventArgs e = new();
|
public int PlatePosX;
|
||||||
|
public int PlatePosY;
|
||||||
Properties.Settings.Default.UnitTesting = TestingType;
|
public int PlateWidthPixels;
|
||||||
Properties.Settings.Default.Save();
|
|
||||||
|
|
||||||
CAMTYPE CAMTYPE = TestingType.Substring(0, TestingType.IndexOf('_')) switch
|
|
||||||
{
|
|
||||||
"GOOD" => CAMTYPE.GOOD,
|
|
||||||
"BAD" => CAMTYPE.BAD,
|
|
||||||
"BIZARRE" => CAMTYPE.BIZARRE,
|
|
||||||
_ => CAMTYPE.GOOD,
|
|
||||||
};
|
|
||||||
|
|
||||||
FakeCamera fakeCamera = new(80); // Create an instance of FakeCamera
|
|
||||||
|
|
||||||
_ = fakeCamera.StartAsync(CAMTYPE).ContinueWith(task =>
|
|
||||||
{
|
|
||||||
if (task.IsFaulted)
|
|
||||||
AddToActionsList("Error starting FakeCamera: " + task.Exception?.Message);
|
|
||||||
else
|
|
||||||
AddToActionsList($"FakeCamera started successfully. IP: {fakeCamera}", false);
|
|
||||||
});
|
|
||||||
|
|
||||||
await Task.Delay(5000); // Wait for server to start
|
|
||||||
CbBxFoundCams.Text = "localhost"; // Should force update in creds an network reinit
|
|
||||||
CbBxFoundCams_SelectedIndexChanged(sender, e);
|
|
||||||
CbBxCameraType.SelectedIndex = CbBxCameraType.Items.Count - 1; // Selects AB12CD as model number
|
|
||||||
|
|
||||||
while(TxBxOutput.Text.Length < 2) // Wait for developer password to be generated
|
|
||||||
await Task.Delay(1000);
|
|
||||||
|
|
||||||
if (TestingType.Contains("FINAL"))
|
|
||||||
BtnStartTest_Click(sender, e); // Run final test
|
|
||||||
else if (TestingType.Contains("PRE"))
|
|
||||||
BtnPreTest_Click(sender, e); // Run pre-test
|
|
||||||
|
|
||||||
fakeCamera.Stop(); // Stop the server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double EstimateSpeed(List<FrameData> frames)
|
||||||
|
{
|
||||||
|
double TimeElapsed = 0;
|
||||||
|
int frameCount = frames.Count;
|
||||||
|
|
||||||
|
for (int i = 1; i < frameCount; i++)
|
||||||
|
{
|
||||||
|
double time = (frames[i].FrameID - frames[i - 1].FrameID) / FrameRate;
|
||||||
|
TimeElapsed += time;
|
||||||
|
}
|
||||||
|
|
||||||
|
double FarDist = (FocalLengthPixels * RealPlateWidthMeters) / frames[0].PlateWidthPixels;
|
||||||
|
double CloseDist = (FocalLengthPixels * RealPlateWidthMeters) / frames[frameCount - 1].PlateWidthPixels;
|
||||||
|
|
||||||
|
double speedMph = (Math.Abs(FarDist - CloseDist) / TimeElapsed) * 2.237;
|
||||||
|
return speedMph;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ***** Test & Debug *****
|
// ***** Test & Debug *****
|
||||||
private void BtnTest_Click(object sender, EventArgs e)
|
private void BtnTest_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Stopwatch stopWatchTest = Stopwatch.StartNew();
|
Stopwatch stopWatchTest = Stopwatch.StartNew();
|
||||||
|
|
||||||
// *** To be put in startup code!!!! ***
|
|
||||||
if (Properties.Settings.Default.UnitTesting != "NOT_STARTED")
|
|
||||||
BtnTest_Click(sender, e);
|
|
||||||
|
|
||||||
// *** TO be put in test button ***
|
List<FrameData> frames = new List<FrameData>
|
||||||
if (Properties.Settings.Default.UnitTesting == "NOT_STARTED")
|
|
||||||
{
|
{
|
||||||
SwitchTest("GOOD_PRE");
|
new FrameData { FrameID = 60192555, PlatePosX = 1172, PlatePosY = 393, PlateWidthPixels = 108 },
|
||||||
|
new FrameData { FrameID = 60192556, PlatePosX = 1103, PlatePosY = 361, PlateWidthPixels = 105 },
|
||||||
|
new FrameData { FrameID = 60192558, PlatePosX = 983, PlatePosY = 331, PlateWidthPixels = 99 },
|
||||||
|
new FrameData { FrameID = 60192559, PlatePosX = 930, PlatePosY = 301, PlateWidthPixels = 95 },
|
||||||
|
new FrameData { FrameID = 60192560, PlatePosX = 880, PlatePosY = 304, PlateWidthPixels = 93 },
|
||||||
|
new FrameData { FrameID = 60192561, PlatePosX = 834, PlatePosY = 278, PlateWidthPixels = 89 },
|
||||||
|
new FrameData { FrameID = 60192562, PlatePosX = 792, PlatePosY = 229, PlateWidthPixels = 87 },
|
||||||
|
new FrameData { FrameID = 60192563, PlatePosX = 752, PlatePosY = 208, PlateWidthPixels = 85 },
|
||||||
|
new FrameData { FrameID = 60192565, PlatePosX = 680, PlatePosY = 187, PlateWidthPixels = 81 },
|
||||||
|
new FrameData { FrameID = 60192566, PlatePosX = 648, PlatePosY = 167, PlateWidthPixels = 78 },
|
||||||
|
new FrameData { FrameID = 60192567, PlatePosX = 617, PlatePosY = 149, PlateWidthPixels = 76 },
|
||||||
|
new FrameData { FrameID = 60192568, PlatePosX = 588, PlatePosY = 132, PlateWidthPixels = 75 },
|
||||||
|
new FrameData { FrameID = 60192569, PlatePosX = 561, PlatePosY = 100, PlateWidthPixels = 70 },
|
||||||
|
new FrameData { FrameID = 60192570, PlatePosX = 535, PlatePosY = 85, PlateWidthPixels = 72 },
|
||||||
|
new FrameData { FrameID = 60192572, PlatePosX = 488, PlatePosY = 70, PlateWidthPixels = 69 },
|
||||||
|
new FrameData { FrameID = 60192573, PlatePosX = 466, PlatePosY = 55, PlateWidthPixels = 67 }
|
||||||
|
};
|
||||||
|
|
||||||
// Run Good pre test
|
double Spd = EstimateSpeed(frames);
|
||||||
// Check it was the correct outcome
|
AddToActionsList("Estimated Speed: " + Spd.ToString("F2") + " MPH");
|
||||||
// Restart GUI
|
|
||||||
}
|
|
||||||
else if (Properties.Settings.Default.UnitTesting == "GOOD_PRE")
|
|
||||||
{
|
|
||||||
SwitchTest("GOOD_FINAL");
|
|
||||||
|
|
||||||
// Run Good final test
|
|
||||||
// Check it was the correct outcome
|
|
||||||
// Restart GUI
|
|
||||||
}
|
|
||||||
else if (Properties.Settings.Default.UnitTesting == "GOOD_FINAL")
|
|
||||||
{
|
|
||||||
SwitchTest("BAD_PRE");
|
|
||||||
|
|
||||||
// Run Bad pre test
|
|
||||||
// Check it was the correct outcome
|
|
||||||
// Restart GUI
|
|
||||||
}
|
|
||||||
// etc...
|
|
||||||
|
|
||||||
//// SSH testing
|
|
||||||
//sshData = SSH.CollectSSHData("localhost");
|
|
||||||
//AddToActionsList(sshData.packages);
|
|
||||||
//AddToActionsList(sshData.FilesystemSize);
|
|
||||||
//AddToActionsList($"{sshData.tailscale}");
|
|
||||||
|
|
||||||
//// Functionality testing
|
|
||||||
//// TODO - SSH server needs to be running at this point for this to work
|
|
||||||
//var server = new FakeCamera(80); // Start the HTTP server in a background task
|
|
||||||
//_ = server.StartAsync(CAMTYPE.GOOD); // Start the server running with correct responses
|
|
||||||
//Task.Delay(1000).Wait(); // Wait for server to start
|
|
||||||
|
|
||||||
//CbBxCameraType.SelectedIndex = CbBxCameraType.Items.Count - 1; // Selects AB12CD as model number
|
|
||||||
//CbBxFoundCams.Text = "localhost"; // Should force update in creds an network reinit
|
|
||||||
|
|
||||||
//BtnPreTest_Click(sender, e); // Run pre-test
|
|
||||||
//BtnStartTest_Click(sender, e); // Run full test
|
|
||||||
//server.Stop(); // Stop the server
|
|
||||||
|
|
||||||
//_ = server.StartAsync(CAMTYPE.BAD); // Start the server running with bad responses
|
|
||||||
//Task.Delay(1000).Wait(); // Wait for server to start
|
|
||||||
//BtnPreTest_Click(sender, e); // Run pre-test
|
|
||||||
//BtnStartTest_Click(sender, e); // Run full test
|
|
||||||
//server.Stop(); // Stop the server
|
|
||||||
|
|
||||||
//_ = server.StartAsync(CAMTYPE.BIZARRE); // Start the server running with incorrect types and odd responses
|
|
||||||
//Task.Delay(1000).Wait(); // Wait for server to start
|
|
||||||
//BtnPreTest_Click(sender, e); // Run pre-test
|
|
||||||
//BtnStartTest_Click(sender, e); // Run full test
|
|
||||||
//server.Stop(); // Stop the server
|
|
||||||
|
|
||||||
stopWatchTest.Stop();
|
stopWatchTest.Stop();
|
||||||
AddToActionsList("RunTime " + stopWatchTest.Elapsed.ToString(@"hh\:mm\:ss\.ff"));
|
AddToActionsList("RunTime " + stopWatchTest.Elapsed.ToString(@"hh\:mm\:ss\.ff"));
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
<Product>AiQ GUI</Product>
|
<Product>AiQ GUI</Product>
|
||||||
<Authors>MAV Systems Ltd</Authors>
|
<Authors>MAV Systems Ltd</Authors>
|
||||||
<PackageId>AiQ GUI</PackageId>
|
<PackageId>AiQ GUI</PackageId>
|
||||||
<Version>3.12.0</Version>
|
<Version>3.14.0</Version>
|
||||||
<Description>A GUI to control and test the AiQ</Description>
|
<Description>A GUI to control and test the AiQ</Description>
|
||||||
<Copyright>MAV Systems Ltd 2025</Copyright>
|
<Copyright>MAV Systems Ltd 2025</Copyright>
|
||||||
<PackageIcon>MAV - Plain - Blue.png</PackageIcon>
|
<PackageIcon>MAV - Plain - Blue.png</PackageIcon>
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<RootNamespace>AiQ_GUI</RootNamespace>
|
<RootNamespace>AiQ_GUI</RootNamespace>
|
||||||
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<SignAssembly>False</SignAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
@@ -41,18 +42,18 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ClosedXML" Version="0.105.0" />
|
<PackageReference Include="ClosedXML" Version="0.105.0" />
|
||||||
<PackageReference Include="Emgu.CV" Version="4.12.0.5763" />
|
<PackageReference Include="Emgu.CV" Version="4.12.0.5764" />
|
||||||
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.12.0.5763" />
|
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.12.0.5764" />
|
||||||
<PackageReference Include="Google.Apis.Auth" Version="1.70.0" />
|
<PackageReference Include="Google.Apis.Auth" Version="1.71.0" />
|
||||||
<PackageReference Include="Google.Apis.Gmail.v1" Version="1.70.0.3833" />
|
<PackageReference Include="Google.Apis.Gmail.v1" Version="1.70.0.3833" />
|
||||||
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.70.0.3819" />
|
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.70.0.3819" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="PDFsharp-MigraDoc-gdi" Version="6.2.1" />
|
<PackageReference Include="PDFsharp-MigraDoc-gdi" Version="6.2.1" />
|
||||||
<PackageReference Include="Selenium.Support" Version="4.35.0" />
|
<PackageReference Include="Selenium.Support" Version="4.35.0" />
|
||||||
<PackageReference Include="Selenium.WebDriver" Version="4.35.0" />
|
<PackageReference Include="Selenium.WebDriver" Version="4.35.0" />
|
||||||
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="139.0.7258.15400" />
|
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="140.0.7339.8200" />
|
||||||
<PackageReference Include="SSH.NET" Version="2025.0.0" />
|
<PackageReference Include="SSH.NET" Version="2025.0.0" />
|
||||||
<PackageReference Include="System.Data.OleDb" Version="9.0.8" />
|
<PackageReference Include="System.Data.OleDb" Version="9.0.9" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
127
AvailableCondigID.json
Normal file
127
AvailableCondigID.json
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
{
|
||||||
|
"ids": [
|
||||||
|
"Dispatcher3-meta",
|
||||||
|
"RaptorOCRColour",
|
||||||
|
"MMCQueueInfrared",
|
||||||
|
"Wizards",
|
||||||
|
"TargetDetection--sequence-target-finder",
|
||||||
|
"Colour--LiveVideoInput",
|
||||||
|
"SightingCreator--CropPreview",
|
||||||
|
"Dispatcher2-json",
|
||||||
|
"SightingAmmend0-lane-ids",
|
||||||
|
"SightingAmmend1-custom-fields",
|
||||||
|
"colourHistory",
|
||||||
|
"Dispatcher0-json",
|
||||||
|
"SightingAmmend1-lane-ids",
|
||||||
|
"TargetDetectionColour-zone-10",
|
||||||
|
"Audit--Infrared",
|
||||||
|
"Dispatcher1-utmc-constants",
|
||||||
|
"-dev-ttyACM1",
|
||||||
|
"SightingAmmend2-zone-names",
|
||||||
|
"TargetDetection-zone--2",
|
||||||
|
"TargetDetection-zone--1",
|
||||||
|
"Dispatcher3-json",
|
||||||
|
"-dev-ttyACM0",
|
||||||
|
"Dispatcher2-utmc-constants",
|
||||||
|
"SightingAmmend0-overlay",
|
||||||
|
"SightingAmmend0-zone-name-overrides",
|
||||||
|
"TargetDetection-zone-4",
|
||||||
|
"TargetDetection-zone-5",
|
||||||
|
"GLOBAL--GPS",
|
||||||
|
"Dispatcher2-bof2-constants",
|
||||||
|
"TargetDetection-zone-1",
|
||||||
|
"TargetDetection-zone-2",
|
||||||
|
"SightingCreator-timing-line-config",
|
||||||
|
"TargetDetection-zone-3",
|
||||||
|
"Infrared",
|
||||||
|
"Dispatcher1-bof2",
|
||||||
|
"UpdateSentinel",
|
||||||
|
"Infrared--RTSP",
|
||||||
|
"Colour",
|
||||||
|
"TargetDetectionColour--TrakVideoWidget",
|
||||||
|
"Infrared--VMS",
|
||||||
|
"Dispatcher0-bof2",
|
||||||
|
"SightingCreator",
|
||||||
|
"TargetDetection",
|
||||||
|
"SightingAmmend3-overlay",
|
||||||
|
"Telemetry",
|
||||||
|
"Colour--camera-control-widget-config",
|
||||||
|
"GLOBAL--NetworkConfig",
|
||||||
|
"Audit",
|
||||||
|
"Dispatcher2-meta",
|
||||||
|
"TargetDetection--VideoPreview",
|
||||||
|
"TargetDetectionColour--sequence-target-finder",
|
||||||
|
"MMCQueueColour",
|
||||||
|
"mergedHistory",
|
||||||
|
"TargetDetection--TrakVideoWidget",
|
||||||
|
"SightingCreator--SightingHeatMap",
|
||||||
|
"GLOBAL--Passwords",
|
||||||
|
"TargetDetectionColour--VideoPreview",
|
||||||
|
"LogView",
|
||||||
|
"Colour--RTSP",
|
||||||
|
"Dispatcher2-utmc",
|
||||||
|
"Dispatcher3-utmc-constants",
|
||||||
|
"SightingAmmend3-zone-name-overrides",
|
||||||
|
"SightingAmmend0-zone-names",
|
||||||
|
"SightingAmmend2",
|
||||||
|
"SightingAmmend1",
|
||||||
|
"SightingAmmend0",
|
||||||
|
"SightingCreator-camera-offset",
|
||||||
|
"SightingAmmend3",
|
||||||
|
"TargetDetectionColour--TargetDetectionFilter",
|
||||||
|
"SightingAmmend3-lane-ids",
|
||||||
|
"Dispatcher3-bof2",
|
||||||
|
"Dispatcher1-utmc",
|
||||||
|
"Dispatcher0-utmc-constants",
|
||||||
|
"Audit--Recorder",
|
||||||
|
"Dispatcher0-bof2-constants",
|
||||||
|
"SightingAmmend2-overlay",
|
||||||
|
"Store2",
|
||||||
|
"Store1",
|
||||||
|
"Store3",
|
||||||
|
"TargetDetectionColour-zone--2",
|
||||||
|
"TargetDetectionColour",
|
||||||
|
"TargetDetectionColour-zone--1",
|
||||||
|
"SightingAmmend0-custom-fields",
|
||||||
|
"Dispatcher1-bof2-constants",
|
||||||
|
"RaptorOCR",
|
||||||
|
"Dispatcher0-utmc",
|
||||||
|
"Store0",
|
||||||
|
"Dispatcher1",
|
||||||
|
"Dispatcher2",
|
||||||
|
"TargetIdentifiedProcessingQueue",
|
||||||
|
"Dispatcher0",
|
||||||
|
"GLOBAL--Device",
|
||||||
|
"Dispatcher3-utmc",
|
||||||
|
"SightingAmmend3-zone-names",
|
||||||
|
"Dispatcher3",
|
||||||
|
"Dispatcher0-meta",
|
||||||
|
"SightingCreator--TimingLineVideoWidgetInfrared",
|
||||||
|
"SightingCreator--TimingLineVideoWidgetColour",
|
||||||
|
"SightingAmmend2-lane-ids",
|
||||||
|
"Dispatcher3-bof2-constants",
|
||||||
|
"WidgetViewer",
|
||||||
|
"TargetDetectionColour-zone-8",
|
||||||
|
"TargetDetectionColour-zone-9",
|
||||||
|
"TargetDetectionColour-zone-6",
|
||||||
|
"TargetDetectionColour-zone-7",
|
||||||
|
"Dispatcher1-meta",
|
||||||
|
"SightingAmmend1-zone-names",
|
||||||
|
"Audit--Colour",
|
||||||
|
"SightingAmmend1-zone-name-overrides",
|
||||||
|
"TargetDetectionProcessingQueue",
|
||||||
|
"SightingAmmend2-zone-name-overrides",
|
||||||
|
"Infrared--camera-control-widget-config",
|
||||||
|
"SightingAmmend3-custom-fields",
|
||||||
|
"Infrared--LiveVideoInput",
|
||||||
|
"TargetDetectionProcessingQueueColour",
|
||||||
|
"VideoFramePairCreator",
|
||||||
|
"Colour--VMS",
|
||||||
|
"Dispatcher2-bof2",
|
||||||
|
"infraredHistory",
|
||||||
|
"Dispatcher1-json",
|
||||||
|
"SightingAmmend1-overlay",
|
||||||
|
"SightingAmmend2-custom-fields",
|
||||||
|
"TargetDetection--TargetDetectionFilter"
|
||||||
|
]
|
||||||
|
}
|
@@ -71,10 +71,8 @@ namespace AiQ_GUI
|
|||||||
string OneshotReply = await FlexiAPI.APIHTTPVISCA(IPAddress, "8101041801FF", true); // Oneshot auto focus
|
string OneshotReply = await FlexiAPI.APIHTTPVISCA(IPAddress, "8101041801FF", true); // Oneshot auto focus
|
||||||
|
|
||||||
if (!ShutterReply.Contains("41") || !IrisReply.Contains("41") || !GainReply.Contains("41") || !OneshotReply.Contains("41"))
|
if (!ShutterReply.Contains("41") || !IrisReply.Contains("41") || !GainReply.Contains("41") || !OneshotReply.Contains("41"))
|
||||||
{
|
|
||||||
MainForm.Instance.AddToActionsList("Could not set Shutter, Iris, Gain correctly" + Environment.NewLine + "Shutter: " + ShutterReply + Environment.NewLine + "Iris: " + IrisReply + Environment.NewLine + "Gain: " + GainReply + Environment.NewLine + "Oneshot: " + OneshotReply);
|
MainForm.Instance.AddToActionsList("Could not set Shutter, Iris, Gain correctly" + Environment.NewLine + "Shutter: " + ShutterReply + Environment.NewLine + "Iris: " + IrisReply + Environment.NewLine + "Gain: " + GainReply + Environment.NewLine + "Oneshot: " + OneshotReply);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Sets back to the latest factory defaults CSV that is in Flexi.
|
// Sets back to the latest factory defaults CSV that is in Flexi.
|
||||||
public static async Task FactoryResetModules(string IPAddress)
|
public static async Task FactoryResetModules(string IPAddress)
|
||||||
|
@@ -49,9 +49,8 @@ namespace AiQ_GUI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string JSONdata = "{ \"id\":\"" + ID + "\" }";
|
string url = $"http://{IPAddress}/api/fetch-config?id={ID}";
|
||||||
string url = $"http://{IPAddress}/api/fetch-config";
|
return await Network.SendHttpRequest(url, HttpMethod.Get, Timeout);
|
||||||
return await Network.SendHttpRequest(url, HttpMethod.Get, Timeout, JSONdata);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -87,14 +86,13 @@ namespace AiQ_GUI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Network.Client.DefaultRequestHeaders.ExpectContinue = false;
|
Network.Client.DefaultRequestHeaders.ExpectContinue = false;
|
||||||
MultipartFormDataContent content;
|
|
||||||
|
|
||||||
byte[] fileBytes = await File.ReadAllBytesAsync(filePath).ConfigureAwait(false);
|
byte[] fileBytes = await File.ReadAllBytesAsync(filePath).ConfigureAwait(false);
|
||||||
MemoryStream ms = new(fileBytes);
|
MemoryStream ms = new(fileBytes);
|
||||||
StreamContent streamContent = new(ms);
|
StreamContent streamContent = new(ms);
|
||||||
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
|
|
||||||
content = new MultipartFormDataContent { { streamContent, "upload", fileName } };
|
MultipartFormDataContent content = new() { { streamContent, "upload", fileName } };
|
||||||
|
|
||||||
using HttpResponseMessage response = await Network.Client.PostAsync(url, content);
|
using HttpResponseMessage response = await Network.Client.PostAsync(url, content);
|
||||||
string responseBody = await response.Content.ReadAsStringAsync();
|
string responseBody = await response.Content.ReadAsStringAsync();
|
||||||
@@ -189,6 +187,80 @@ namespace AiQ_GUI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task SetTrim(string IPAddress, string LblTxt, int RetryCount = 0) // Sets trim by getting plate postion as metric
|
||||||
|
{
|
||||||
|
Trim trim;
|
||||||
|
string trimData = await APIHTTPRequest("/SightingCreator-plate-positions", IPAddress, 5); // Get plate positions
|
||||||
|
|
||||||
|
try // Deserialise the JSON
|
||||||
|
{
|
||||||
|
Logging.LogMessage("Trim Data: " + trimData);
|
||||||
|
trim = JsonConvert.DeserializeObject<Trim>(trimData);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
MainForm.Instance.AddToActionsList("Error reading trim JSON - " + trimData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check no value is -1 (no plate found) or if the positions are identical (one plate found). If it is then try again 3 times
|
||||||
|
if (new[] { trim.infraredX, trim.infraredY, trim.colourX, trim.colourY }.Any(value => value == -1)
|
||||||
|
|| (trim.infraredX == trim.colourX && trim.infraredY == trim.colourY))
|
||||||
|
{
|
||||||
|
if (RetryCount >= 3)
|
||||||
|
{
|
||||||
|
await MainForm.Instance.DisplayOK("Please align trim in webpage then click OK."); // Awaited till OK has been clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(5000); // Give 5 second delay for it to see a plate
|
||||||
|
await SetTrim(IPAddress, LblTxt, RetryCount++);
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 105;
|
||||||
|
|
||||||
|
if (LblTxt == "❌") // Test tube not connected so do the 2.7m check.
|
||||||
|
offset = 98;
|
||||||
|
|
||||||
|
// Horizontal distance offset for 2.7m compared to 30m is 98 pixels. This was empirically found from testing in the car park
|
||||||
|
// Colour camera is to the right of the infrared so it gets the offset.
|
||||||
|
// Using similar triangles going from 2.7m -> 0.65m which is the length of the test tube (Also exactly 1/4 length).
|
||||||
|
// 98 * (29.35/27.3) = 105.35 pixels
|
||||||
|
int OverviewX = trim.colourX + offset;
|
||||||
|
|
||||||
|
if (OverviewX > 1920) // If adding on the offset has pushed it out of limits then remove 0.1
|
||||||
|
{
|
||||||
|
if (OverviewX < 2120 && trim.infraredX > 400) // Within enough of a limit to automatically do it
|
||||||
|
{
|
||||||
|
OverviewX -= 200;
|
||||||
|
trim.infraredX -= 200;
|
||||||
|
}
|
||||||
|
else // Ask user to centre the plate in the field of view
|
||||||
|
{
|
||||||
|
await MainForm.Instance.DisplayOK("Please centralise plate in view THEN press OK"); // Awaited till OK has been clicked
|
||||||
|
|
||||||
|
if (RetryCount >= 3)
|
||||||
|
{
|
||||||
|
await MainForm.Instance.DisplayOK("Please align trim in webpage then click OK."); // Awaited till OK has been clicked
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await Task.Delay(5000); // Give 5 second delay for it to see a plate
|
||||||
|
await SetTrim(IPAddress, LblTxt, RetryCount++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compensated trim values, therefore should be close to 0,0 with limits of ±5% of 1920 and 1080 respectivly being ±96 and ±54
|
||||||
|
int TrimX = trim.infraredX - OverviewX;
|
||||||
|
int TrimY = trim.infraredY - trim.colourY;
|
||||||
|
|
||||||
|
// Update trim values
|
||||||
|
string[,] Trim_JSON = { { "propInterCameraOffsetX", Convert.ToString(TrimX) }, { "propInterCameraOffsetY", Convert.ToString(TrimY) } };
|
||||||
|
string TrimResp = await HTTP_Update("SightingCreator", IPAddress, Trim_JSON);
|
||||||
|
|
||||||
|
if (!TrimResp.Contains($"\"propInterCameraOffsetX\": {{\"value\": \"{Convert.ToString(TrimX)}\", \"datatype\": \"int\"}}, \"propInterCameraOffsetY\": {{\"value\": \"{Convert.ToString(TrimY)}\", \"datatype\": \"int\"}},"))
|
||||||
|
MainForm.Instance.AddToActionsList("Could not set camera trim");
|
||||||
|
}
|
||||||
|
|
||||||
// Processes the network config from the camera and returns a string indicating the status
|
// Processes the network config from the camera and returns a string indicating the status
|
||||||
public static async Task<string> ProcessNetworkConfig(string IPAddress)
|
public static async Task<string> ProcessNetworkConfig(string IPAddress)
|
||||||
{
|
{
|
||||||
@@ -210,7 +282,7 @@ namespace AiQ_GUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Knowing the format this builds the message to send to AiQ
|
// Knowing the format this builds the message to send to AiQ
|
||||||
private static string BuildJsonUpdate(string[,] jsonData, string id)
|
public static string BuildJsonUpdate(string[,] jsonData, string id)
|
||||||
{
|
{
|
||||||
if (jsonData == null || jsonData.GetLength(1) != 2)
|
if (jsonData == null || jsonData.GetLength(1) != 2)
|
||||||
throw new ArgumentException("Input data must be a non-null 2D array with two columns.");
|
throw new ArgumentException("Input data must be a non-null 2D array with two columns.");
|
||||||
|
@@ -14,7 +14,7 @@ namespace AiQ_GUI
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using SshClient client = new SshClient(IPAddress, SSHUsername, SSHPassword);
|
using SshClient client = new(IPAddress, SSHUsername, SSHPassword);
|
||||||
client.Connect();
|
client.Connect();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@@ -12,7 +12,7 @@ namespace AiQ_GUI
|
|||||||
|
|
||||||
public static void Initialize(string username, string password)
|
public static void Initialize(string username, string password)
|
||||||
{
|
{
|
||||||
HttpClientHandler handler = new HttpClientHandler
|
HttpClientHandler handler = new()
|
||||||
{
|
{
|
||||||
MaxConnectionsPerServer = 25,
|
MaxConnectionsPerServer = 25,
|
||||||
Credentials = new NetworkCredential(username, password)
|
Credentials = new NetworkCredential(username, password)
|
||||||
@@ -30,7 +30,7 @@ namespace AiQ_GUI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpRequestMessage request = new HttpRequestMessage(method, url);
|
HttpRequestMessage request = new(method, url);
|
||||||
|
|
||||||
if (jsonData != null) // Fills in the body of the request if jsonData is provided
|
if (jsonData != null) // Fills in the body of the request if jsonData is provided
|
||||||
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
|
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
|
||||||
@@ -48,8 +48,8 @@ namespace AiQ_GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int timeoutMs = (Timeout ?? 10) * 1000; // Convert from seconds to ms
|
int timeoutMs = (Timeout ?? 10) * 1000; // Convert from seconds to ms, default to 10s if null
|
||||||
using CancellationTokenSource cts = new CancellationTokenSource(timeoutMs);
|
using CancellationTokenSource cts = new(timeoutMs);
|
||||||
|
|
||||||
using HttpResponseMessage response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
|
using HttpResponseMessage response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
73
Test.json
Normal file
73
Test.json
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"id": "GLOBAL--Device",
|
||||||
|
"configHash": "101478235",
|
||||||
|
"propHardwarePlatform": {
|
||||||
|
"value": "JETSON_NANO",
|
||||||
|
"datatype": "mav.flexi.web.pages.SystemConfig$HardwareConfigurationOption",
|
||||||
|
"accepted": "[NONE, JETSON_NANO, JETSON_XAVIER, RASPBERRY_PI_CM4, RASPBERRY_PI_CM5, DEVELOPER_WORKSTATION]"
|
||||||
|
},
|
||||||
|
"propApplicationPlatform": {
|
||||||
|
"value": "CUSTOM",
|
||||||
|
"datatype": "mav.flexi.web.pages.SystemConfig$ApplicationConfigurationOption",
|
||||||
|
"accepted": "[NONE, CUSTOM, MONO_BASIC_ANPR, DUAL_CAMERA_BASIC_ANPR, SINGLE_SAF_DUAL_CAMERA_BASIC_ANPR, DUAL_CAMERA_STREAMING, BAYGUARD, SITE_ACCESS_CONTROL_WITH_MODBUS, WAPOL_IQ50_VRM_CORRECTION, BAYWATCH_MONO_CAM, BAYWATCH_DUAL_CAM, BAYWATCH_TRIPLE_CAM, BAYWATCH_QUADRUPLE_CAM, IN_CAR_ANPR]"
|
||||||
|
},
|
||||||
|
"propDeviceName": {
|
||||||
|
"value": "Test Nano",
|
||||||
|
"datatype": "java.lang.String"
|
||||||
|
},
|
||||||
|
"propLocalTimeZone": {
|
||||||
|
"value": "Europe/London (UTC+00)",
|
||||||
|
"datatype": "mav.util.TimeZoneEnum",
|
||||||
|
"accepted": "[Africa/Cairo (UTC+02), Africa/Johannesburg (UTC+02), Africa/Lagos (UTC+01), Africa/Monrousing (UTC+00), America/Anchorage (UTC-09), America/Chicago (UTC-06), America/Denver (UTC-07), America/Edmonton (UTC-07), America/Jamaica (UTC-05), America/Los Angeles (UTC-08), America/Mexico City (UTC-06), America/Montreal (UTC-05), America/New/York (UTC-05), America/Phoenix (UTC-07), America/Puerto Rico (UTC-04), America/Sao Paulo (UTC-03), America/Toronto (UTC-05), America/Vancouver (UTC-08), Asia/Hong Kong (UTC+08), Asia/Jerusalem (UTC+02), Asia/Manila (UTC+08), Asia/Seoul (UTC+09), Asia/Tokyo (UTC+09), Atlantic/Reykjavik (UTC+00), Australia/Perth (UTC+08), Australia/Sydney (UTC+10), Europe/Athens (UTC+02), Europe/Berlin (UTC+01), Europe/Brussels (UTC+01), Europe/Copenhagen (UTC+01), Europe/London (UTC+00), Europe/Madrid (UTC+01), Europe/Moscow (UTC+04), Europe/Paris (UTC+01), Europe/Prague (UTC+01), Europe/Rome (UTC+01), Europe/Warsaw (UTC+01), Pacific/Guam (UTC+10), Pacific/Honolulu (UTC-10), UTC (UTC-00)]"
|
||||||
|
},
|
||||||
|
"propTimeSource": {
|
||||||
|
"value": "SNTP Only",
|
||||||
|
"datatype": "mav.flexi.web.pages.SystemConfig$TimeSourceEnum",
|
||||||
|
"accepted": "[SNTP Only, GPS Only, SNTP + Soft GPS]"
|
||||||
|
},
|
||||||
|
"propSNTPServer": {
|
||||||
|
"value": "1.uk.pool.ntp.org",
|
||||||
|
"datatype": "java.lang.String"
|
||||||
|
},
|
||||||
|
"propSNTPIntervalMinutes": {
|
||||||
|
"value": "public long mav.flexi.web.pages.SystemConfig$DeviceConfig.propSNTPIntervalMinutes",
|
||||||
|
"datatype": "long",
|
||||||
|
"range": {
|
||||||
|
"minimum": "1.000000",
|
||||||
|
"maximum": "99999.000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"propOutputsMaxTimeSyncAge": {
|
||||||
|
"value": "24 hours",
|
||||||
|
"datatype": "mav.flexi.web.pages.SystemConfig$HoursEnum",
|
||||||
|
"accepted": "[NO LIMIT, 01 hours, 02 hours, 03 hours, 04 hours, 05 hours, 06 hours, 07 hours, 08 hours, 09 hours, 10 hours, 11 hours, 12 hours, 18 hours, 24 hours, 36 hours, 48 hours, 72 hours, 96 hours]"
|
||||||
|
},
|
||||||
|
"propReservedMemoryMegabytes": {
|
||||||
|
"value": "public long mav.flexi.web.pages.SystemConfig$DeviceConfig.propReservedMemoryMegabytes",
|
||||||
|
"datatype": "long",
|
||||||
|
"range": {
|
||||||
|
"minimum": "1000.000000",
|
||||||
|
"maximum": "128000.000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"propClientTrustStorePassword": {
|
||||||
|
"value": "",
|
||||||
|
"datatype": "java.lang.String"
|
||||||
|
},
|
||||||
|
"propFlexiScriptPath": {
|
||||||
|
"value": "/home/mav/FlexiAI/bin/FlexiAI",
|
||||||
|
"datatype": "java.lang.String"
|
||||||
|
},
|
||||||
|
"propVideo0Tee": {
|
||||||
|
"value": "video0tee",
|
||||||
|
"datatype": "java.lang.String"
|
||||||
|
},
|
||||||
|
"propVideo1Tee": {
|
||||||
|
"value": "video1tee",
|
||||||
|
"datatype": "java.lang.String"
|
||||||
|
},
|
||||||
|
"propRestartCameraModulesOnBoot": {
|
||||||
|
"value": "true",
|
||||||
|
"datatype": "boolean"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user