786 lines
36 KiB
C#
786 lines
36 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.IO.Ports;
|
|
using XYLEM.Communication;
|
|
using System.Xml.Linq;
|
|
using XYLEM.Base;
|
|
using XYLEM.Communication.ValueEncoders;
|
|
using System.Linq.Expressions;
|
|
using System.Threading;
|
|
using MagFlux6200_metrology_reg_list;
|
|
using XYLEM.Device;
|
|
using static modbus_master_csharp.Program;
|
|
using System.Diagnostics.Contracts;
|
|
using System.Security.Policy;
|
|
using System.IO;
|
|
using System.Diagnostics;
|
|
using System.Xml.Schema;
|
|
using System.Net.NetworkInformation;
|
|
|
|
namespace modbus_master_csharp
|
|
{
|
|
internal class Program
|
|
{
|
|
static bool LIVE_RUN = true;
|
|
#if (DEBUG)
|
|
//static bool LIVE_RUN = false; // overwrite default
|
|
static bool LIVE_RUN_DIRECT_MET = false; // Run using RS485 9600,8,E setup as default
|
|
//static bool LIVE_RUN_DIRECT_MET = LIVE_RUN & true; // overwrite default to Run using 115200,8,N setup as default
|
|
#endif
|
|
|
|
/*For testing directly to metrology */
|
|
static string[] argsDefault1 = new string[] { "TEST", "COM11", "115200", "N" };
|
|
/*For metrology RS485 when transparent to metrology*/
|
|
static string[] argsDefault2 = new string[] { "SAVE_CAL", "COM2" };
|
|
// Having more ports
|
|
static string[] argsDefault3 = new string[] { "TEST", "COM2", "COM6" };
|
|
|
|
/*For metrology RS485 when transparent to metrology*/
|
|
static string[] argsDefault4 = new string[] { "LOAD_CAL=\"0_sensor_cal_for_testing.xml\"", "COM2" };
|
|
|
|
/*For metrology RS485 when transparent to metrology*/
|
|
static string[] argsDefault5 = new string[] { "TEST", "COM2" };
|
|
|
|
|
|
#region Reused functions for testing
|
|
private static bool GetDeviceHealthy(IMagFluxRequestProtocol dut)
|
|
{
|
|
var name = nameof(dut.GetDeviceHealthy);
|
|
var isOkay = dut.GetDeviceHealthy();
|
|
var message = $"{name}: {(isOkay ? "Is okay" : "Has errors")}";
|
|
if (!isOkay)
|
|
{
|
|
if (dut.GetDeviceErrorMessages(out var errorList))
|
|
{
|
|
Console.WriteLine(message + "\nError List:\n" + errorList.ToSingleString(false));
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine(message);
|
|
}
|
|
}
|
|
return isOkay;
|
|
}
|
|
|
|
private static bool GetCalibrationPoints(IMagFluxRequestProtocol dut, out CalibrationPoints value_out, bool printoutPoints)
|
|
{
|
|
var name = nameof(dut.GetCalibrationPoints);
|
|
var isOkay = dut.GetCalibrationPoints(out value_out);
|
|
if (printoutPoints)
|
|
{
|
|
Console.WriteLine($"{name}: Read points-> {(isOkay ? "\n"+value_out.ToString() : "!Read failed!")}");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"{name}: Reading calibration points {(isOkay ? "Okay" : "!Read failed!")}");
|
|
}
|
|
return isOkay;
|
|
}
|
|
|
|
private static bool SetCalibrationPoints(IMagFluxRequestProtocol dut, CalibrationPoints new_calibration_points)
|
|
{
|
|
var isOkay = dut.SetCalibrationPoints(new_calibration_points);
|
|
Console.WriteLine($"{nameof(dut.SetCalibrationPoints)}: {(isOkay ? "Okay" : "Failed")}\n{new_calibration_points}");
|
|
return isOkay;
|
|
}
|
|
|
|
|
|
private static void RunTestCalibrationPoints(IMagFluxRequestProtocol dut, CalibrationPoints new_calibration_points)
|
|
{
|
|
{ // Write calibrations
|
|
var isOkay = SetCalibrationPoints(dut, new_calibration_points);
|
|
if (!isOkay)
|
|
{
|
|
GetDeviceHealthy(dut);
|
|
throw new Exception("Failed writing the calibration to device");
|
|
}
|
|
}
|
|
{ // Get calibrations and check it
|
|
if (!GetCalibrationPoints(dut, out var value_out, false/*Don't printout*/) || (new_calibration_points != value_out))
|
|
{
|
|
GetDeviceHealthy(dut);
|
|
var msg = $"Failed! Calibration is not the same read as written to device\nWritten:\n{new_calibration_points}\nRead:\n{value_out}";
|
|
Console.WriteLine(msg);
|
|
throw new Exception(msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// save and load what is read from device
|
|
/// </summary>
|
|
/// <param name="dut"></param>
|
|
/// <param name="value_out"></param>
|
|
private static void SaveCalPointsToTempFolder(IMagFluxRequestProtocol dut, CalibrationPoints value_out)
|
|
{
|
|
var tempSaveFolder = Environment.GetEnvironmentVariable("USERPROFILE")+@"\Downloads\";
|
|
if (dut.GetSensorSerialNo(out var sensorSerial))
|
|
{
|
|
dut.GetUniqueId(out var id);
|
|
var sensor_cal_file = tempSaveFolder+$"{sensorSerial}_sensor_cal_id_{id}_{DateTime.Now.ToFileTimeTxt()}.xml";
|
|
Console.WriteLine($"Save to:\n{sensor_cal_file}");
|
|
value_out.SaveToFile(sensor_cal_file);
|
|
// Check saved data
|
|
var to_saved_points = value_out.calibrations.ToArray();
|
|
value_out.LoadFromFile(sensor_cal_file);
|
|
var loaded_points = value_out.calibrations.ToArray();
|
|
if (!to_saved_points.SequenceEqual(loaded_points))
|
|
{
|
|
var msg = $"Failed save of calibrations\nSaved:\n{to_saved_points}\nLoaded:\n{loaded_points}";
|
|
Console.WriteLine(msg);
|
|
throw new Exception(msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void SAVE_CAL(List<IMagFluxRequestProtocol> duts)
|
|
{
|
|
{ // Check Save all calibrations one DUT at a time
|
|
for (var dutIdx = 0; dutIdx < duts.Count(); dutIdx++)
|
|
{
|
|
var dut = duts[dutIdx];
|
|
Console.WriteLine($"------------------- DUT{dutIdx+1} --------------------");
|
|
try
|
|
{
|
|
if (!GetCalibrationPoints(dut, out var value_out, true/*printout points*/))
|
|
{
|
|
GetDeviceHealthy(dut);
|
|
throw new Exception("Failed saving device calibration");
|
|
}
|
|
else
|
|
{
|
|
// save and load what is read from device
|
|
SaveCalPointsToTempFolder(dut, value_out);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
dut.OpenLogFile();
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Load Calibrations
|
|
/// </summary>
|
|
/// <param name="duts"></param>
|
|
/// <param name="loadedCalibrations"></param>
|
|
private static void LOAD_CAL(List<IMagFluxRequestProtocol> duts, List<CalibrationPoints> loadedCalibrations)
|
|
{
|
|
{ // Check all Values one by one a DUT at a time
|
|
if (duts.Count() != loadedCalibrations.Count())
|
|
{
|
|
throw new Exception("The number of calibrations is not the same as DUT's to load it in");
|
|
}
|
|
Console.WriteLine("\nSave Calibrations before starting writing new calibrations\n");
|
|
SAVE_CAL(duts);
|
|
Console.WriteLine("\nStarting writing new calibrations\n");
|
|
for (var dutIdx = 0; dutIdx < duts.Count(); dutIdx++)
|
|
{
|
|
var dut = duts[dutIdx];
|
|
Console.WriteLine($"------------------- DUT{dutIdx+1} --------------------");
|
|
try
|
|
{
|
|
var new_calibration_points = loadedCalibrations[dutIdx];
|
|
var isOkay = SetCalibrationPoints(dut, new_calibration_points);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception($"Writing calibration Fail!\n{new_calibration_points}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
dut.OpenLogFile();
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void TEST(List<IMagFluxRequestProtocol> duts)
|
|
{
|
|
{ // Check all Values one by one a DUT at a time
|
|
for (var dutIdx = 0; dutIdx < duts.Count(); dutIdx++)
|
|
{
|
|
Console.WriteLine($"------------------- DUT{dutIdx+1} --------------------");
|
|
var dut = duts[dutIdx];
|
|
try
|
|
{
|
|
//if (false) // Don't do basic reads
|
|
if (true) // Do basic read test
|
|
{
|
|
{
|
|
var name = nameof(dut.GetFwGitHash);
|
|
var isOkay = dut.GetFwGitHash(out var value_out);
|
|
var message = $"{name}: {(isOkay ? value_out : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.GetSensorSerialNo);
|
|
var isOkay = dut.GetSensorSerialNo(out var value_out);
|
|
var message = $"{name}: {(isOkay ? value_out : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.GetUniqueId);
|
|
var isOkay = dut.GetUniqueId(out var value_out);
|
|
var message = $"{name}: {(isOkay ? value_out : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.GetFirmwareVersion);
|
|
var isOkay = dut.GetFirmwareVersion(out var value_out);
|
|
var message = $"{name}: {(isOkay ? value_out : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.GetFwBuildDate);
|
|
var isOkay = dut.GetFwBuildDate(out var value_out);
|
|
var message = $"{name}: {(isOkay ? value_out : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.GetFlowRate_lps);
|
|
var isOkay = dut.GetFlowRate_lps(out var value_out);
|
|
var message = $"{name}: {(isOkay ? $"{value_out} l/s or {value_out*3.6} m3/h" : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.GetDn_mm);
|
|
var isOkay = dut.GetDn_mm(out var value_out);
|
|
var message = $"{name}: {(isOkay ? $"{value_out}mm" : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
|
|
{
|
|
GetDeviceHealthy(dut);
|
|
}
|
|
{
|
|
var name = nameof(dut.GetDeviceErrorMessages);
|
|
var isOkay = dut.GetDeviceErrorMessages(out var value_out);
|
|
var message = $"{name}: \n{(isOkay ? String.Join("\n", value_out) : "!Read failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
var name = nameof(dut.AbortDeviceForCalibration);
|
|
var isOkay = dut.AbortDeviceForCalibration();
|
|
var message = $"{name}: {(isOkay ? "Done" : "!Abort failed!")}";
|
|
Console.WriteLine(message);
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
{
|
|
if (!GetCalibrationPoints(dut, out var value_out, true/*printout points*/))
|
|
{
|
|
GetDeviceHealthy(dut);
|
|
}
|
|
else
|
|
{
|
|
// save and load what is read from device
|
|
SaveCalPointsToTempFolder(dut, value_out);
|
|
}
|
|
}
|
|
}
|
|
//if (false) // Do not execute calibration test
|
|
if (LIVE_RUN && true) // execute calibration test
|
|
{ // A single calibration Test
|
|
{ // --- Test setting the device ready for the first measurement used for calibrations ---
|
|
{
|
|
var isOkay = dut.PrepareDeviceForCalibration();
|
|
Console.WriteLine($"{nameof(dut.PrepareDeviceForCalibration)}: {(isOkay ? "Okay" : "Failed")}");
|
|
if (!isOkay || !GetCalibrationPoints(dut, out var value_out, true/*printout points*/))
|
|
{
|
|
GetDeviceHealthy(dut);
|
|
throw new Exception("Failed Setting device up for calibration");
|
|
}
|
|
}
|
|
}
|
|
{ // --- Do a simple 2 point calibration with zero ---
|
|
var new_calibration_points = new CalibrationPoints(
|
|
new List<CalibrationPoint> {
|
|
new CalibrationPoint(0,0.001f), // 0
|
|
new CalibrationPoint(1,1.002f), // 1
|
|
new CalibrationPoint(2,2.003f), // 2
|
|
},
|
|
dut.CalibrationPointsMax // Extend to
|
|
);
|
|
RunTestCalibrationPoints(dut, new_calibration_points);
|
|
}
|
|
{ // --- Do a 6 point calibration with negative zero ---
|
|
var new_calibration_points = new CalibrationPoints(
|
|
new List<CalibrationPoint> {
|
|
new CalibrationPoint(0,-0.001f), // 0
|
|
new CalibrationPoint(1,1.002f), // 1
|
|
new CalibrationPoint(2,2.003f), // 2
|
|
new CalibrationPoint(3,3.004f), // 3
|
|
new CalibrationPoint(4,4.005f), // 4
|
|
new CalibrationPoint(5,5.006f), // 5
|
|
},
|
|
dut.CalibrationPointsMax // Extend to
|
|
);
|
|
RunTestCalibrationPoints(dut, new_calibration_points);
|
|
// save and load what is read from device
|
|
SaveCalPointsToTempFolder(dut, new_calibration_points);
|
|
}
|
|
{ // --- Do a check of write of calibrations points that is not ordered correct ---
|
|
Console.WriteLine($"Test writing calibration in wrong order is failing and Background check service is running");
|
|
{
|
|
var new_calibration_points = new CalibrationPoints(
|
|
new List<CalibrationPoint> {
|
|
new CalibrationPoint(0,-0.001f), // 0
|
|
new CalibrationPoint(3,3.002f), // 1 Error this an error in order and need to brake calibrations
|
|
new CalibrationPoint(2,2.003f), // 2
|
|
},
|
|
dut.CalibrationPointsMax // Extend to
|
|
);
|
|
var isOkay = SetCalibrationPoints(dut, new_calibration_points);
|
|
if (isOkay)
|
|
{
|
|
throw new Exception($"Writing calibration in wrong order needs to Fail!\n{new_calibration_points}");
|
|
}
|
|
int maxWait_s = 5;
|
|
while (maxWait_s-- > 0)
|
|
{
|
|
Console.Write($"\rWait timer out in {maxWait_s}s for getting Device Healthy is returning showing error: ");
|
|
if (!dut.GetFlowRate_lps(out var value_out))
|
|
{
|
|
throw new Exception($"read of flow failed during polling Device Healthy!");
|
|
}
|
|
if (!GetDeviceHealthy(dut))
|
|
{
|
|
Console.WriteLine($"\nGot correct replay that is Device healthy is \"false\"");
|
|
break; // Exit
|
|
}
|
|
Task.Delay(1000).GetAwaiter().GetResult();
|
|
}
|
|
if (maxWait_s <= 0)
|
|
{
|
|
throw new Exception($"Device Healthy was returning \"false\" when calibration was failing!\n{new_calibration_points}");
|
|
}
|
|
}
|
|
{// Cleanup by returning calibration to default
|
|
var isOkay = dut.PrepareDeviceForCalibration();
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception("Failing returning calibration to default!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
dut.OpenLogFile();
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#endregion
|
|
enum RUN_ACTION
|
|
{
|
|
UNKNOWN,
|
|
TEST,
|
|
SAVE_CAL,
|
|
LOAD_CAL,
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// For unit testing setup
|
|
/// </summary>
|
|
/// <param name="args"></param>
|
|
static void Main(string[] args)
|
|
{
|
|
int ret_error = 0; // Is okay
|
|
List<IMagFluxRequestProtocol> duts = new List<IMagFluxRequestProtocol>();
|
|
try
|
|
{
|
|
var runMode = RUN_TYPE.Mock;
|
|
if (LIVE_RUN)
|
|
{
|
|
runMode = RUN_TYPE.Normal;
|
|
}
|
|
|
|
// Just for internal testing
|
|
#if (DEBUG)
|
|
if (args.Length <= 0)
|
|
{
|
|
if(LIVE_RUN)
|
|
{
|
|
args = argsDefault5; //metrology RS485 when transparent to metrology
|
|
}
|
|
else
|
|
{
|
|
args = argsDefault5; // Run the functional test as mock
|
|
}
|
|
if (LIVE_RUN_DIRECT_MET)
|
|
{
|
|
args = argsDefault1; //testing directly to metrology
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#region Handle if arguments
|
|
bool gotArgs = (args.Length >= 1);
|
|
List<string> comports = new List<string>();
|
|
int? baudrate = null;
|
|
Parity? parity = null;
|
|
var runtask = RUN_ACTION.UNKNOWN;
|
|
var loadedCalibrations = new List<CalibrationPoints>();
|
|
var argHelpNeeded = gotArgs ? false : true;
|
|
// Use Default connection if nothing is provided by arguments
|
|
var arg_offset = 0;
|
|
if (args.Length > arg_offset)
|
|
{
|
|
// What task to do
|
|
if (args.Length > arg_offset)
|
|
{
|
|
if ("-H" == args[arg_offset].ToUpper())
|
|
{
|
|
argHelpNeeded = true;
|
|
}
|
|
else if ("TEST" == args[arg_offset].ToUpper())
|
|
{
|
|
runtask = RUN_ACTION.TEST;
|
|
}
|
|
else if ("SAVE_CAL" == args[arg_offset].ToUpper())
|
|
{
|
|
runtask = RUN_ACTION.SAVE_CAL;
|
|
}
|
|
else if (args[arg_offset].ToUpper().StartsWith("LOAD_CAL="))
|
|
{
|
|
runtask = RUN_ACTION.LOAD_CAL;
|
|
var calFilePath = args[arg_offset].Split('=').Last();
|
|
var cal = new CalibrationPoints();
|
|
if (!File.Exists(calFilePath) || !cal.LoadFromFile(calFilePath))
|
|
{
|
|
throw new InvalidDataException($"Error load calibrations from\n {calFilePath}");
|
|
}
|
|
loadedCalibrations.Add(cal);
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException($"Missing support for parameter {args[arg_offset]}");
|
|
}
|
|
}
|
|
arg_offset++;
|
|
{ // Parse com port / ports
|
|
var exit = false;
|
|
while (!exit)
|
|
{
|
|
if (args.Length > arg_offset)
|
|
{
|
|
var arg = args[arg_offset].ToUpper();
|
|
if ("COM" == arg.Remove(3))
|
|
{
|
|
comports.Add(arg);
|
|
}
|
|
else if (comports.Count <= 0)
|
|
{
|
|
Console.WriteLine($"Com port {arg} not understood.");
|
|
argHelpNeeded = true;
|
|
exit = true;
|
|
}
|
|
else
|
|
{
|
|
exit = true; // No more com to connect to
|
|
}
|
|
arg_offset++;
|
|
}
|
|
else
|
|
{
|
|
exit = true; // No more com to connect to
|
|
}
|
|
}
|
|
}
|
|
if (args.Length > arg_offset)
|
|
{
|
|
var arg = args[arg_offset].ToUpper();
|
|
var allowed_baudrate = new string[] { "9600", "19200", "38400", "57600", "115200", "230400" };
|
|
if (allowed_baudrate.Contains(arg))
|
|
{
|
|
baudrate = int.Parse(arg);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"Baud rate {arg} not known.");
|
|
baudrate = -1;
|
|
argHelpNeeded = true;
|
|
}
|
|
}
|
|
arg_offset++;
|
|
if (args.Length > arg_offset)
|
|
{
|
|
var arg = args[arg_offset].ToUpper();
|
|
if (arg == "E")
|
|
{
|
|
parity = Parity.Even;
|
|
}
|
|
else if (arg == "N")
|
|
{
|
|
parity = Parity.None;
|
|
}
|
|
else if (arg == "O")
|
|
{
|
|
parity = Parity.Odd;
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"Parity {arg} not known.");
|
|
parity = Parity.None;
|
|
argHelpNeeded = true;
|
|
}
|
|
}
|
|
}
|
|
if (argHelpNeeded)
|
|
{
|
|
var name_exe = System.AppDomain.CurrentDomain.FriendlyName;
|
|
var message = $@"
|
|
Arglist indicates help needed. See stdout.
|
|
Example of from command line:
|
|
Save calibrations only include COMx to use standard baudrate and parity setup:
|
|
""{name_exe} {argsDefault2.ToSingleString(false)}""
|
|
|
|
or run functional test for 2 MagFlux
|
|
""{name_exe} {argsDefault3.ToSingleString(false)}""
|
|
|
|
To run functional test and configure both COMx, baudrate, parity. (Used for com directly to Metrology)
|
|
""{name_exe} {argsDefault1.ToSingleString(false)}""
|
|
|
|
To Load calibrations only include COMx to use standard baudrate and parity setup:
|
|
""{name_exe} {argsDefault4.ToSingleString(false)}""
|
|
";
|
|
Console.WriteLine(message);
|
|
return; // exit main
|
|
}
|
|
#endregion
|
|
// Set window to max size to better fit content
|
|
// Not needed for now! Console.SetWindowSize(Console.LargestWindowWidth, Console.LargestWindowHeight);
|
|
#region Setup Communication to dut's
|
|
foreach (var comport in comports)
|
|
{
|
|
if (runMode != RUN_TYPE.Normal)
|
|
{
|
|
Console.WriteLine($"{new string('!', 50)}\n Warning is in running in {runMode} mode\n{new string('!', 50)}");
|
|
}
|
|
MagFlux6200 dut = null;
|
|
try
|
|
{ // Set up on DUT
|
|
dut = new MagFlux6200(runMode);
|
|
var log_path = Environment.GetEnvironmentVariable("USERPROFILE")+@"\Downloads\";
|
|
var isOkay = dut.SetLogLocation(log_path, "logs_"+comport);
|
|
Console.WriteLine($"Using program log path:\n{log_path}");
|
|
isOkay &=gotArgs;
|
|
if (isOkay)
|
|
{ // Use standard and just setup as port
|
|
if (baudrate == null)
|
|
{
|
|
isOkay &=dut.Connect(comport);
|
|
}
|
|
else if ((baudrate != null) && (parity != null))
|
|
{
|
|
isOkay &=dut.Connect(comport, baudrate.Value, parity.Value);
|
|
}
|
|
else
|
|
{
|
|
isOkay = false; // Error in settings
|
|
}
|
|
}
|
|
|
|
if (isOkay)
|
|
{
|
|
duts.Add(dut);
|
|
}
|
|
else
|
|
{
|
|
var port = comport;
|
|
if (String.IsNullOrEmpty(port))
|
|
{
|
|
port = "COM ?";
|
|
}
|
|
throw new Exception($"Fail to setup device for {port}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (dut!=null)
|
|
{
|
|
dut.OpenLogFile();
|
|
}
|
|
throw ex;
|
|
}
|
|
}
|
|
#endregion //#region Setup Communication to dut's
|
|
switch (runtask)
|
|
{
|
|
case RUN_ACTION.TEST:
|
|
TEST(duts);
|
|
break;
|
|
case RUN_ACTION.SAVE_CAL:
|
|
{
|
|
SAVE_CAL(duts);
|
|
}
|
|
break;
|
|
case RUN_ACTION.LOAD_CAL:
|
|
{
|
|
LOAD_CAL(duts, loadedCalibrations);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
throw new NotImplementedException($"Missing support run mode {runtask}");
|
|
}
|
|
}
|
|
Console.WriteLine("finished functional testing");
|
|
// Is set to true when the monitoring values also needs to stop
|
|
bool exitMonitoringLoop = false, pauseMonitoringLoop = false, _LastPauseMonitoringLoop = false;
|
|
// Start a task for monitoring a key for exit
|
|
Console.WriteLine("Press key 'x' exit, 'p' for pause read, 'c' continue read");
|
|
Task.Run(() =>
|
|
{
|
|
ConsoleKeyInfo keyinfo;
|
|
do
|
|
{
|
|
keyinfo = Console.ReadKey();
|
|
if (keyinfo.Key == ConsoleKey.P)
|
|
{
|
|
pauseMonitoringLoop = true;
|
|
}
|
|
else if (keyinfo.Key == ConsoleKey.C)
|
|
{
|
|
pauseMonitoringLoop = false;
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"\n{keyinfo.Key} was pressed. Press key 'x' exit");
|
|
}
|
|
}
|
|
while (keyinfo.Key != ConsoleKey.X);
|
|
exitMonitoringLoop = true;
|
|
});
|
|
// Just read flow and other values for testing general measurement
|
|
int count = 0;
|
|
// "Structure of an interpolated string"
|
|
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
|
|
while (!exitMonitoringLoop)
|
|
{
|
|
if (!pauseMonitoringLoop)
|
|
{
|
|
var message = "\r";
|
|
var dutNum = 1;
|
|
foreach (var dut in duts)
|
|
{
|
|
{ // Read Flow
|
|
var isOkay = dut.GetFlowRate_lps(out var value_out);
|
|
if (dutNum > 1)
|
|
{
|
|
message += " | ";
|
|
}
|
|
message += $"DUT{dutNum++}: ";
|
|
if (!dut.GetDeviceHealthy())
|
|
{
|
|
message += $"Error:";
|
|
if (dut.GetDeviceErrorMessages(out var errorList))
|
|
{
|
|
message += $"{errorList.ToSingleString(false)} ";
|
|
}
|
|
else
|
|
{
|
|
message += $"No Text to display!";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const int w = 9;
|
|
message += $"{(isOkay ? $"{value_out*3.6,w:F3} m3/h" : $"!Read failed!")} {dut.GetComCounters()}\t";
|
|
if (!isOkay)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Console.Write(message + $" msg={++count}\t");
|
|
}
|
|
{ // Print out if paused read
|
|
if (_LastPauseMonitoringLoop != pauseMonitoringLoop)
|
|
{
|
|
_LastPauseMonitoringLoop = pauseMonitoringLoop;
|
|
if (pauseMonitoringLoop)
|
|
{
|
|
Console.Write("\rRead is Paused!\t\t\t\t\t\t\t\t");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var name_exe = System.AppDomain.CurrentDomain.FriendlyName;
|
|
AppConst.Logger.AddFuncLog(true, name_exe, "main()", ex);
|
|
AppConst.Logger.OpenProgramLogFile();
|
|
ret_error = -1; //https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes
|
|
}
|
|
finally
|
|
{
|
|
// Close connection before exit
|
|
try
|
|
{
|
|
if (duts.Count != 0)
|
|
{
|
|
foreach (var dut in duts)
|
|
{
|
|
dut.CloseConnection();
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
Environment.Exit(ret_error); //https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes
|
|
}
|
|
}
|
|
}
|
|
}
|