using System; using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using System.ComponentModel; using PepperDash.Core; namespace PepperDash.Essentials.Core { /// /// Used for monitoring comms that are IBasicCommunication. Will send a poll string and provide an event when /// statuses change. /// public class GenericCommunicationMonitor : StatusMonitorBase { public IBasicCommunication Client { get; private set; } long PollTime; CTimer PollTimer; string PollString; Action PollAction; /// /// /// /// /// in MS, >= 5000 /// in MS, >= 5000 /// in MS, >= 5000 /// String to send to comm public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, long pollTime, long warningTime, long errorTime, string pollString) : base(parent, warningTime, errorTime) { if (pollTime > warningTime || pollTime > errorTime) throw new ArgumentException("pollTime must be less than warning or errorTime"); //if (pollTime < 5000) // throw new ArgumentException("pollTime cannot be less than 5000 ms"); Client = client; PollTime = pollTime; PollString = pollString; } /// /// Poll is a provided action instead of string /// /// /// /// /// /// /// public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, long pollTime, long warningTime, long errorTime, Action pollAction) : base(parent, warningTime, errorTime) { if (pollTime > warningTime || pollTime > errorTime) throw new ArgumentException("pollTime must be less than warning or errorTime"); //if (pollTime < 5000) // throw new ArgumentException("pollTime cannot be less than 5000 ms"); Client = client; PollTime = pollTime; PollAction = pollAction; } /// /// Build the monitor from a config object /// public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, CommunicationMonitorConfig props) : this(parent, client, props.PollInterval, props.TimeToWarning, props.TimeToError, props.PollString) { } public override void Start() { Client.BytesReceived += Client_BytesReceived; Poll(); PollTimer = new CTimer(o => Poll(), null, PollTime, PollTime); } public override void Stop() { Client.BytesReceived -= this.Client_BytesReceived; PollTimer.Stop(); PollTimer = null; StopErrorTimers(); } /// /// Upon any receipt of data, set everything to ok! /// /// /// void Client_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e) { Status = MonitorStatus.IsOk; ResetErrorTimers(); } void Poll() { StartErrorTimers(); if (Client.IsConnected) { //Debug.Console(2, this, "Polling"); if(PollAction != null) PollAction.Invoke(); else Client.SendText(PollString); } else { Debug.Console(2, this, "Comm not connected"); } } /// /// When the client connects, and we're waiting for it, respond and disconect from event /// void OneTimeConnectHandler(object o, EventArgs a) { if (Client.IsConnected) { //Client.IsConnected -= OneTimeConnectHandler; Debug.Console(2, this, "Comm connected"); Poll(); } } } public class CommunicationMonitorConfig { public int PollInterval { get; set; } public int TimeToWarning { get; set; } public int TimeToError { get; set; } public string PollString { get; set; } public CommunicationMonitorConfig() { PollInterval = 30000; TimeToWarning = 120000; TimeToError = 300000; PollString = ""; } } }