using System.Globalization;
using ZB.MOM.WW.HistorianGateway.Contracts.Grpc;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Mapping;
///
/// Maps a gateway wire event () onto the driver-agnostic
/// consumed by the Server's HistoryReadEvents path.
///
internal static class EventMapper
{
/// OPC UA severity range (Part 9): 1 (lowest) … 1000 (highest).
private const ushort MinSeverity = 1;
private const ushort MaxSeverity = 1000;
/// Maps a single gateway event to a historical event.
/// The gateway wire event.
/// The driver-agnostic historical event.
public static HistoricalEvent ToHistoricalEvent(HistorianEvent historianEvent)
{
// Message: prefer the "Message" property, else fall back to the event Type (best-effort
// render); never null-crash on a missing property.
string? message;
if (historianEvent.Properties.TryGetValue("Message", out var m) && !string.IsNullOrEmpty(m))
message = m;
else
message = string.IsNullOrEmpty(historianEvent.Type) ? null : historianEvent.Type;
return new HistoricalEvent(
EventId: historianEvent.Id,
SourceName: string.IsNullOrEmpty(historianEvent.SourceName) ? null : historianEvent.SourceName,
EventTimeUtc: historianEvent.EventTime?.ToDateTime() ?? default, // Utc kind
ReceivedTimeUtc: historianEvent.ReceivedTime?.ToDateTime() ?? default, // Utc kind
Message: message,
Severity: ParseSeverity(historianEvent.Properties));
}
/// Maps a batch of gateway events to historical events, in order.
/// The gateway wire events.
/// The driver-agnostic historical events.
public static IReadOnlyList ToHistoricalEvents(IEnumerable events)
{
var result = new List();
foreach (var historianEvent in events)
result.Add(ToHistoricalEvent(historianEvent));
return result;
}
///
/// Parses an OPC UA severity from the "Severity" property (else "Priority"), clamped to
/// [1, 1000]. Missing or unparseable values default to the minimum severity (1).
///
private static ushort ParseSeverity(IDictionary properties)
{
string? raw = null;
if (properties.TryGetValue("Severity", out var severity))
raw = severity;
else if (properties.TryGetValue("Priority", out var priority))
raw = priority;
if (int.TryParse(raw, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value))
return (ushort)Math.Clamp(value, MinSeverity, MaxSeverity);
return MinSeverity;
}
}