A – Registration and execution - Register GenesisCommunication Factory in the component list. - Separate the Genesis form and sequence from iPerl communication. B – Communication activities - Restore initialization, connection, PCB reading, password and login. - Include grouped login, mode switching and disconnection. - Support processing up to 10 slots. C1 – Input calibration factors - Read three factors from Water meters / Text1–Text3. - Validate integer values in the range 1–65535. - Preserve the default of 15625 when all three fields are empty. D – Q3 calibration - Connect the Prepare Q3 → measurement → Write Q3 workflow. - Add channel processing to FlyingStart and FlyingStartMassCollection. - Reset previous measurement data and validate calculated factors. - Mark factors as stored only after StoreCalibration succeeds. E – Results and database - Store calibration factors separately for each meter and channel. - Add result entities, mappings and Q3 data. - Extend DB.cs / EnsureSchema to create and update the schema. - Preserve compatibility with the existing binary format. Validation: - Debug build and 18 tests passed. - Simulated communication runs follow the same activity sequence. - The complete Q3 workflow has not yet been verified on hardware. Known limitation: - An inherited mismatch in simulated responses and error propagation can produce an incorrect OK result; this change does not fix it.
2059 lines
85 KiB
C#
2059 lines
85 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Common;
|
|
using Config.Entities;
|
|
using CordonelPreadjustmentUi.Processes.Itinerary;
|
|
using GenesisCordonelInterface.API;
|
|
using log4net;
|
|
using Results.Entities;
|
|
using Results.Entities.helpers;
|
|
using TBF.Rig.BridgeComponents.GciBridge;
|
|
using TBF.Rig.RegisterReaders.GenesisRegReader.communication.common;
|
|
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
|
using TBF.Rig.Sequences;
|
|
using TBF.Rig.TestMethods.GenesisCommunication;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed;
|
|
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
|
|
|
|
|
namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
|
|
{
|
|
public class PcbReadResult
|
|
{
|
|
public bool Success { get; set; }
|
|
public string? PcbId { get; set; }
|
|
public string? ErrorMessage { get; set; }
|
|
|
|
public static PcbReadResult Ok(string pcbId) =>
|
|
new PcbReadResult
|
|
{
|
|
Success = true,
|
|
PcbId = pcbId
|
|
};
|
|
|
|
public static PcbReadResult Fail(string error) =>
|
|
new PcbReadResult
|
|
{
|
|
Success = false,
|
|
ErrorMessage = error
|
|
};
|
|
}
|
|
|
|
public class OptoHeadTest : IDisposable
|
|
{
|
|
//protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(OptoHeadTest));
|
|
|
|
private GenesisSmartReader genesisHead;
|
|
//private SerialDriver serialDriver;
|
|
|
|
public static string ResultOk = "OK";
|
|
public static string ResultNok = "NOK";
|
|
|
|
|
|
public async Task BuildConnection(GenesisSmartReader genesidHead)
|
|
{
|
|
await BuildConnectionAsync(genesidHead).ConfigureAwait(false);
|
|
}
|
|
|
|
public async Task BuildConnectionAsync(GenesisSmartReader genesidHead)
|
|
{
|
|
if (genesidHead == null)
|
|
throw new ArgumentNullException(nameof(genesidHead));
|
|
|
|
bool simulation = genesidHead.DebugLevel == DebugMode.Simulate;
|
|
|
|
//No simulation
|
|
var bridge = genesidHead.CommInterfaceBridge;
|
|
if (bridge == null)
|
|
throw new InvalidOperationException($"CommInterfaceBridge is null. Head: {genesidHead.GetSlotNr}");
|
|
|
|
//Check if exist and connected
|
|
PublicModels.GciSlotInfo gciSlotInfo = await bridge.GetSlotAsync(genesidHead.GetSlotNr);
|
|
|
|
if (gciSlotInfo == null && gciSlotInfo.IsConnected)
|
|
{
|
|
log.Debug($"BuildConnection() - SlotNr: {genesidHead.GetSlotNr} already exist and connected!");
|
|
return;
|
|
}
|
|
|
|
//Unconnected - do connection
|
|
var request = new PublicModels.GciInitSlotRequest
|
|
{
|
|
SlotId = genesidHead.GetSlotNr,
|
|
ConfigSource = PublicModels.GciConfigSource.InterfaceInputConfig,
|
|
PasswordSource = PublicModels.GciPasswordSource.InterfaceInputPassword,
|
|
|
|
RequestPort = new PublicModels.GciPortConfig
|
|
{
|
|
PortName = $"COM{genesidHead.RfidComPortNr}",
|
|
Type = simulation ? "SIMULATE" : PublicModels.MapPortType("IRDA")
|
|
},
|
|
|
|
StreamingPort = new PublicModels.GciPortConfig
|
|
{
|
|
PortName = "NA", //$"COM{genesidHead.OptoComPortNr}",
|
|
Type = simulation ? "SIMULATE" : string.Empty
|
|
}
|
|
};
|
|
|
|
log.Debug($"BuildConnection() - SlotNr: {genesidHead.GetSlotNr} initializing... Request: {request}");
|
|
|
|
|
|
|
|
var initResult = await ExecuteWithRetryAsync(
|
|
() => bridge.InitSlotAsync(request),
|
|
r => r.Success,
|
|
$"InitSlotAsync({genesidHead.GetSlotNr})");
|
|
|
|
|
|
log.Debug($"BuildConnection() - SlotNr: {genesidHead.GetSlotNr} initialized. Result: {initResult}");
|
|
|
|
if (initResult == null)
|
|
throw new InvalidOperationException("InitSlotAsync returned null.");
|
|
|
|
var updateResult = await ExecuteWithRetryAsync(
|
|
() => bridge.UpdateSlotAsync(request),
|
|
r => r.Success,
|
|
$"UpdateSlotAsync({genesidHead.GetSlotNr})");
|
|
|
|
log.Debug($"BuildConnection() - SlotNr: {genesidHead.GetSlotNr} updated! Result: {updateResult}");
|
|
|
|
if (updateResult == null)
|
|
throw new InvalidOperationException("UpdateSlotAsync returned null.");
|
|
|
|
slotDefined = true;
|
|
}
|
|
|
|
public async Task<bool> InitialiseBuild_Async(GenesisSmartReader genesidHead)
|
|
{
|
|
if (genesidHead == null)
|
|
throw new ArgumentNullException(nameof(genesidHead));
|
|
|
|
bool simulation = genesidHead.DebugLevel == DebugMode.Simulate;
|
|
|
|
//No simulation
|
|
var bridge = genesidHead.CommInterfaceBridge;
|
|
if (bridge == null)
|
|
throw new InvalidOperationException($"CommInterfaceBridge is null. Head: {genesidHead.GetSlotNr}");
|
|
|
|
//Check if exist and connected
|
|
PublicModels.GciSlotInfo gciSlotInfo = await bridge.GetSlotAsync(genesidHead.GetSlotNr);
|
|
|
|
if (gciSlotInfo == null)
|
|
{
|
|
log.Debug($"InitialiseBuild_Async() - SlotNr: {genesidHead.GetSlotNr} already exist and connected!");
|
|
return true;
|
|
}
|
|
|
|
//Unconnected - do connection
|
|
var request = new PublicModels.GciInitSlotRequest
|
|
{
|
|
SlotId = genesidHead.GetSlotNr,
|
|
ConfigSource = PublicModels.GciConfigSource.InterfaceInputConfig,
|
|
PasswordSource = PublicModels.GciPasswordSource.InterfaceInputPassword,
|
|
|
|
RequestPort = new PublicModels.GciPortConfig
|
|
{
|
|
PortName = $"COM{genesidHead.RfidComPortNr}",
|
|
Type = simulation ? "SIMULATE" : PublicModels.MapPortType("IRDA")
|
|
},
|
|
|
|
StreamingPort = new PublicModels.GciPortConfig
|
|
{
|
|
PortName = "NA", //$"COM{genesidHead.OptoComPortNr}",
|
|
Type = simulation ? "SIMULATE" : string.Empty
|
|
}
|
|
};
|
|
|
|
log.Debug($"InitialiseBuild_Async() - SlotNr: {genesidHead.GetSlotNr} initializing... Request: {request}");
|
|
var initResult = await ExecuteWithRetryAsync(
|
|
() => bridge.InitSlotAsync(request),
|
|
r => r.Success,
|
|
$"InitSlotAsync({genesidHead.GetSlotNr})");
|
|
log.Debug($"InitialiseBuild_Async() - SlotNr: {genesidHead.GetSlotNr} initialized. Result: {initResult}");
|
|
return initResult.Success;
|
|
}
|
|
|
|
public async Task<bool> UpdateBuild_Async(GenesisSmartReader genesidHead)
|
|
{
|
|
if (genesidHead == null)
|
|
throw new ArgumentNullException(nameof(genesidHead));
|
|
|
|
bool simulation = genesidHead.DebugLevel == DebugMode.Simulate;
|
|
|
|
//No simulation
|
|
var bridge = genesidHead.CommInterfaceBridge;
|
|
if (bridge == null)
|
|
throw new InvalidOperationException($"UpdateBuild_Async CommInterfaceBridge is null. Head: {genesidHead.GetSlotNr}");
|
|
|
|
//Check if exist - must step before
|
|
PublicModels.GciSlotInfo gciSlotInfo = await bridge.GetSlotAsync(genesidHead.GetSlotNr);
|
|
|
|
if (gciSlotInfo == null)
|
|
{
|
|
log.Debug($"UpdateBuild_Async() - SlotNr: {genesidHead.GetSlotNr} INIT missing! - must be initialised first!");
|
|
return false;
|
|
}
|
|
|
|
//Unconnected - do connection
|
|
var request = new PublicModels.GciInitSlotRequest
|
|
{
|
|
SlotId = genesidHead.GetSlotNr,
|
|
ConfigSource = PublicModels.GciConfigSource.InterfaceInputConfig,
|
|
PasswordSource = PublicModels.GciPasswordSource.InterfaceInputPassword,
|
|
|
|
RequestPort = new PublicModels.GciPortConfig
|
|
{
|
|
PortName = $"COM{genesidHead.RfidComPortNr}",
|
|
Type = simulation ? "SIMULATE" : PublicModels.MapPortType("IRDA")
|
|
},
|
|
|
|
StreamingPort = new PublicModels.GciPortConfig
|
|
{
|
|
PortName = "NA", //$"COM{genesidHead.OptoComPortNr}",
|
|
Type = simulation ? "SIMULATE" : string.Empty
|
|
}
|
|
};
|
|
|
|
log.Debug($"UpdateBuild_Async() - SlotNr: {genesidHead.GetSlotNr} updating... Request: {request}");
|
|
var updateResult = await ExecuteWithRetryAsync(
|
|
() => bridge.UpdateSlotAsync(request),
|
|
r => r.Success,
|
|
$"UpdateSlotAsync({genesidHead.GetSlotNr})");
|
|
log.Debug($"UpdateBuild_Async() - SlotNr: {genesidHead.GetSlotNr} updated. Result: {updateResult}");
|
|
return updateResult.Success;
|
|
}
|
|
|
|
private async Task<T> ExecuteWithRetryAsync<T>(
|
|
Func<Task<T>> action,
|
|
Func<T, bool> successCondition,
|
|
string operationName,
|
|
int maxRetries = 5,
|
|
int timeoutSeconds = 30,
|
|
int delayMs = 1000)
|
|
{
|
|
using var cts = new CancellationTokenSource( TimeSpan.FromSeconds(timeoutSeconds));
|
|
|
|
Exception lastException = null;
|
|
|
|
for (int attempt = 1; attempt <= maxRetries; attempt++)
|
|
{
|
|
if (cts.IsCancellationRequested)
|
|
{
|
|
throw new TimeoutException( $"{operationName} timeout after {timeoutSeconds} seconds.");
|
|
}
|
|
|
|
try
|
|
{
|
|
log.Debug($"{operationName} attempt {attempt}/{maxRetries}");
|
|
|
|
T result = await action();
|
|
|
|
if (result == null)
|
|
throw new InvalidOperationException(
|
|
$"{operationName} returned null.");
|
|
|
|
if (successCondition(result))
|
|
{
|
|
log.Debug($"{operationName} success.");
|
|
return result;
|
|
}
|
|
|
|
log.Debug($"{operationName} failed. Success condition not met.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
lastException = ex;
|
|
log.Error($"{operationName} failed on attempt {attempt}/{maxRetries}", ex);
|
|
}
|
|
|
|
await Task.Delay(delayMs, cts.Token);
|
|
}
|
|
|
|
throw new InvalidOperationException(
|
|
$"{operationName} failed after {maxRetries} attempts.",
|
|
lastException);
|
|
}
|
|
|
|
private static async Task<T> WithTimeout<T>(
|
|
Task<T> task,
|
|
TimeSpan timeout,
|
|
string timeoutMessage)
|
|
{
|
|
var timeoutTask = Task.Delay(timeout);
|
|
|
|
var completedTask = await Task.WhenAny(task, timeoutTask);
|
|
|
|
if (completedTask == timeoutTask)
|
|
throw new TimeoutException(timeoutMessage);
|
|
|
|
return await task;
|
|
}
|
|
|
|
public OptoHeadTest(GenesisSmartReader genesisHead)
|
|
{
|
|
this.genesisHead = genesisHead;
|
|
}
|
|
|
|
public void CloseConnection()
|
|
{
|
|
Task.Run(CloseConnectionAsync)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
return;
|
|
}
|
|
|
|
public async Task<bool> CloseConnectionAsync()
|
|
{
|
|
log.Debug("CloseConnectionAsync called for iHead: " + genesisHead);
|
|
await genesisHead?.CommInterfaceBridge?.DisconnectAsync(genesisHead.GetSlotNr)!;
|
|
log.Debug("DisconnectAsync completed for iHead: " + genesisHead);
|
|
await genesisHead?.CommInterfaceBridge?.CleanSlotAsync(genesisHead.GetSlotNr)!;
|
|
log.Debug("CleanSlotAsync completed for iHead: " + genesisHead);
|
|
DisposeSlot();
|
|
|
|
// if (serialDriver != null)
|
|
// serialDriver.CloseConnection();
|
|
// serialDriver = null;
|
|
return true;
|
|
}
|
|
|
|
private bool isConnected = false;
|
|
private bool slotDefined = false;
|
|
|
|
public bool IsSlotDefined { get => slotDefined; }
|
|
public bool IsConnected { get => isConnected; }
|
|
|
|
public void DisposeSlot() { slotDefined = false; isConnected = false; }
|
|
|
|
public async Task<string> ReadRequest_PCBAsync(GenesisSmartReader genesisHead)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("ReadRequest_PCBAsync called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null)
|
|
return string.Empty;
|
|
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
return string.Empty;
|
|
|
|
if (genesisHead.CommInterfaceBridge == null)
|
|
return string.Empty;
|
|
|
|
|
|
await BuildConnectionAsync(genesisHead);
|
|
|
|
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug($"ReadRequest_PCBAsync({genesisHead.GetSlotNr}) - Simulated response");
|
|
return "-OK Simulated PCB-";
|
|
}
|
|
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
|
|
log.Debug($"ReadRequest_PCBAsync({genesisHead.GetSlotNr}) - GciBridge created");
|
|
|
|
gciBridge.GciBridgeCfg.EnableExternalAccess = true;
|
|
gciBridge.GciBridgeCfg.EnableGuiAccess = false;
|
|
|
|
gciBridge.Initialize();
|
|
|
|
log.Debug($"ReadRequest_PCBAsync({genesisHead.GetSlotNr}) - GciBridge initialized");
|
|
|
|
RadioService headService = new RadioService(gciBridge);
|
|
|
|
|
|
ReadPcbResult pcbResult = await headService.ReadRequest_PCBAsync(genesisHead);
|
|
|
|
if (pcbResult == null)
|
|
{
|
|
log.Info( $"PCB Number NOT found on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr}");
|
|
return string.Empty;
|
|
}
|
|
|
|
isConnected = pcbResult.IsConnected;
|
|
|
|
string serialNo = pcbResult.PcbId;
|
|
log.Info( $"PCB Number: {serialNo} on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr}");
|
|
|
|
if (pcbResult.IsValidPcb)
|
|
{
|
|
log.Debug($"Setting PCB: {pcbResult.PcbId} for Head: {genesisHead.Name}");
|
|
genesisHead.SerialNr = pcbResult.PcbId;
|
|
if (genesisHead.ConfigStruct != null)
|
|
{
|
|
genesisHead.ConfigStruct.PCBNumberString = pcbResult.PcbId;
|
|
}
|
|
log.Info( $"PCB STORED TO HEAD Number: {serialNo} on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr} is valid");
|
|
}
|
|
|
|
return serialNo;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"ReadRequest_PCBAsync({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
public string ReadRequest_PCB()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("ReadRequest_PCB() - Simulated response");
|
|
return "Simulated PCB-123";
|
|
}
|
|
return Task.Run(() => ReadRequest_PCBAsync(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
public string InitialiseSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Initialise() - Simulated response");
|
|
return "Simulated Initialise";
|
|
}
|
|
return Task.Run(() => Initialise_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
public string UpdateSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Update() - Simulated response");
|
|
return "Simulated Update";
|
|
}
|
|
return Task.Run(() => Update_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
public string ConnectSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return "Simulated Connect";
|
|
}
|
|
return Task.Run(() => Connect_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
public PcbReadResult PCB_ReadSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("PCB_Read() - Simulated response");
|
|
genesisHead.SerialNr = $"PCB_Simul_{genesisHead.GetSlotNr}";
|
|
if (genesisHead.ConfigStruct != null)
|
|
genesisHead.ConfigStruct.PCBNumberString = $"PCB_Simul_{genesisHead.GetSlotNr}";
|
|
return PcbReadResult.Ok("Simulated PCB_Read");
|
|
}
|
|
|
|
return Task.Run(() => PCB_Read_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
}
|
|
|
|
private async Task<PcbReadResult> PCB_Read_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("PCB_Read_Async called for iHead: " + genesisHead);
|
|
if (genesisHead == null) return PcbReadResult.Fail("genesisHead is null.");
|
|
if (genesisHead.CommInterfaceBridge == null) return PcbReadResult.Fail("genesisHead is null.");;
|
|
|
|
var pbcReadBuildAsync = await PBC_Read_Build_Async(genesisHead);
|
|
|
|
if (pbcReadBuildAsync.Success && !string.IsNullOrEmpty(pbcReadBuildAsync.PcbId))
|
|
{
|
|
log.Debug($"Setting PCB: {pbcReadBuildAsync.PcbId} for Head: {genesisHead.Name}");
|
|
genesisHead.SerialNr = pbcReadBuildAsync.PcbId;
|
|
}
|
|
|
|
return pbcReadBuildAsync;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PCB_Read_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return PcbReadResult.Fail(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task<PcbReadResult> PBC_Read_Build_Async( GenesisSmartReader genesisSmartReader)
|
|
{
|
|
log.Debug($"PBC_Read_Build_Async called for iHead: {genesisSmartReader}");
|
|
var slotInfo = await genesisSmartReader.CommInterfaceBridge.GetSlotWithRetryAsync(genesisSmartReader.GetSlotNr);
|
|
if (slotInfo == null)
|
|
{
|
|
log.Debug($"PBC_Read_Build_Async({genesisSmartReader.GetSlotNr}) - SlotInfo is null.");
|
|
return PcbReadResult.Fail("SlotInfo is null.");
|
|
}
|
|
|
|
if (!slotInfo.Success)
|
|
{
|
|
log.Debug($"PBC_Read_Build_Async({genesisSmartReader.GetSlotNr}) - SlotInfo failed.");
|
|
return PcbReadResult.Fail("SlotInfo failed.");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(slotInfo?.Result?.PcbId))
|
|
{
|
|
log.Debug($"PBC_Read_Build_Async({genesisSmartReader.GetSlotNr}) - Slot already has PcbId.");
|
|
return PcbReadResult.Ok(slotInfo.Result.PcbId);
|
|
}
|
|
|
|
log.Debug($"PBC_Read_Build_Async({genesisSmartReader.GetSlotNr}) - Connecting...");
|
|
CancellationToken token = default;
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// PCB READ LOOP
|
|
try
|
|
{
|
|
string validPcbId = null;
|
|
int maxAttempts = 5;
|
|
|
|
var pcbTask = genesisSmartReader.CommInterfaceBridge.GetPcbIdWithRetryAsync(genesisSmartReader.GetSlotNr);
|
|
|
|
if (pcbTask?.Result?.Success == true)
|
|
{
|
|
validPcbId = pcbTask.Result.Result.PcbId;
|
|
}
|
|
|
|
|
|
if (string.IsNullOrEmpty(validPcbId))
|
|
{
|
|
return PcbReadResult.Fail("Failed to read PCB ID.");
|
|
}
|
|
|
|
if (genesisSmartReader.ConfigStruct != null)
|
|
{
|
|
genesisSmartReader.ConfigStruct.PCBNumberString = validPcbId;
|
|
}
|
|
genesisSmartReader.SerialNr = validPcbId;
|
|
log.Debug( $"PBC_Read_Build_Async({genesisSmartReader.GetSlotNr}) " + $"ValidPcbId:({validPcbId})");
|
|
return PcbReadResult.Ok(validPcbId);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
log.Error($"PBC_Read_Build_Async({genesisSmartReader.GetSlotNr}) - Exception:", e);
|
|
return PcbReadResult.Fail(e.Message);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public async Task<string> Initialise_Async(GenesisSmartReader genesisHead)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("Initialise_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null)
|
|
return string.Empty;
|
|
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
return string.Empty;
|
|
|
|
if (genesisHead.CommInterfaceBridge == null)
|
|
return string.Empty;
|
|
|
|
var initialiseBuildAsync = await InitialiseBuild_Async(genesisHead);
|
|
|
|
return initialiseBuildAsync ? "OK" : "NOK";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"Initialise_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
|
|
return "NOK";
|
|
}
|
|
|
|
public async Task<string> Update_Async(GenesisSmartReader genesisHead)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("Update_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null)
|
|
return string.Empty;
|
|
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
return string.Empty;
|
|
|
|
if (genesisHead.CommInterfaceBridge == null)
|
|
return string.Empty;
|
|
|
|
bool updateBuildAsync = await UpdateBuild_Async(genesisHead);
|
|
|
|
return updateBuildAsync ? "OK" : "NOK";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"UpdateBuild_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
|
|
return "NOK";
|
|
}
|
|
|
|
public async Task<string> Connect_Async(GenesisSmartReader genesisHead)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("Initialise_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null)
|
|
return string.Empty;
|
|
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
return string.Empty;
|
|
|
|
if (genesisHead.CommInterfaceBridge == null)
|
|
return string.Empty;
|
|
|
|
bool updateBuildAsync = await ConnectBuild_Async(genesisHead);
|
|
|
|
return updateBuildAsync ? "OK" : "NOK";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"Initialise_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
|
|
return "NOK";
|
|
}
|
|
|
|
private async Task<bool> ConnectBuild_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
log.Debug("ConnectBuild_Async called for iHead: " + genesisSmartReader);
|
|
var slotInfo = await genesisSmartReader.CommInterfaceBridge.GetSlotAsync(genesisSmartReader.GetSlotNr);
|
|
if (slotInfo == null || !slotInfo.Success)
|
|
{
|
|
//just no definet yet ?
|
|
log.Debug($"ConnectBuild_Async({genesisSmartReader.GetSlotNr}) - SlotInfo is null.");
|
|
}
|
|
else if (slotInfo.IsConnected)
|
|
{
|
|
log.Debug($"ConnectBuild_Async({genesisSmartReader.GetSlotNr}) - Slot is already connected.");
|
|
return true;
|
|
}
|
|
|
|
log.Debug($"ConnectBuild_Async({genesisSmartReader.GetSlotNr}) - Connecting...");
|
|
CancellationToken token = default;//new CancellationToken();
|
|
var connectTask = await genesisSmartReader.CommInterfaceBridge.ConnectAsync(genesisSmartReader.GetSlotNr, token);
|
|
log.Debug($"ConnectBuild_Async({genesisSmartReader.GetSlotNr}) Result: Success({connectTask.Success}) - IsConnected({connectTask.IsConnected})");
|
|
return connectTask.Success && connectTask.IsConnected;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Set Test mode
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
public bool SetTestMode()
|
|
{
|
|
return Task.Run(SetTestMode_Async)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
public async Task<bool> SetTestMode_Async()
|
|
{
|
|
try
|
|
{
|
|
log.Debug("SetTestMode_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null)
|
|
return false;
|
|
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
return false;
|
|
|
|
if (genesisHead.CommInterfaceBridge == null)
|
|
return false;
|
|
|
|
await BuildConnectionAsync(genesisHead);
|
|
|
|
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("SetTestMode_Async() - Simulated response");
|
|
return true;
|
|
}
|
|
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
|
|
log.Debug("SetTestMode_Async() - GciBridge created");
|
|
|
|
gciBridge.GciBridgeCfg.EnableExternalAccess = true;
|
|
gciBridge.GciBridgeCfg.EnableGuiAccess = false;
|
|
gciBridge.Initialize();
|
|
|
|
log.Debug("SetTestMode_Async() - GciBridge initialized");
|
|
|
|
RadioService headService = new RadioService(gciBridge);
|
|
var ledModeAsync = await headService.SetLedMode_Async(genesisHead, LedState.active, isConnected);
|
|
|
|
if (!ledModeAsync)
|
|
{
|
|
log.Info(
|
|
$"FAILED - SET LED MODE ACTIVE on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr}");
|
|
return false;
|
|
}
|
|
|
|
isConnected = true;
|
|
|
|
try
|
|
{
|
|
await headService.Disconnect_Async(genesisHead);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetTestMode_Async() - DISCONNECT Exception:", ex);
|
|
}
|
|
|
|
|
|
return ledModeAsync;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetTestMode_Async() - Exception:", ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Active mode
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
public bool SetActiveMode()
|
|
{
|
|
return Task.Run(SetActiveMode_Async)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
public async Task<bool> SetActiveMode_Async()
|
|
{
|
|
try
|
|
{
|
|
log.Debug("SetActiveMode_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null)
|
|
return false;
|
|
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
return false;
|
|
|
|
if (genesisHead.CommInterfaceBridge == null)
|
|
return false;
|
|
|
|
await BuildConnectionAsync(genesisHead);
|
|
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("SetActiveMode_Async() - Simulated response");
|
|
return true;
|
|
}
|
|
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
|
|
log.Debug("SetActiveMode_Async() - GciBridge created");
|
|
|
|
gciBridge.GciBridgeCfg.EnableExternalAccess = true;
|
|
gciBridge.GciBridgeCfg.EnableGuiAccess = false;
|
|
gciBridge.Initialize();
|
|
|
|
log.Debug("SetActiveMode_Async() - GciBridge initialized");
|
|
|
|
RadioService headService = new RadioService(gciBridge);
|
|
var ledModeAsync = await headService.SetLedMode_Async(genesisHead, LedState.inactive, isConnected);
|
|
|
|
if (!ledModeAsync)
|
|
{
|
|
log.Info(
|
|
$"FAILED - SET LED MODE INACTIVE on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr}");
|
|
return false;
|
|
}
|
|
|
|
isConnected = true;
|
|
|
|
try
|
|
{
|
|
await headService.Disconnect_Async(genesisHead);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetActiveMode_Async() - DISCONNECT Exception:", ex);
|
|
}
|
|
|
|
|
|
return ledModeAsync;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetActiveMode_Async() - Exception:", ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Idle mode - only
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
public bool SetIdleMode()
|
|
{
|
|
log.Debug("SetIdleMode called for iHead: " + genesisHead.ToString());
|
|
bool activityModeIdle = SetActivityMode_Idle();
|
|
|
|
return activityModeIdle;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Test mode - string response
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <param name="isTestModeSuccessful"></param>
|
|
/// <returns></returns>
|
|
public string SetTestMode(ref bool isTestModeSuccessful)
|
|
{
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
isTestModeSuccessful = true;
|
|
return "-OK SetTestMode Simulated response-";
|
|
}
|
|
|
|
try
|
|
{
|
|
bool testMode = SetTestMode();
|
|
isTestModeSuccessful = testMode;
|
|
return testMode ? "Set Test Mode - OK" : "Set Test Mode - FAILED";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetTestMode() - Exception:" + ex.StackTrace);
|
|
return "Set Test Mode - Exception";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Active mode
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
public bool TurnOffRadio()
|
|
{
|
|
return Task.Run(CloseConnectionAsync)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Set Optical -> Test mode
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
private bool SetOptTestMode()
|
|
{
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// try
|
|
// {
|
|
// if (genesisHead != null)
|
|
// {
|
|
// if(genesisHead.RfidComPortNr != 0 && !genesisHead?.CommInterfaceBridgeComponent?.GciExternalInterface?.IsConnected == false)
|
|
// BuildConnection(genesisHead).ConfigureAwait(false).GetAwaiter().GetResult();
|
|
//
|
|
//
|
|
// RadioService headService = new RadioService(genesisHead?.CommInterfaceBridgeComponent);
|
|
// bool optTestMode = headService.SetOptTestMode(genesisHead);
|
|
// if (genesisHead.ConfigStruct != null)
|
|
// genesisHead.ConfigStruct.OpthoStatusMode = optTestMode ? DiagnosticLedState.State4 : DiagnosticLedState.StatusUnknown;
|
|
// return optTestMode;
|
|
// }
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// log.Error("SetOptTestMode() - Exception:" + ex.StackTrace);
|
|
// }
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// TurnOffRadio - string response
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <param name="isTestModeSuccessful"></param>
|
|
/// <returns></returns>
|
|
public string TurnOffRadio(ref bool isTestModeSuccessful)
|
|
{
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
isTestModeSuccessful = true;
|
|
return "-OK TurnOffRadio Simulated response-";
|
|
}
|
|
|
|
try
|
|
{
|
|
bool turnOffRadio = TurnOffRadio();
|
|
isTestModeSuccessful = turnOffRadio;
|
|
return turnOffRadio ? "TurnOffRadio - OK" : "TurnOffRadio - FAILED";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetActiveMode() - Exception:" + ex.StackTrace);
|
|
return "Set Active Mode - Exception";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Active mode - string response
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <param name="isTestModeSuccessful"></param>
|
|
/// <returns></returns>
|
|
public string SetActiveMode(ref bool isTestModeSuccessful)
|
|
{
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
isTestModeSuccessful = true;
|
|
return "-OK SetActiveMode Simulated response-";
|
|
}
|
|
|
|
try
|
|
{
|
|
bool testMode = SetActiveMode();
|
|
isTestModeSuccessful = testMode;
|
|
return testMode ? "Set Active Mode - OK" : "Set Active Mode - FAILED";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetActiveMode() - Exception:" + ex.StackTrace);
|
|
return "Set Active Mode - Exception";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Optical -> Active mode
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
private bool SetOptActiveMode(GenesisSmartReader iHead)
|
|
{
|
|
// try
|
|
// {
|
|
// if (iHead != null)
|
|
// {
|
|
// if(genesisHead.RfidComPortNr != 0 && !genesisHead?.CommInterfaceBridgeComponent?.GciExternalInterface?.IsConnected == false)
|
|
// BuildConnection(genesisHead).ConfigureAwait(false).GetAwaiter().GetResult();
|
|
//
|
|
// RadioService headService = new RadioService(genesisHead?.CommInterfaceBridgeComponent);
|
|
// return headService.SetOptActiveMode(iHead);
|
|
// }
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// log.Error("SetOptActiveMode() - Exception:" + ex.StackTrace);
|
|
// }
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set activity mode to active
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
private async Task<bool> SetActivityMode_Active()
|
|
{
|
|
|
|
try
|
|
{
|
|
log.Debug("SetActivityMode_Active called for iHead: " + genesisHead);
|
|
if (genesisHead == null) return false;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return false;
|
|
if (genesisHead.CommInterfaceBridge == null) return false;
|
|
|
|
await BuildConnectionAsync(genesisHead);
|
|
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("SetActivityMode_Active() - Simulated response");
|
|
return true;
|
|
}
|
|
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
|
|
log.Debug("SetActivityMode_Active() - GciBridge created");
|
|
|
|
gciBridge.GciBridgeCfg.EnableExternalAccess = true;
|
|
gciBridge.GciBridgeCfg.EnableGuiAccess = false;
|
|
|
|
gciBridge.Initialize();
|
|
|
|
log.Debug("SetActivityMode_Active() - GciBridge initialized");
|
|
|
|
RadioService headService = new RadioService(gciBridge);
|
|
var active = await headService.SetActivityMode_Active(genesisHead, isConnected);
|
|
|
|
if (!active)
|
|
{
|
|
log.Info( $"SetActivityMode_Active not set on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr}");
|
|
return false;
|
|
}
|
|
|
|
log.Info( $"SetActivityMode_Active set on COM{genesisHead.RfidComPortNr} SlotNr: {genesisHead.GetSlotNr}");
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetActivityMode_Active() - Exception:", ex);
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set activity mode to idle
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
private bool SetActivityMode_Idle()
|
|
{
|
|
// try
|
|
// {
|
|
// if (genesisHead != null)
|
|
// {
|
|
// if (genesisHead.RfidComPortNr != 0 &&
|
|
// !genesisHead?.CommInterfaceBridgeComponent?.GciExternalInterface?.IsConnected == false)
|
|
// BuildConnection(genesisHead).ConfigureAwait(false).GetAwaiter().GetResult();
|
|
//
|
|
// log.Debug("SetActivityMode_Idle called for iHead: " + genesisHead.ToString());
|
|
//
|
|
// RadioService headService = new RadioService(genesisHead?.CommInterfaceBridgeComponent);
|
|
// return headService.SetActivityMode_Idle(genesisHead);
|
|
// }
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// log.Error("SetActivityMode_Idle() - Exception:" + ex.StackTrace);
|
|
// }
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
CloseConnectionAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read configuration from iHead
|
|
/// DiagnosticLedState is not readable, mus only be set!
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <param name="ledState"></param>
|
|
/// <returns></returns>
|
|
public bool ReadConfiguration(DiagnosticLedState ledState )
|
|
{
|
|
if (genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
try
|
|
{
|
|
|
|
// if (genesisHead != null)
|
|
// {
|
|
// genesisHead.ConfigStruct = new ConfigStruct();
|
|
//
|
|
// if (genesisHead.RfidComPortNr != 0 &&
|
|
// !genesisHead?.CommInterfaceBridgeComponent?.GciExternalInterface?.IsConnected == false)
|
|
// BuildConnection(genesisHead).ConfigureAwait(false).GetAwaiter().GetResult();
|
|
//
|
|
// RadioService headService = new RadioService(genesisHead?.CommInterfaceBridgeComponent);
|
|
// genesisHead.ConfigStruct.PCBNumberString = headService.ReadRequest_PCB(ref genesisHead);
|
|
// genesisHead.ConfigStruct.StatusMode = headService.GetActivityStatusMode(genesisHead);
|
|
// genesisHead.ConfigStruct.Unit = headService.GetUnit(genesisHead);
|
|
//
|
|
// if (ledState != DiagnosticLedState.StatusUnknown) // do set
|
|
// {
|
|
// genesisHead.ConfigStruct.OpthoStatusMode = headService.SetLedMode_Async(genesisHead, ledState);
|
|
// }
|
|
// else
|
|
// {
|
|
// genesisHead.ConfigStruct.OpthoStatusMode = DiagnosticLedState.StatusUnknown;
|
|
// }
|
|
//
|
|
// genesisHead.ConfigStruct.Version = headService.GetVersion(genesisHead);
|
|
//
|
|
// return true;
|
|
// }
|
|
//
|
|
// else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public string SetPasswordSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return "Simulated Connect";
|
|
}
|
|
return Task.Run(() => SetPasswordSlot_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
private async Task<string> SetPasswordSlot_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("SetPasswordSlot_Async called for iHead: " + genesisHead);
|
|
if (genesisHead == null) return string.Empty;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return string.Empty;
|
|
if (genesisHead.CommInterfaceBridge == null) return string.Empty;
|
|
//GET PASSWORD SLOT
|
|
string serialNr = genesisSmartReader.SerialNr;
|
|
CancellationToken token = default;
|
|
var result = await genesisSmartReader.CommInterfaceBridge.GetPasswordAsync(serialNr, token);
|
|
|
|
if (!result.Success)
|
|
{
|
|
log.Error($"SetPasswordSlot_Async({serialNr}) - GetPasswordAsync failed. Result: {result.Message}");
|
|
return $"Failed FIND PASSWORD, Deatils: " + result.Message;
|
|
}
|
|
|
|
log.Debug("GetPasswordAsync PCB=" + serialNr + " Result: " + result);
|
|
string txtPassword = result.Password;
|
|
|
|
log.Debug($"SetPasswordSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - set password to: " + txtPassword.Substring(0, 4) + "************");
|
|
var gciSetPasswordResult = await genesisSmartReader.CommInterfaceBridge.SetPasswordAsync(genesisSmartReader.GetSlotNr,txtPassword, token);
|
|
log.Debug($"SetPasswordSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - SetPasswordAsync Result: " + gciSetPasswordResult);
|
|
|
|
return gciSetPasswordResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"SetPasswordSlot_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
public string LoginSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return "Simulated Connect";
|
|
}
|
|
return Task.Run(() => LoginSlot_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
private async Task<string> LoginSlot_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("LoginSlot_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null) return string.Empty;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return string.Empty;
|
|
if (genesisHead.CommInterfaceBridge == null) return string.Empty;
|
|
|
|
CancellationToken token = default;
|
|
|
|
log.Debug($"LoginSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start");
|
|
var gciSetPasswordResult = await genesisSmartReader.CommInterfaceBridge.LoginAsync(genesisSmartReader.GetSlotNr, token);
|
|
log.Debug($"LoginSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - SetPasswordAsync Result: " + gciSetPasswordResult);
|
|
|
|
return gciSetPasswordResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"LoginSlot_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
public BridgeComponents.GciBridge.Interfaces.PublicModels.GciFullLoginResult GroupedLoginSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return new BridgeComponents.GciBridge.Interfaces.PublicModels.GciFullLoginResult
|
|
{
|
|
SlotId = genesisHead.GetSlotNr,
|
|
Success = true,
|
|
Message = "Simulated Connect",
|
|
ConnectResult = null,
|
|
PcbResult = null,
|
|
PasswordResult = null,
|
|
SetPasswordResult = null,
|
|
LoginResult = null,
|
|
};
|
|
}
|
|
|
|
var gciFullLoginResult = Task.Run(() => GroupedLoginSlot_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
return gciFullLoginResult;
|
|
}
|
|
|
|
public string GroupedLoginSlotStr()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return "Simulated Connect";
|
|
}
|
|
|
|
var gciFullLoginResult = Task.Run(() => GroupedLoginSlot_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
return gciFullLoginResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
|
|
private async Task<BridgeComponents.GciBridge.Interfaces.PublicModels.GciFullLoginResult> GroupedLoginSlot_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("GroupedLoginSlot_Async called for iHead: " + genesisHead);
|
|
|
|
var gciFullLoginResult = new BridgeComponents.GciBridge.Interfaces.PublicModels.GciFullLoginResult()
|
|
{
|
|
Success = false,
|
|
};
|
|
|
|
if (genesisHead == null) return gciFullLoginResult;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return gciFullLoginResult;
|
|
if (genesisHead.CommInterfaceBridge == null) return gciFullLoginResult;
|
|
|
|
CancellationToken token = default;
|
|
|
|
log.Debug($"GroupedLoginSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start");
|
|
BridgeComponents.GciBridge.Interfaces.PublicModels.GciFullLoginResult connectFullPassLoginWithRetryAsync = await genesisSmartReader.CommInterfaceBridge.ConnectFullPassLoginWithRetryAsync(genesisSmartReader.GetSlotNr, token);
|
|
log.Debug($"GroupedLoginSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - Result: " + connectFullPassLoginWithRetryAsync);
|
|
|
|
if (connectFullPassLoginWithRetryAsync?.PcbResult?.Success == true)
|
|
{
|
|
log.Debug($"Setting PCB: {connectFullPassLoginWithRetryAsync?.PcbResult?.Result?.PcbId} for Head: {genesisSmartReader.Name}");
|
|
genesisSmartReader.SerialNr = connectFullPassLoginWithRetryAsync?.PcbResult?.Result?.PcbId;
|
|
if (genesisSmartReader.ConfigStruct != null)
|
|
{
|
|
genesisSmartReader.ConfigStruct.PCBNumberString = genesisSmartReader.SerialNr;
|
|
}
|
|
}
|
|
|
|
return connectFullPassLoginWithRetryAsync;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"GroupedLoginSlot_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return new BridgeComponents.GciBridge.Interfaces.PublicModels.GciFullLoginResult()
|
|
{
|
|
Success = false,
|
|
Message = ex.Message
|
|
};
|
|
}
|
|
}
|
|
|
|
public string SetTestModeSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return "Simulated SetTestModeSlot";
|
|
}
|
|
return Task.Run(() => SetTestModeSlot_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
private async Task<string> SetTestModeSlot_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("SetTestModeSlot_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null) return string.Empty;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return string.Empty;
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
if (gciBridge == null) return string.Empty;
|
|
|
|
CancellationToken token = default;
|
|
|
|
//Get Activity Status
|
|
LedState ledMode = LedState.active; // swich on LED
|
|
byte valueLed = (ledMode == LedState.active) ? (byte)6 : (byte)0;
|
|
|
|
log.Debug($"SetTestModeSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set Led Mode: {valueLed}");
|
|
var registerWriteResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.LedMode, valueLed, false, false, token);
|
|
|
|
if (registerWriteResult == null || !registerWriteResult.Success)
|
|
{
|
|
log.Error($"SetTestModeSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - WriteRegisterAsync failed. Result: {registerWriteResult}");
|
|
return "Failed to set Led Mode";
|
|
}
|
|
log.Debug($"SetTestModeSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - SetTestModeSlot_Async Result: " + registerWriteResult);
|
|
|
|
return registerWriteResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"LoginSlot_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
public string SetActiveModeSlot()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return "Simulated SetActiveModeSlot";
|
|
}
|
|
return Task.Run(() => SetActiveModeSlot_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
|
|
private async Task<string> SetActiveModeSlot_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("SetActiveModeSlot_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null) return string.Empty;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return string.Empty;
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
if (gciBridge == null) return string.Empty;
|
|
|
|
CancellationToken token = default;
|
|
|
|
//Get Activity Status
|
|
LedState ledMode = LedState.inactive; // swich on LED
|
|
byte valueLed = (ledMode == LedState.active) ? (byte)6 : (byte)0;
|
|
|
|
log.Debug(
|
|
$"SetActiveModeSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set Led Mode: {valueLed}");
|
|
var registerWriteResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr,
|
|
RadioService.LedMode, valueLed, false, false, token);
|
|
|
|
if (registerWriteResult == null || !registerWriteResult.Success)
|
|
{
|
|
log.Error(
|
|
$"SetActiveModeSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - WriteRegisterAsync failed. Result: {registerWriteResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
|
|
log.Debug(
|
|
$"SetTestModeSlot_Async( Slot: {genesisSmartReader.GetSlotNr}) - SetTestModeSlot_Async Result: " +
|
|
registerWriteResult);
|
|
|
|
return registerWriteResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"LoginSlot_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
public string WriteQ3Calibration(TestMethodCfg cfg, Test test, WaterMeter wm)
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
if (test == null || wm == null) return "Missing Genesis meter or test";
|
|
if (!genesisHead.CalculateQ3Calibration() || !genesisHead.Q3CalibValid)
|
|
return "Q3 simulation requires valid measurement data";
|
|
var result = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
|
|
StoreCalibrationValuesResults(result, genesisHead, wm);
|
|
foreach (var row in result.GetCalibrationFactors(wm))
|
|
{
|
|
row.Stored = false;
|
|
row.ErrorStr = "Simulated; no register write.";
|
|
}
|
|
return ResultOk;
|
|
}
|
|
|
|
if (cfg == null)
|
|
{
|
|
log.Error("WriteQ3Calibration() - Missing TestMethodCfg");
|
|
return "Missing TestMethodCfg";
|
|
}
|
|
if (test == null)
|
|
{
|
|
log.Error("WriteQ3Calibration() - Missing Test");
|
|
return "Missing Test";
|
|
}
|
|
|
|
return Task.Run(() => WriteQ3Calibration_Async(genesisHead, cfg, test, wm))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
|
|
private async Task<string> WriteQ3Calibration_Async(GenesisSmartReader genesisSmartReader,
|
|
TestMethodCfg cfg,
|
|
Test test, WaterMeter wm)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("WriteQ3Calibration_Async called for iHead: " + genesisHead?.Name + " , cfg: " + cfg?.Name + " , test: " + test?.Name);
|
|
|
|
if (genesisHead == null)
|
|
{
|
|
log.Error("WriteQ3Calibration_Async() - Missing GenesisSmartReader");
|
|
return string.Empty;
|
|
}
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
{
|
|
log.Error("WriteQ3Calibration_Async() - Missing CommInterface");
|
|
return string.Empty;
|
|
}
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
if (gciBridge == null)
|
|
{
|
|
log.Error("WriteQ3Calibration_Async() - Missing GciBridge");
|
|
return string.Empty;
|
|
}
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
|
|
log.Debug($"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Test: {test.Name} - Part: {test.Part} - IsTestRslt: {(tstRslt==null?true:false)}");
|
|
|
|
try
|
|
{
|
|
if (tstRslt.GetCalibrationFactors(wm).Count == 0)
|
|
{
|
|
for (int i = 0; i < genesisSmartReader.ChannelsCount; i++)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm).Add(new TestRsltCalibFactor()
|
|
{
|
|
Stored = false,
|
|
CalibFactorIndex = i
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}catch(Exception ex)
|
|
{
|
|
log.Error($"WriteQ3Calibration_Async() - DB Exception: {ex.Message}");
|
|
}
|
|
|
|
CancellationToken token = default;
|
|
|
|
bool areInitialisedData = genesisSmartReader.CalculateQ3Calibration();
|
|
if (!areInitialisedData)
|
|
{
|
|
log.Error("WriteQ3Calibration_Async() - CalculateQ3Calibration Initialised Data not valid");
|
|
return "CalculateQ3Calibration Initialised Data not valid";
|
|
}
|
|
|
|
StoreCalibrationValuesResults(tstRslt, genesisSmartReader, wm);
|
|
|
|
if (!genesisSmartReader.Q3CalibValid)
|
|
{
|
|
log.Error("WriteQ3Calibration_Async() - Q3Channel not valid");
|
|
return "Q3Channel not valid";
|
|
}
|
|
|
|
//Get Activity Status
|
|
LedState ledMode = LedState.inactive; // swich on LED
|
|
byte valueLed = (ledMode == LedState.active) ? (byte)6 : (byte)0;
|
|
|
|
UInt16 calibFactor1 = Convert.ToUInt16(genesisSmartReader.Q3Calib_Ch1Value);
|
|
UInt16 calibFactor2 = Convert.ToUInt16(genesisSmartReader.Q3Calib_Ch2Value);
|
|
UInt16 calibFactor3 = Convert.ToUInt16(genesisSmartReader.Q3Calib_Ch3Value);
|
|
|
|
UInt16 valueSampleRate = 2;
|
|
UInt16 ResetAccumulatorsValue = 0;
|
|
UInt16 ForwardArrowValue = 0;
|
|
UInt16 StoreCalibrationValue = 1;
|
|
|
|
|
|
|
|
|
|
|
|
log.Debug( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start");
|
|
|
|
log.Debug( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set CalFactor1: {calibFactor1}");
|
|
var CalFactor1AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.CalFactor1, calibFactor1, false, false, token);
|
|
if (CalFactor1AsyncResult == null || !CalFactor1AsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor1AsyncResult failed. Result: {CalFactor1AsyncResult}");
|
|
return "Failed to set CalFactor1";
|
|
}
|
|
wm.OrigCalibFactor = calibFactor1;
|
|
if (genesisSmartReader.Q3CalibDiffPercentageValue.Length == 3)
|
|
wm.Q2ErrWOCorrection = genesisSmartReader.Q3CalibDiffPercentageValue[0];
|
|
//CH3 to DB
|
|
try
|
|
{
|
|
if (tstRslt != null &&
|
|
tstRslt?.GetCalibrationFactors(wm)?.Count == 3 &&
|
|
tstRslt?.GetCalibrationFactors(wm)?[0] != null)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm)[0].CalculatedCalibFactor = Convert.ToInt32(calibFactor1);
|
|
tstRslt.GetCalibrationFactors(wm)[0].Stored = false;
|
|
tstRslt.GetCalibrationFactors(wm)[0].IsCalibFactorValid = true;
|
|
tstRslt.GetCalibrationFactors(wm)[0].Error = genesisSmartReader.Q3CalibDiffPercentageValue[0];
|
|
}
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB Stored tstRslt:{tstRslt.Name()} - CalFactor3: {calibFactor1}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB CH1 Exception:", ex);
|
|
}
|
|
|
|
|
|
log.Debug( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set CalFactor2: {calibFactor2}");
|
|
var CalFactor2AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.CalFactor2, calibFactor2, false, false, token);
|
|
if (CalFactor2AsyncResult == null || !CalFactor2AsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor2AsyncResult failed. Result: {CalFactor2AsyncResult}");
|
|
return "Failed to set CalFactor2";
|
|
}
|
|
wm.CalibFactorLNA = calibFactor2;
|
|
if (genesisSmartReader.Q3CalibDiffPercentageValue.Length == 3)
|
|
wm.OrigCalibFactorLNA = genesisSmartReader.Q3CalibDiffPercentageValue[1];
|
|
//CH3 to DB
|
|
try
|
|
{
|
|
if (tstRslt != null &&
|
|
tstRslt?.GetCalibrationFactors(wm)?.Count == 3 &&
|
|
tstRslt?.GetCalibrationFactors(wm)?[1] != null)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm)[1].CalculatedCalibFactor = Convert.ToInt32(calibFactor2);
|
|
tstRslt.GetCalibrationFactors(wm)[1].Stored = false;
|
|
tstRslt.GetCalibrationFactors(wm)[1].IsCalibFactorValid = true;
|
|
tstRslt.GetCalibrationFactors(wm)[1].Error = genesisSmartReader.Q3CalibDiffPercentageValue[1];
|
|
}
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB Stored tstRslt:{tstRslt.Name()} - CalFactor3: {calibFactor2}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB CH2 Exception:", ex);
|
|
}
|
|
|
|
|
|
|
|
log.Debug( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set CalFactor3: {calibFactor3}");
|
|
var CalFactor3AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.CalFactor3, calibFactor3, false, false, token);
|
|
if (CalFactor3AsyncResult == null || !CalFactor3AsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor3AsyncResult failed. Result: {CalFactor3AsyncResult}");
|
|
return "Failed to set CalFactor3";
|
|
}
|
|
wm.CalibFactor = calibFactor3;
|
|
if (genesisSmartReader.Q3CalibDiffPercentageValue.Length == 3)
|
|
wm.Diff2Hz8Hz = genesisSmartReader.Q3CalibDiffPercentageValue[2];
|
|
//CH3 to DB
|
|
try
|
|
{
|
|
if (tstRslt != null &&
|
|
tstRslt?.GetCalibrationFactors(wm)?.Count == 3 &&
|
|
tstRslt?.GetCalibrationFactors(wm)?[2] != null)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm)[2].CalculatedCalibFactor = Convert.ToInt32(calibFactor3);
|
|
tstRslt.GetCalibrationFactors(wm)[2].Stored = false;
|
|
tstRslt.GetCalibrationFactors(wm)[2].IsCalibFactorValid = true;
|
|
tstRslt.GetCalibrationFactors(wm)[2].Error = genesisSmartReader.Q3CalibDiffPercentageValue[2];
|
|
}
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB Stored tstRslt:{tstRslt.Name()} - CalFactor3: {calibFactor3}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB CH3 Exception:", ex);
|
|
}
|
|
|
|
|
|
log.Info( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Set DONE CalFactor1: {calibFactor1}, CalFactor2: {calibFactor2}, CalFactor2: {calibFactor3}");
|
|
|
|
var SampleRateAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.SampleRate, valueSampleRate, false, false, token);
|
|
if (SampleRateAsyncResult == null || !SampleRateAsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - SampleRateAsyncResult failed. Result: {SampleRateAsyncResult}");
|
|
return "Failed to set SampleRate";
|
|
}
|
|
|
|
var LedModeAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.LedMode, valueLed, false, false, token);
|
|
if (LedModeAsyncResult == null || !LedModeAsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - LedModeAsyncResult failed. Result: {LedModeAsyncResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
|
|
var ResetAccumulatorsAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.ResetAccumulators, ResetAccumulatorsValue, false, false, token);
|
|
if (ResetAccumulatorsAsyncResult == null || !ResetAccumulatorsAsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - ResetAccumulatorsAsyncResult failed. Result: {ResetAccumulatorsAsyncResult}");
|
|
return "Failed set ResetAccumulators to 1";
|
|
}
|
|
|
|
var ForwardArrowAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.ForwardArrow, ForwardArrowValue, false, false, token);
|
|
if (ForwardArrowAsyncResult == null || !ForwardArrowAsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - ForwardArrowAsyncResult failed. Result: {ForwardArrowAsyncResult}");
|
|
return "Failed set ForwardArrow to 0";
|
|
}
|
|
|
|
var StoreCalibrationAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.StoreCalibration, StoreCalibrationValue, false, false, token);
|
|
if (StoreCalibrationAsyncResult == null || !StoreCalibrationAsyncResult.Success)
|
|
{
|
|
log.Error( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - StoreCalibrationAsyncResult failed. Result: {StoreCalibrationAsyncResult}");
|
|
return "Failed set StoreCalibration to 1";
|
|
}
|
|
|
|
log.Debug( $"WriteQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - StoreCalibrationAsyncResult Result: " + StoreCalibrationAsyncResult);
|
|
|
|
foreach (var row in tstRslt.GetCalibrationFactors(wm))
|
|
{
|
|
row.Stored = true;
|
|
row.ErrorStr = string.Empty;
|
|
}
|
|
return StoreCalibrationAsyncResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"WriteQ3Calibration_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
private void StoreCalibrationValuesResults(TestRslt result, GenesisSmartReader reader, WaterMeter meter)
|
|
{
|
|
if (result == null) throw new InvalidOperationException("Missing Q3 test result");
|
|
var rows = result.GetCalibrationFactors(meter);
|
|
var values = new[] { reader.Q3Calib_Ch1Value, reader.Q3Calib_Ch2Value, reader.Q3Calib_Ch3Value };
|
|
for (int channel = 0; channel < 3; channel++)
|
|
{
|
|
var row = rows[channel];
|
|
var value = values[channel];
|
|
var difference = reader.Q3CalibDiffPercentageValue[channel];
|
|
bool finite = !double.IsNaN(value) && !double.IsInfinity(value) && value >= 1 && value <= ushort.MaxValue;
|
|
row.BaseCalibFactor = (int)reader.Q3CalibValue[channel];
|
|
row.CalculatedCalibFactor = finite ? Convert.ToInt32(value) : 0;
|
|
row.IsCalibFactorValid = finite && reader.Q3CalibValid;
|
|
row.Error = double.IsNaN(difference) || double.IsInfinity(difference) ? 0 : difference;
|
|
row.Stored = false;
|
|
row.ErrorStr = row.IsCalibFactorValid ? string.Empty : "Invalid Q3 measurement or factor";
|
|
}
|
|
}
|
|
|
|
public string PrepareQ3Calibration(TestMethodCfg cfg, Test test, WaterMeter wm)
|
|
{
|
|
double[] factors;
|
|
string factorError;
|
|
if (!GenesisCalibrationFactors.TryParse(wm?.WaterMeterData?.Text1, wm?.WaterMeterData?.Text2,
|
|
wm?.WaterMeterData?.Text3, out factors, out factorError)) return factorError;
|
|
if (genesisHead == null || test == null || wm == null) return "Missing Genesis meter or test";
|
|
genesisHead.SetQ3Calibration(factors);
|
|
var prepared = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part).GetCalibrationFactors(wm);
|
|
for (int channel = 0; channel < 3; channel++)
|
|
{
|
|
prepared[channel].BaseCalibFactor = (int)factors[channel];
|
|
prepared[channel].Stored = false;
|
|
prepared[channel].IsCalibFactorValid = false;
|
|
}
|
|
|
|
log.Debug("PrepareQ3Calibration() - Start, Head: " + genesisHead?.Name);
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("PrepareQ3Calibration() - Simulated response - Config: " + cfg.ToString() + " Test: " + test.ToString() + " WaterMeter: " + wm.ToString());
|
|
try
|
|
{
|
|
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
|
|
if (tstRslt.GetCalibrationFactors(wm).Count > 0)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm).Clear();
|
|
}
|
|
if (tstRslt.GetCalibrationFactors(wm).Count == 0)
|
|
{
|
|
for (int i = 0; i < genesisHead.ChannelsCount; i++)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm).Add(new TestRsltCalibFactor()
|
|
{
|
|
Stored = false,
|
|
CalibFactorIndex = i,
|
|
BaseCalibFactor = 15625,
|
|
}
|
|
);
|
|
}
|
|
|
|
log.Debug($" Calib factor from Text1: {wm.WaterMeterData.Text1}");
|
|
log.Debug($" Calib factor from Text2: {wm.WaterMeterData.Text2}");
|
|
log.Debug($" Calib factor from Text3: {wm.WaterMeterData.Text3}");
|
|
}
|
|
}catch(Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration() - Simulated DB Exception: {ex.Message}");
|
|
}
|
|
|
|
return ResultOk;//"Simulated Connect";
|
|
}
|
|
|
|
|
|
if (cfg == null)
|
|
{
|
|
log.Error($"PrepareQ3Calibration({genesisHead?.Name}) - Missing TestMethodCfg");
|
|
return "PrepareQ3Calibration - Missing TestMethodCfg";
|
|
}
|
|
|
|
if (test == null)
|
|
{
|
|
log.Error($"PrepareQ3Calibration({genesisHead?.Name}) - Missing Test");
|
|
return "PrepareQ3Calibration - Missing Test";
|
|
}
|
|
|
|
return Task.Run(() => PrepareQ3Calibration_Async(genesisHead, cfg, test, wm))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
|
|
private async Task<string> PrepareQ3Calibration_Async(GenesisSmartReader genesisSmartReader,
|
|
TestMethodCfg cfg,
|
|
Test test, WaterMeter wm)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("PrepareQ3Calibration_Async called for iHead: " + genesisHead?.Name + ", cfg: " + cfg?.Name + ", test: " + test?.Name);
|
|
|
|
if (genesisHead == null)
|
|
{
|
|
log.Error("PrepareQ3Calibration_Async() - Missing GenesisSmartReader");
|
|
return string.Empty;
|
|
}
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface))
|
|
{
|
|
log.Error("PrepareQ3Calibration_Async() - Missing CommInterface");
|
|
return string.Empty;
|
|
}
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
if (gciBridge == null)
|
|
{
|
|
log.Error("PrepareQ3Calibration_Async() - Missing GciBridge");
|
|
return string.Empty;
|
|
}
|
|
|
|
|
|
|
|
Results.Entities.TestRslt tstRslt = null;
|
|
|
|
try
|
|
{
|
|
if (test == null)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async({genesisHead?.Name}) - Missing Test");
|
|
return "Valid Test Missing!";
|
|
}
|
|
tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
|
|
log.Debug($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Test: {test.Name} - Part: {test.Part} - IsTestRslt: {(tstRslt==null?true:false)}");
|
|
if (tstRslt?.GetCalibrationFactors(wm)?.Count > 0)
|
|
{
|
|
tstRslt?.GetCalibrationFactors(wm).Clear();
|
|
}
|
|
if (tstRslt?.GetCalibrationFactors(wm)?.Count == 0)
|
|
{
|
|
for (int i = 0; i < genesisSmartReader.ChannelsCount; i++)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm).Add(new TestRsltCalibFactor()
|
|
{
|
|
Stored = false,
|
|
CalibFactorIndex = i
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async({genesisSmartReader.GetSlotNr}) - DB TestRslt Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
|
|
|
|
CancellationToken token = default;
|
|
|
|
//Get Activity Status
|
|
LedState ledMode = LedState.active; // swich on LED
|
|
byte valueLed = (ledMode == LedState.active) ? (byte)6 : (byte)0;
|
|
//TODO BUMI - implement variable values for Q3Channel
|
|
UInt16 valueSampleRate = 10;
|
|
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Calib Factors from Dialog - Text1:{wm?.WaterMeterData?.Text1} Text2:{ wm?.WaterMeterData?.Text2}, Text3: {wm?.WaterMeterData?.Text3}");
|
|
ushort calibrationFactor1 = Convert.ToUInt16(genesisSmartReader?.Q3CalibValue[0]);
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set CalFactor1: {calibrationFactor1}");
|
|
var CalFactor1AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.CalFactor1, calibrationFactor1, false, false, token);
|
|
if (CalFactor1AsyncResult == null || !CalFactor1AsyncResult.Success)
|
|
{
|
|
log.Error( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor1AsyncResult failed. Result: {CalFactor1AsyncResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
|
|
//CH1 to DB
|
|
try
|
|
{
|
|
if (tstRslt != null &&
|
|
tstRslt?.GetCalibrationFactors(wm)?.Count == 3 &&
|
|
tstRslt?.GetCalibrationFactors(wm)?[0] != null)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm)[0].BaseCalibFactor = Convert.ToInt32(calibrationFactor1);
|
|
tstRslt.GetCalibrationFactors(wm)[0].Stored = false;
|
|
}
|
|
//wm.OrigCalibFactor = calibrationFactor1; // now dosabled
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB Stored tstRslt:{tstRslt.Name()} - CalFactor1: {calibrationFactor1}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB CH1 Exception:", ex);
|
|
}
|
|
|
|
|
|
ushort calibrationFactor2 = Convert.ToUInt16(genesisSmartReader?.Q3CalibValue[1]);
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set CalFactor2: {calibrationFactor2}");
|
|
var CalFactor2AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.CalFactor2, calibrationFactor2, false, false, token);
|
|
if (CalFactor2AsyncResult == null || !CalFactor2AsyncResult.Success)
|
|
{
|
|
log.Error( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor2AsyncResult failed. Result: {CalFactor2AsyncResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
//CH2 to DB
|
|
try
|
|
{
|
|
if (tstRslt != null &&
|
|
tstRslt?.GetCalibrationFactors(wm)?.Count == 3 &&
|
|
tstRslt?.GetCalibrationFactors(wm)?[1] != null)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm)[1].BaseCalibFactor = Convert.ToInt32(calibrationFactor2);
|
|
tstRslt.GetCalibrationFactors(wm)[1].Stored = false;
|
|
}
|
|
//wm.CalibFactorLNA = calibrationFactor2; // now dosabled
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB Stored tstRslt:{tstRslt.Name()} - CalFactor2: {calibrationFactor2}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB CH2 Exception:", ex);
|
|
}
|
|
|
|
|
|
ushort calibrationFactor3 = Convert.ToUInt16(genesisSmartReader?.Q3CalibValue[2]);
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Set CalFactor1: {calibrationFactor3}");
|
|
var CalFactor3AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.CalFactor3, calibrationFactor3, false, false, token);
|
|
if (CalFactor3AsyncResult == null || !CalFactor3AsyncResult.Success)
|
|
{
|
|
log.Error( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor3AsyncResult failed. Result: {CalFactor3AsyncResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
//CH3 to DB
|
|
try
|
|
{
|
|
if (tstRslt != null &&
|
|
tstRslt?.GetCalibrationFactors(wm)?.Count == 3 &&
|
|
tstRslt?.GetCalibrationFactors(wm)?[2] != null)
|
|
{
|
|
tstRslt.GetCalibrationFactors(wm)[2].BaseCalibFactor = Convert.ToInt32(calibrationFactor3);
|
|
tstRslt.GetCalibrationFactors(wm)[2].Stored = false;
|
|
}
|
|
//wm.CalibFactor = calibrationFactor3; // now dosabled
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB Stored tstRslt:{tstRslt.Name()} - CalFactor3: {calibrationFactor3}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - DB CH3 Exception:", ex);
|
|
}
|
|
|
|
|
|
|
|
var SampleRateAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.SampleRate, valueSampleRate, false, false, token);
|
|
if (SampleRateAsyncResult == null || !SampleRateAsyncResult.Success)
|
|
{
|
|
log.Error( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - SampleRateAsyncResult failed. Result: {SampleRateAsyncResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
|
|
var LedModeAsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.LedMode, valueLed, false, false, token);
|
|
if (LedModeAsyncResult == null || !LedModeAsyncResult.Success)
|
|
{
|
|
log.Error( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - LedModeAsyncResult failed. Result: {LedModeAsyncResult}");
|
|
return "Failed to disable Led Mode";
|
|
}
|
|
|
|
log.Debug( $"PrepareQ3Calibration_Async( Slot: {genesisSmartReader.GetSlotNr}) - PrepareQ3Calibration_Async Result: " + LedModeAsyncResult);
|
|
|
|
return LedModeAsyncResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"PrepareQ3Calibration_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Used for test only.
|
|
/// </summary>
|
|
/// <param name="genesisSmartReader"></param>
|
|
/// <param name="cfg"></param>
|
|
/// <param name="rawHex"></param>
|
|
/// <returns></returns>
|
|
|
|
|
|
public string CheckMeterPrepare()
|
|
{
|
|
if (genesisHead != null && genesisHead.DebugLevel == DebugMode.Simulate)
|
|
{
|
|
log.Debug("Connect() - Simulated response");
|
|
return ResultOk;//"Simulated Connect";
|
|
}
|
|
return Task.Run(() => CheckMeterPrepare_Async(genesisHead))
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
}
|
|
|
|
private async Task<string> CheckMeterPrepare_Async(GenesisSmartReader genesisSmartReader)
|
|
{
|
|
try
|
|
{
|
|
log.Debug("CheckMeterPrepare_Async called for iHead: " + genesisHead);
|
|
|
|
if (genesisHead == null) return string.Empty;
|
|
if (string.IsNullOrEmpty(genesisHead.CommInterface)) return string.Empty;
|
|
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
|
|
if (gciBridge == null) return string.Empty;
|
|
|
|
CancellationToken token = default;
|
|
|
|
//Get Activity Status
|
|
UInt16 valueTrigerIdle = 0;
|
|
log.Debug( $"CheckMeterPrepare_Async( Slot: {genesisSmartReader.GetSlotNr}) - Start - Will Set TriggerIdle: {valueTrigerIdle}");
|
|
|
|
var TriggerIdleAsyncResult = await gciBridge.ReadRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.TriggerIdle);
|
|
if (TriggerIdleAsyncResult == null || !TriggerIdleAsyncResult.Success)
|
|
{
|
|
log.Error( $"CheckMeterPrepare_Async( Slot: {genesisSmartReader.GetSlotNr}) - CheckMeterPrepare failed. Result: {TriggerIdleAsyncResult}");
|
|
//return "Failed to disable Led Mode";
|
|
}
|
|
|
|
try
|
|
{
|
|
UInt32 int32 = ParseRawHexToUInt32(TriggerIdleAsyncResult?.Result?.RawHex);
|
|
if (int32 == 0)
|
|
{
|
|
log.Debug("Already set ");
|
|
return ResultOk;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error( $"CheckMeterPrepare_Async( Slot: {genesisSmartReader.GetSlotNr}) - CheckMeterPrepare failed. Result: {TriggerIdleAsyncResult}");
|
|
}
|
|
|
|
var CalFactor2AsyncResult = await gciBridge.WriteRegisterWithRetryAsync(genesisSmartReader.GetSlotNr, RadioService.TriggerIdle, valueTrigerIdle, false, false, token);
|
|
if (CalFactor2AsyncResult == null || !CalFactor2AsyncResult.Success)
|
|
{
|
|
log.Error( $"CheckMeterPrepare_Async( Slot: {genesisSmartReader.GetSlotNr}) - CalFactor2AsyncResult failed. Result: {CalFactor2AsyncResult}");
|
|
return $"Failed to set register {RadioService.TriggerIdle} to {valueTrigerIdle}";
|
|
}
|
|
|
|
|
|
log.Debug( $"CheckMeterPrepare_Async( Slot: {genesisSmartReader.GetSlotNr}) - CheckMeterPrepare_Async Result: " + CalFactor2AsyncResult);
|
|
|
|
return CalFactor2AsyncResult.Success ? ResultOk : ResultNok;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"CheckMeterPrepare_Async({genesisHead.GetSlotNr}) - Exception:", ex);
|
|
return ex.Message;
|
|
}
|
|
}
|
|
|
|
private static uint ParseRawHexToUInt32(string rawHex, bool littleEndian = false)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(rawHex))
|
|
throw new FormatException("RawHex is empty.");
|
|
|
|
// Remove spaces/tabs/newlines
|
|
string cleaned = rawHex.Replace(" ", "")
|
|
.Replace("\t", "")
|
|
.Replace("\r", "")
|
|
.Replace("\n", "");
|
|
|
|
// Must be even number of hex chars
|
|
if (cleaned.Length % 2 != 0)
|
|
throw new FormatException($"Invalid hex length: {cleaned.Length}");
|
|
|
|
// Max 4 bytes = 8 hex chars
|
|
if (cleaned.Length > 8)
|
|
throw new FormatException($"Too many bytes for UInt32: '{rawHex}'");
|
|
|
|
byte[] bytes = new byte[cleaned.Length / 2];
|
|
|
|
for (int i = 0; i < bytes.Length; i++)
|
|
{
|
|
bytes[i] = Convert.ToByte(cleaned.Substring(i * 2, 2), 16);
|
|
}
|
|
|
|
if (littleEndian)
|
|
Array.Reverse(bytes);
|
|
|
|
uint value = 0;
|
|
|
|
foreach (byte b in bytes)
|
|
{
|
|
value = (value << 8) | b;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
}
|
|
} |