using ExperionCrawler.Core.Domain.Entities; using System.Collections.Generic; namespace ExperionCrawler.Core.Application.Interfaces; // ── Certificate ────────────────────────────────────────────────────────────── public interface IExperionCertificateService { /// 인증서가 없으면 생성, 있으면 기존 반환 Task EnsureCertificateAsync( string applicationUri, string clientHostName, IEnumerable subjectAltNames, string pfxPassword = ""); bool CertificateExists(string clientHostName); ExperionCertInfo GetCertificateInfo(string clientHostName); } // ── OPC UA Client ──────────────────────────────────────────────────────────── public interface IExperionOpcClient { Task TestConnectionAsync(ExperionServerConfig cfg); Task ReadTagAsync(ExperionServerConfig cfg, string nodeId); Task> ReadTagsAsync(ExperionServerConfig cfg, IEnumerable nodeIds); Task BrowseNodesAsync(ExperionServerConfig cfg, string? startNodeId = null); Task BrowseAllNodesAsync(ExperionServerConfig cfg, int maxDepth = 10, CancellationToken ct = default); } // ── CSV ────────────────────────────────────────────────────────────────────── public interface IExperionCsvService { Task ExportAsync(IEnumerable records, string fileName); Task> ImportAsync(string filePath); IEnumerable GetAvailableFiles(); Task ExportNodeMapAsync(IEnumerable entries, string fileName); } // ── Database ───────────────────────────────────────────────────────────────── public interface IExperionDbService { Task InitializeAsync(); Task SaveRecordsAsync(IEnumerable records); Task ClearRecordsAsync(); Task BuildMasterFromRawAsync(bool truncate = false); Task> GetRecordsAsync(DateTime? from = null, DateTime? to = null, int limit = 1000); Task GetTotalCountAsync(); Task> GetNameListAsync(); Task GetMasterStatsAsync(); Task QueryMasterAsync( int? minLevel, int? maxLevel, string? nodeClass, IEnumerable? names, string? nodeId, string? dataType, int limit, int offset); // ── RealtimeTable ───────────────────────────────────────────────────────── Task BuildRealtimeTableAsync(IEnumerable names, IEnumerable dataTypes); Task> GetRealtimePointsAsync(); Task AddRealtimePointAsync(string nodeId); Task DeleteRealtimePointAsync(int id); Task UpdateLiveValueAsync(string nodeId, string? value, DateTime timestamp); Task BatchUpdateLiveValuesAsync(IEnumerable updates); // ── HistoryTable ────────────────────────────────────────────────────────── Task SnapshotToHistoryAsync(); Task> GetTagNamesAsync(); Task QueryHistoryAsync( IEnumerable tagNames, DateTime? from, DateTime? to, int limit); // ── OPC UA Server 지원 ──────────────────────────────────────────────────── /// realtime_table × node_map_master 조인 → nodeId → dataType 사전 반환 Task> GetRealtimeNodeDataTypesAsync(); } // ── Realtime Service ───────────────────────────────────────────────────────── public interface IExperionRealtimeService { Task StartAsync(ExperionServerConfig cfg); Task StopAsync(); RealtimeServiceStatus GetStatus(); /// /// 구독 중이면 MonitoredItem 핫 추가 후 OPC UA 서버 응답 검증. /// 구독 중이지 않으면 (true, "구독 중 아님") 반환. /// Task<(bool Success, string Message)> AddMonitoredItemAsync(string nodeId); } public record RealtimeServiceStatus(bool Running, int SubscribedCount, string Message); // ── OPC UA Server ───────────────────────────────────────────────────────────── public interface IExperionOpcServerService { Task StartServerAsync(); Task StopServerAsync(); OpcServerStatus GetStatus(); void UpdateNodeValue(string tagname, string? value, DateTime timestamp); void RebuildAddressSpace(IEnumerable points); } public record OpcServerStatus( bool Running, int ConnectedClientCount, int NodeCount, string EndpointUrl, DateTime? StartedAt); // ── Status Code ────────────────────────────────────────────────────────────── public interface IExperionStatusCodeService { ExperionStatusCodeInfo? GetByHex(string hexCode); ExperionStatusCodeInfo? GetByUint(uint statusCode); int LoadedCount { get; } } // ── Result records ─────────────────────────────────────────────────────────── public record ExperionCertResult (bool Success, string Message, string? ThumbPrint = null); public record ExperionCertInfo (bool Exists, string? SubjectName, DateTime? NotAfter, string? ThumbPrint, string FilePath); public record ExperionConnectResult(bool Success, string Message, string? SessionId = null, string? PolicyUri = null); public record ExperionReadResult (bool Success, string NodeId, object? Value, string StatusCode, string? ErrorMessage = null, DateTime? Timestamp = null); public record ExperionBrowseResult(bool Success, IEnumerable Nodes, string? ErrorMessage = null); public record ExperionNodeInfo (string NodeId, string DisplayName, string NodeClass, bool HasChildren); public record ExperionNodeMapEntry(int Level, string NodeClass, string DisplayName, string NodeId, string DataType); public record ExperionNodeMapResult(bool Success, IEnumerable Nodes, int TotalCount, string? ErrorMessage = null); public record NodeMapStats(int Total, int ObjectCount, int VariableCount, int MaxLevel, IEnumerable DataTypes); public record NodeMapQueryResult(int Total, IEnumerable Items); public record HistoryQueryResult(IEnumerable TagNames, IEnumerable Rows); public record HistoryRow(DateTime RecordedAt, IReadOnlyDictionary Values); public record LiveValueUpdate(string NodeId, string? Value, DateTime Timestamp);