tbf/TBF/Rig/RegisterReaders/GenesisRegReader/communication/OptoHeadTest.cs
Michal Buzik 52bd0d01ce Restore Genesis communication and Q3 calibration from special branches
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.
2026-09-09 15:04:49 +02:00

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;
}
}
}