using System; using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; using System.Text.RegularExpressions; using Crestron.SimplSharp.Net.Http; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials; namespace PepperDash.Essentials.Devices.Common { [Obsolete("This Device will be moved to a plugin in a future update")] public class DigitalLogger : EssentialsBridgeableDevice { public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } public StatusMonitorBase CommunicationMonitor { get; private set; } private HttpClient WebClient; public string userName; public string password; public string address; private bool OnlineStatus; public BoolFeedback OnlineFeedback; //private ushort CurrentPreset; public IntFeedback PresetFeedback; public Dictionary CircuitStatus; public uint CircuitCount; public Dictionary CircuitNameFeedbacks { get; private set; } public Dictionary CircuitIsCritical{ get; private set; } public Dictionary CircuitState { get; private set; } // new public Dictionary LevelControlPoints { get; private set; } // public List PresetList = new List(); public bool isSubscribed; private CTimer SubscriptionTimer; CrestronQueue CommandQueue; bool CommandQueueInProgress = false; //new public Dictionary DialerControlPoints { get; private set; } //new public Dictionary SwitcherControlPoints { get; private set; } /// /// Shows received lines as hex /// public bool ShowHexResponse { get; set; } public DigitalLogger(string key, string name, DigitalLoggerPropertiesConfig props) : base(key, name) { CircuitCount = 8; this.userName = props.userName; this.password = props.password; CommandQueue = new CrestronQueue(100); WebClient = new HttpClient(); WebClient.UserName = this.userName; WebClient.Password = this.password; this.address = props.address; WebClient.HostAddress = props.address; } public override bool CustomActivate() { /* Communication.Connect(); CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); }; CommunicationMonitor.Start(); */ OnlineFeedback = new BoolFeedback(() => { return OnlineStatus; }); CircuitStatus = new Dictionary(); CircuitNameFeedbacks = new Dictionary(); CircuitIsCritical = new Dictionary(); CircuitState = new Dictionary(); for (uint i = 0; i < CircuitCount; i++) { uint circuit = i; CircuitStatus[circuit] = new DigitalLoggerCircuit(); CircuitNameFeedbacks[circuit] = new StringFeedback(() => { if (CircuitStatus[circuit].name != null) { return CircuitStatus[circuit].name; } else { return ""; } }); CircuitIsCritical[circuit] = new BoolFeedback(() => { if (CircuitStatus.ContainsKey(circuit)) { return CircuitStatus[circuit].critical; } else { return false; } }); CircuitState[circuit] = new BoolFeedback(() => { if (CircuitStatus.ContainsKey(circuit)) { return CircuitStatus[circuit].state; } else { return false; } }); PollCircuit(circuit); } CrestronConsole.AddNewConsoleCommand(SendLine, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator); return true; } public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { var joinMap = new DigitalLoggerJoinMap(); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); joinMap.OffsetJoinNumbers(joinStart); Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); for (uint i = 1; i <= CircuitCount; i++) { var circuit = i; CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]); CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]); CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]); trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => CycleCircuit(circuit - 1)); trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => TurnOnCircuit(circuit - 1)); trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => TurnOffCircuit(circuit - 1)); } } void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) { Debug.Console(2, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString()); if (e.Client.IsConnected) { OnlineStatus = true; OnlineFeedback.FireUpdate(); } else { OnlineStatus = false; OnlineFeedback.FireUpdate(); if (SubscriptionTimer != null) { SubscriptionTimer.Stop(); SubscriptionTimer = null; } isSubscribed = false; CommandQueue.Clear(); CommandQueueInProgress = false; } } public void PollCircuit(uint circuit) { try { string PollCircuitResponse = SendRequest(String.Format("/restapi/relay/outlets/{0}/", circuit)); CircuitStatus[circuit] = JsonConvert.DeserializeObject(PollCircuitResponse); DigitalLoggerCircuit temp = CircuitStatus[circuit]; Debug.Console(2, this, "DigitalLogger Circuit {0} Name: {1} State:{2}'", circuit, CircuitStatus[circuit].name, CircuitStatus[circuit].state); CircuitNameFeedbacks[circuit].FireUpdate(); CircuitState[circuit].FireUpdate(); CircuitIsCritical[circuit].FireUpdate(); } catch (Exception e) { Debug.Console(0, this, "PollCircuit {0}", e); } } void Port_LineReceived(string response, HTTP_CALLBACK_ERROR error) { } public string SendRequest(string s) { HttpClientRequest request = new HttpClientRequest(); string url = string.Format("http://{0}{1}", this.address, s); request.Url = new UrlParser(url); HttpClientResponse response = WebClient.Dispatch(request); return response.ContentString; } /// /// Sends a command to the DSP (with delimiter appended) /// /// Command to send /// public void SendLine(string s) { HttpClientRequest request = new HttpClientRequest(); string url = string.Format("http://{0}{1}", this.address, s); request.Url = new UrlParser(url); HttpClientResponse response = WebClient.Dispatch(request); } public void CycleCircuit(uint circuit) { SendLine(String.Format("/outlet?{0}=CCL", circuit)); //PollCircuit(circuit); } public void TurnOnCircuit(uint circuit) { SendLine(String.Format("/outlet?{0}=ON", circuit)); //PollCircuit(circuit); } public void TurnOffCircuit(uint circuit) { SendLine(String.Format("/outlet?{0}=Off", circuit)); //PollCircuit(circuit); } /// /// Adds a command from a child module to the queue /// /// Command object from child module public void EnqueueCommand(QueuedCommand commandToEnqueue) { CommandQueue.Enqueue(commandToEnqueue); //Debug.Console(1, this, "Command (QueuedCommand) Enqueued '{0}'. CommandQueue has '{1}' Elements.", commandToEnqueue.Command, CommandQueue.Count); if(!CommandQueueInProgress) SendNextQueuedCommand(); } /// /// Adds a raw string command to the queue /// /// public void EnqueueCommand(string command) { CommandQueue.Enqueue(command); //Debug.Console(1, this, "Command (string) Enqueued '{0}'. CommandQueue has '{1}' Elements.", command, CommandQueue.Count); if (!CommandQueueInProgress) SendNextQueuedCommand(); } /// /// Sends the next queued command to the DSP /// void SendNextQueuedCommand() { if (Communication.IsConnected && !CommandQueue.IsEmpty) { CommandQueueInProgress = true; if (CommandQueue.Peek() is QueuedCommand) { QueuedCommand nextCommand = new QueuedCommand(); nextCommand = (QueuedCommand)CommandQueue.Peek(); SendLine(nextCommand.Command); } else { string nextCommand = (string)CommandQueue.Peek(); SendLine(nextCommand); } } } public void CallPreset(ushort presetNumber) { SendLine(string.Format("Preset.Take = {0}", presetNumber)); // SendLine("cgp 1"); } public class QueuedCommand { public string Command { get; set; } public string AttributeCode { get; set; } // public QscDspControlPoint ControlPoint { get; set; } } public class DigitalLoggerCircuit { public string name; public bool locked; public bool critical; public bool transient_state; public bool physical_state; //public int cycle_delay; public bool state; } } public class DigitalLoggerFactory : EssentialsDeviceFactory { public DigitalLoggerFactory() { TypeNames = new List() { "digitallogger" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) { Debug.Console(1, "Factory Attempting to create new DigitalLogger Device"); var props = JsonConvert.DeserializeObject( dc.Properties.ToString()); return new DigitalLogger(dc.Key, dc.Name, props); } } }