using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using IOB_UT_NEXT; using MTConnect; using MTConnect.Assets; using MTConnect.Clients; using MTConnect.Devices; using MTConnect.Observations; using MTConnect.Streams; using NLog; using Spectre.Console; namespace IOB_WIN_MTC_CLI { public class IobComm { #region Public Constructors /// /// Init classe /// public IobComm() { } /// /// Init Classe /// /// public IobComm(string opcAddr) { baseUrl = opcAddr; } /// /// Init Classe /// /// /// /// public IobComm(string opcAddr, string titolo, string sottotitolo) { baseUrl = opcAddr; title = titolo; subtitle = sottotitolo; } #endregion Public Constructors #region Public Methods public void DoConfig() { msgData = new List(); dispData = new Dictionary(); // primo display msgData.Add("Starting CLI setup..."); DoDisplayAsync(); } /// /// Esecuzione log secondo conf /// /// public void doLog(string msg = "") { try { if (fileLog) { lg.Info($"{msg}"); } if (consoleLog) { Console.WriteLine(msg); } } catch (Exception exc) { Console.WriteLine($"Eccezione in log:{Environment.NewLine}{exc}"); } } /// /// Esecuzione probe call indipendente /// public void ForceProbe() { // init sw.Restart(); msgData = new List(); dispData = new Dictionary(); // primo display msgData.Add("Calling PROBE..."); DoDisplayAsync(); // inizio processing var prbClient = new MTConnectHttpProbeClient(baseUrl); prbClient.Timeout = 20000; var prbDoc = prbClient.Get(); // preparo output if (prbDoc == null) { msgData.Add($"Preliminari Probe | {sw.ElapsedMilliseconds}ms | No answer, continue..."); } else { displayProbeDoc("Preliminari Probe RECEIVED", prbDoc); } } public void MainLoop() { sw.Restart(); msgData = new List(); dispData = new Dictionary(); ConsoleKeyInfo answ = Console.ReadKey(); while (answ.Key != ConsoleKey.Escape) { msgData.Add($"CONSOLE LOG: {consoleLog}"); msgData.Add($"FILE LOG: {fileLog}"); DoDisplayAsync(); answ = Console.ReadKey(); // controllo key... if (answ.Key == ConsoleKey.C) { consoleLog = !consoleLog; } else if (answ.Key == ConsoleKey.F) { fileLog = !fileLog; } else if (answ.Key == ConsoleKey.P) { msgData = new List(); dispData = new Dictionary(); ForceProbe(); } else if (answ.Key == ConsoleKey.R) { msgData = new List(); dispData = new Dictionary(); client.Stop(); Task.Delay(500); dtStart = DateTime.Now; StartClient(); msgData.Add($"Client restarted!"); } else if (answ.Key == ConsoleKey.S) { msgData = new List(); dispData = new Dictionary(); client.Stop(); msgData.Add($"Client stopped!"); } } doLog("...closing Now!"); } private DateTime displayVeto = DateTime.Now; /// /// Avvio del thread principale /// public void StartClient() { // init sw.Restart(); msgData = new List(); dispData = new Dictionary(); // primo display msgData.Add("Client App setup..."); DoDisplayAsync(); // setup client client = new MTConnectHttpClient(baseUrl); // sample interval client.Interval = 500; // timeout x richieste client.Timeout = 4000; // timeout riconnessione client.ReconnectionInterval = 5000; // aggancio eventi if (enabAsset) { client.AssetsReceived += Client_AssetsReceived; } client.ClientStarted += Client_ClientStarted; client.ClientStopped += Client_ClientStopped; client.ConnectionError += Client_ConnectionError; client.CurrentReceived += Client_CurrentReceived; client.ProbeReceived += Client_ProbeReceived; if (enabSample) { client.SampleReceived += Client_SampleReceived; } if (enabObserv) { // conviene usare sample x avere la stessa cosa ma con altre info... client.ObservationReceived += Client_ObservationReceived; } msgData.Add($"Setup completed! | {sw.ElapsedMilliseconds}ms"); DoDisplayAsync(); // vero avvio client.Start(); msgData.Add($"Client Started | {sw.ElapsedMilliseconds} ms"); DoDisplayAsync(); } #endregion Public Methods #region Protected Fields protected bool enabAsset = true; protected bool enabObserv = false; protected bool enabSample = true; #endregion Protected Fields #region Protected Properties protected bool consoleLog { get; set; } = false; protected bool fileLog { get; set; } = true; #endregion Protected Properties #region Protected Methods /// /// Main display function /// /// /// protected async Task DoDisplayAsync() { // attesa che non sia in corso update while (inRefresh || displayVeto > DateTime.Now) { //Thread.Sleep(rand.Next(50, 150)); await Task.Delay(rand.Next(50, 150)); } try { inRefresh = true; displayVeto = DateTime.Now.AddMilliseconds(1000); AnsiConsole.Clear(); // titolo AnsiConsole.Write( new FigletText(title) .LeftJustified() .Color(Color.Cyan1)); var rule = new Rule(subtitle); rule.RightJustified(); AnsiConsole.Write(rule); // se presenti messaggi if (msgData.Count > 0) { foreach (var msg in msgData) { if (fileLog) { lg.Info(msg); } AnsiConsole.MarkupLine(msg); } rule = new Rule(); rule.RuleStyle("grey dim"); AnsiConsole.Write(rule); } // se presenti graph... if (dispData.Count > 0) { foreach (var graph in dispData) { } rule = new Rule(); rule.RuleStyle("grey dim"); AnsiConsole.Write(rule); } // comandi if (commandList.Count > 0) { // mostro cmd list... foreach (var cmd in commandList) { AnsiConsole.MarkupLine(cmd); } rule = new Rule(); rule.RuleStyle("grey dim"); AnsiConsole.Write(rule); } string uptime = $"Uptime: {DateTime.Now.Subtract(dtStart).TotalMinutes:N1} min"; AnsiConsole.WriteLine(uptime); } catch (Exception exc) { Console.WriteLine($"Eccezione in DoDisplay:{Environment.NewLine}{exc}"); } inRefresh = false; } #endregion Protected Methods #region Private Fields private DateTime dtStart = DateTime.Now; private static Logger lg = LogManager.GetCurrentClassLogger(); private string baseUrl = "192.168.1.27:5000"; private List commandList = new List() { "R = Restart Service | S = Stop Service | P = force probe", "C = toggle console log | F = toggle file log | Press ESC to exit" }; /// /// Dizionario variabili conteggio collezionate /// private Dictionary DataCounters = new Dictionary(); private Dictionary dispData = new Dictionary(); private bool inRefresh = false; private List msgData = new List(); private Random rand = new Random(); private string sep = "------------------------"; private string subtitle = "EgalWare 2024+"; private Stopwatch sw = new Stopwatch(); private string title = "MtConnect Client"; #endregion Private Fields #region Private Properties private MTConnectHttpClient client { get; set; } = new MTConnectHttpClient(""); #endregion Private Properties #region Private Methods private void Client_AssetsReceived(object sender, MTConnect.Assets.IAssetsResponseDocument document) { displayAsset(document); } private void Client_ClientStarted(object sender, EventArgs e) { msgData = new List(); msgData.Add($"Client Started!"); msgData.Add(sep); DoDisplayAsync(); } private void Client_ClientStopped(object sender, EventArgs e) { msgData = new List(); msgData.Add($"Client Stopped!"); msgData.Add(sep); DoDisplayAsync(); } private void Client_ConnectionError(object sender, Exception exc) { msgData = new List(); msgData.Add($"Connection ERROR returned!"); msgData.Add($"{exc}"); msgData.Add(sep); DoDisplayAsync(); } private void Client_CurrentReceived(object sender, MTConnect.Streams.IStreamsResponseDocument document) { displayCurrent(document); } private void Client_ObservationReceived(object sender, IObservation observ) { msgData = new List(); msgData.Add("OBSERVATION"); msgData.Add(sep); processObservation(observ); } private void Client_ProbeReceived(object sender, MTConnect.Devices.IDevicesResponseDocument document) { displayProbeDoc("Client Probe RECEIVED", document); } private void Client_SampleReceived(object sender, MTConnect.Streams.IStreamsResponseDocument document) { displaySample(document); } private void displayAsset(IAssetsResponseDocument document) { msgData = new List(); int numAssets = 0; msgData.Add("ASSET received"); doLog(sep); foreach (var asset in document.Assets) { // Print AssetId to the Console doLog($"Asset: {asset.AssetId}"); numAssets++; } msgData.Add($" Found [green]{numAssets} Assets[/]"); DoDisplayAsync(); } private void displayCurrent(IStreamsResponseDocument document) { msgData = new List(); int numStream = 0; int numCompo = 0; msgData.Add($"CURRENT received!"); foreach (var deviceStream in document.Streams) { // DeviceStream msgData.Add($" Stream: {deviceStream.Name}"); numStream++; // Component Streams foreach (var componentStream in deviceStream.ComponentStreams) { processData(componentStream); numCompo++; } } msgData.Add($" Found [green]{numStream} Streams[/]"); msgData.Add($" Found [yellow]{numCompo} Components[/]"); DoDisplayAsync(); } private void displayProbeDoc(string message, IDevicesResponseDocument prbDoc) { msgData = new List(); msgData.Add(message); msgData.Add(sep); foreach (var device in prbDoc.Devices) { // Device msgData.Add($"DEV: {device.Id}"); int numDataItem = 0; int numComponents = 0; int numCompositions = 0; // All DataItems (traverse the entire Device model) if (device.DataItems.Count() > 0) { foreach (var dataItem in device.GetDataItems()) { lg.Trace($" DItm | {dataItem.IdPath}"); numDataItem++; } } msgData.Add($" Found [green]{numDataItem} DataItems[/]"); // All Components (traverse the entire Device model) if (device.Components.Count() > 0) { foreach (var component in device.GetComponents()) { lg.Trace($" Comp | {component.IdPath}"); numComponents++; } } msgData.Add($" Found [blue]{numComponents} Components[/]"); // All Compositions (traverse the entire Device model) if (device.Compositions.Count() > 0) { foreach (var composition in device.GetCompositions()) { lg.Trace($" Cpst | {composition.IdPath}"); numCompositions++; } } msgData.Add($" Found [yellow]{numCompositions} Compositions[/]"); } msgData.Add(sep); DoDisplayAsync(); } private void displaySample(IStreamsResponseDocument document) { msgData = new List(); int numStream = 0; int numCompo = 0; msgData.Add($"SAMPLE"); foreach (var deviceStream in document.Streams) { // DeviceStream msgData.Add($" Stream: {deviceStream.Name}"); numStream++; // Component Streams foreach (var componentStream in deviceStream.ComponentStreams) { processData(componentStream); numCompo++; } } msgData.Add($" Found [green]{numStream} Streams[/]"); msgData.Add($" Found [yellow]{numCompo} Components[/]"); DoDisplayAsync(); } private void processData(IComponentStream dataStream) { int numCondition = 0; int numEvent = 0; int numSample = 0; // DataItems (Samples, Events, and Conditions) foreach (var observation in dataStream.Observations) { processObservation(observation); switch (observation.Category) { case DataItemCategory.CONDITION: numCondition++; break; case DataItemCategory.EVENT: numEvent++; break; case DataItemCategory.SAMPLE: numSample++; break; default: break; } } msgData.Add($" Component {dataStream.Name} | {numCondition} Conditions | {numEvent} Events | {numSample} Samples"); } private void processObservation(IObservation observation) { string sMsg = $" - {observation.DataItemId} | {observation.Category}"; #if false switch (observation.Category) { case MTConnect.Devices.DataItemCategory.CONDITION: break; case MTConnect.Devices.DataItemCategory.EVENT: break; case MTConnect.Devices.DataItemCategory.SAMPLE: break; default: break; } #endif if (observation.Values != null && observation.Values.Count() > 0) { foreach (var item in observation.Values) { sMsg += $" | {item.Key}: {item.Value}"; } } doLog(sMsg); } #endregion Private Methods } }