diff --git a/GenesisCordonelInterface/API/GciPublicModels.cs b/GenesisCordonelInterface/API/GciPublicModels.cs
new file mode 100644
index 000000000..aee36896a
--- /dev/null
+++ b/GenesisCordonelInterface/API/GciPublicModels.cs
@@ -0,0 +1,312 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static GenesisCordonelInterface.API.InterfaceOutsideToGCI;
+using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
+using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
+
+namespace GenesisCordonelInterface.API
+{
+ ///
+ /// Public data contract layer for the Genesis Cordonel Interface (GCI).
+ ///
+ /// This class defines all Data Transfer Objects (DTOs) that are exposed
+ /// to external consumers (e.g. TBF, UI, or other integration layers).
+ ///
+ /// Responsibilities:
+ /// - Provide stable, dependency-free models for external usage
+ /// - Decouple internal GCI implementation (GenesisMeter, Xylem libraries)
+ /// from external systems
+ /// - Define request/response contracts for all supported operations
+ /// - Contain mapping methods between public DTOs and internal domain models
+ ///
+ /// Architecture:
+ /// External world (TBF / UI)
+ /// ↓
+ /// GciPublicModels (this layer)
+ /// ↓
+ /// Internal GCI API (InterfaceGCIToLaatzen, GenesisMeter, etc.)
+ ///
+ /// Notes:
+ /// - Public models must NOT expose internal types (e.g. GenesisMeter, IPort, etc.)
+ /// - All mapping between internal and external representations must be done here
+ /// - DTOs are designed to be simple, serializable, and stable over time
+ /// - Any change in internal implementation should not affect these models
+ ///
+ /// Pattern:
+ /// Each operation follows a consistent structure:
+ /// Request → Operation → Result
+ ///
+ /// Example:
+ /// GciInitSlotRequest → InitSlot → GciInitSlotResult
+ /// GetSlot → GciSlotInfo
+ /// GetPcbId → GciGetPcbIdResult
+ ///
+ /// This layer acts as a boundary between domain logic and integration logic.
+ ///
+ public class GciPublicModels
+ {
+ ///
+ /// Public DTOs exposed to external systems.
+ /// These models represent the contract of the GCI API.
+ /// They must remain stable and independent of internal implementation.
+ ///
+ #region ================================== PUBLIC MODELS ===========================================
+
+ public class GciSlotInfo
+ {
+ public int SlotId { get; set; }
+
+ public bool Exists { get; set; }
+ public bool Success { get; set; }
+ public string Message { get; set; }
+ public string PcbId { get; set; }
+
+ public GciConfigSource ConfigSource { get; set; }
+ public GciPasswordSource PasswordSource { get; set; }
+
+ public GciPortConfig RequestPort { get; set; }
+ public GciPortConfig StreamingPort { get; set; }
+ }
+
+ public class Result
+ {
+ public int SlotId { get; set; }
+ public bool Success { get; set; }
+ public string Message { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "SlotId={0}, Success={1}, Message={2}",
+ SlotId,
+ Success,
+ Message);
+ }
+ }
+
+ public enum GciPasswordSource
+ {
+ RestApi = 0,
+ OfflineFile = 1,
+ InterfaceInputPassword = 2,
+ }
+ public enum GciConfigSource
+ {
+ FileConfig = 0,
+ InterfaceInputConfig = 1,
+ }
+
+ ///
+ /// Collection of port settings
+ ///
+ public class GciPortConfig
+ {
+ public string PortName { get; set; }
+ public string Type { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format("PortName={0}, Type={1}", PortName, Type);
+ }
+ }
+
+ public class GciInitSlotRequest
+ {
+ public int SlotId { get; set; }
+ public GciConfigSource ConfigSource { get; set; }
+ public GciPasswordSource PasswordSource { get; set; }
+ public GciPortConfig RequestPort { get; set; }
+ public GciPortConfig StreamingPort { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "SlotId={0}, GciConfigSource={1}, PasswordSource={2}, RequestPort={3}, StreamingPort={4}",
+ SlotId,
+ ConfigSource,
+ PasswordSource,
+ RequestPort,
+ StreamingPort);
+ }
+ }
+
+ public class GciInitSlotResult
+ {
+ public int SlotId { get; set; }
+
+ public bool Success { get; set; }
+
+ public string Message { get; set; }
+
+ public string PcbId { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "SlotId={0}, Success={1}, Message={2}, PcbId={3}",
+ SlotId,
+ Success,
+ Message,
+ PcbId);
+ }
+ }
+
+ public class GciCleanSlotsResult
+ {
+ public bool Success { get; set; }
+ public string Message { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "Success={0}, Message={1}",
+ Success,
+ Message);
+ }
+ }
+
+ public class GciGetPcbIdResult
+ {
+ public int SlotId { get; set; }
+
+ public bool Success { get; set; }
+
+ public string PcbId { get; set; }
+
+ public string Message { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "SlotId={0}, Success={1}, PcbId={2}, Message={3}",
+ SlotId,
+ Success,
+ PcbId,
+ Message);
+ }
+ }
+ public class GciConnectResult
+ {
+ public int SlotId { get; set; }
+ public bool Success { get; set; }
+ public string PcbId { get; set; }
+ public bool IsLoggedOn { get; set; }
+ public string FwVersion { get; set; }
+ public string InterfaceVersion { get; set; }
+ public bool InterfaceSupportsFwVersion { get; set; }
+ public List Registers { get; set; } = new List();
+ public string Message { get; set; }
+ }
+
+ public class GciRegisterSnapshot
+ {
+ public string Name { get; set; }
+ public string Type { get; set; }
+ public string RawValue { get; set; }
+ public string Min { get; set; }
+ public string Max { get; set; }
+ public string Description { get; set; }
+ public string Version { get; set; }
+ public string IsAvailable { get; set; }
+ public string Privilege { get; set; }
+ }
+
+ public class GciDisconnectResult
+ {
+ public int SlotId { get; set; }
+ public bool Success { get; set; }
+ public string Message { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "SlotId={0}, Success={1}, Message={2}",
+ SlotId,
+ Success,
+ Message);
+ }
+ }
+ #endregion
+
+ ///
+ /// Mapping methods between public DTOs and internal GCI models.
+ /// Ensures separation between external contracts and internal domain objects.
+ ///
+ #region ================================== OUTERN/INTERN and back models mapping ==================================
+ public static PasswordSource MapPasswordSource(GciPasswordSource src)
+ {
+ return (PasswordSource)src;
+ }
+
+ public static ConfigSource MapConfigSource(GciConfigSource src)
+ {
+ return (ConfigSource)src;
+ }
+
+ public static Xylem.Common.Hardware.Interfaces.Ports.PortCore.PortConfig? MapPort(GciPortConfig port)
+ {
+ if (port == null)
+ return null;
+
+ Xylem.Common.Hardware.Interfaces.Ports.PortCore.PortConfig result = new Xylem.Common.Hardware.Interfaces.Ports.PortCore.PortConfig();
+
+ result.PortName = port.PortName;
+ result.Type = port.Type;
+
+ return result;
+ }
+
+ public static GciInitSlotResult MapInitResult(GciInitSlotResult result)
+ {
+ if (result == null)
+ return null;
+
+ return new GciInitSlotResult
+ {
+ SlotId = result.SlotId,
+ Success = result.Success,
+ Message = result.Message
+ };
+ }
+
+ public static GciPasswordSource MapPasswordSourceBack(PasswordSource src)
+ {
+ return (GciPasswordSource)src;
+ }
+
+ public static GciConfigSource MapConfigSourceBack(ConfigSource src)
+ {
+ return (GciConfigSource)src;
+ }
+
+ public static GciPortConfig MapPortBack(PortConfig? port)
+ {
+ if (!port.HasValue)
+ return null;
+
+ PortConfig value = port.Value;
+
+ return new GciPortConfig
+ {
+ PortName = value.PortName,
+ Type = value.Type
+ };
+ }
+
+ public static GciPortConfig MapPortBack(IPort port)
+ {
+ if (port == null)
+ return null;
+
+ return new GciPortConfig
+ {
+ PortName = port.GetPortName(),
+ Type = port.GetType().Name
+ };
+ }
+ #endregion
+ }
+}
diff --git a/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs b/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs
index 8e0fdefd3..e0fdc31e6 100644
--- a/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs
+++ b/GenesisCordonelInterface/API/InterfaceGCIToLaatzen.cs
@@ -1,15 +1,16 @@
-using System;
+using GenesisCordonelInterface.Core.Threading;
+using NLog;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using GenesisCordonelInterface.Core.Threading;
-using NLog;
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
+using static GenesisCordonelInterface.API.GciPublicModels;
using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
namespace GenesisCordonelInterface.API
@@ -31,7 +32,7 @@ namespace GenesisCordonelInterface.API
#endregion
- #region Worker
+ #region ================================== Worker ==================================
private ApiWorker GetWorker(int slot)
{
@@ -43,7 +44,7 @@ namespace GenesisCordonelInterface.API
#endregion
- #region Worker Debug
+ #region ================================== Worker Debug ==================================
public class WorkerDebugStatus
{
public int Slot { get; set; }
@@ -73,7 +74,7 @@ namespace GenesisCordonelInterface.API
}
#endregion
- #region MeterBatch Debug
+ #region ================================== MeterBatch Debug ==================================
public class MeterBatchDebugStatus
{
public int Slot { get; set; }
@@ -134,7 +135,7 @@ namespace GenesisCordonelInterface.API
}
#endregion
- #region Helpers
+ #region ================================== Helpers ==================================
private GenesisMeter GetMeter(int slot)
{
@@ -178,40 +179,32 @@ namespace GenesisCordonelInterface.API
#endregion
- #region INIT
+ #region ================================== INIT ==================================
- public class InitResult
+ public Task InitOneMeterFromExternAsync(
+ int slot,
+ ConfigSource cfg,
+ PasswordSource pwd,
+ PortConfig? req,
+ PortConfig? str,
+ CancellationToken token = default)
{
- public bool Success { get; set; }
- public int Slot { get; set; }
- public string ErrorMessage { get; set; }
+ return GetWorker(slot).RunAsync(() => InitOneMeterFromExtern(slot, cfg, pwd, req, str), token);
}
- public Task InitOneMeterFromExternAsync(
- int slot,
- ConfigSource cfg,
- PasswordSource pwd,
- PortConfig? req,
- PortConfig? str,
- CancellationToken token = default)
- {
- return GetWorker(slot).RunAsync(() =>
- InitOneMeterFromExtern(slot, cfg, pwd, req, str), token);
- }
-
- public InitResult InitOneMeterFromExtern(
- int slot,
- ConfigSource cfg,
- PasswordSource pwd,
- PortConfig? req,
- PortConfig? str)
+ public GciPublicModels.GciInitSlotResult InitOneMeterFromExtern(
+ int slot,
+ ConfigSource cfg,
+ PasswordSource pwd,
+ PortConfig? req,
+ PortConfig? str)
{
const string operation = nameof(InitOneMeterFromExtern);
try
{
LogInfo(operation,
- $"Start. Slot={slot}, ConfigSource={cfg}, PasswordSource={pwd}, " +
+ $"Start. Slot={slot}, GciConfigSource={cfg}, PasswordSource={pwd}, " +
$"RequestPort={(req.HasValue ? req.Value.PortName.ToString() : "")}, " +
$"StreamingPort={(str.HasValue ? str.Value.PortName.ToString() : "")}");
@@ -227,24 +220,128 @@ namespace GenesisCordonelInterface.API
LogInfo(operation, $"Success. Slot={slot}, MeterBatchCount={_meterBatch.ListOfMeters.Count}");
- return new InitResult { Success = true, Slot = slot };
+ return new GciPublicModels.GciInitSlotResult { Success = true, SlotId = slot };
}
catch (Exception ex)
{
LogError(operation, ex);
- return new InitResult
+ return new GciPublicModels.GciInitSlotResult
{
Success = false,
- Slot = slot,
- ErrorMessage = ex.Message
+ SlotId = slot,
+ Message = ex.Message
+ };
+ }
+ }
+
+ public Task GetOneMeterInfo(
+ int slot,
+ CancellationToken token = default)
+ {
+ return GetWorker(slot).RunAsync(() => GetOneMeterInfo(slot), token);
+ }
+
+ public GciPublicModels.GciSlotInfo GetOneMeterInfo(int slotId)
+ {
+ const string operation = nameof(GetOneMeterInfo);
+
+ try
+ {
+ LogInfo(operation, $"Start. Slot={slotId}");
+
+ var meter = _meterBatch.ListOfMeters
+ .OfType()
+ .FirstOrDefault(m => m.Slot == slotId);
+
+ if (meter == null)
+ {
+ return new GciPublicModels.GciSlotInfo
+ {
+ SlotId = slotId,
+ Success = true,
+ Exists = false,
+ Message = "Slot is empty."
+ };
+ }
+
+ return new GciPublicModels.GciSlotInfo
+ {
+ SlotId = slotId,
+ Success = true,
+ Exists = true,
+ Message = "Slot found.",
+
+ // PcbId = meter.PcbId,
+
+ ConfigSource = GciPublicModels.MapConfigSourceBack(meter.useConfigSource),
+ PasswordSource = GciPublicModels.MapPasswordSourceBack(meter.usePasswordSource),
+
+ RequestPort = GciPublicModels.MapPortBack(meter.RequestPort),
+ StreamingPort = GciPublicModels.MapPortBack(meter.StreamingPort)
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError(operation, ex);
+
+ return new GciPublicModels.GciSlotInfo
+ {
+ SlotId = slotId,
+ Success = false,
+ Exists = false,
+ Message = ex.Message
+ };
+ }
+ }
+
+ public Task CleanSlotsAsync(
+ CancellationToken token = default)
+ {
+ return Task.Run(() => CleanSlots(), token);
+ }
+
+ public GciPublicModels.GciCleanSlotsResult CleanSlots()
+ {
+ const string operation = nameof(CleanSlots);
+
+ try
+ {
+ LogInfo(operation, "Start.");
+
+ _meterBatch.ListOfMeters.Clear();
+ _selectedSlots.Clear();
+
+ foreach (var worker in _workers.Values)
+ {
+ worker.Dispose();
+ }
+
+ _workers.Clear();
+
+ LogInfo(operation, "Success. Meter batch, selected slots and workers cleared.");
+
+ return new GciPublicModels.GciCleanSlotsResult
+ {
+ Success = true,
+ Message = "Slots cleaned."
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError(operation, ex);
+
+ return new GciPublicModels.GciCleanSlotsResult
+ {
+ Success = false,
+ Message = ex.Message
};
}
}
#endregion
- #region PORT DETECTION
+ #region ================================== PORT DETECTION ==================================
public class PortDetectionResult
{
@@ -361,45 +458,16 @@ namespace GenesisCordonelInterface.API
#endregion
- #region CONNECT
+ #region ================================== CONNECT ==================================
- public class ConnectResult
+ public Task ConnectOneSlotAsync(int slot, CancellationToken token = default)
{
- public bool Success { get; set; }
- public int Slot { get; set; }
- public string PcbId { get; set; }
- public bool IsLoggedOn { get; set; }
-
- public string FwVersion { get; set; }
- public string InterfaceVersion { get; set; }
- public bool InterfaceSupportsFwVersion { get; set; }
-
- public List Registers { get; set; } = new List();
-
- public string ErrorMessage { get; set; }
+ return GetWorker(slot).RunAsync(() => ConnectOneSlot(slot), token);
}
- public class RegisterSnapshot
+ public GciPublicModels.GciConnectResult ConnectOneSlot(int slot)
{
- public string Name { get; set; }
- public string Type { get; set; }
- public string RawValue { get; set; }
- public string Min { get; set; }
- public string Max { get; set; }
- public string Description { get; set; }
- public string Version { get; set; }
- public string IsAvailable { get; set; }
- public string Privilege { get; set; }
- }
-
- public Task ConnectOneMeterAsync(int slot, CancellationToken token = default)
- {
- return GetWorker(slot).RunAsync(() => ConnectOneMeter(slot), token);
- }
-
- public ConnectResult ConnectOneMeter(int slot)
- {
- const string operation = nameof(ConnectOneMeter);
+ const string operation = nameof(ConnectOneSlot);
try
{
@@ -413,18 +481,18 @@ namespace GenesisCordonelInterface.API
{
LogInfo(operation, $"Failed. Slot={slot}, Reason=Login failed.");
- return new ConnectResult
+ return new GciPublicModels.GciConnectResult
{
Success = false,
- Slot = slot,
- ErrorMessage = "Login failed."
+ SlotId = slot,
+ Message = "Login failed."
};
}
- var result = new ConnectResult
+ var result = new GciPublicModels.GciConnectResult
{
Success = true,
- Slot = slot,
+ SlotId = slot,
PcbId = meter.PcbId,
IsLoggedOn = true,
FwVersion = meter.FwVersion,
@@ -444,25 +512,25 @@ namespace GenesisCordonelInterface.API
{
LogError(operation, ex);
- return new ConnectResult
+ return new GciPublicModels.GciConnectResult
{
Success = false,
- Slot = slot,
- ErrorMessage = ex.Message
+ SlotId = slot,
+ Message = ex.Message
};
}
}
- private List BuildRegisters(GenesisMeter meter)
+ private List BuildRegisters(GenesisMeter meter)
{
- var list = new List();
+ var list = new List();
foreach (var item in meter.GetRegistersDic())
{
var from = item.Key.RegisterDetail.Version.First?.ToString() ?? "-";
var to = item.Key.RegisterDetail.Version.Last?.ToString() ?? "-";
- list.Add(new RegisterSnapshot
+ list.Add(new GciRegisterSnapshot
{
Name = item.Key.GetIdent(),
Type = item.Key.DataType.Name,
@@ -481,14 +549,72 @@ namespace GenesisCordonelInterface.API
#endregion
- #region PCB
+ #region ================================== DISCONNECT ==================================
- public Task GetPcbIdAsync(int slot, CancellationToken token = default(CancellationToken))
+ public Task DisconnectAsync(
+ int slot,
+ CancellationToken token = default)
+ {
+ return GetWorker(slot).RunAsync(() => Disconnect(slot), token);
+ }
+
+ public GciPublicModels.GciDisconnectResult Disconnect(int slot)
+ {
+ const string operation = nameof(Disconnect);
+
+ try
+ {
+ LogInfo(operation, $"Start. Slot={slot}");
+
+ var meter = GetMeter(slot);
+
+ if (meter.IsLoggedOn)
+ meter.Logout();
+
+ meter.DisposeMeter();
+
+ LogInfo(operation, $"Success. Slot={slot}");
+
+ return new GciPublicModels.GciDisconnectResult
+ {
+ SlotId = slot,
+ Success = true,
+ Message = "Disconnected successfully."
+ };
+ }
+ catch (Exception ex)
+ {
+ LogError(operation, ex);
+
+ return new GciPublicModels.GciDisconnectResult
+ {
+ SlotId = slot,
+ Success = false,
+ Message = ex.Message
+ };
+ }
+ finally
+ {
+ if (_workers.TryRemove(slot, out var worker))
+ {
+ worker.Dispose();
+ LogInfo(operation, $"Worker disposed. Slot={slot}");
+ }
+ }
+ }
+
+ #endregion
+
+ #region ================================== PCB ==================================
+
+ public Task GetPcbIdAsync(
+ int slot,
+ CancellationToken token = default(CancellationToken))
{
return GetWorker(slot).RunAsync(() => GetPcbId(slot), token, "GetPcbId");
}
- public string GetPcbId(int slot)
+ public GciPublicModels.GciGetPcbIdResult GetPcbId(int slot)
{
const string operation = nameof(GetPcbId);
@@ -507,19 +633,34 @@ namespace GenesisCordonelInterface.API
LogInfo(operation, $"Finish. Slot={slot}, PcbId={pcbId ?? ""}");
- return pcbId;
+ return new GciPublicModels.GciGetPcbIdResult
+ {
+ SlotId = slot,
+ Success = !string.IsNullOrWhiteSpace(pcbId),
+ PcbId = pcbId,
+ Message = !string.IsNullOrWhiteSpace(pcbId)
+ ? "PCB ID read successfully."
+ : "PCB ID is empty."
+ };
}
}
catch (Exception ex)
{
LogError(operation, ex);
- throw;
+
+ return new GciPublicModels.GciGetPcbIdResult
+ {
+ SlotId = slot,
+ Success = false,
+ PcbId = null,
+ Message = ex.Message
+ };
}
}
#endregion
- #region REGISTER READ
+ #region ================================== REGISTER READ ==================================
public class RegisterReadResult
{
@@ -573,7 +714,7 @@ namespace GenesisCordonelInterface.API
#endregion
- #region REGISTER WRITE
+ #region ================================== REGISTER WRITE ==================================
public class RegisterWriteResult
{
@@ -700,47 +841,7 @@ namespace GenesisCordonelInterface.API
#endregion
- #region DISCONNECT
-
- public Task DisconnectAsync(int slot, CancellationToken token = default)
- {
- return GetWorker(slot).RunAsync(() => Disconnect(slot), token);
- }
-
- public void Disconnect(int slot)
- {
- const string operation = nameof(Disconnect);
-
- try
- {
- LogInfo(operation, $"Start. Slot={slot}");
-
- var meter = GetMeter(slot);
-
- if (meter.IsLoggedOn)
- meter.Logout();
-
- meter.DisposeMeter();
-
- LogInfo(operation, $"Success. Slot={slot}");
- }
- catch (Exception ex)
- {
- LogError(operation, ex);
- }
- finally
- {
- if (_workers.TryRemove(slot, out var worker))
- {
- worker.Dispose();
- LogInfo(operation, $"Worker disposed. Slot={slot}");
- }
- }
- }
-
- #endregion
-
- #region PASSWORD
+ #region ================================== PASSWORD ==================================
public Task SetMeterPasswordAsync(
int slot,
@@ -776,7 +877,7 @@ namespace GenesisCordonelInterface.API
#endregion
- #region METER BATCH SETUP
+ #region ================================== METER BATCH SETUP ==================================
// ----------------------------------------------------
public void ReloadSlotSetup()
diff --git a/GenesisCordonelInterface/API/InterfaceOutsideToGCI.cs b/GenesisCordonelInterface/API/InterfaceOutsideToGCI.cs
index 4101830df..e29aa1e92 100644
--- a/GenesisCordonelInterface/API/InterfaceOutsideToGCI.cs
+++ b/GenesisCordonelInterface/API/InterfaceOutsideToGCI.cs
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
+using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
-using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
-using static Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.GenesisMeter;
namespace GenesisCordonelInterface.API
{
@@ -15,10 +14,6 @@ namespace GenesisCordonelInterface.API
{
private readonly InterfaceGCIToLaatzen _innerMeterAPI;
- private readonly Dictionary _requestPorts = new Dictionary();
- private readonly Dictionary _streamingPorts = new Dictionary();
- private readonly object _portLock = new object();
-
public event Action> MeterBatchStatusChanged;
public InterfaceOutsideToGCI()
@@ -26,8 +21,7 @@ namespace GenesisCordonelInterface.API
_innerMeterAPI = new InterfaceGCIToLaatzen();
}
- #region PORT DETECTION
- // ----------------------------------------------------
+ #region ================================== PORT DETECTION ==================================
public InterfaceGCIToLaatzen.PortDetectionResult DetectStreamingPort(int slot)
{
@@ -61,132 +55,96 @@ namespace GenesisCordonelInterface.API
return result;
}
- // ----------------------------------------------------
#endregion
- #region INIT
- // ----------------------------------------------------
+ #region ================================== INIT ==================================
- public InterfaceGCIToLaatzen.InitResult InitOneMeterFromExtern(
- int slot,
- ConfigSource useConfigSource,
- PasswordSource usePasswordSource,
- PortConfig? requestPort,
- PortConfig? streamingPort)
+ public async Task InitSlotAsync(GciPublicModels.GciInitSlotRequest request, CancellationToken token = default)
{
- var result = _innerMeterAPI.InitOneMeterFromExtern(
- slot,
- useConfigSource,
- usePasswordSource,
- requestPort,
- streamingPort);
+ if (request == null)
+ throw new ArgumentNullException(nameof(request));
- RaiseMeterBatchStatusChanged();
- return result;
- }
-
- public async Task InitOneMeterFromExternAsync(
- int slot,
- ConfigSource useConfigSource,
- PasswordSource usePasswordSource,
- PortConfig? requestPort,
- PortConfig? streamingPort,
- CancellationToken token = default(CancellationToken))
- {
var result = await _innerMeterAPI.InitOneMeterFromExternAsync(
- slot,
- useConfigSource,
- usePasswordSource,
- requestPort,
- streamingPort,
+ request.SlotId,
+ GciPublicModels.MapConfigSource(request.ConfigSource),
+ GciPublicModels.MapPasswordSource(request.PasswordSource),
+ GciPublicModels.MapPort(request.RequestPort),
+ GciPublicModels.MapPort(request.StreamingPort),
token);
RaiseMeterBatchStatusChanged();
+
return result;
}
- public InterfaceGCIToLaatzen.InitResult InitSlotWithConfiguredPorts(
- int slot,
- ConfigSource useConfigSource,
- PasswordSource usePasswordSource)
+ public async Task GetSlotAsync(
+ int slotId,
+ CancellationToken token = default)
{
- return InitOneMeterFromExtern(
- slot,
- useConfigSource,
- usePasswordSource,
- GetSlotRequestPort(slot),
- GetSlotStreamingPort(slot));
+ if (slotId <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ var result = await _innerMeterAPI.GetOneMeterInfo(slotId, token);
+
+ return result;
}
- public Task InitSlotWithConfiguredPortsAsync(
- int slot,
- ConfigSource useConfigSource,
- PasswordSource usePasswordSource,
- CancellationToken token = default(CancellationToken))
+ public async Task CleanSlotsAsync(
+ CancellationToken token = default)
{
- return InitOneMeterFromExternAsync(
- slot,
- useConfigSource,
- usePasswordSource,
- GetSlotRequestPort(slot),
- GetSlotStreamingPort(slot),
- token);
- }
+ var result = await _innerMeterAPI.CleanSlotsAsync(token);
- // ----------------------------------------------------
+ RaiseMeterBatchStatusChanged();
+
+ return result;
+ }
#endregion
- #region CONNECTION
- // ----------------------------------------------------
+ #region ================================== CONNECTION ==================================
- public InterfaceGCIToLaatzen.ConnectResult ConnectOneMeter(int slot)
+ public async Task ConnectOneSlotAsync(
+ int slot,
+ CancellationToken token = default)
{
- var result = _innerMeterAPI.ConnectOneMeter(slot);
+ GciPublicModels.GciConnectResult result = await _innerMeterAPI.ConnectOneSlotAsync(slot, token);
+
RaiseMeterBatchStatusChanged();
+
return result;
}
- public async Task ConnectOneMeterAsync(
- int slot,
- CancellationToken token = default(CancellationToken))
+ public async Task DisconnectAsync(
+ int slot,
+ CancellationToken token = default)
{
- var result = await _innerMeterAPI.ConnectOneMeterAsync(slot, token);
+ if (slot <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ var result = await _innerMeterAPI.DisconnectAsync(slot, token);
+
RaiseMeterBatchStatusChanged();
+
return result;
}
-
- public void Disconnect(int slot)
- {
- _innerMeterAPI.Disconnect(slot);
- RaiseMeterBatchStatusChanged();
- }
-
- public async Task DisconnectAsync(
- int slot,
- CancellationToken token = default(CancellationToken))
- {
- await _innerMeterAPI.DisconnectAsync(slot, token);
- RaiseMeterBatchStatusChanged();
- }
-
- // ----------------------------------------------------
#endregion
- #region READ
+ #region ================================== PCB ==================================
+ public async Task GetPcbIdAsync(
+ int slot,
+ CancellationToken token = default)
+ {
+ if (slot <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ var result = await _innerMeterAPI.GetPcbIdAsync(slot, token);
+
+ return result;
+ }
+ #endregion
+
+ #region ================================== READ ==================================
// ----------------------------------------------------
- public string GetPcbId(int slot)
- {
- return _innerMeterAPI.GetPcbId(slot);
- }
-
- public Task GetPcbIdAsync(
- int slot,
- CancellationToken token = default(CancellationToken))
- {
- return _innerMeterAPI.GetPcbIdAsync(slot, token);
- }
-
public InterfaceGCIToLaatzen.RegisterReadResult ReadRegister(
int slot,
string registerName)
@@ -205,7 +163,7 @@ namespace GenesisCordonelInterface.API
// ----------------------------------------------------
#endregion
- #region WRITE
+ #region ================================== WRITE ==================================
// ----------------------------------------------------
public async Task WriteRegisterAsync(
@@ -261,7 +219,7 @@ namespace GenesisCordonelInterface.API
// ----------------------------------------------------
#endregion
- #region DEBUG STATUS
+ #region ================================== DEBUG STATUS ==================================
// ----------------------------------------------------
public List GetWorkerDebugStatuses()
@@ -286,7 +244,7 @@ namespace GenesisCordonelInterface.API
// ----------------------------------------------------
#endregion
- #region SLOT SELECTION
+ #region ================================== SLOT SELECTION ==================================
// ----------------------------------------------------
public void SetSlotSelected(int slot, bool selected)
@@ -308,10 +266,10 @@ namespace GenesisCordonelInterface.API
// ----------------------------------------------------
#endregion
- #region SLOT PORT CONFIG
+ #region ================================== SLOT PORT CONFIG ==================================
// ----------------------------------------------------
- public void SetSlotRequestPort(int slot, string portName)
+ /*public void SetSlotRequestPort(int slot, string portName)
{
lock (_portLock)
{
@@ -321,7 +279,7 @@ namespace GenesisCordonelInterface.API
}
else
{
- _requestPorts[slot] = new PortConfig
+ _requestPorts[slot] = new GciPortConfig
{
PortName = portName,
Type = "Serial"
@@ -342,7 +300,7 @@ namespace GenesisCordonelInterface.API
}
else
{
- _streamingPorts[slot] = new PortConfig
+ _streamingPorts[slot] = new GciPortConfig
{
PortName = portName,
Type = "Serial"
@@ -353,11 +311,11 @@ namespace GenesisCordonelInterface.API
RaiseMeterBatchStatusChanged();
}
- public PortConfig? GetSlotRequestPort(int slot)
+ public GciPortConfig? GetSlotRequestPort(int slot)
{
lock (_portLock)
{
- PortConfig port;
+ GciPortConfig port;
if (_requestPorts.TryGetValue(slot, out port))
return port;
@@ -365,22 +323,22 @@ namespace GenesisCordonelInterface.API
}
}
- public PortConfig? GetSlotStreamingPort(int slot)
+ public GciPortConfig? GetSlotStreamingPort(int slot)
{
lock (_portLock)
{
- PortConfig port;
+ GciPortConfig port;
if (_streamingPorts.TryGetValue(slot, out port))
return port;
return null;
}
- }
+ }*/
// ----------------------------------------------------
#endregion
- #region METER BATCH SETUP
+ #region ================================== METER BATCH SETUP ==================================
// ----------------------------------------------------
public void ReloadSlotSetup()
diff --git a/GenesisCordonelInterface/GenesisCordonelInterface.csproj b/GenesisCordonelInterface/GenesisCordonelInterface.csproj
index f619b0610..b9ba6997d 100644
--- a/GenesisCordonelInterface/GenesisCordonelInterface.csproj
+++ b/GenesisCordonelInterface/GenesisCordonelInterface.csproj
@@ -58,6 +58,7 @@
+
diff --git a/GenesisCordonelInterface/UI/Debug/MeterBatchConfigPanel.cs b/GenesisCordonelInterface/UI/Debug/MeterBatchConfigPanel.cs
index a59fd9c4f..a877d4f41 100644
--- a/GenesisCordonelInterface/UI/Debug/MeterBatchConfigPanel.cs
+++ b/GenesisCordonelInterface/UI/Debug/MeterBatchConfigPanel.cs
@@ -266,13 +266,13 @@ namespace GenesisCordonelInterface.UI.Debug
if (columnName == "RequestPort")
{
- api.SetSlotRequestPort(slot, port);
+ //api.SetSlotRequestPort(slot, port);
return;
}
if (columnName == "StreamingPort")
{
- api.SetSlotStreamingPort(slot, port);
+ //api.SetSlotStreamingPort(slot, port);
return;
}
}
diff --git a/GenesisCordonelInterface/UI/LaatzenAPI_GenesisToolBox/FrmRegisterStore.cs b/GenesisCordonelInterface/UI/LaatzenAPI_GenesisToolBox/FrmRegisterStore.cs
index 7b7de7756..c66250f39 100644
--- a/GenesisCordonelInterface/UI/LaatzenAPI_GenesisToolBox/FrmRegisterStore.cs
+++ b/GenesisCordonelInterface/UI/LaatzenAPI_GenesisToolBox/FrmRegisterStore.cs
@@ -492,7 +492,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_GenesisToolBox
DisableAllButtons();
_dataTable.Rows.Clear();
- var result = await interfaceToLaatzen.ConnectOneMeterAsync(slotNo);
+ var result = await interfaceToLaatzen.ConnectOneSlotAsync(slotNo);
if (result.Success)
{
@@ -571,7 +571,7 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_GenesisToolBox
lblState.Text = $@"Not Connected to PcbId:{result.PcbId}";
registerGridView.Visible = false;
- MessageBox.Show(result.ErrorMessage ?? "Connect failed.", @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show(result.Message ?? "Connect failed.", @"FAILED", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
@@ -1172,11 +1172,16 @@ namespace GenesisCordonelInterface.UI.LaatzenAPI_GenesisToolBox
SetBusy(true, "GetPcbId");
- // as new meter object will be generated the data grid shows outdated data
_dataTable.Rows.Clear();
DisableAllButtons();
- _currentPcbId = await Task.Run(() => interfaceToLaatzen.GetPcbId(slotNr));
+ GciPublicModels.GciGetPcbIdResult result =
+ await interfaceToLaatzen.GetPcbIdAsync(slotNr);
+
+ if (!result.Success)
+ throw new Exception(result.Message);
+
+ _currentPcbId = result.PcbId;
btnConnect.Enabled = true;
diff --git a/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.Designer.cs b/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.Designer.cs
index c5a97d57f..5a760221d 100644
--- a/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.Designer.cs
+++ b/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.Designer.cs
@@ -82,7 +82,7 @@
this.lblConfigSource.Name = "lblConfigSource";
this.lblConfigSource.Size = new System.Drawing.Size(75, 13);
this.lblConfigSource.TabIndex = 2;
- this.lblConfigSource.Text = "ConfigSource:";
+ this.lblConfigSource.Text = "GciConfigSource:";
//
// cmbConfigSource
//
diff --git a/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.cs b/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.cs
index 619dcf41e..d56f7d441 100644
--- a/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.cs
+++ b/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/FrmGCIAPI.cs
@@ -160,9 +160,15 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
}
///
- /// Creates PortConfig from UI values.
+ /// Creates a public GCI port configuration object from UI input values.
///
- private PortConfig? CreatePortConfig(string portName, string baudRateText)
+ /// Name of the port (e.g. COM3).
+ /// Baud rate entered in the UI.
+ ///
+ /// Instance of or null if port name is empty.
+ ///
+ /// Thrown when baud rate is invalid.
+ private GciPublicModels.GciPortConfig CreateGciPortConfig(string portName, string baudRateText)
{
if (string.IsNullOrWhiteSpace(portName))
return null;
@@ -170,35 +176,37 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
if (!int.TryParse(baudRateText, out int baudRate))
throw new Exception($"Invalid baud rate for port {portName}.");
- var cfg = new PortConfig
+ return new GciPublicModels.GciPortConfig
{
PortName = portName,
- Type = "Serial"
+ Type = "Serial",
};
-
- var sp = cfg.GetSerialPort();
- if (sp == null)
- throw new Exception($"Serial port object was not created for {portName}.");
-
- sp.BaudRate = baudRate;
-
- return cfg;
}
- private ConfigSource GetConfigSource()
+ ///
+ /// Gets selected configuration source from UI and maps it to public GCI model.
+ ///
+ /// Selected .
+ /// Thrown when no value is selected.
+ private GciPublicModels.GciConfigSource GetConfigSource()
{
if (cmbConfigSource.SelectedItem == null)
- throw new Exception("ConfigSource is not selected.");
+ throw new Exception("Config source is not selected.");
- return (ConfigSource)cmbConfigSource.SelectedItem;
+ return (GciPublicModels.GciConfigSource)cmbConfigSource.SelectedItem;
}
- private PasswordSource GetPasswordSource()
+ ///
+ /// Gets selected password source from UI and maps it to public GCI model.
+ ///
+ /// Selected .
+ /// Thrown when no value is selected.
+ private GciPublicModels.GciPasswordSource GetPasswordSource()
{
if (cmbPasswordSource.SelectedItem == null)
- throw new Exception("PasswordSource is not selected.");
+ throw new Exception("Password source is not selected.");
- return (PasswordSource)cmbPasswordSource.SelectedItem;
+ return (GciPublicModels.GciPasswordSource)cmbPasswordSource.SelectedItem;
}
#endregion
@@ -221,15 +229,19 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
await ExecuteApiActionAsync(async () =>
{
- var result = await _api.InitOneMeterFromExternAsync(
- slot,
- GetConfigSource(),
- GetPasswordSource(),
- CreatePortConfig(txtRequestPort.Text, txtRequestBaudRate.Text),
- CreatePortConfig(txtStreamingPort.Text, txtStreamingBaudRate.Text));
+ var request = new GciPublicModels.GciInitSlotRequest
+ {
+ SlotId = slot,
+ ConfigSource = GetConfigSource(),
+ PasswordSource = GetPasswordSource(),
+ RequestPort = CreateGciPortConfig(txtRequestPort.Text, txtRequestBaudRate.Text),
+ StreamingPort = CreateGciPortConfig(txtStreamingPort.Text, txtStreamingBaudRate.Text)
+ };
+
+ var result = await _api.InitSlotAsync(request);
if (!result.Success)
- throw new Exception(result.ErrorMessage);
+ throw new Exception(result.Message);
MessageBox.Show("Meter initialized.");
});
@@ -251,10 +263,10 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
await ExecuteApiActionAsync(async () =>
{
- var result = await _api.ConnectOneMeterAsync(slot);
+ var result = await _api.ConnectOneSlotAsync(slot);
if (!result.Success)
- throw new Exception(result.ErrorMessage);
+ throw new Exception(result.Message);
MessageBox.Show($"Connected.\r\nPCB ID: {result.PcbId}");
});
@@ -280,7 +292,6 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
MessageBox.Show("Disconnected.");
});
}
-
///
/// Reads PCB ID asynchronously.
///
@@ -297,8 +308,13 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
await ExecuteApiActionAsync(async () =>
{
- string pcbId = await _api.GetPcbIdAsync(slot);
- MessageBox.Show($"PCB ID: {pcbId}");
+ GciPublicModels.GciGetPcbIdResult result =
+ await _api.GetPcbIdAsync(slot);
+
+ if (!result.Success)
+ throw new Exception(result.Message);
+
+ MessageBox.Show($"PCB ID: {result.PcbId}");
});
}
@@ -345,10 +361,10 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
foreach (int slot in slots)
{
- var result = await _api.ConnectOneMeterAsync(slot);
+ var result = await _api.ConnectOneSlotAsync(slot);
if (!result.Success)
- throw new Exception($"Slot {slot}: {result.ErrorMessage}");
+ throw new Exception($"Slot {slot}: {result.Message}");
}
MessageBox.Show("Selected meters connected.");
diff --git a/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/MetersActionView.cs b/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/MetersActionView.cs
index 563925bcf..a3ff9046b 100644
--- a/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/MetersActionView.cs
+++ b/GenesisCordonelInterface/UI/StaraTuraAPI_GenesisCordonelInterface/MetersActionView.cs
@@ -66,10 +66,10 @@ namespace GenesisCordonelInterface.UI.StaraTuraAPI_GenesisCordonelInterface
foreach (int slot in _api.GetSelectedSlots())
{
- var result = await _api.ConnectOneMeterAsync(slot);
+ var result = await _api.ConnectOneSlotAsync(slot);
if (!result.Success)
- throw new Exception($"Slot {slot}: {result.ErrorMessage}");
+ throw new Exception($"Slot {slot}: {result.Message}");
}
MessageBox.Show("Selected meters connected.");
diff --git a/TBF/Build/CopyGci.targets.xml b/TBF/Build/CopyGci.targets.xml
new file mode 100644
index 000000000..9eb4197ee
--- /dev/null
+++ b/TBF/Build/CopyGci.targets.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ $(ProjectDir)..\GenesisCordonelInterface\RuntimePackage\Package\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TBF/Rig/BridgeComponents/GciBridge/GciBridge.cs b/TBF/Rig/BridgeComponents/GciBridge/GciBridge.cs
index fc9111e22..7aed00bb4 100644
--- a/TBF/Rig/BridgeComponents/GciBridge/GciBridge.cs
+++ b/TBF/Rig/BridgeComponents/GciBridge/GciBridge.cs
@@ -1,13 +1,16 @@
-using log4net;
+using GenesisCordonelInterface.API;
+using log4net;
///
/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows.Forms;
using TBF.Rig.Generic;
-using ExternalInterfaceGUIType = GenesisCordonelInterface.UI.MainView;
-using ExternalInterfaceType = GenesisCordonelInterface.API.InterfaceOutsideToGCI;
+using GciGUIType = GenesisCordonelInterface.UI.MainView;
+using GciType = GenesisCordonelInterface.API.InterfaceOutsideToGCI;
using UdsReaderType = TBF.Rig.Input.DataStorage.UniDataStorageReader.Reader;
using UdsWriterType = TBF.Rig.Output.DataStorage.UniDataStorageWriter.Writer;
@@ -20,42 +23,37 @@ namespace TBF.Rig.BridgeComponents.GciBridge
public class GciBridge : ComponentBase
{
private static readonly ILog log = LogManager.GetLogger(typeof(GciBridge));
- public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
+
+ public override string ToString()
+ {
+ return string.Format("{0}({1})", ClassName, Cfg.ToString(-1));
+ }
readonly GciBridgeCfg gciBridgeCfg;
- ///
- /// Linked UniDataStorage reader component.
- ///
readonly UdsReaderType reader;
-
- ///
- /// Linked UniDataStorage writer component.
- ///
readonly UdsWriterType writer;
- ///
- /// Placeholder for GCI GUI entry point.
- /// Replace object with real GCI MainForm type later.
- ///
- ExternalInterfaceGUIType gciGUI;
-
- ///
- ///
- ///
+ GciGUIType gciGUI;
Form gciGuiHostForm;
- ///
- /// Placeholder for GCI external/public interface.
- /// Replace object with real GCI interface type later.
- ///
- ExternalInterfaceType gciExternalInterface;
+ GciType gciExternalInterface;
public bool HasReader { get { return reader != null; } }
public bool HasWriter { get { return writer != null; } }
public bool IsGuiInitialized { get { return gciGUI != null; } }
public bool IsExternalInitialized { get { return gciExternalInterface != null; } }
+ public UdsReaderType GetReader()
+ {
+ return reader;
+ }
+
+ public UdsWriterType GetWriter()
+ {
+ return writer;
+ }
+
public GciBridge() { }
public GciBridge(IComponentCfg cfg, IList components)
@@ -97,10 +95,6 @@ namespace TBF.Rig.BridgeComponents.GciBridge
log.FatalFormat("{0} initialized: {1}", Name, this);
}
- ///
- /// Initializes access to GCI GUI.
- /// Replace placeholder implementation with real MainForm creation.
- ///
void TryInitializeGui()
{
try
@@ -108,7 +102,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
if (gciGuiHostForm != null && !gciGuiHostForm.IsDisposed)
return;
- gciGUI = new ExternalInterfaceGUIType();
+ gciGUI = new GciGUIType();
gciGUI.Dock = DockStyle.Fill;
gciGuiHostForm = new Form();
@@ -127,15 +121,14 @@ namespace TBF.Rig.BridgeComponents.GciBridge
}
}
- ///
- /// Initializes access to GCI external/public interface.
- /// Replace placeholder implementation with real interface creation.
- ///
void TryInitializeExternalInterface()
{
try
{
- gciExternalInterface = new ExternalInterfaceType();
+ if (gciExternalInterface != null)
+ return;
+
+ gciExternalInterface = new GciType();
log.InfoFormat("{0}: GCI external interface initialized.", Name);
}
@@ -145,9 +138,6 @@ namespace TBF.Rig.BridgeComponents.GciBridge
}
}
- ///
- /// Shows GCI GUI if GUI access is enabled.
- ///
public void ShowGui()
{
if (!gciBridgeCfg.EnableGuiAccess) return;
@@ -165,9 +155,6 @@ namespace TBF.Rig.BridgeComponents.GciBridge
log.InfoFormat("{0}: ShowGui invoked.", Name);
}
- ///
- /// Hides GCI GUI if GUI access is enabled.
- ///
public void HideGui()
{
if (!gciBridgeCfg.EnableGuiAccess) return;
@@ -178,50 +165,120 @@ namespace TBF.Rig.BridgeComponents.GciBridge
log.InfoFormat("{0}: HideGui invoked.", Name);
}
- ///
- /// Connects the external GCI interface.
- ///
- public void ConnectExternal()
+ void EnsureExternalInterface()
{
- if (!gciBridgeCfg.EnableExternalAccess) return;
+ if (!gciBridgeCfg.EnableExternalAccess)
+ throw new Exception("GCI external access is disabled.");
if (!IsExternalInitialized)
- {
TryInitializeExternalInterface();
- }
- /// TODO:
- /// Replace with real external interface connect call.
- log.InfoFormat("{0}: ConnectExternal invoked.", Name);
+ if (gciExternalInterface == null)
+ throw new Exception("GCI external interface is not initialized.");
}
- ///
- /// Disconnects the external GCI interface.
- ///
- public void DisconnectExternal()
+ void EnsureReader()
{
- if (!gciBridgeCfg.EnableExternalAccess) return;
- if (!IsExternalInitialized) return;
-
- /// TODO:
- /// Replace with real external interface disconnect call.
- log.InfoFormat("{0}: DisconnectExternal invoked.", Name);
+ if (reader == null)
+ throw new Exception("UniDataStorageReader is not linked to GciBridge.");
}
- ///
- /// Returns linked reader component.
- ///
- public UdsReaderType GetReader()
+ // API:
+ #region ======================================= GCI Public Interface =======================================
+
+ public async Task InitSlotAsync(GciPublicModels.GciInitSlotRequest request)
{
- return reader;
+ EnsureExternalInterface();
+
+ if (request == null)
+ throw new ArgumentNullException("request");
+
+ if (request.SlotId <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ GciPublicModels.GciInitSlotResult result =
+ await gciExternalInterface.InitSlotAsync(request);
+
+ log.InfoFormat("{0}: InitSlotAsync invoked. {1}, Result={2}", Name, request, result);
+
+ return result;
}
- ///
- /// Returns linked writer component.
- ///
- public UdsWriterType GetWriter()
+ public async Task GetSlotAsync(int slotId)
{
- return writer;
+ EnsureExternalInterface();
+
+ if (slotId <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ GciPublicModels.GciSlotInfo result =
+ await gciExternalInterface.GetSlotAsync(slotId);
+
+ log.InfoFormat("{0}: GetSlotAsync({1}) invoked. Result={2}", Name, slotId, result);
+
+ return result;
}
+
+ public async Task CleanSlotsAsync()
+ {
+ EnsureExternalInterface();
+
+ GciPublicModels.GciCleanSlotsResult result =
+ await gciExternalInterface.CleanSlotsAsync();
+
+ log.InfoFormat("{0}: CleanSlotsAsync invoked.", Name);
+
+ return result;
+ }
+
+ public async Task GetPcbIdAsync(
+ int slotId,
+ CancellationToken token = default)
+ {
+ EnsureExternalInterface();
+
+ if (slotId <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ var result = await gciExternalInterface.GetPcbIdAsync(slotId, token);
+
+ log.InfoFormat("{0}: GetPcbIdAsync({1}) invoked. Result={2}", Name, slotId, result);
+
+ return result;
+ }
+
+ public async Task ConnectAsync(
+ int slotId,
+ CancellationToken token = default)
+ {
+ EnsureExternalInterface();
+
+ if (slotId <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ var result = await gciExternalInterface.ConnectOneSlotAsync(slotId, token);
+
+ log.InfoFormat("{0}: ConnectAsync({1}) invoked. Result={2}", Name, slotId, result);
+
+ return result;
+ }
+
+ public async Task DisconnectAsync(
+ int slotId,
+ CancellationToken token = default)
+ {
+ EnsureExternalInterface();
+
+ if (slotId <= 0)
+ throw new ArgumentException("Invalid slot id.");
+
+ var result = await gciExternalInterface.DisconnectAsync(slotId, token);
+
+ log.InfoFormat("{0}: DisconnectAsync({1}) invoked. Result={2}", Name, slotId, result);
+
+ return result;
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/TBF/Rig/BridgeComponents/GciBridge/GciBridgeCfgCtrl.cs b/TBF/Rig/BridgeComponents/GciBridge/GciBridgeCfgCtrl.cs
index 346669b87..ab7787721 100644
--- a/TBF/Rig/BridgeComponents/GciBridge/GciBridgeCfgCtrl.cs
+++ b/TBF/Rig/BridgeComponents/GciBridge/GciBridgeCfgCtrl.cs
@@ -182,7 +182,7 @@ namespace TBF.Rig.BridgeComponents.GciBridge
return;
}
- bridge.ConnectExternal();
+ //bridge.ConnectExternal();
}
catch (Exception ex)
{
diff --git a/TBF/Rig/BridgeComponents/GciBridge/GciBridgeOp.cs b/TBF/Rig/BridgeComponents/GciBridge/GciBridgeOp.cs
new file mode 100644
index 000000000..a318dc1b6
--- /dev/null
+++ b/TBF/Rig/BridgeComponents/GciBridge/GciBridgeOp.cs
@@ -0,0 +1,14 @@
+using log4net;
+///
+/// Copyright (c) 2015-2021 Sensus Slovensko a.s.
+///
+using System;
+using TBF.Rig.Sequences;
+
+namespace TBF.Rig.BridgeComponents.GciBridge
+{
+ public class GciBridgeOp
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj
index d3385c8e6..3dc69a350 100644
--- a/TBF/TBF.csproj
+++ b/TBF/TBF.csproj
@@ -173,6 +173,10 @@
..\packages\Common\Xylem.Common.CommonCore.dll
+
+ False
+ ..\packages\Common\Xylem.Common.Hardware.Interfaces.Ports.PortCore.dll
+
..\packages\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.dll
@@ -211,6 +215,7 @@
GciBridgeCfgCtrl.cs
+
@@ -4168,6 +4173,7 @@
TestProgressCtrl.cs
+
Always
@@ -4385,6 +4391,7 @@
Results
+