chore: run code cleanup

Ran code cleanup with the options set to remove unused
usings, sort usings, and adjust namespaces to match
folders.
This commit is contained in:
Andrew Welker
2023-03-23 09:26:17 -06:00
parent 046caba889
commit 2f2ea964cb
67 changed files with 4192 additions and 4693 deletions

View File

@@ -1,76 +1,70 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using PepperDash.Core; namespace PepperDash.Core.Comm
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Defines the string event handler for line events on the gather /// Defines the string event handler for line events on the gather
/// </summary> /// </summary>
/// <param name="text"></param> /// <param name="text"></param>
public delegate void LineReceivedHandler(string text); public delegate void LineReceivedHandler(string text);
/// <summary> /// <summary>
/// Attaches to IBasicCommunication as a text gather /// Attaches to IBasicCommunication as a text gather
/// </summary> /// </summary>
public class CommunicationGather public class CommunicationGather
{ {
/// <summary> /// <summary>
/// Event that fires when a line is received from the IBasicCommunication source. /// Event that fires when a line is received from the IBasicCommunication source.
/// The event merely contains the text, not an EventArgs type class. /// The event merely contains the text, not an EventArgs type class.
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveTextArgs> LineReceived; public event EventHandler<GenericCommMethodReceiveTextArgs> LineReceived;
/// <summary> /// <summary>
/// The communication port that this gathers on /// The communication port that this gathers on
/// </summary> /// </summary>
public ICommunicationReceiver Port { get; private set; } public ICommunicationReceiver Port { get; private set; }
/// <summary> /// <summary>
/// Default false. If true, the delimiter will be included in the line output /// Default false. If true, the delimiter will be included in the line output
/// events /// events
/// </summary> /// </summary>
public bool IncludeDelimiter { get; set; } public bool IncludeDelimiter { get; set; }
/// <summary> /// <summary>
/// For receive buffer /// For receive buffer
/// </summary> /// </summary>
StringBuilder ReceiveBuffer = new StringBuilder(); StringBuilder ReceiveBuffer = new StringBuilder();
/// <summary> /// <summary>
/// Delimiter, like it says! /// Delimiter, like it says!
/// </summary> /// </summary>
char Delimiter; char Delimiter;
string[] StringDelimiters; string[] StringDelimiters;
/// <summary> /// <summary>
/// Constructor for using a char delimiter /// Constructor for using a char delimiter
/// </summary> /// </summary>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="delimiter"></param> /// <param name="delimiter"></param>
public CommunicationGather(ICommunicationReceiver port, char delimiter) public CommunicationGather(ICommunicationReceiver port, char delimiter)
{ {
Port = port; Port = port;
Delimiter = delimiter; Delimiter = delimiter;
port.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Port_TextReceived); port.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Port_TextReceived);
} }
/// <summary> /// <summary>
/// Constructor for using a single string delimiter /// Constructor for using a single string delimiter
/// </summary> /// </summary>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="delimiter"></param> /// <param name="delimiter"></param>
public CommunicationGather(ICommunicationReceiver port, string delimiter) public CommunicationGather(ICommunicationReceiver port, string delimiter)
:this(port, new string[] { delimiter} ) : this(port, new string[] { delimiter })
{ {
} }
/// <summary> /// <summary>
/// Constructor for using an array of string delimiters /// Constructor for using an array of string delimiters
@@ -84,57 +78,57 @@ namespace PepperDash.Core
port.TextReceived += Port_TextReceivedStringDelimiter; port.TextReceived += Port_TextReceivedStringDelimiter;
} }
/// <summary> /// <summary>
/// Disconnects this gather from the Port's TextReceived event. This will not fire LineReceived /// Disconnects this gather from the Port's TextReceived event. This will not fire LineReceived
/// after the this call. /// after the this call.
/// </summary> /// </summary>
public void Stop() public void Stop()
{ {
Port.TextReceived -= Port_TextReceived; Port.TextReceived -= Port_TextReceived;
Port.TextReceived -= Port_TextReceivedStringDelimiter; Port.TextReceived -= Port_TextReceivedStringDelimiter;
} }
/// <summary> /// <summary>
/// Handler for raw data coming from port /// Handler for raw data coming from port
/// </summary> /// </summary>
void Port_TextReceived(object sender, GenericCommMethodReceiveTextArgs args) void Port_TextReceived(object sender, GenericCommMethodReceiveTextArgs args)
{ {
var handler = LineReceived; var handler = LineReceived;
if (handler != null) if (handler != null)
{ {
ReceiveBuffer.Append(args.Text); ReceiveBuffer.Append(args.Text);
var str = ReceiveBuffer.ToString(); var str = ReceiveBuffer.ToString();
var lines = str.Split(Delimiter); var lines = str.Split(Delimiter);
if (lines.Length > 0) if (lines.Length > 0)
{ {
for (int i = 0; i < lines.Length - 1; i++) for (int i = 0; i < lines.Length - 1; i++)
{ {
string strToSend = null; string strToSend = null;
if (IncludeDelimiter) if (IncludeDelimiter)
strToSend = lines[i] + Delimiter; strToSend = lines[i] + Delimiter;
else else
strToSend = lines[i]; strToSend = lines[i];
handler(this, new GenericCommMethodReceiveTextArgs(strToSend)); handler(this, new GenericCommMethodReceiveTextArgs(strToSend));
} }
ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]); ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]);
} }
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
void Port_TextReceivedStringDelimiter(object sender, GenericCommMethodReceiveTextArgs args) void Port_TextReceivedStringDelimiter(object sender, GenericCommMethodReceiveTextArgs args)
{ {
var handler = LineReceived; var handler = LineReceived;
if (handler != null) if (handler != null)
{ {
// Receive buffer should either be empty or not contain the delimiter // Receive buffer should either be empty or not contain the delimiter
// If the line does not have a delimiter, append the // If the line does not have a delimiter, append the
ReceiveBuffer.Append(args.Text); ReceiveBuffer.Append(args.Text);
var str = ReceiveBuffer.ToString(); var str = ReceiveBuffer.ToString();
// Case: Receiving DEVICE get version\x0d\0x0a+OK "value":"1234"\x0d\x0a // Case: Receiving DEVICE get version\x0d\0x0a+OK "value":"1234"\x0d\x0a
@@ -165,15 +159,15 @@ namespace PepperDash.Core
} }
ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]); ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]);
} }
} }
} }
/// <summary> /// <summary>
/// Deconstructor. Disconnects from port TextReceived events. /// Deconstructor. Disconnects from port TextReceived events.
/// </summary> /// </summary>
~CommunicationGather() ~CommunicationGather()
{ {
Stop(); Stop();
} }
} }
} }

View File

@@ -1,11 +1,8 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic; using PepperDash.Core.Logging;
using System.Linq; using System;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Controls the ability to disable/enable debugging of TX/RX data sent to/from a device with a built in timer to disable /// Controls the ability to disable/enable debugging of TX/RX data sent to/from a device with a built in timer to disable
@@ -37,14 +34,14 @@ namespace PepperDash.Core
{ {
get get
{ {
return _DebugTimeoutInMs/60000; return _DebugTimeoutInMs / 60000;
} }
} }
/// <summary> /// <summary>
/// Indicates that receive stream debugging is enabled /// Indicates that receive stream debugging is enabled
/// </summary> /// </summary>
public bool RxStreamDebuggingIsEnabled{ get; private set; } public bool RxStreamDebuggingIsEnabled { get; private set; }
/// <summary> /// <summary>
/// Indicates that transmit stream debugging is enabled /// Indicates that transmit stream debugging is enabled

View File

@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Config properties that indicate how to communicate with a device for control /// Config properties that indicate how to communicate with a device for control

View File

@@ -8,15 +8,10 @@ and in all parts thereof, regardless of the use to which it is being put. Any u
of this material by another party without the express written permission of PepperDash Technology Corporation is prohibited. of this material by another party without the express written permission of PepperDash Technology Corporation is prohibited.
PepperDash Technology Corporation reserves all rights under applicable laws. PepperDash Technology Corporation reserves all rights under applicable laws.
------------------------------------ */ ------------------------------------ */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using System;
namespace PepperDash.Core.Comm
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Delegate for notifying of socket status changes /// Delegate for notifying of socket status changes
@@ -28,7 +23,7 @@ namespace PepperDash.Core
/// EventArgs class for socket status changes /// EventArgs class for socket status changes
/// </summary> /// </summary>
public class GenericSocketStatusChageEventArgs : EventArgs public class GenericSocketStatusChageEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -39,13 +34,13 @@ namespace PepperDash.Core
/// </summary> /// </summary>
/// <param name="client"></param> /// <param name="client"></param>
public GenericSocketStatusChageEventArgs(ISocketStatus client) public GenericSocketStatusChageEventArgs(ISocketStatus client)
{ {
Client = client; Client = client;
} }
/// <summary> /// <summary>
/// S+ Constructor /// S+ Constructor
/// </summary> /// </summary>
public GenericSocketStatusChageEventArgs() { } public GenericSocketStatusChageEventArgs() { }
} }
/// <summary> /// <summary>
@@ -72,10 +67,10 @@ namespace PepperDash.Core
{ {
State = state; State = state;
} }
/// <summary> /// <summary>
/// S+ Constructor /// S+ Constructor
/// </summary> /// </summary>
public GenericTcpServerStateChangedEventArgs() { } public GenericTcpServerStateChangedEventArgs() { }
} }
/// <summary> /// <summary>
@@ -126,10 +121,10 @@ namespace PepperDash.Core
ReceivedFromClientIndex = clientIndex; ReceivedFromClientIndex = clientIndex;
ClientStatus = clientStatus; ClientStatus = clientStatus;
} }
/// <summary> /// <summary>
/// S+ Constructor /// S+ Constructor
/// </summary> /// </summary>
public GenericTcpServerSocketStatusChangeEventArgs() { } public GenericTcpServerSocketStatusChangeEventArgs() { }
} }
/// <summary> /// <summary>
@@ -146,12 +141,12 @@ namespace PepperDash.Core
/// ///
/// </summary> /// </summary>
public ushort ReceivedFromClientIndexShort public ushort ReceivedFromClientIndexShort
{ {
get get
{ {
return (ushort)ReceivedFromClientIndex; return (ushort)ReceivedFromClientIndex;
} }
} }
/// <summary> /// <summary>
/// ///
@@ -177,10 +172,10 @@ namespace PepperDash.Core
Text = text; Text = text;
ReceivedFromClientIndex = clientIndex; ReceivedFromClientIndex = clientIndex;
} }
/// <summary> /// <summary>
/// S+ Constructor /// S+ Constructor
/// </summary> /// </summary>
public GenericTcpServerCommMethodReceiveTextArgs() { } public GenericTcpServerCommMethodReceiveTextArgs() { }
} }
/// <summary> /// <summary>
@@ -201,10 +196,10 @@ namespace PepperDash.Core
{ {
IsReady = isReady; IsReady = isReady;
} }
/// <summary> /// <summary>
/// S+ Constructor /// S+ Constructor
/// </summary> /// </summary>
public GenericTcpServerClientReadyForcommunicationsEventArgs() { } public GenericTcpServerClientReadyForcommunicationsEventArgs() { }
} }
/// <summary> /// <summary>

View File

@@ -1,10 +1,8 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Background class that manages debug features for sockets /// Background class that manages debug features for sockets
@@ -38,30 +36,30 @@ namespace PepperDash.Core
if (tokens.Length == 0) if (tokens.Length == 0)
return; return;
var command = tokens[0].ToLower(); var command = tokens[0].ToLower();
if(command == "connect") if (command == "connect")
{ {
} }
else if(command == "disco") else if (command == "disco")
{ {
} }
else if(command =="list") else if (command == "list")
{ {
CrestronConsole.ConsoleCommandResponse("{0} sockets", Sockets.Count); CrestronConsole.ConsoleCommandResponse("{0} sockets", Sockets.Count);
if(Sockets.Count == 0) if (Sockets.Count == 0)
return; return;
// get the longest key name, for formatting // get the longest key name, for formatting
var longestLength = Sockets.Aggregate("", var longestLength = Sockets.Aggregate("",
(max, cur) => max.Length > cur.Key.Length ? max : cur.Key).Length; (max, cur) => max.Length > cur.Key.Length ? max : cur.Key).Length;
for(int i = 0; i < Sockets.Count; i++) for (int i = 0; i < Sockets.Count; i++)
{ {
var sock = Sockets[i]; var sock = Sockets[i];
CrestronConsole.ConsoleCommandResponse("{0} {1} {2} {3}", CrestronConsole.ConsoleCommandResponse("{0} {1} {2} {3}",
i, sock.Key, GetSocketType(sock), sock.ClientStatus); i, sock.Key, GetSocketType(sock), sock.ClientStatus);
} }
} }
else if(command == "send") else if (command == "send")
{ {
} }
@@ -87,7 +85,7 @@ namespace PepperDash.Core
/// <param name="socket"></param> /// <param name="socket"></param>
public static void AddSocket(ISocketStatus socket) public static void AddSocket(ISocketStatus socket)
{ {
if(!Sockets.Contains(socket)) if (!Sockets.Contains(socket))
Sockets.Add(socket); Sockets.Add(socket);
} }

View File

@@ -1,12 +1,11 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Net.Http; using Crestron.SimplSharp.Net.Http;
using PepperDash.Core.Logging;
using System;
using System.Text;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Client for communicating with an HTTP Server Side Event pattern /// Client for communicating with an HTTP Server Side Event pattern
@@ -94,7 +93,7 @@ namespace PepperDash.Core
{ {
try try
{ {
if(string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
{ {
Debug.Console(0, this, "Error connecting to Server. No URL specified"); Debug.Console(0, this, "Error connecting to Server. No URL specified");
return; return;

View File

@@ -1,12 +1,11 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic; using Crestron.SimplSharp.CrestronSockets;
using PepperDash.Core.Logging;
using System;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// A class to handle secure TCP/IP communications with a server /// A class to handle secure TCP/IP communications with a server
@@ -261,7 +260,7 @@ namespace PepperDash.Core
/// <summary> /// <summary>
/// Simpl+ Heartbeat Analog value in seconds /// Simpl+ Heartbeat Analog value in seconds
/// </summary> /// </summary>
public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatInterval = (value * 1000); } } public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatInterval = value * 1000; } }
CTimer HeartbeatSendTimer; CTimer HeartbeatSendTimer;
CTimer HeartbeatAckTimer; CTimer HeartbeatAckTimer;
@@ -424,7 +423,7 @@ namespace PepperDash.Core
{ {
if (_client != null) if (_client != null)
{ {
_client.SocketStatusChange -= this.Client_SocketStatusChange; _client.SocketStatusChange -= Client_SocketStatusChange;
DisconnectClient(); DisconnectClient();
} }
return true; return true;
@@ -483,7 +482,7 @@ namespace PepperDash.Core
_client = new SecureTCPClient(Hostname, Port, BufferSize); _client = new SecureTCPClient(Hostname, Port, BufferSize);
_client.SocketStatusChange += Client_SocketStatusChange; _client.SocketStatusChange += Client_SocketStatusChange;
if (HeartbeatEnabled) if (HeartbeatEnabled)
_client.SocketSendOrReceiveTimeOutInMs = (HeartbeatInterval * 5); _client.SocketSendOrReceiveTimeOutInMs = HeartbeatInterval * 5;
_client.AddressClientConnectedTo = Hostname; _client.AddressClientConnectedTo = Hostname;
_client.PortNumber = Port; _client.PortNumber = Port;
// SecureClient = c; // SecureClient = c;
@@ -744,11 +743,11 @@ namespace PepperDash.Core
if (HeartbeatSendTimer == null) if (HeartbeatSendTimer == null)
{ {
HeartbeatSendTimer = new CTimer(this.SendHeartbeat, null, HeartbeatInterval, HeartbeatInterval); HeartbeatSendTimer = new CTimer(SendHeartbeat, null, HeartbeatInterval, HeartbeatInterval);
} }
if (HeartbeatAckTimer == null) if (HeartbeatAckTimer == null)
{ {
HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, (HeartbeatInterval * 2), (HeartbeatInterval * 2)); HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, HeartbeatInterval * 2, HeartbeatInterval * 2);
} }
} }
@@ -772,7 +771,7 @@ namespace PepperDash.Core
} }
void SendHeartbeat(object notused) void SendHeartbeat(object notused)
{ {
this.SendText(HeartbeatString); SendText(HeartbeatString);
Debug.Console(2, this, "Sending Heartbeat"); Debug.Console(2, this, "Sending Heartbeat");
} }
@@ -796,7 +795,7 @@ namespace PepperDash.Core
} }
else else
{ {
HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, (HeartbeatInterval * 2), (HeartbeatInterval * 2)); HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, HeartbeatInterval * 2, HeartbeatInterval * 2);
} }
Debug.Console(2, this, "Heartbeat Received: {0}, from Server", HeartbeatString); Debug.Console(2, this, "Heartbeat Received: {0}, from Server", HeartbeatString);
return remainingText; return remainingText;
@@ -861,7 +860,7 @@ namespace PepperDash.Core
// HOW IN THE HELL DO WE CATCH AN EXCEPTION IN SENDING????? // HOW IN THE HELL DO WE CATCH AN EXCEPTION IN SENDING?????
if (n <= 0) if (n <= 0)
{ {
Debug.Console(1, Debug.ErrorLogLevel.Warning, "[{0}] Sent zero bytes. Was there an error?", this.Key); Debug.Console(1, Debug.ErrorLogLevel.Warning, "[{0}] Sent zero bytes. Was there an error?", Key);
} }
}); });
} }
@@ -906,7 +905,7 @@ namespace PepperDash.Core
} }
try try
{ {
Debug.Console(2, this, "Socket status change: {0} ({1})", client.ClientStatus, (ushort)(client.ClientStatus)); Debug.Console(2, this, "Socket status change: {0} ({1})", client.ClientStatus, (ushort)client.ClientStatus);
OnConnectionChange(); OnConnectionChange();
// The client could be null or disposed by this time... // The client could be null or disposed by this time...

View File

@@ -10,15 +10,14 @@ of this material by another party without the express written permission of Pepp
PepperDash Technology Corporation reserves all rights under applicable laws. PepperDash Technology Corporation reserves all rights under applicable laws.
------------------------------------ */ ------------------------------------ */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using PepperDash.Core.Logging;
using System;
using System.Linq;
using System.Text;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Generic secure TCP/IP client for server /// Generic secure TCP/IP client for server
@@ -250,7 +249,7 @@ namespace PepperDash.Core
/// <summary> /// <summary>
/// Simpl+ Heartbeat Analog value in seconds /// Simpl+ Heartbeat Analog value in seconds
/// </summary> /// </summary>
public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatInterval = (value * 1000); } } public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatInterval = value * 1000; } }
CTimer HeartbeatSendTimer; CTimer HeartbeatSendTimer;
CTimer HeartbeatAckTimer; CTimer HeartbeatAckTimer;
@@ -446,7 +445,7 @@ namespace PepperDash.Core
Client = new SecureTCPClient(Hostname, Port, BufferSize); Client = new SecureTCPClient(Hostname, Port, BufferSize);
Client.SocketStatusChange += Client_SocketStatusChange; Client.SocketStatusChange += Client_SocketStatusChange;
if (HeartbeatEnabled) if (HeartbeatEnabled)
Client.SocketSendOrReceiveTimeOutInMs = (HeartbeatInterval * 5); Client.SocketSendOrReceiveTimeOutInMs = HeartbeatInterval * 5;
Client.AddressClientConnectedTo = Hostname; Client.AddressClientConnectedTo = Hostname;
Client.PortNumber = Port; Client.PortNumber = Port;
// SecureClient = c; // SecureClient = c;
@@ -590,7 +589,7 @@ namespace PepperDash.Core
RetryTimer.Stop(); RetryTimer.Stop();
RetryTimer = null; RetryTimer = null;
} }
if(AutoReconnectTriggered != null) if (AutoReconnectTriggered != null)
AutoReconnectTriggered(this, new EventArgs()); AutoReconnectTriggered(this, new EventArgs());
RetryTimer = new CTimer(o => Connect(), rndTime); RetryTimer = new CTimer(o => Connect(), rndTime);
} }
@@ -702,11 +701,11 @@ namespace PepperDash.Core
if (HeartbeatSendTimer == null) if (HeartbeatSendTimer == null)
{ {
HeartbeatSendTimer = new CTimer(this.SendHeartbeat, null, HeartbeatInterval, HeartbeatInterval); HeartbeatSendTimer = new CTimer(SendHeartbeat, null, HeartbeatInterval, HeartbeatInterval);
} }
if (HeartbeatAckTimer == null) if (HeartbeatAckTimer == null)
{ {
HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, (HeartbeatInterval * 2), (HeartbeatInterval * 2)); HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, HeartbeatInterval * 2, HeartbeatInterval * 2);
} }
} }
@@ -730,7 +729,7 @@ namespace PepperDash.Core
} }
void SendHeartbeat(object notused) void SendHeartbeat(object notused)
{ {
this.SendText(HeartbeatString); SendText(HeartbeatString);
Debug.Console(2, this, "Sending Heartbeat"); Debug.Console(2, this, "Sending Heartbeat");
} }
@@ -754,7 +753,7 @@ namespace PepperDash.Core
} }
else else
{ {
HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, (HeartbeatInterval * 2), (HeartbeatInterval * 2)); HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, HeartbeatInterval * 2, HeartbeatInterval * 2);
} }
Debug.Console(2, this, "Heartbeat Received: {0}, from Server", HeartbeatString); Debug.Console(2, this, "Heartbeat Received: {0}, from Server", HeartbeatString);
return remainingText; return remainingText;
@@ -819,7 +818,7 @@ namespace PepperDash.Core
// HOW IN THE HELL DO WE CATCH AN EXCEPTION IN SENDING????? // HOW IN THE HELL DO WE CATCH AN EXCEPTION IN SENDING?????
if (n <= 0) if (n <= 0)
{ {
Debug.Console(1, Debug.ErrorLogLevel.Warning, "[{0}] Sent zero bytes. Was there an error?", this.Key); Debug.Console(1, Debug.ErrorLogLevel.Warning, "[{0}] Sent zero bytes. Was there an error?", Key);
} }
}); });
} }
@@ -864,7 +863,7 @@ namespace PepperDash.Core
} }
try try
{ {
Debug.Console(2, this, "Socket status change: {0} ({1})", client.ClientStatus, (ushort)(client.ClientStatus)); Debug.Console(2, this, "Socket status change: {0} ({1})", client.ClientStatus, (ushort)client.ClientStatus);
OnConnectionChange(); OnConnectionChange();
// The client could be null or disposed by this time... // The client could be null or disposed by this time...
@@ -897,7 +896,7 @@ namespace PepperDash.Core
void OnClientReadyForcommunications(bool isReady) void OnClientReadyForcommunications(bool isReady)
{ {
IsReadyForCommunication = isReady; IsReadyForCommunication = isReady;
if (this.IsReadyForCommunication) { HeartbeatStart(); } if (IsReadyForCommunication) { HeartbeatStart(); }
var handler = ClientReadyForCommunications; var handler = ClientReadyForCommunications;
if (handler != null) if (handler != null)
handler(this, new GenericTcpServerClientReadyForcommunicationsEventArgs(IsReadyForCommunication)); handler(this, new GenericTcpServerClientReadyForcommunicationsEventArgs(IsReadyForCommunication));

View File

@@ -10,16 +10,15 @@ of this material by another party without the express written permission of Pepp
PepperDash Technology Corporation reserves all rights under applicable laws. PepperDash Technology Corporation reserves all rights under applicable laws.
------------------------------------ */ ------------------------------------ */
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
using PepperDash.Core.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Generic secure TCP/IP server /// Generic secure TCP/IP server
@@ -257,7 +256,7 @@ namespace PepperDash.Core
/// <summary> /// <summary>
/// Simpl+ Heartbeat Analog value in seconds /// Simpl+ Heartbeat Analog value in seconds
/// </summary> /// </summary>
public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatRequiredIntervalMs = (value * 1000); } } public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatRequiredIntervalMs = value * 1000; } }
/// <summary> /// <summary>
/// String to Match for heartbeat. If null or empty any string will reset heartbeat timer /// String to Match for heartbeat. If null or empty any string will reset heartbeat timer
@@ -418,33 +417,33 @@ namespace PepperDash.Core
} }
if (SecureServer == null) if (SecureServer == null)
{ {
SecureServer = new SecureTCPServer(Port, MaxClients); SecureServer = new SecureTCPServer(Port, MaxClients);
if (HeartbeatRequired) if (HeartbeatRequired)
SecureServer.SocketSendOrReceiveTimeOutInMs = (this.HeartbeatRequiredIntervalMs * 5); SecureServer.SocketSendOrReceiveTimeOutInMs = HeartbeatRequiredIntervalMs * 5;
SecureServer.HandshakeTimeout = 30; SecureServer.HandshakeTimeout = 30;
SecureServer.SocketStatusChange += new SecureTCPServerSocketStatusChangeEventHandler(SecureServer_SocketStatusChange); SecureServer.SocketStatusChange += new SecureTCPServerSocketStatusChangeEventHandler(SecureServer_SocketStatusChange);
} }
else else
{ {
SecureServer.PortNumber = Port; SecureServer.PortNumber = Port;
} }
ServerStopped = false; ServerStopped = false;
// Start the listner // Start the listner
SocketErrorCodes status = SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); SocketErrorCodes status = SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING) if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING)
{ {
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error starting WaitForConnectionAsync {0}", status); Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error starting WaitForConnectionAsync {0}", status);
} }
else else
{ {
ServerStopped = false; ServerStopped = false;
} }
OnServerStateChange(SecureServer.State); OnServerStateChange(SecureServer.State);
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Secure Server Status: {0}, Socket Status: {1}", SecureServer.State, SecureServer.ServerSocketStatus); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Secure Server Status: {0}, Socket Status: {1}", SecureServer.State, SecureServer.ServerSocketStatus);
ServerCCSection.Leave(); ServerCCSection.Leave();
} }
catch (Exception ex) catch (Exception ex)
@@ -459,21 +458,21 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public void StopListening() public void StopListening()
{ {
try try
{ {
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Stopping Listener"); Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Stopping Listener");
if (SecureServer != null) if (SecureServer != null)
{ {
SecureServer.Stop(); SecureServer.Stop();
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Server State: {0}", SecureServer.State); Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Server State: {0}", SecureServer.State);
OnServerStateChange(SecureServer.State); OnServerStateChange(SecureServer.State);
} }
ServerStopped = true; ServerStopped = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error stopping server. Error: {0}", ex); Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error stopping server. Error: {0}", ex);
} }
} }
/// <summary> /// <summary>
@@ -528,7 +527,7 @@ namespace PepperDash.Core
OnServerStateChange(SecureServer.State); //State shows both listening and connected OnServerStateChange(SecureServer.State); //State shows both listening and connected
} }
// var o = new { }; // var o = new { };
} }
/// <summary> /// <summary>
@@ -546,7 +545,7 @@ namespace PepperDash.Core
byte[] b = Encoding.GetEncoding(28591).GetBytes(text); byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
foreach (uint i in ConnectedClientsIndexes) foreach (uint i in ConnectedClientsIndexes)
{ {
if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(i))) if (!SharedKeyRequired || SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(i))
{ {
SocketErrorCodes error = SecureServer.SendDataAsync(i, b, b.Length, (x, y, z) => { }); SocketErrorCodes error = SecureServer.SendDataAsync(i, b, b.Length, (x, y, z) => { });
if (error != SocketErrorCodes.SOCKET_OK && error != SocketErrorCodes.SOCKET_OPERATION_PENDING) if (error != SocketErrorCodes.SOCKET_OK && error != SocketErrorCodes.SOCKET_OPERATION_PENDING)
@@ -575,7 +574,7 @@ namespace PepperDash.Core
byte[] b = Encoding.GetEncoding(28591).GetBytes(text); byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
if (SecureServer != null && SecureServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) if (SecureServer != null && SecureServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
{ {
if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))) if (!SharedKeyRequired || SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))
SecureServer.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { }); SecureServer.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { });
} }
} }
@@ -639,9 +638,9 @@ namespace PepperDash.Core
public string GetClientIPAddress(uint clientIndex) public string GetClientIPAddress(uint clientIndex)
{ {
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress Index: {0}", clientIndex); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress Index: {0}", clientIndex);
if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))) if (!SharedKeyRequired || SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))
{ {
var ipa = this.SecureServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex); var ipa = SecureServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex);
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress IPAddreess: {0}", ipa); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress IPAddreess: {0}", ipa);
return ipa; return ipa;
@@ -666,7 +665,7 @@ namespace PepperDash.Core
address = SecureServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex); address = SecureServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex);
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Heartbeat not received for Client index {2} IP: {0}, DISCONNECTING BECAUSE HEARTBEAT REQUIRED IS TRUE {1}", Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Heartbeat not received for Client index {2} IP: {0}, DISCONNECTING BECAUSE HEARTBEAT REQUIRED IS TRUE {1}",
address, string.IsNullOrEmpty(HeartbeatStringToMatch) ? "" : ("HeartbeatStringToMatch: " + HeartbeatStringToMatch), clientIndex); address, string.IsNullOrEmpty(HeartbeatStringToMatch) ? "" : "HeartbeatStringToMatch: " + HeartbeatStringToMatch, clientIndex);
if (SecureServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) if (SecureServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
SendTextToClient("Heartbeat not received by server, closing connection", clientIndex); SendTextToClient("Heartbeat not received by server, closing connection", clientIndex);
@@ -702,10 +701,10 @@ namespace PepperDash.Core
{ {
// Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange Index:{0} status:{1} Port:{2} IP:{3}", clientIndex, serverSocketStatus, this.SecureServer.GetPortNumberServerAcceptedConnectionFromForSpecificClient(clientIndex), this.SecureServer.GetLocalAddressServerAcceptedConnectionFromForSpecificClient(clientIndex)); // Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange Index:{0} status:{1} Port:{2} IP:{3}", clientIndex, serverSocketStatus, this.SecureServer.GetPortNumberServerAcceptedConnectionFromForSpecificClient(clientIndex), this.SecureServer.GetLocalAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
{ {
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange ConnectedCLients: {0} ServerState: {1} Port: {2}", SecureServer.NumberOfClientsConnected, SecureServer.State, SecureServer.PortNumber); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange ConnectedCLients: {0} ServerState: {1} Port: {2}", SecureServer.NumberOfClientsConnected, SecureServer.State, SecureServer.PortNumber);
if (ConnectedClientsIndexes.Contains(clientIndex)) if (ConnectedClientsIndexes.Contains(clientIndex))
ConnectedClientsIndexes.Remove(clientIndex); ConnectedClientsIndexes.Remove(clientIndex);
@@ -717,12 +716,12 @@ namespace PepperDash.Core
} }
if (ClientReadyAfterKeyExchange.Contains(clientIndex)) if (ClientReadyAfterKeyExchange.Contains(clientIndex))
ClientReadyAfterKeyExchange.Remove(clientIndex); ClientReadyAfterKeyExchange.Remove(clientIndex);
if (WaitingForSharedKey.Contains(clientIndex)) if (WaitingForSharedKey.Contains(clientIndex))
WaitingForSharedKey.Remove(clientIndex); WaitingForSharedKey.Remove(clientIndex);
if (SecureServer.MaxNumberOfClientSupported > SecureServer.NumberOfClientsConnected) if (SecureServer.MaxNumberOfClientSupported > SecureServer.NumberOfClientsConnected)
{ {
Listen(); Listen();
} }
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -794,19 +793,19 @@ namespace PepperDash.Core
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex); Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex);
} }
// Rearm the listner // Rearm the listner
SocketErrorCodes status = server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); SocketErrorCodes status = server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING) if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING)
{ {
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Socket status connect callback status {0}", status); Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Socket status connect callback status {0}", status);
if (status == SocketErrorCodes.SOCKET_CONNECTION_IN_PROGRESS) if (status == SocketErrorCodes.SOCKET_CONNECTION_IN_PROGRESS)
{ {
// There is an issue where on a failed negotiation we need to stop and start the server. This should still leave connected clients intact. // There is an issue where on a failed negotiation we need to stop and start the server. This should still leave connected clients intact.
server.Stop(); server.Stop();
Listen(); Listen();
} }
} }
} }
#endregion #endregion
@@ -827,7 +826,7 @@ namespace PepperDash.Core
try try
{ {
byte[] bytes = mySecureTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex); byte[] bytes = mySecureTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex);
received = System.Text.Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived); received = Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived);
if (WaitingForSharedKey.Contains(clientIndex)) if (WaitingForSharedKey.Contains(clientIndex))
{ {
received = received.Replace("\r", ""); received = received.Replace("\r", "");
@@ -861,8 +860,8 @@ namespace PepperDash.Core
{ {
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Receiving data: {0}. Error: {1}", received, ex); Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Receiving data: {0}. Error: {1}", received, ex);
} }
if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback);
//Check to see if there is a subscription to the TextReceivedQueueInvoke event. If there is start the dequeue thread. //Check to see if there is a subscription to the TextReceivedQueueInvoke event. If there is start the dequeue thread.
if (handler != null) if (handler != null)
@@ -872,9 +871,9 @@ namespace PepperDash.Core
CrestronInvoke.BeginInvoke((o) => DequeueEvent()); CrestronInvoke.BeginInvoke((o) => DequeueEvent());
} }
} }
else else
{ {
mySecureTCPServer.Disconnect(clientIndex); mySecureTCPServer.Disconnect(clientIndex);
} }
} }
@@ -1011,8 +1010,8 @@ namespace PepperDash.Core
void RunMonitorClient() void RunMonitorClient()
{ {
MonitorClient = new GenericSecureTcpIpClient_ForServer(Key + "-MONITOR", "127.0.0.1", Port, 2000); MonitorClient = new GenericSecureTcpIpClient_ForServer(Key + "-MONITOR", "127.0.0.1", Port, 2000);
MonitorClient.SharedKeyRequired = this.SharedKeyRequired; MonitorClient.SharedKeyRequired = SharedKeyRequired;
MonitorClient.SharedKey = this.SharedKey; MonitorClient.SharedKey = SharedKey;
MonitorClient.ConnectionHasHungCallback = MonitorClientHasHungCallback; MonitorClient.ConnectionHasHungCallback = MonitorClientHasHungCallback;
//MonitorClient.ConnectionChange += MonitorClient_ConnectionChange; //MonitorClient.ConnectionChange += MonitorClient_ConnectionChange;
MonitorClient.ClientReadyForCommunications += MonitorClient_IsReadyForComm; MonitorClient.ClientReadyForCommunications += MonitorClient_IsReadyForComm;

View File

@@ -1,174 +1,174 @@
using System; using Crestron.SimplSharp;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using Crestron.SimplSharp.Ssh; using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharp.Ssh.Common; using Crestron.SimplSharp.Ssh.Common;
using PepperDash.Core.Logging;
using System;
using System.Text;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class GenericSshClient : Device, ISocketStatusWithStreamDebugging, IAutoReconnect public class GenericSshClient : Device, ISocketStatusWithStreamDebugging, IAutoReconnect
{ {
private const string SPlusKey = "Uninitialized SshClient"; private const string SPlusKey = "Uninitialized SshClient";
/// <summary> /// <summary>
/// Object to enable stream debugging /// Object to enable stream debugging
/// </summary> /// </summary>
public CommunicationStreamDebugging StreamDebugging { get; private set; } public CommunicationStreamDebugging StreamDebugging { get; private set; }
/// <summary> /// <summary>
/// Event that fires when data is received. Delivers args with byte array /// Event that fires when data is received. Delivers args with byte array
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived; public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
/// <summary> /// <summary>
/// Event that fires when data is received. Delivered as text. /// Event that fires when data is received. Delivered as text.
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived; public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
/// <summary> /// <summary>
/// Event when the connection status changes. /// Event when the connection status changes.
/// </summary> /// </summary>
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange; public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
///// <summary> ///// <summary>
///// /////
///// </summary> ///// </summary>
//public event GenericSocketStatusChangeEventDelegate SocketStatusChange; //public event GenericSocketStatusChangeEventDelegate SocketStatusChange;
/// <summary> /// <summary>
/// Address of server /// Address of server
/// </summary> /// </summary>
public string Hostname { get; set; } public string Hostname { get; set; }
/// <summary> /// <summary>
/// Port on server /// Port on server
/// </summary> /// </summary>
public int Port { get; set; } public int Port { get; set; }
/// <summary> /// <summary>
/// Username for server /// Username for server
/// </summary> /// </summary>
public string Username { get; set; } public string Username { get; set; }
/// <summary> /// <summary>
/// And... Password for server. That was worth documenting! /// And... Password for server. That was worth documenting!
/// </summary> /// </summary>
public string Password { get; set; } public string Password { get; set; }
/// <summary> /// <summary>
/// True when the server is connected - when status == 2. /// True when the server is connected - when status == 2.
/// </summary> /// </summary>
public bool IsConnected public bool IsConnected
{ {
// returns false if no client or not connected // returns false if no client or not connected
get { return Client != null && ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } get { return Client != null && ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
} }
/// <summary> /// <summary>
/// S+ helper for IsConnected /// S+ helper for IsConnected
/// </summary> /// </summary>
public ushort UIsConnected public ushort UIsConnected
{ {
get { return (ushort)(IsConnected ? 1 : 0); } get { return (ushort)(IsConnected ? 1 : 0); }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public SocketStatus ClientStatus public SocketStatus ClientStatus
{ {
get { return _ClientStatus; } get { return _ClientStatus; }
private set private set
{ {
if (_ClientStatus == value) if (_ClientStatus == value)
return; return;
_ClientStatus = value; _ClientStatus = value;
OnConnectionChange(); OnConnectionChange();
} }
} }
SocketStatus _ClientStatus; SocketStatus _ClientStatus;
/// <summary> /// <summary>
/// Contains the familiar Simpl analog status values. This drives the ConnectionChange event /// Contains the familiar Simpl analog status values. This drives the ConnectionChange event
/// and IsConnected with be true when this == 2. /// and IsConnected with be true when this == 2.
/// </summary> /// </summary>
public ushort UStatus public ushort UStatus
{ {
get { return (ushort)_ClientStatus; } get { return (ushort)_ClientStatus; }
} }
/// <summary> /// <summary>
/// Determines whether client will attempt reconnection on failure. Default is true /// Determines whether client will attempt reconnection on failure. Default is true
/// </summary> /// </summary>
public bool AutoReconnect { get; set; } public bool AutoReconnect { get; set; }
/// <summary> /// <summary>
/// Will be set and unset by connect and disconnect only /// Will be set and unset by connect and disconnect only
/// </summary> /// </summary>
public bool ConnectEnabled { get; private set; } public bool ConnectEnabled { get; private set; }
/// <summary> /// <summary>
/// S+ helper for AutoReconnect /// S+ helper for AutoReconnect
/// </summary> /// </summary>
public ushort UAutoReconnect public ushort UAutoReconnect
{ {
get { return (ushort)(AutoReconnect ? 1 : 0); } get { return (ushort)(AutoReconnect ? 1 : 0); }
set { AutoReconnect = value == 1; } set { AutoReconnect = value == 1; }
} }
/// <summary> /// <summary>
/// Millisecond value, determines the timeout period in between reconnect attempts. /// Millisecond value, determines the timeout period in between reconnect attempts.
/// Set to 5000 by default /// Set to 5000 by default
/// </summary> /// </summary>
public int AutoReconnectIntervalMs { get; set; } public int AutoReconnectIntervalMs { get; set; }
SshClient Client; SshClient Client;
ShellStream TheStream; ShellStream TheStream;
CTimer ReconnectTimer; CTimer ReconnectTimer;
//Lock object to prevent simulatneous connect/disconnect operations //Lock object to prevent simulatneous connect/disconnect operations
private CCriticalSection connectLock = new CCriticalSection(); private CCriticalSection connectLock = new CCriticalSection();
private bool DisconnectLogged = false; private bool DisconnectLogged = false;
/// <summary> /// <summary>
/// Typical constructor. /// Typical constructor.
/// </summary> /// </summary>
public GenericSshClient(string key, string hostname, int port, string username, string password) : public GenericSshClient(string key, string hostname, int port, string username, string password) :
base(key) base(key)
{ {
StreamDebugging = new CommunicationStreamDebugging(key); StreamDebugging = new CommunicationStreamDebugging(key);
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
Key = key; Key = key;
Hostname = hostname; Hostname = hostname;
Port = port; Port = port;
Username = username; Username = username;
Password = password; Password = password;
AutoReconnectIntervalMs = 5000; AutoReconnectIntervalMs = 5000;
ReconnectTimer = new CTimer(o => ReconnectTimer = new CTimer(o =>
{ {
if (ConnectEnabled) if (ConnectEnabled)
{ {
Connect(); Connect();
} }
}, Timeout.Infinite); }, Timeout.Infinite);
} }
/// <summary> /// <summary>
/// S+ Constructor - Must set all properties before calling Connect /// S+ Constructor - Must set all properties before calling Connect
/// </summary> /// </summary>
public GenericSshClient() public GenericSshClient()
: base(SPlusKey) : base(SPlusKey)
{ {
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
AutoReconnectIntervalMs = 5000; AutoReconnectIntervalMs = 5000;
ReconnectTimer = new CTimer(o => ReconnectTimer = new CTimer(o =>
{ {
@@ -177,35 +177,35 @@ namespace PepperDash.Core
Connect(); Connect();
} }
}, Timeout.Infinite); }, Timeout.Infinite);
} }
/// <summary> /// <summary>
/// Just to help S+ set the key /// Just to help S+ set the key
/// </summary> /// </summary>
public void Initialize(string key) public void Initialize(string key)
{ {
Key = key; Key = key;
} }
/// <summary> /// <summary>
/// Handles closing this up when the program shuts down /// Handles closing this up when the program shuts down
/// </summary> /// </summary>
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{ {
if (programEventType == eProgramStatusEventType.Stopping) if (programEventType == eProgramStatusEventType.Stopping)
{ {
if (Client != null) if (Client != null)
{ {
Debug.Console(1, this, "Program stopping. Closing connection"); Debug.Console(1, this, "Program stopping. Closing connection");
Disconnect(); Disconnect();
} }
} }
} }
/// <summary> /// <summary>
/// Connect to the server, using the provided properties. /// Connect to the server, using the provided properties.
/// </summary> /// </summary>
public void Connect() public void Connect()
{ {
// Don't go unless everything is here // Don't go unless everything is here
if (string.IsNullOrEmpty(Hostname) || Port < 1 || Port > 65535 if (string.IsNullOrEmpty(Hostname) || Port < 1 || Port > 65535
@@ -307,21 +307,21 @@ namespace PepperDash.Core
} }
} }
/// <summary> /// <summary>
/// Disconnect the clients and put away it's resources. /// Disconnect the clients and put away it's resources.
/// </summary> /// </summary>
public void Disconnect() public void Disconnect()
{ {
ConnectEnabled = false; ConnectEnabled = false;
// Stop trying reconnects, if we are // Stop trying reconnects, if we are
if (ReconnectTimer != null) if (ReconnectTimer != null)
{ {
ReconnectTimer.Stop(); ReconnectTimer.Stop();
ReconnectTimer = null; ReconnectTimer = null;
} }
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY); KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
} }
/// <summary> /// <summary>
/// Kills the stream, cleans up the client and sets it to null /// Kills the stream, cleans up the client and sets it to null
@@ -339,96 +339,96 @@ namespace PepperDash.Core
} }
} }
/// <summary> /// <summary>
/// Anything to do with reestablishing connection on failures /// Anything to do with reestablishing connection on failures
/// </summary> /// </summary>
void HandleConnectionFailure() void HandleConnectionFailure()
{ {
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED); KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
Debug.Console(1, this, "Client nulled due to connection failure. AutoReconnect: {0}, ConnectEnabled: {1}", AutoReconnect, ConnectEnabled); Debug.Console(1, this, "Client nulled due to connection failure. AutoReconnect: {0}, ConnectEnabled: {1}", AutoReconnect, ConnectEnabled);
if (AutoReconnect && ConnectEnabled) if (AutoReconnect && ConnectEnabled)
{ {
Debug.Console(1, this, "Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs); Debug.Console(1, this, "Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs);
if (ReconnectTimer == null) if (ReconnectTimer == null)
{ {
ReconnectTimer = new CTimer(o => ReconnectTimer = new CTimer(o =>
{ {
Connect(); Connect();
}, AutoReconnectIntervalMs); }, AutoReconnectIntervalMs);
Debug.Console(1, this, "Attempting connection in {0} seconds", Debug.Console(1, this, "Attempting connection in {0} seconds",
(float) (AutoReconnectIntervalMs/1000)); (float)(AutoReconnectIntervalMs / 1000));
} }
else else
{ {
Debug.Console(1, this, "{0} second reconnect cycle running", Debug.Console(1, this, "{0} second reconnect cycle running",
(float) (AutoReconnectIntervalMs/1000)); (float)(AutoReconnectIntervalMs / 1000));
} }
} }
} }
/// <summary> /// <summary>
/// Kills the stream /// Kills the stream
/// </summary> /// </summary>
void KillStream() void KillStream()
{ {
if (TheStream != null) if (TheStream != null)
{ {
TheStream.DataReceived -= Stream_DataReceived; TheStream.DataReceived -= Stream_DataReceived;
TheStream.Close(); TheStream.Close();
TheStream.Dispose(); TheStream.Dispose();
TheStream = null; TheStream = null;
Debug.Console(1, this, "Disconnected stream"); Debug.Console(1, this, "Disconnected stream");
} }
} }
/// <summary> /// <summary>
/// Handles the keyboard interactive authentication, should it be required. /// Handles the keyboard interactive authentication, should it be required.
/// </summary> /// </summary>
void kauth_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e) void kauth_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e)
{ {
foreach (AuthenticationPrompt prompt in e.Prompts) foreach (AuthenticationPrompt prompt in e.Prompts)
if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1) if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
prompt.Response = Password; prompt.Response = Password;
} }
/// <summary> /// <summary>
/// Handler for data receive on ShellStream. Passes data across to queue for line parsing. /// Handler for data receive on ShellStream. Passes data across to queue for line parsing.
/// </summary> /// </summary>
void Stream_DataReceived(object sender, Crestron.SimplSharp.Ssh.Common.ShellDataEventArgs e) void Stream_DataReceived(object sender, ShellDataEventArgs e)
{ {
var bytes = e.Data; var bytes = e.Data;
if (bytes.Length > 0) if (bytes.Length > 0)
{ {
var bytesHandler = BytesReceived; var bytesHandler = BytesReceived;
if (bytesHandler != null) if (bytesHandler != null)
{ {
if (StreamDebugging.RxStreamDebuggingIsEnabled) if (StreamDebugging.RxStreamDebuggingIsEnabled)
{ {
Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length); Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
} }
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
} }
var textHandler = TextReceived; var textHandler = TextReceived;
if (textHandler != null) if (textHandler != null)
{ {
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length); var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
if (StreamDebugging.RxStreamDebuggingIsEnabled) if (StreamDebugging.RxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetDebugText(str)); Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetDebugText(str));
textHandler(this, new GenericCommMethodReceiveTextArgs(str)); textHandler(this, new GenericCommMethodReceiveTextArgs(str));
} }
} }
} }
/// <summary> /// <summary>
/// Error event handler for client events - disconnect, etc. Will forward those events via ConnectionChange /// Error event handler for client events - disconnect, etc. Will forward those events via ConnectionChange
/// event /// event
/// </summary> /// </summary>
void Client_ErrorOccurred(object sender, Crestron.SimplSharp.Ssh.Common.ExceptionEventArgs e) void Client_ErrorOccurred(object sender, ExceptionEventArgs e)
{ {
CrestronInvoke.BeginInvoke(o => CrestronInvoke.BeginInvoke(o =>
{ {
if (e.Exception is SshConnectionException || e.Exception is System.Net.Sockets.SocketException) if (e.Exception is SshConnectionException || e.Exception is System.Net.Sockets.SocketException)
@@ -451,27 +451,27 @@ namespace PepperDash.Core
ReconnectTimer.Reset(AutoReconnectIntervalMs); ReconnectTimer.Reset(AutoReconnectIntervalMs);
} }
}); });
} }
/// <summary> /// <summary>
/// Helper for ConnectionChange event /// Helper for ConnectionChange event
/// </summary> /// </summary>
void OnConnectionChange() void OnConnectionChange()
{ {
if (ConnectionChange != null) if (ConnectionChange != null)
ConnectionChange(this, new GenericSocketStatusChageEventArgs(this)); ConnectionChange(this, new GenericSocketStatusChageEventArgs(this));
} }
#region IBasicCommunication Members #region IBasicCommunication Members
/// <summary> /// <summary>
/// Sends text to the server /// Sends text to the server
/// </summary> /// </summary>
/// <param name="text"></param> /// <param name="text"></param>
public void SendText(string text) public void SendText(string text)
{ {
try try
{ {
if (Client != null && TheStream != null && IsConnected) if (Client != null && TheStream != null && IsConnected)
{ {
if (StreamDebugging.TxStreamDebuggingIsEnabled) if (StreamDebugging.TxStreamDebuggingIsEnabled)
@@ -485,24 +485,24 @@ namespace PepperDash.Core
{ {
Debug.Console(1, this, "Client is null or disconnected. Cannot Send Text"); Debug.Console(1, this, "Client is null or disconnected. Cannot Send Text");
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(0, "Exception: {0}", ex.Message); Debug.Console(0, "Exception: {0}", ex.Message);
Debug.Console(0, "Stack Trace: {0}", ex.StackTrace); Debug.Console(0, "Stack Trace: {0}", ex.StackTrace);
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed. Disconnected, closing"); Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed. Disconnected, closing");
} }
} }
/// <summary> /// <summary>
/// Sends Bytes to the server /// Sends Bytes to the server
/// </summary> /// </summary>
/// <param name="bytes"></param> /// <param name="bytes"></param>
public void SendBytes(byte[] bytes) public void SendBytes(byte[] bytes)
{ {
try try
{ {
if (Client != null && TheStream != null && IsConnected) if (Client != null && TheStream != null && IsConnected)
{ {
if (StreamDebugging.TxStreamDebuggingIsEnabled) if (StreamDebugging.TxStreamDebuggingIsEnabled)
@@ -515,23 +515,23 @@ namespace PepperDash.Core
{ {
Debug.Console(1, this, "Client is null or disconnected. Cannot Send Bytes"); Debug.Console(1, this, "Client is null or disconnected. Cannot Send Bytes");
} }
} }
catch catch
{ {
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed. Disconnected, closing"); Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed. Disconnected, closing");
} }
} }
#endregion #endregion
} }
//***************************************************************************************************** //*****************************************************************************************************
//***************************************************************************************************** //*****************************************************************************************************
/// <summary> /// <summary>
/// Fired when connection changes /// Fired when connection changes
/// </summary> /// </summary>
public class SshConnectionChangeEventArgs : EventArgs public class SshConnectionChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// Connection State /// Connection State
/// </summary> /// </summary>
@@ -552,10 +552,10 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public ushort Status { get { return Client.UStatus; } } public ushort Status { get { return Client.UStatus; } }
/// <summary> /// <summary>
/// S+ Constructor /// S+ Constructor
/// </summary> /// </summary>
public SshConnectionChangeEventArgs() { } public SshConnectionChangeEventArgs() { }
/// <summary> /// <summary>
/// EventArgs class /// EventArgs class
@@ -563,9 +563,9 @@ namespace PepperDash.Core
/// <param name="isConnected">Connection State</param> /// <param name="isConnected">Connection State</param>
/// <param name="client">The Client</param> /// <param name="client">The Client</param>
public SshConnectionChangeEventArgs(bool isConnected, GenericSshClient client) public SshConnectionChangeEventArgs(bool isConnected, GenericSshClient client)
{ {
IsConnected = isConnected; IsConnected = isConnected;
Client = client; Client = client;
} }
} }
} }

View File

@@ -1,14 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core.Logging;
using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// A class to handle basic TCP/IP communications with a server /// A class to handle basic TCP/IP communications with a server
@@ -21,44 +21,44 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public CommunicationStreamDebugging StreamDebugging { get; private set; } public CommunicationStreamDebugging StreamDebugging { get; private set; }
/// <summary> /// <summary>
/// Fires when data is received from the server and returns it as a Byte array /// Fires when data is received from the server and returns it as a Byte array
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived; public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
/// <summary> /// <summary>
/// Fires when data is received from the server and returns it as text /// Fires when data is received from the server and returns it as text
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived; public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
//public event GenericSocketStatusChangeEventDelegate SocketStatusChange; //public event GenericSocketStatusChangeEventDelegate SocketStatusChange;
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange; public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
private string _hostname; private string _hostname;
/// <summary> /// <summary>
/// Address of server /// Address of server
/// </summary> /// </summary>
public string Hostname public string Hostname
{ {
get get
{ {
return _hostname; return _hostname;
} }
set set
{ {
_hostname = value; _hostname = value;
if (_client != null) if (_client != null)
{ {
_client.AddressClientConnectedTo = _hostname; _client.AddressClientConnectedTo = _hostname;
} }
} }
} }
/// <summary> /// <summary>
/// Port on server /// Port on server
@@ -80,15 +80,15 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public int BufferSize { get; set; } public int BufferSize { get; set; }
/// <summary> /// <summary>
/// The actual client class /// The actual client class
/// </summary> /// </summary>
private TCPClient _client; private TCPClient _client;
/// <summary> /// <summary>
/// Bool showing if socket is connected /// Bool showing if socket is connected
/// </summary> /// </summary>
public bool IsConnected public bool IsConnected
{ {
get { return _client != null && _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } get { return _client != null && _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
} }
@@ -101,10 +101,10 @@ namespace PepperDash.Core
get { return (ushort)(IsConnected ? 1 : 0); } get { return (ushort)(IsConnected ? 1 : 0); }
} }
/// <summary> /// <summary>
/// _client socket status Read only /// _client socket status Read only
/// </summary> /// </summary>
public SocketStatus ClientStatus public SocketStatus ClientStatus
{ {
get get
{ {
@@ -121,26 +121,26 @@ namespace PepperDash.Core
get { return (ushort)ClientStatus; } get { return (ushort)ClientStatus; }
} }
/// <summary> /// <summary>
/// Status text shows the message associated with socket status /// Status text shows the message associated with socket status
/// </summary> /// </summary>
public string ClientStatusText { get { return ClientStatus.ToString(); } } public string ClientStatusText { get { return ClientStatus.ToString(); } }
/// <summary> /// <summary>
/// Ushort representation of client status /// Ushort representation of client status
/// </summary> /// </summary>
[Obsolete] [Obsolete]
public ushort UClientStatus { get { return (ushort)ClientStatus; } } public ushort UClientStatus { get { return (ushort)ClientStatus; } }
/// <summary> /// <summary>
/// Connection failure reason /// Connection failure reason
/// </summary> /// </summary>
public string ConnectionFailure { get { return ClientStatus.ToString(); } } public string ConnectionFailure { get { return ClientStatus.ToString(); } }
/// <summary> /// <summary>
/// bool to track if auto reconnect should be set on the socket /// bool to track if auto reconnect should be set on the socket
/// </summary> /// </summary>
public bool AutoReconnect { get; set; } public bool AutoReconnect { get; set; }
/// <summary> /// <summary>
/// S+ helper for AutoReconnect /// S+ helper for AutoReconnect
@@ -151,29 +151,29 @@ namespace PepperDash.Core
set { AutoReconnect = value == 1; } set { AutoReconnect = value == 1; }
} }
/// <summary> /// <summary>
/// Milliseconds to wait before attempting to reconnect. Defaults to 5000 /// Milliseconds to wait before attempting to reconnect. Defaults to 5000
/// </summary> /// </summary>
public int AutoReconnectIntervalMs { get; set; } public int AutoReconnectIntervalMs { get; set; }
/// <summary> /// <summary>
/// Set only when the disconnect method is called /// Set only when the disconnect method is called
/// </summary> /// </summary>
bool DisconnectCalledByUser; bool DisconnectCalledByUser;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public bool Connected public bool Connected
{ {
get { return _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } get { return _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
} }
//Lock object to prevent simulatneous connect/disconnect operations //Lock object to prevent simulatneous connect/disconnect operations
private CCriticalSection connectLock = new CCriticalSection(); private CCriticalSection connectLock = new CCriticalSection();
// private Timer for auto reconnect // private Timer for auto reconnect
private CTimer RetryTimer; private CTimer RetryTimer;
/// <summary> /// <summary>
/// Constructor /// Constructor
@@ -183,8 +183,8 @@ namespace PepperDash.Core
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="bufferSize"></param> /// <param name="bufferSize"></param>
public GenericTcpIpClient(string key, string address, int port, int bufferSize) public GenericTcpIpClient(string key, string address, int port, int bufferSize)
: base(key) : base(key)
{ {
StreamDebugging = new CommunicationStreamDebugging(key); StreamDebugging = new CommunicationStreamDebugging(key);
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
AutoReconnectIntervalMs = 5000; AutoReconnectIntervalMs = 5000;
@@ -220,17 +220,17 @@ namespace PepperDash.Core
/// Default constructor for S+ /// Default constructor for S+
/// </summary> /// </summary>
public GenericTcpIpClient() public GenericTcpIpClient()
: base(SplusKey) : base(SplusKey)
{ {
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
AutoReconnectIntervalMs = 5000; AutoReconnectIntervalMs = 5000;
BufferSize = 2000; BufferSize = 2000;
RetryTimer = new CTimer(o => RetryTimer = new CTimer(o =>
{ {
Reconnect(); Reconnect();
}, Timeout.Infinite); }, Timeout.Infinite);
} }
/// <summary> /// <summary>
/// Just to help S+ set the key /// Just to help S+ set the key
@@ -257,22 +257,22 @@ namespace PepperDash.Core
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public override bool Deactivate() public override bool Deactivate()
{ {
RetryTimer.Stop(); RetryTimer.Stop();
RetryTimer.Dispose(); RetryTimer.Dispose();
if (_client != null) if (_client != null)
{ {
_client.SocketStatusChange -= this.Client_SocketStatusChange; _client.SocketStatusChange -= Client_SocketStatusChange;
DisconnectClient(); DisconnectClient();
} }
return true; return true;
} }
/// <summary> /// <summary>
/// Attempts to connect to the server /// Attempts to connect to the server
/// </summary> /// </summary>
public void Connect() public void Connect()
{ {
if (string.IsNullOrEmpty(Hostname)) if (string.IsNullOrEmpty(Hostname))
{ {
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericTcpIpClient '{0}': No address set", Key); Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericTcpIpClient '{0}': No address set", Key);
@@ -308,7 +308,7 @@ namespace PepperDash.Core
{ {
connectLock.Leave(); connectLock.Leave();
} }
} }
private void Reconnect() private void Reconnect()
{ {
@@ -339,7 +339,7 @@ namespace PepperDash.Core
/// Attempts to disconnect the client /// Attempts to disconnect the client
/// </summary> /// </summary>
public void Disconnect() public void Disconnect()
{ {
try try
{ {
connectLock.Enter(); connectLock.Enter();
@@ -353,7 +353,7 @@ namespace PepperDash.Core
{ {
connectLock.Leave(); connectLock.Leave();
} }
} }
/// <summary> /// <summary>
/// Does the actual disconnect business /// Does the actual disconnect business
@@ -373,7 +373,7 @@ namespace PepperDash.Core
/// </summary> /// </summary>
/// <param name="c"></param> /// <param name="c"></param>
void ConnectToServerCallback(TCPClient c) void ConnectToServerCallback(TCPClient c)
{ {
if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED) if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
{ {
Debug.Console(0, this, "Server connection result: {0}", c.ClientStatus); Debug.Console(0, this, "Server connection result: {0}", c.ClientStatus);
@@ -383,13 +383,13 @@ namespace PepperDash.Core
{ {
Debug.Console(1, this, "Server connection result: {0}", c.ClientStatus); Debug.Console(1, this, "Server connection result: {0}", c.ClientStatus);
} }
} }
/// <summary> /// <summary>
/// Disconnects, waits and attemtps to connect again /// Disconnects, waits and attemtps to connect again
/// </summary> /// </summary>
void WaitAndTryReconnect() void WaitAndTryReconnect()
{ {
CrestronInvoke.BeginInvoke(o => CrestronInvoke.BeginInvoke(o =>
{ {
try try
@@ -407,7 +407,7 @@ namespace PepperDash.Core
connectLock.Leave(); connectLock.Leave();
} }
}); });
} }
/// <summary> /// <summary>
/// Recieves incoming data /// Recieves incoming data
@@ -415,7 +415,7 @@ namespace PepperDash.Core
/// <param name="client"></param> /// <param name="client"></param>
/// <param name="numBytes"></param> /// <param name="numBytes"></param>
void Receive(TCPClient client, int numBytes) void Receive(TCPClient client, int numBytes)
{ {
if (client != null) if (client != null)
{ {
if (numBytes > 0) if (numBytes > 0)
@@ -445,45 +445,45 @@ namespace PepperDash.Core
} }
client.ReceiveDataAsync(Receive); client.ReceiveDataAsync(Receive);
} }
} }
/// <summary> /// <summary>
/// General send method /// General send method
/// </summary> /// </summary>
public void SendText(string text) public void SendText(string text)
{ {
var bytes = Encoding.GetEncoding(28591).GetBytes(text); var bytes = Encoding.GetEncoding(28591).GetBytes(text);
// Check debug level before processing byte array // Check debug level before processing byte array
if (StreamDebugging.TxStreamDebuggingIsEnabled) if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text)); Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
if (_client != null) if (_client != null)
_client.SendData(bytes, bytes.Length); _client.SendData(bytes, bytes.Length);
} }
/// <summary> /// <summary>
/// This is useful from console and...? /// This is useful from console and...?
/// </summary> /// </summary>
public void SendEscapedText(string text) public void SendEscapedText(string text)
{ {
var unescapedText = Regex.Replace(text, @"\\x([0-9a-fA-F][0-9a-fA-F])", s => var unescapedText = Regex.Replace(text, @"\\x([0-9a-fA-F][0-9a-fA-F])", s =>
{ {
var hex = s.Groups[1].Value; var hex = s.Groups[1].Value;
return ((char)Convert.ToByte(hex, 16)).ToString(); return ((char)Convert.ToByte(hex, 16)).ToString();
}); });
SendText(unescapedText); SendText(unescapedText);
} }
/// <summary> /// <summary>
/// Sends Bytes to the server /// Sends Bytes to the server
/// </summary> /// </summary>
/// <param name="bytes"></param> /// <param name="bytes"></param>
public void SendBytes(byte[] bytes) public void SendBytes(byte[] bytes)
{ {
if (StreamDebugging.TxStreamDebuggingIsEnabled) if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes)); Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
if (_client != null) if (_client != null)
_client.SendData(bytes, bytes.Length); _client.SendData(bytes, bytes.Length);
} }
/// <summary> /// <summary>
/// Socket Status Change Handler /// Socket Status Change Handler
@@ -491,7 +491,7 @@ namespace PepperDash.Core
/// <param name="client"></param> /// <param name="client"></param>
/// <param name="clientSocketStatus"></param> /// <param name="clientSocketStatus"></param>
void Client_SocketStatusChange(TCPClient client, SocketStatus clientSocketStatus) void Client_SocketStatusChange(TCPClient client, SocketStatus clientSocketStatus)
{ {
if (clientSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) if (clientSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
{ {
Debug.Console(0, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText); Debug.Console(0, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText);
@@ -500,68 +500,68 @@ namespace PepperDash.Core
else else
{ {
Debug.Console(1, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText); Debug.Console(1, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText);
_client.ReceiveDataAsync(Receive); _client.ReceiveDataAsync(Receive);
} }
var handler = ConnectionChange; var handler = ConnectionChange;
if (handler != null) if (handler != null)
ConnectionChange(this, new GenericSocketStatusChageEventArgs(this)); ConnectionChange(this, new GenericSocketStatusChageEventArgs(this));
} }
} }
/// <summary> /// <summary>
/// Configuration properties for TCP/SSH Connections /// Configuration properties for TCP/SSH Connections
/// </summary> /// </summary>
public class TcpSshPropertiesConfig public class TcpSshPropertiesConfig
{ {
/// <summary> /// <summary>
/// Address to connect to /// Address to connect to
/// </summary> /// </summary>
[JsonProperty(Required = Required.Always)] [JsonProperty(Required = Required.Always)]
public string Address { get; set; } public string Address { get; set; }
/// <summary> /// <summary>
/// Port to connect to /// Port to connect to
/// </summary> /// </summary>
[JsonProperty(Required = Required.Always)] [JsonProperty(Required = Required.Always)]
public int Port { get; set; } public int Port { get; set; }
/// <summary> /// <summary>
/// Username credential /// Username credential
/// </summary> /// </summary>
public string Username { get; set; } public string Username { get; set; }
/// <summary> /// <summary>
/// Passord credential /// Passord credential
/// </summary> /// </summary>
public string Password { get; set; } public string Password { get; set; }
/// <summary> /// <summary>
/// Defaults to 32768 /// Defaults to 32768
/// </summary> /// </summary>
public int BufferSize { get; set; } public int BufferSize { get; set; }
/// <summary> /// <summary>
/// Defaults to true /// Defaults to true
/// </summary> /// </summary>
public bool AutoReconnect { get; set; } public bool AutoReconnect { get; set; }
/// <summary> /// <summary>
/// Defaults to 5000ms /// Defaults to 5000ms
/// </summary> /// </summary>
public int AutoReconnectIntervalMs { get; set; } public int AutoReconnectIntervalMs { get; set; }
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
public TcpSshPropertiesConfig() public TcpSshPropertiesConfig()
{ {
BufferSize = 32768; BufferSize = 32768;
AutoReconnect = true; AutoReconnect = true;
AutoReconnectIntervalMs = 5000; AutoReconnectIntervalMs = 5000;
Username = ""; Username = "";
Password = ""; Password = "";
} }
} }
} }

View File

@@ -10,15 +10,14 @@ of this material by another party without the express written permission of Pepp
PepperDash Technology Corporation reserves all rights under applicable laws. PepperDash Technology Corporation reserves all rights under applicable laws.
------------------------------------ */ ------------------------------------ */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using PepperDash.Core.Logging;
using System;
using System.Linq;
using System.Text;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Generic TCP/IP client for server /// Generic TCP/IP client for server
@@ -361,8 +360,8 @@ namespace PepperDash.Core
Client = new TCPClient(Hostname, Port, BufferSize); Client = new TCPClient(Hostname, Port, BufferSize);
Client.SocketStatusChange += Client_SocketStatusChange; Client.SocketStatusChange += Client_SocketStatusChange;
if(HeartbeatEnabled) if (HeartbeatEnabled)
Client.SocketSendOrReceiveTimeOutInMs = (HeartbeatInterval * 5); Client.SocketSendOrReceiveTimeOutInMs = HeartbeatInterval * 5;
Client.AddressClientConnectedTo = Hostname; Client.AddressClientConnectedTo = Hostname;
Client.PortNumber = Port; Client.PortNumber = Port;
// SecureClient = c; // SecureClient = c;
@@ -385,7 +384,7 @@ namespace PepperDash.Core
} }
}, 30000); }, 30000);
Debug.Console(2, this, "Making Connection Count:{0}", ConnectionCount); Debug.Console(2, this, "Making Connection Count:{0}", ConnectionCount);
Client.ConnectToServerAsync(o => Client.ConnectToServerAsync(o =>
{ {
Debug.Console(2, this, "ConnectToServerAsync Count:{0} Ran!", ConnectionCount); Debug.Console(2, this, "ConnectToServerAsync Count:{0} Ran!", ConnectionCount);
@@ -563,15 +562,15 @@ namespace PepperDash.Core
{ {
if (HeartbeatEnabled) if (HeartbeatEnabled)
{ {
Debug.Console(2, this, "Starting Heartbeat"); Debug.Console(2, this, "Starting Heartbeat");
if (HeartbeatSendTimer == null) if (HeartbeatSendTimer == null)
{ {
HeartbeatSendTimer = new CTimer(this.SendHeartbeat, null, HeartbeatInterval, HeartbeatInterval); HeartbeatSendTimer = new CTimer(SendHeartbeat, null, HeartbeatInterval, HeartbeatInterval);
} }
if (HeartbeatAckTimer == null) if (HeartbeatAckTimer == null)
{ {
HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, (HeartbeatInterval * 2), (HeartbeatInterval * 2)); HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, HeartbeatInterval * 2, HeartbeatInterval * 2);
} }
} }
@@ -581,7 +580,7 @@ namespace PepperDash.Core
if (HeartbeatSendTimer != null) if (HeartbeatSendTimer != null)
{ {
Debug.Console(2, this, "Stoping Heartbeat Send"); Debug.Console(2, this, "Stoping Heartbeat Send");
HeartbeatSendTimer.Stop(); HeartbeatSendTimer.Stop();
HeartbeatSendTimer = null; HeartbeatSendTimer = null;
} }
@@ -595,7 +594,7 @@ namespace PepperDash.Core
} }
void SendHeartbeat(object notused) void SendHeartbeat(object notused)
{ {
this.SendText(HeartbeatString); SendText(HeartbeatString);
Debug.Console(2, this, "Sending Heartbeat"); Debug.Console(2, this, "Sending Heartbeat");
} }
@@ -619,7 +618,7 @@ namespace PepperDash.Core
} }
else else
{ {
HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, (HeartbeatInterval * 2), (HeartbeatInterval * 2)); HeartbeatAckTimer = new CTimer(HeartbeatAckTimerFail, null, HeartbeatInterval * 2, HeartbeatInterval * 2);
} }
Debug.Console(2, this, "Heartbeat Received: {0}, from Server", HeartbeatString); Debug.Console(2, this, "Heartbeat Received: {0}, from Server", HeartbeatString);
return remainingText; return remainingText;
@@ -684,7 +683,7 @@ namespace PepperDash.Core
// HOW IN THE HELL DO WE CATCH AN EXCEPTION IN SENDING????? // HOW IN THE HELL DO WE CATCH AN EXCEPTION IN SENDING?????
if (n <= 0) if (n <= 0)
{ {
Debug.Console(1, Debug.ErrorLogLevel.Warning, "[{0}] Sent zero bytes. Was there an error?", this.Key); Debug.Console(1, Debug.ErrorLogLevel.Warning, "[{0}] Sent zero bytes. Was there an error?", Key);
} }
}); });
} }
@@ -729,7 +728,7 @@ namespace PepperDash.Core
} }
try try
{ {
Debug.Console(2, this, "Socket status change: {0} ({1})", client.ClientStatus, (ushort)(client.ClientStatus)); Debug.Console(2, this, "Socket status change: {0} ({1})", client.ClientStatus, (ushort)client.ClientStatus);
OnConnectionChange(); OnConnectionChange();
@@ -763,7 +762,7 @@ namespace PepperDash.Core
void OnClientReadyForcommunications(bool isReady) void OnClientReadyForcommunications(bool isReady)
{ {
IsReadyForCommunication = isReady; IsReadyForCommunication = isReady;
if (this.IsReadyForCommunication) { HeartbeatStart(); } if (IsReadyForCommunication) { HeartbeatStart(); }
var handler = ClientReadyForCommunications; var handler = ClientReadyForCommunications;
if (handler != null) if (handler != null)
handler(this, new GenericTcpServerClientReadyForcommunicationsEventArgs(IsReadyForCommunication)); handler(this, new GenericTcpServerClientReadyForcommunicationsEventArgs(IsReadyForCommunication));

View File

@@ -10,16 +10,15 @@ of this material by another party without the express written permission of Pepp
PepperDash Technology Corporation reserves all rights under applicable laws. PepperDash Technology Corporation reserves all rights under applicable laws.
------------------------------------ */ ------------------------------------ */
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
using PepperDash.Core.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Generic TCP/IP server device /// Generic TCP/IP server device
@@ -238,7 +237,7 @@ namespace PepperDash.Core
/// <summary> /// <summary>
/// Simpl+ Heartbeat Analog value in seconds /// Simpl+ Heartbeat Analog value in seconds
/// </summary> /// </summary>
public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatRequiredIntervalMs = (value * 1000); } } public ushort HeartbeatRequiredIntervalInSeconds { set { HeartbeatRequiredIntervalMs = value * 1000; } }
/// <summary> /// <summary>
/// String to Match for heartbeat. If null or empty any string will reset heartbeat timer /// String to Match for heartbeat. If null or empty any string will reset heartbeat timer
@@ -402,10 +401,10 @@ namespace PepperDash.Core
if (myTcpServer == null) if (myTcpServer == null)
{ {
myTcpServer = new TCPServer(Port, MaxClients); myTcpServer = new TCPServer(Port, MaxClients);
if(HeartbeatRequired) if (HeartbeatRequired)
myTcpServer.SocketSendOrReceiveTimeOutInMs = (this.HeartbeatRequiredIntervalMs * 5); myTcpServer.SocketSendOrReceiveTimeOutInMs = HeartbeatRequiredIntervalMs * 5;
// myTcpServer.HandshakeTimeout = 30; // myTcpServer.HandshakeTimeout = 30;
} }
else else
{ {
@@ -445,9 +444,9 @@ namespace PepperDash.Core
{ {
myTcpServer.Stop(); myTcpServer.Stop();
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Server State: {0}", myTcpServer.State); Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Server State: {0}", myTcpServer.State);
OnServerStateChange(myTcpServer.State); OnServerStateChange(myTcpServer.State);
} }
ServerStopped = true; ServerStopped = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -525,7 +524,7 @@ namespace PepperDash.Core
byte[] b = Encoding.GetEncoding(28591).GetBytes(text); byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
foreach (uint i in ConnectedClientsIndexes) foreach (uint i in ConnectedClientsIndexes)
{ {
if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(i))) if (!SharedKeyRequired || SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(i))
{ {
SocketErrorCodes error = myTcpServer.SendDataAsync(i, b, b.Length, (x, y, z) => { }); SocketErrorCodes error = myTcpServer.SendDataAsync(i, b, b.Length, (x, y, z) => { });
if (error != SocketErrorCodes.SOCKET_OK && error != SocketErrorCodes.SOCKET_OPERATION_PENDING) if (error != SocketErrorCodes.SOCKET_OK && error != SocketErrorCodes.SOCKET_OPERATION_PENDING)
@@ -554,7 +553,7 @@ namespace PepperDash.Core
byte[] b = Encoding.GetEncoding(28591).GetBytes(text); byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
if (myTcpServer != null && myTcpServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) if (myTcpServer != null && myTcpServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
{ {
if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))) if (!SharedKeyRequired || SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))
myTcpServer.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { }); myTcpServer.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { });
} }
} }
@@ -618,9 +617,9 @@ namespace PepperDash.Core
public string GetClientIPAddress(uint clientIndex) public string GetClientIPAddress(uint clientIndex)
{ {
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress Index: {0}", clientIndex); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress Index: {0}", clientIndex);
if (!SharedKeyRequired || (SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))) if (!SharedKeyRequired || SharedKeyRequired && ClientReadyAfterKeyExchange.Contains(clientIndex))
{ {
var ipa = this.myTcpServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex); var ipa = myTcpServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex);
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress IPAddreess: {0}", ipa); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "GetClientIPAddress IPAddreess: {0}", ipa);
return ipa; return ipa;
@@ -645,7 +644,7 @@ namespace PepperDash.Core
address = myTcpServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex); address = myTcpServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex);
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Heartbeat not received for Client index {2} IP: {0}, DISCONNECTING BECAUSE HEARTBEAT REQUIRED IS TRUE {1}", Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Heartbeat not received for Client index {2} IP: {0}, DISCONNECTING BECAUSE HEARTBEAT REQUIRED IS TRUE {1}",
address, string.IsNullOrEmpty(HeartbeatStringToMatch) ? "" : ("HeartbeatStringToMatch: " + HeartbeatStringToMatch), clientIndex); address, string.IsNullOrEmpty(HeartbeatStringToMatch) ? "" : "HeartbeatStringToMatch: " + HeartbeatStringToMatch, clientIndex);
if (myTcpServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) if (myTcpServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
SendTextToClient("Heartbeat not received by server, closing connection", clientIndex); SendTextToClient("Heartbeat not received by server, closing connection", clientIndex);
@@ -680,7 +679,7 @@ namespace PepperDash.Core
try try
{ {
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange Index:{0} status:{1} Port:{2} IP:{3}", clientIndex, serverSocketStatus, this.myTcpServer.GetPortNumberServerAcceptedConnectionFromForSpecificClient(clientIndex), this.myTcpServer.GetLocalAddressServerAcceptedConnectionFromForSpecificClient(clientIndex)); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange Index:{0} status:{1} Port:{2} IP:{3}", clientIndex, serverSocketStatus, myTcpServer.GetPortNumberServerAcceptedConnectionFromForSpecificClient(clientIndex), myTcpServer.GetLocalAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
{ {
if (ConnectedClientsIndexes.Contains(clientIndex)) if (ConnectedClientsIndexes.Contains(clientIndex))
@@ -693,8 +692,8 @@ namespace PepperDash.Core
} }
if (ClientReadyAfterKeyExchange.Contains(clientIndex)) if (ClientReadyAfterKeyExchange.Contains(clientIndex))
ClientReadyAfterKeyExchange.Remove(clientIndex); ClientReadyAfterKeyExchange.Remove(clientIndex);
if (WaitingForSharedKey.Contains(clientIndex)) if (WaitingForSharedKey.Contains(clientIndex))
WaitingForSharedKey.Remove(clientIndex); WaitingForSharedKey.Remove(clientIndex);
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -790,48 +789,48 @@ namespace PepperDash.Core
/// <param name="numberOfBytesReceived"></param> /// <param name="numberOfBytesReceived"></param>
void TcpServerReceivedDataAsyncCallback(TCPServer myTCPServer, uint clientIndex, int numberOfBytesReceived) void TcpServerReceivedDataAsyncCallback(TCPServer myTCPServer, uint clientIndex, int numberOfBytesReceived)
{ {
if (numberOfBytesReceived > 0) if (numberOfBytesReceived > 0)
{ {
string received = "Nothing"; string received = "Nothing";
try try
{ {
byte[] bytes = myTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex); byte[] bytes = myTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex);
received = System.Text.Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived); received = Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived);
if (WaitingForSharedKey.Contains(clientIndex)) if (WaitingForSharedKey.Contains(clientIndex))
{ {
received = received.Replace("\r", ""); received = received.Replace("\r", "");
received = received.Replace("\n", ""); received = received.Replace("\n", "");
if (received != SharedKey) if (received != SharedKey)
{ {
byte[] b = Encoding.GetEncoding(28591).GetBytes("Shared key did not match server. Disconnecting"); byte[] b = Encoding.GetEncoding(28591).GetBytes("Shared key did not match server. Disconnecting");
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Client at index {0} Shared key did not match the server, disconnecting client. Key: {1}", clientIndex, received); Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Client at index {0} Shared key did not match the server, disconnecting client. Key: {1}", clientIndex, received);
myTCPServer.SendData(clientIndex, b, b.Length); myTCPServer.SendData(clientIndex, b, b.Length);
myTCPServer.Disconnect(clientIndex); myTCPServer.Disconnect(clientIndex);
return; return;
} }
WaitingForSharedKey.Remove(clientIndex); WaitingForSharedKey.Remove(clientIndex);
byte[] success = Encoding.GetEncoding(28591).GetBytes("Shared Key Match"); byte[] success = Encoding.GetEncoding(28591).GetBytes("Shared Key Match");
myTCPServer.SendDataAsync(clientIndex, success, success.Length, null); myTCPServer.SendDataAsync(clientIndex, success, success.Length, null);
OnServerClientReadyForCommunications(clientIndex); OnServerClientReadyForCommunications(clientIndex);
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Client with index {0} provided the shared key and successfully connected to the server", clientIndex); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Client with index {0} provided the shared key and successfully connected to the server", clientIndex);
} }
else if (!string.IsNullOrEmpty(checkHeartbeat(clientIndex, received))) else if (!string.IsNullOrEmpty(checkHeartbeat(clientIndex, received)))
onTextReceived(received, clientIndex); onTextReceived(received, clientIndex);
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Receiving data: {0}. Error: {1}", received, ex); Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Receiving data: {0}. Error: {1}", received, ex);
} }
if (myTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) if (myTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
myTCPServer.ReceiveDataAsync(clientIndex, TcpServerReceivedDataAsyncCallback); myTCPServer.ReceiveDataAsync(clientIndex, TcpServerReceivedDataAsyncCallback);
} }
else else
{ {
// If numberOfBytesReceived <= 0 // If numberOfBytesReceived <= 0
myTCPServer.Disconnect(); myTCPServer.Disconnect();
} }
} }
@@ -938,8 +937,8 @@ namespace PepperDash.Core
void RunMonitorClient() void RunMonitorClient()
{ {
MonitorClient = new GenericTcpIpClient_ForServer(Key + "-MONITOR", "127.0.0.1", Port, 2000); MonitorClient = new GenericTcpIpClient_ForServer(Key + "-MONITOR", "127.0.0.1", Port, 2000);
MonitorClient.SharedKeyRequired = this.SharedKeyRequired; MonitorClient.SharedKeyRequired = SharedKeyRequired;
MonitorClient.SharedKey = this.SharedKey; MonitorClient.SharedKey = SharedKey;
MonitorClient.ConnectionHasHungCallback = MonitorClientHasHungCallback; MonitorClient.ConnectionHasHungCallback = MonitorClientHasHungCallback;
//MonitorClient.ConnectionChange += MonitorClient_ConnectionChange; //MonitorClient.ConnectionChange += MonitorClient_ConnectionChange;
MonitorClient.ClientReadyForCommunications += MonitorClient_IsReadyForComm; MonitorClient.ClientReadyForCommunications += MonitorClient_IsReadyForComm;

View File

@@ -1,21 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using PepperDash.Core.Logging;
using System;
using System.Linq;
using System.Text;
namespace PepperDash.Core.Comm
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Generic UDP Server device /// Generic UDP Server device
@@ -233,7 +225,7 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public void Disconnect() public void Disconnect()
{ {
if(Server != null) if (Server != null)
Server.DisableUDPServer(); Server.DisableUDPServer();
IsConnected = false; IsConnected = false;
@@ -331,7 +323,7 @@ namespace PepperDash.Core
/// ///
/// </summary> /// </summary>
public class GenericUdpReceiveTextExtraArgs : EventArgs public class GenericUdpReceiveTextExtraArgs : EventArgs
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -343,7 +335,7 @@ namespace PepperDash.Core
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int Port { get; private set; } public int Port { get; private set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -357,18 +349,18 @@ namespace PepperDash.Core
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="bytes"></param> /// <param name="bytes"></param>
public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes) public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes)
{ {
Text = text; Text = text;
IpAddress = ipAddress; IpAddress = ipAddress;
Port = port; Port = port;
Bytes = bytes; Bytes = bytes;
} }
/// <summary> /// <summary>
/// Stupid S+ Constructor /// Stupid S+ Constructor
/// </summary> /// </summary>
public GenericUdpReceiveTextExtraArgs() { } public GenericUdpReceiveTextExtraArgs() { }
} }
/// <summary> /// <summary>
/// ///

View File

@@ -1,10 +1,9 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic; using PepperDash.Core.Interfaces;
using System.Linq; using PepperDash.Core.Logging;
using System.Text; using System;
using Crestron.SimplSharp;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Allows for two simultaneous TCP clients to connect to a redundant pair of QSC Core DSPs and manages /// Allows for two simultaneous TCP clients to connect to a redundant pair of QSC Core DSPs and manages

View File

@@ -2,7 +2,7 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace PepperDash.Core namespace PepperDash.Core.Comm
{ {
/// <summary> /// <summary>
/// Client config object for TCP client with server that inherits from TcpSshPropertiesConfig and adds properties for shared key and heartbeat /// Client config object for TCP client with server that inherits from TcpSshPropertiesConfig and adds properties for shared key and heartbeat

View File

@@ -1,10 +1,4 @@
using System; namespace PepperDash.Core.Comm
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Tcp Server Config object with properties for a tcp server with shared key and heartbeat capabilities /// Tcp Server Config object with properties for a tcp server with shared key and heartbeat capabilities

View File

@@ -1,10 +1,4 @@
using System; namespace PepperDash.Core.Comm
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Crestron Control Methods for a comm object /// Crestron Control Methods for a comm object

View File

@@ -1,243 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core
{
/// <summary>
/// An incoming communication stream
/// </summary>
public interface ICommunicationReceiver : IKeyed
{
/// <summary>
/// Notifies of bytes received
/// </summary>
event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
/// <summary>
/// Notifies of text received
/// </summary>
event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
/// <summary>
/// Indicates connection status
/// </summary>
bool IsConnected { get; }
/// <summary>
/// Connect to the device
/// </summary>
void Connect();
/// <summary>
/// Disconnect from the device
/// </summary>
void Disconnect();
}
/// <summary>
/// Represents a device that uses basic connection
/// </summary>
public interface IBasicCommunication : ICommunicationReceiver
{
/// <summary>
/// Send text to the device
/// </summary>
/// <param name="text"></param>
void SendText(string text);
/// <summary>
/// Send bytes to the device
/// </summary>
/// <param name="bytes"></param>
void SendBytes(byte[] bytes);
}
/// <summary>
/// Represents a device that implements IBasicCommunication and IStreamDebugging
/// </summary>
public interface IBasicCommunicationWithStreamDebugging : IBasicCommunication, IStreamDebugging
{
}
/// <summary>
/// Represents a device with stream debugging capablities
/// </summary>
public interface IStreamDebugging
{
/// <summary>
/// Object to enable stream debugging
/// </summary>
CommunicationStreamDebugging StreamDebugging { get; }
}
/// <summary>
/// For IBasicCommunication classes that have SocketStatus. GenericSshClient,
/// GenericTcpIpClient
/// </summary>
public interface ISocketStatus : IBasicCommunication
{
/// <summary>
/// Notifies of socket status changes
/// </summary>
event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
/// <summary>
/// The current socket status of the client
/// </summary>
SocketStatus ClientStatus { get; }
}
/// <summary>
/// Describes a device that implements ISocketStatus and IStreamDebugging
/// </summary>
public interface ISocketStatusWithStreamDebugging : ISocketStatus, IStreamDebugging
{
}
/// <summary>
/// Describes a device that can automatically attempt to reconnect
/// </summary>
public interface IAutoReconnect
{
/// <summary>
/// Enable automatic recconnect
/// </summary>
bool AutoReconnect { get; set; }
/// <summary>
/// Interval in ms to attempt automatic recconnections
/// </summary>
int AutoReconnectIntervalMs { get; set; }
}
/// <summary>
///
/// </summary>
public enum eGenericCommMethodStatusChangeType
{
/// <summary>
/// Connected
/// </summary>
Connected,
/// <summary>
/// Disconnected
/// </summary>
Disconnected
}
/// <summary>
/// This delegate defines handler for IBasicCommunication status changes
/// </summary>
/// <param name="comm">Device firing the status change</param>
/// <param name="status"></param>
public delegate void GenericCommMethodStatusHandler(IBasicCommunication comm, eGenericCommMethodStatusChangeType status);
/// <summary>
///
/// </summary>
public class GenericCommMethodReceiveBytesArgs : EventArgs
{
/// <summary>
///
/// </summary>
public byte[] Bytes { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="bytes"></param>
public GenericCommMethodReceiveBytesArgs(byte[] bytes)
{
Bytes = bytes;
}
/// <summary>
/// S+ Constructor
/// </summary>
public GenericCommMethodReceiveBytesArgs() { }
}
/// <summary>
///
/// </summary>
public class GenericCommMethodReceiveTextArgs : EventArgs
{
/// <summary>
///
/// </summary>
public string Text { get; private set; }
/// <summary>
///
/// </summary>
public string Delimiter { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="text"></param>
public GenericCommMethodReceiveTextArgs(string text)
{
Text = text;
}
/// <summary>
///
/// </summary>
/// <param name="text"></param>
/// <param name="delimiter"></param>
public GenericCommMethodReceiveTextArgs(string text, string delimiter)
:this(text)
{
Delimiter = delimiter;
}
/// <summary>
/// S+ Constructor
/// </summary>
public GenericCommMethodReceiveTextArgs() { }
}
/// <summary>
///
/// </summary>
public class ComTextHelper
{
/// <summary>
/// Gets escaped text for a byte array
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string GetEscapedText(byte[] bytes)
{
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
}
/// <summary>
/// Gets escaped text for a string
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static string GetEscapedText(string text)
{
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
}
/// <summary>
/// Gets debug text for a string
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static string GetDebugText(string text)
{
return Regex.Replace(text, @"[^\u0020-\u007E]", a => GetEscapedText(a.Value));
}
}
}

View File

@@ -1,16 +1,11 @@
using System; using Crestron.SimplSharp.CrestronIO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Crestron.SimplSharp; using PepperDash.Core.Logging;
using Crestron.SimplSharp.CrestronIO; using System;
using System.Linq;
using PepperDash.Core;
namespace PepperDash.Core.Config namespace PepperDash.Core.Config
{ {
@@ -18,127 +13,127 @@ namespace PepperDash.Core.Config
/// Reads a Portal formatted config file /// Reads a Portal formatted config file
/// </summary> /// </summary>
public class PortalConfigReader public class PortalConfigReader
{ {
/// <summary> /// <summary>
/// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object. /// Reads the config file, checks if it needs a merge, merges and saves, then returns the merged Object.
/// </summary> /// </summary>
/// <returns>JObject of config file</returns> /// <returns>JObject of config file</returns>
public static void ReadAndMergeFileIfNecessary(string filePath, string savePath) public static void ReadAndMergeFileIfNecessary(string filePath, string savePath)
{ {
try try
{ {
if (!File.Exists(filePath)) if (!File.Exists(filePath))
{ {
Debug.Console(1, Debug.ErrorLogLevel.Error, Debug.Console(1, Debug.ErrorLogLevel.Error,
"ERROR: Configuration file not present. Please load file to {0} and reset program", filePath); "ERROR: Configuration file not present. Please load file to {0} and reset program", filePath);
} }
using (StreamReader fs = new StreamReader(filePath)) using (StreamReader fs = new StreamReader(filePath))
{ {
var jsonObj = JObject.Parse(fs.ReadToEnd()); var jsonObj = JObject.Parse(fs.ReadToEnd());
if(jsonObj["template"] != null && jsonObj["system"] != null) if (jsonObj["template"] != null && jsonObj["system"] != null)
{ {
// it's a double-config, merge it. // it's a double-config, merge it.
var merged = MergeConfigs(jsonObj); var merged = MergeConfigs(jsonObj);
if (jsonObj["system_url"] != null) if (jsonObj["system_url"] != null)
{ {
merged["systemUrl"] = jsonObj["system_url"].Value<string>(); merged["systemUrl"] = jsonObj["system_url"].Value<string>();
} }
if (jsonObj["template_url"] != null) if (jsonObj["template_url"] != null)
{ {
merged["templateUrl"] = jsonObj["template_url"].Value<string>(); merged["templateUrl"] = jsonObj["template_url"].Value<string>();
} }
jsonObj = merged; jsonObj = merged;
} }
using (StreamWriter fw = new StreamWriter(savePath)) using (StreamWriter fw = new StreamWriter(savePath))
{ {
fw.Write(jsonObj.ToString(Formatting.Indented)); fw.Write(jsonObj.ToString(Formatting.Indented));
Debug.Console(1, "JSON config merged and saved to {0}", savePath); Debug.Console(1, "JSON config merged and saved to {0}", savePath);
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(1, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e); Debug.Console(1, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="doubleConfig"></param> /// <param name="doubleConfig"></param>
/// <returns></returns> /// <returns></returns>
public static JObject MergeConfigs(JObject doubleConfig) public static JObject MergeConfigs(JObject doubleConfig)
{ {
var system = JObject.FromObject(doubleConfig["system"]); var system = JObject.FromObject(doubleConfig["system"]);
var template = JObject.FromObject(doubleConfig["template"]); var template = JObject.FromObject(doubleConfig["template"]);
var merged = new JObject(); var merged = new JObject();
// Put together top-level objects // Put together top-level objects
if (system["info"] != null) if (system["info"] != null)
merged.Add("info", Merge(template["info"], system["info"], "infO")); merged.Add("info", Merge(template["info"], system["info"], "infO"));
else else
merged.Add("info", template["info"]); merged.Add("info", template["info"]);
merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray, merged.Add("devices", MergeArraysOnTopLevelProperty(template["devices"] as JArray,
system["devices"] as JArray, "uid", "devices")); system["devices"] as JArray, "uid", "devices"));
if (system["rooms"] == null) if (system["rooms"] == null)
merged.Add("rooms", template["rooms"]); merged.Add("rooms", template["rooms"]);
else else
merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray, merged.Add("rooms", MergeArraysOnTopLevelProperty(template["rooms"] as JArray,
system["rooms"] as JArray, "key", "rooms")); system["rooms"] as JArray, "key", "rooms"));
if (system["sourceLists"] == null) if (system["sourceLists"] == null)
merged.Add("sourceLists", template["sourceLists"]); merged.Add("sourceLists", template["sourceLists"]);
else else
merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists")); merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"], "sourceLists"));
if (system["destinationLists"] == null) if (system["destinationLists"] == null)
merged.Add("destinationLists", template["destinationLists"]); merged.Add("destinationLists", template["destinationLists"]);
else else
merged.Add("destinationLists", merged.Add("destinationLists",
Merge(template["destinationLists"], system["destinationLists"], "destinationLists")); Merge(template["destinationLists"], system["destinationLists"], "destinationLists"));
// Template tie lines take precedence. Config tool doesn't do them at system // Template tie lines take precedence. Config tool doesn't do them at system
// level anyway... // level anyway...
if (template["tieLines"] != null) if (template["tieLines"] != null)
merged.Add("tieLines", template["tieLines"]); merged.Add("tieLines", template["tieLines"]);
else if (system["tieLines"] != null) else if (system["tieLines"] != null)
merged.Add("tieLines", system["tieLines"]); merged.Add("tieLines", system["tieLines"]);
else else
merged.Add("tieLines", new JArray()); merged.Add("tieLines", new JArray());
if (template["joinMaps"] != null) if (template["joinMaps"] != null)
merged.Add("joinMaps", template["joinMaps"]); merged.Add("joinMaps", template["joinMaps"]);
else else
merged.Add("joinMaps", new JObject()); merged.Add("joinMaps", new JObject());
if (system["global"] != null) if (system["global"] != null)
merged.Add("global", Merge(template["global"], system["global"], "global")); merged.Add("global", Merge(template["global"], system["global"], "global"));
else else
merged.Add("global", template["global"]); merged.Add("global", template["global"]);
Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged); Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
return merged; return merged;
} }
/// <summary> /// <summary>
/// Merges the contents of a base and a delta array, matching the entries on a top-level property /// Merges the contents of a base and a delta array, matching the entries on a top-level property
/// given by propertyName. Returns a merge of them. Items in the delta array that do not have /// given by propertyName. Returns a merge of them. Items in the delta array that do not have
/// a matched item in base array will not be merged. Non keyed system items will replace the template items. /// a matched item in base array will not be merged. Non keyed system items will replace the template items.
/// </summary> /// </summary>
static JArray MergeArraysOnTopLevelProperty(JArray a1, JArray a2, string propertyName, string path) static JArray MergeArraysOnTopLevelProperty(JArray a1, JArray a2, string propertyName, string path)
{ {
var result = new JArray(); var result = new JArray();
if (a2 == null || a2.Count == 0) // If the system array is null or empty, return the template array if (a2 == null || a2.Count == 0) // If the system array is null or empty, return the template array
return a1; return a1;
else if (a1 != null) else if (a1 != null)
{ {
if (a2[0]["key"] == null) // If the first item in the system array has no key, overwrite the template array if (a2[0]["key"] == null) // If the first item in the system array has no key, overwrite the template array
{ // with the system array { // with the system array
return a2; return a2;
@@ -159,69 +154,69 @@ namespace PepperDash.Core.Config
result.Add(a1Dev); result.Add(a1Dev);
} }
} }
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Helper for using with JTokens. Converts to JObject /// Helper for using with JTokens. Converts to JObject
/// </summary> /// </summary>
static JObject Merge(JToken t1, JToken t2, string path) static JObject Merge(JToken t1, JToken t2, string path)
{ {
return Merge(JObject.FromObject(t1), JObject.FromObject(t2), path); return Merge(JObject.FromObject(t1), JObject.FromObject(t2), path);
} }
/// <summary> /// <summary>
/// Merge o2 onto o1 /// Merge o2 onto o1
/// </summary> /// </summary>
/// <param name="o1"></param> /// <param name="o1"></param>
/// <param name="o2"></param> /// <param name="o2"></param>
/// <param name="path"></param> /// <param name="path"></param>
static JObject Merge(JObject o1, JObject o2, string path) static JObject Merge(JObject o1, JObject o2, string path)
{ {
foreach (var o2Prop in o2) foreach (var o2Prop in o2)
{ {
var propKey = o2Prop.Key; var propKey = o2Prop.Key;
var o1Value = o1[propKey]; var o1Value = o1[propKey];
var o2Value = o2[propKey]; var o2Value = o2[propKey];
// if the property doesn't exist on o1, then add it. // if the property doesn't exist on o1, then add it.
if (o1Value == null) if (o1Value == null)
{ {
o1.Add(propKey, o2Value); o1.Add(propKey, o2Value);
} }
// otherwise merge them // otherwise merge them
else else
{ {
// Drill down // Drill down
var propPath = String.Format("{0}.{1}", path, propKey); var propPath = String.Format("{0}.{1}", path, propKey);
try try
{ {
if (o1Value is JArray) if (o1Value is JArray)
{ {
if (o2Value is JArray) if (o2Value is JArray)
{ {
o1Value.Replace(MergeArraysOnTopLevelProperty(o1Value as JArray, o2Value as JArray, "key", propPath)); o1Value.Replace(MergeArraysOnTopLevelProperty(o1Value as JArray, o2Value as JArray, "key", propPath));
} }
} }
else if (o2Prop.Value.HasValues && o1Value.HasValues) else if (o2Prop.Value.HasValues && o1Value.HasValues)
{ {
o1Value.Replace(Merge(JObject.FromObject(o1Value), JObject.FromObject(o2Value), propPath)); o1Value.Replace(Merge(JObject.FromObject(o1Value), JObject.FromObject(o2Value), propPath));
} }
else else
{ {
o1Value.Replace(o2Prop.Value); o1Value.Replace(o2Prop.Value);
} }
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(1, Debug.ErrorLogLevel.Warning, "Cannot merge items at path {0}: \r{1}", propPath, e); Debug.Console(1, Debug.ErrorLogLevel.Warning, "Cannot merge items at path {0}: \r{1}", propPath, e);
} }
} }
} }
return o1; return o1;
} }
} }
} }

View File

@@ -1,10 +1,6 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core namespace PepperDash.Core.Conversion
{ {
public class EncodingHelper public class EncodingHelper
{ {

View File

@@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core
{
/// <summary>
/// Unique key interface to require a unique key for the class
/// </summary>
public interface IKeyed
{
/// <summary>
/// Unique Key
/// </summary>
string Key { get; }
}
/// <summary>
/// Named Keyed device interface. Forces the devie to have a Unique Key and a name.
/// </summary>
public interface IKeyName : IKeyed
{
/// <summary>
/// Isn't it obvious :)
/// </summary>
string Name { get; }
}
}

View File

@@ -1,22 +1,24 @@
using System; using PepperDash.Core.Interfaces;
using PepperDash.Core.Logging;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace PepperDash.Core namespace PepperDash.Core
{ {
//********************************************************************************************************* //*********************************************************************************************************
/// <summary> /// <summary>
/// The core event and status-bearing class that most if not all device and connectors can derive from. /// The core event and status-bearing class that most if not all device and connectors can derive from.
/// </summary> /// </summary>
public class Device : IKeyName public class Device : IKeyName
{ {
/// <summary> /// <summary>
/// Unique Key /// Unique Key
/// </summary> /// </summary>
public string Key { get; protected set; } public string Key { get; protected set; }
/// <summary> /// <summary>
/// Name of the devie /// Name of the devie
/// </summary> /// </summary>
public string Name { get; protected set; } public string Name { get; protected set; }
/// <summary> /// <summary>
/// ///
@@ -33,26 +35,26 @@ namespace PepperDash.Core
///// </summary> ///// </summary>
//public bool HasConfig { get { return Config != null; } } //public bool HasConfig { get { return Config != null; } }
List<Action> _PreActivationActions; List<Action> _PreActivationActions;
List<Action> _PostActivationActions; List<Action> _PostActivationActions;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public static Device DefaultDevice { get { return _DefaultDevice; } } public static Device DefaultDevice { get { return _DefaultDevice; } }
static Device _DefaultDevice = new Device("Default", "Default"); static Device _DefaultDevice = new Device("Default", "Default");
/// <summary> /// <summary>
/// Base constructor for all Devices. /// Base constructor for all Devices.
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
public Device(string key) public Device(string key)
{ {
Key = key; Key = key;
if (key.Contains('.')) Debug.Console(0, this, "WARNING: Device name's should not include '.'"); if (key.Contains('.')) Debug.Console(0, this, "WARNING: Device name's should not include '.'");
Name = ""; Name = "";
} }
/// <summary> /// <summary>
/// Constructor with key and name /// Constructor with key and name
@@ -60,10 +62,10 @@ namespace PepperDash.Core
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="name"></param> /// <param name="name"></param>
public Device(string key, string name) : this(key) public Device(string key, string name) : this(key)
{ {
Name = name; Name = name;
} }
//public Device(DeviceConfig config) //public Device(DeviceConfig config)
// : this(config.Key, config.Name) // : this(config.Key, config.Name)
@@ -76,22 +78,22 @@ namespace PepperDash.Core
/// </summary> /// </summary>
/// <param name="act"></param> /// <param name="act"></param>
public void AddPreActivationAction(Action act) public void AddPreActivationAction(Action act)
{ {
if (_PreActivationActions == null) if (_PreActivationActions == null)
_PreActivationActions = new List<Action>(); _PreActivationActions = new List<Action>();
_PreActivationActions.Add(act); _PreActivationActions.Add(act);
} }
/// <summary> /// <summary>
/// Adds a post activation action /// Adds a post activation action
/// </summary> /// </summary>
/// <param name="act"></param> /// <param name="act"></param>
public void AddPostActivationAction(Action act) public void AddPostActivationAction(Action act)
{ {
if (_PostActivationActions == null) if (_PostActivationActions == null)
_PostActivationActions = new List<Action>(); _PostActivationActions = new List<Action>();
_PostActivationActions.Add(act); _PostActivationActions.Add(act);
} }
/// <summary> /// <summary>
/// Executes the preactivation actions /// Executes the preactivation actions
@@ -102,20 +104,20 @@ namespace PepperDash.Core
_PreActivationActions.ForEach(a => a.Invoke()); _PreActivationActions.ForEach(a => a.Invoke());
} }
/// <summary> /// <summary>
/// Gets this device ready to be used in the system. Runs any added pre-activation items, and /// Gets this device ready to be used in the system. Runs any added pre-activation items, and
/// all post-activation at end. Classes needing additional logic to /// all post-activation at end. Classes needing additional logic to
/// run should override CustomActivate() /// run should override CustomActivate()
/// </summary> /// </summary>
public bool Activate() public bool Activate()
{ {
//if (_PreActivationActions != null) //if (_PreActivationActions != null)
// _PreActivationActions.ForEach(a => a.Invoke()); // _PreActivationActions.ForEach(a => a.Invoke());
var result = CustomActivate(); var result = CustomActivate();
//if(result && _PostActivationActions != null) //if(result && _PostActivationActions != null)
// _PostActivationActions.ForEach(a => a.Invoke()); // _PostActivationActions.ForEach(a => a.Invoke());
return result; return result;
} }
/// <summary> /// <summary>
/// Executes the postactivation actions /// Executes the postactivation actions
@@ -126,37 +128,37 @@ namespace PepperDash.Core
_PostActivationActions.ForEach(a => a.Invoke()); _PostActivationActions.ForEach(a => a.Invoke());
} }
/// <summary> /// <summary>
/// Called in between Pre and PostActivationActions when Activate() is called. /// Called in between Pre and PostActivationActions when Activate() is called.
/// Override to provide addtitional setup when calling activation. Overriding classes /// Override to provide addtitional setup when calling activation. Overriding classes
/// do not need to call base.CustomActivate() /// do not need to call base.CustomActivate()
/// </summary> /// </summary>
/// <returns>true if device activated successfully.</returns> /// <returns>true if device activated successfully.</returns>
public virtual bool CustomActivate() { return true; } public virtual bool CustomActivate() { return true; }
/// <summary> /// <summary>
/// Call to deactivate device - unlink events, etc. Overriding classes do not /// Call to deactivate device - unlink events, etc. Overriding classes do not
/// need to call base.Deactivate() /// need to call base.Deactivate()
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual bool Deactivate() { return true; } public virtual bool Deactivate() { return true; }
/// <summary> /// <summary>
/// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize() /// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize()
/// </summary> /// </summary>
public virtual void Initialize() public virtual void Initialize()
{ {
} }
/// <summary> /// <summary>
/// Helper method to check object for bool value false and fire an Action method /// Helper method to check object for bool value false and fire an Action method
/// </summary> /// </summary>
/// <param name="o">Should be of type bool, others will be ignored</param> /// <param name="o">Should be of type bool, others will be ignored</param>
/// <param name="a">Action to be run when o is false</param> /// <param name="a">Action to be run when o is false</param>
public void OnFalse(object o, Action a) public void OnFalse(object o, Action a)
{ {
if (o is bool && !(bool)o) a(); if (o is bool && !(bool)o) a();
} }
} }
} }

View File

@@ -1,11 +1,7 @@
using Crestron.SimplSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core.Logging;
namespace PepperDash.Core namespace PepperDash.Core
{ {
@@ -13,110 +9,110 @@ namespace PepperDash.Core
/// Class to help with accessing values from the CrestronEthernetHelper class /// Class to help with accessing values from the CrestronEthernetHelper class
/// </summary> /// </summary>
public class EthernetHelper public class EthernetHelper
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public static EthernetHelper LanHelper public static EthernetHelper LanHelper
{ {
get get
{ {
if (_LanHelper == null) _LanHelper = new EthernetHelper(0); if (_LanHelper == null) _LanHelper = new EthernetHelper(0);
return _LanHelper; return _LanHelper;
} }
} }
static EthernetHelper _LanHelper; static EthernetHelper _LanHelper;
// ADD OTHER HELPERS HERE // ADD OTHER HELPERS HERE
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int PortNumber { get; private set; } public int PortNumber { get; private set; }
private EthernetHelper(int portNumber) private EthernetHelper(int portNumber)
{ {
PortNumber = portNumber; PortNumber = portNumber;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("linkActive")] [JsonProperty("linkActive")]
public bool LinkActive public bool LinkActive
{ {
get get
{ {
var status = CrestronEthernetHelper.GetEthernetParameter( var status = CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_LINK_STATUS, 0); CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_LINK_STATUS, 0);
Debug.Console(0, "LinkActive = {0}", status); Debug.Console(0, "LinkActive = {0}", status);
return status == ""; return status == "";
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("dchpActive")] [JsonProperty("dchpActive")]
public bool DhcpActive public bool DhcpActive
{ {
get get
{ {
return CrestronEthernetHelper.GetEthernetParameter( return CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, 0) == "ON"; CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, 0) == "ON";
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("hostname")] [JsonProperty("hostname")]
public string Hostname public string Hostname
{ {
get get
{ {
return CrestronEthernetHelper.GetEthernetParameter( return CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0); CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("ipAddress")] [JsonProperty("ipAddress")]
public string IPAddress public string IPAddress
{ {
get get
{ {
return CrestronEthernetHelper.GetEthernetParameter( return CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0); CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("subnetMask")] [JsonProperty("subnetMask")]
public string SubnetMask public string SubnetMask
{ {
get get
{ {
return CrestronEthernetHelper.GetEthernetParameter( return CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0); CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("defaultGateway")] [JsonProperty("defaultGateway")]
public string DefaultGateway public string DefaultGateway
{ {
get get
{ {
return CrestronEthernetHelper.GetEthernetParameter( return CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0); CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0);
} }
} }
} }
} }

View File

@@ -1,172 +1,168 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Bool change event args /// Bool change event args
/// </summary> /// </summary>
public class BoolChangeEventArgs : EventArgs public class BoolChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// Boolean state property /// Boolean state property
/// </summary> /// </summary>
public bool State { get; set; } public bool State { get; set; }
/// <summary> /// <summary>
/// Boolean ushort value property /// Boolean ushort value property
/// </summary> /// </summary>
public ushort IntValue { get { return (ushort)(State ? 1 : 0); } } public ushort IntValue { get { return (ushort)(State ? 1 : 0); } }
/// <summary> /// <summary>
/// Boolean change event args type /// Boolean change event args type
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// Boolean change event args index /// Boolean change event args index
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public BoolChangeEventArgs() public BoolChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="type"></param> /// <param name="type"></param>
public BoolChangeEventArgs(bool state, ushort type) public BoolChangeEventArgs(bool state, ushort type)
{ {
State = state; State = state;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public BoolChangeEventArgs(bool state, ushort type, ushort index) public BoolChangeEventArgs(bool state, ushort type, ushort index)
{ {
State = state; State = state;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
/// <summary> /// <summary>
/// Ushort change event args /// Ushort change event args
/// </summary> /// </summary>
public class UshrtChangeEventArgs : EventArgs public class UshrtChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// Ushort change event args integer value /// Ushort change event args integer value
/// </summary> /// </summary>
public ushort IntValue { get; set; } public ushort IntValue { get; set; }
/// <summary> /// <summary>
/// Ushort change event args type /// Ushort change event args type
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// Ushort change event args index /// Ushort change event args index
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public UshrtChangeEventArgs() public UshrtChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="intValue"></param> /// <param name="intValue"></param>
/// <param name="type"></param> /// <param name="type"></param>
public UshrtChangeEventArgs(ushort intValue, ushort type) public UshrtChangeEventArgs(ushort intValue, ushort type)
{ {
IntValue = intValue; IntValue = intValue;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="intValue"></param> /// <param name="intValue"></param>
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public UshrtChangeEventArgs(ushort intValue, ushort type, ushort index) public UshrtChangeEventArgs(ushort intValue, ushort type, ushort index)
{ {
IntValue = intValue; IntValue = intValue;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
/// <summary> /// <summary>
/// String change event args /// String change event args
/// </summary> /// </summary>
public class StringChangeEventArgs : EventArgs public class StringChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// String change event args value /// String change event args value
/// </summary> /// </summary>
public string StringValue { get; set; } public string StringValue { get; set; }
/// <summary> /// <summary>
/// String change event args type /// String change event args type
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// string change event args index /// string change event args index
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public StringChangeEventArgs() public StringChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="stringValue"></param> /// <param name="stringValue"></param>
/// <param name="type"></param> /// <param name="type"></param>
public StringChangeEventArgs(string stringValue, ushort type) public StringChangeEventArgs(string stringValue, ushort type)
{ {
StringValue = stringValue; StringValue = stringValue;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="stringValue"></param> /// <param name="stringValue"></param>
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public StringChangeEventArgs(string stringValue, ushort type, ushort index) public StringChangeEventArgs(string stringValue, ushort type, ushort index)
{ {
StringValue = stringValue; StringValue = stringValue;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
} }

View File

@@ -1,39 +1,33 @@
using System; namespace PepperDash.Core.GenericRESTfulCommunications
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.GenericRESTfulCommunications
{ {
/// <summary> /// <summary>
/// Constants /// Constants
/// </summary> /// </summary>
public class GenericRESTfulConstants public class GenericRESTfulConstants
{ {
/// <summary> /// <summary>
/// Generic boolean change /// Generic boolean change
/// </summary> /// </summary>
public const ushort BoolValueChange = 1; public const ushort BoolValueChange = 1;
/// <summary> /// <summary>
/// Generic Ushort change /// Generic Ushort change
/// </summary> /// </summary>
public const ushort UshrtValueChange = 101; public const ushort UshrtValueChange = 101;
/// <summary> /// <summary>
/// Response Code Ushort change /// Response Code Ushort change
/// </summary> /// </summary>
public const ushort ResponseCodeChange = 102; public const ushort ResponseCodeChange = 102;
/// <summary> /// <summary>
/// Generic String chagne /// Generic String chagne
/// </summary> /// </summary>
public const ushort StringValueChange = 201; public const ushort StringValueChange = 201;
/// <summary> /// <summary>
/// Response string change /// Response string change
/// </summary> /// </summary>
public const ushort ResponseStringChange = 202; public const ushort ResponseStringChange = 202;
/// <summary> /// <summary>
/// Error string change /// Error string change
/// </summary> /// </summary>
public const ushort ErrorStringChange = 203; public const ushort ErrorStringChange = 203;
} }
} }

View File

@@ -1,256 +1,253 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Net.Http; using Crestron.SimplSharp.Net.Http;
using Crestron.SimplSharp.Net.Https; using Crestron.SimplSharp.Net.Https;
using System;
namespace PepperDash.Core.GenericRESTfulCommunications namespace PepperDash.Core.GenericRESTfulCommunications
{ {
/// <summary> /// <summary>
/// Generic RESTful communication class /// Generic RESTful communication class
/// </summary> /// </summary>
public class GenericRESTfulClient public class GenericRESTfulClient
{ {
/// <summary> /// <summary>
/// Boolean event handler /// Boolean event handler
/// </summary> /// </summary>
public event EventHandler<BoolChangeEventArgs> BoolChange; public event EventHandler<BoolChangeEventArgs> BoolChange;
/// <summary> /// <summary>
/// Ushort event handler /// Ushort event handler
/// </summary> /// </summary>
public event EventHandler<UshrtChangeEventArgs> UshrtChange; public event EventHandler<UshrtChangeEventArgs> UshrtChange;
/// <summary> /// <summary>
/// String event handler /// String event handler
/// </summary> /// </summary>
public event EventHandler<StringChangeEventArgs> StringChange; public event EventHandler<StringChangeEventArgs> StringChange;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public GenericRESTfulClient() public GenericRESTfulClient()
{ {
} }
/// <summary> /// <summary>
/// Generic RESTful submit request /// Generic RESTful submit request
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="requestType"></param> /// <param name="requestType"></param>
/// <param name="username"></param> /// <param name="username"></param>
/// <param name="password"></param> /// <param name="password"></param>
/// <param name="contentType"></param> /// <param name="contentType"></param>
public void SubmitRequest(string url, ushort port, ushort requestType, string contentType, string username, string password) public void SubmitRequest(string url, ushort port, ushort requestType, string contentType, string username, string password)
{ {
if (url.StartsWith("https:", StringComparison.OrdinalIgnoreCase)) if (url.StartsWith("https:", StringComparison.OrdinalIgnoreCase))
{ {
SubmitRequestHttps(url, port, requestType, contentType, username, password); SubmitRequestHttps(url, port, requestType, contentType, username, password);
} }
else if (url.StartsWith("http:", StringComparison.OrdinalIgnoreCase)) else if (url.StartsWith("http:", StringComparison.OrdinalIgnoreCase))
{ {
SubmitRequestHttp(url, port, requestType, contentType, username, password); SubmitRequestHttp(url, port, requestType, contentType, username, password);
} }
else else
{ {
OnStringChange(string.Format("Invalid URL {0}", url), 0, GenericRESTfulConstants.ErrorStringChange); OnStringChange(string.Format("Invalid URL {0}", url), 0, GenericRESTfulConstants.ErrorStringChange);
} }
} }
/// <summary> /// <summary>
/// Private HTTP submit request /// Private HTTP submit request
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="requestType"></param> /// <param name="requestType"></param>
/// <param name="contentType"></param> /// <param name="contentType"></param>
/// <param name="username"></param> /// <param name="username"></param>
/// <param name="password"></param> /// <param name="password"></param>
private void SubmitRequestHttp(string url, ushort port, ushort requestType, string contentType, string username, string password) private void SubmitRequestHttp(string url, ushort port, ushort requestType, string contentType, string username, string password)
{ {
try try
{ {
HttpClient client = new HttpClient(); HttpClient client = new HttpClient();
HttpClientRequest request = new HttpClientRequest(); HttpClientRequest request = new HttpClientRequest();
HttpClientResponse response; HttpClientResponse response;
client.KeepAlive = false; client.KeepAlive = false;
if(port >= 1 || port <= 65535) if (port >= 1 || port <= 65535)
client.Port = port; client.Port = port;
else else
client.Port = 80; client.Port = 80;
var authorization = ""; var authorization = "";
if (!string.IsNullOrEmpty(username)) if (!string.IsNullOrEmpty(username))
authorization = EncodeBase64(username, password); authorization = EncodeBase64(username, password);
if (!string.IsNullOrEmpty(authorization)) if (!string.IsNullOrEmpty(authorization))
request.Header.SetHeaderValue("Authorization", authorization); request.Header.SetHeaderValue("Authorization", authorization);
if (!string.IsNullOrEmpty(contentType)) if (!string.IsNullOrEmpty(contentType))
request.Header.ContentType = contentType; request.Header.ContentType = contentType;
request.Url.Parse(url); request.Url.Parse(url);
request.RequestType = (Crestron.SimplSharp.Net.Http.RequestType)requestType; request.RequestType = (Crestron.SimplSharp.Net.Http.RequestType)requestType;
response = client.Dispatch(request); response = client.Dispatch(request);
CrestronConsole.PrintLine(string.Format("SubmitRequestHttp Response[{0}]: {1}", response.Code, response.ContentString.ToString())); CrestronConsole.PrintLine(string.Format("SubmitRequestHttp Response[{0}]: {1}", response.Code, response.ContentString.ToString()));
if (!string.IsNullOrEmpty(response.ContentString.ToString())) if (!string.IsNullOrEmpty(response.ContentString.ToString()))
OnStringChange(response.ContentString.ToString(), 0, GenericRESTfulConstants.ResponseStringChange); OnStringChange(response.ContentString.ToString(), 0, GenericRESTfulConstants.ResponseStringChange);
if (response.Code > 0) if (response.Code > 0)
OnUshrtChange((ushort)response.Code, 0, GenericRESTfulConstants.ResponseCodeChange); OnUshrtChange((ushort)response.Code, 0, GenericRESTfulConstants.ResponseCodeChange);
} }
catch (Exception e) catch (Exception e)
{ {
//var msg = string.Format("SubmitRequestHttp({0}, {1}, {2}) failed:{3}", url, port, requestType, e.Message); //var msg = string.Format("SubmitRequestHttp({0}, {1}, {2}) failed:{3}", url, port, requestType, e.Message);
//CrestronConsole.PrintLine(msg); //CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
CrestronConsole.PrintLine(e.Message); CrestronConsole.PrintLine(e.Message);
OnStringChange(e.Message, 0, GenericRESTfulConstants.ErrorStringChange); OnStringChange(e.Message, 0, GenericRESTfulConstants.ErrorStringChange);
} }
} }
/// <summary> /// <summary>
/// Private HTTPS submit request /// Private HTTPS submit request
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="requestType"></param> /// <param name="requestType"></param>
/// <param name="contentType"></param> /// <param name="contentType"></param>
/// <param name="username"></param> /// <param name="username"></param>
/// <param name="password"></param> /// <param name="password"></param>
private void SubmitRequestHttps(string url, ushort port, ushort requestType, string contentType, string username, string password) private void SubmitRequestHttps(string url, ushort port, ushort requestType, string contentType, string username, string password)
{ {
try try
{ {
HttpsClient client = new HttpsClient(); HttpsClient client = new HttpsClient();
HttpsClientRequest request = new HttpsClientRequest(); HttpsClientRequest request = new HttpsClientRequest();
HttpsClientResponse response; HttpsClientResponse response;
client.KeepAlive = false; client.KeepAlive = false;
client.HostVerification = false; client.HostVerification = false;
client.PeerVerification = false; client.PeerVerification = false;
var authorization = ""; var authorization = "";
if (!string.IsNullOrEmpty(username)) if (!string.IsNullOrEmpty(username))
authorization = EncodeBase64(username, password); authorization = EncodeBase64(username, password);
if (!string.IsNullOrEmpty(authorization)) if (!string.IsNullOrEmpty(authorization))
request.Header.SetHeaderValue("Authorization", authorization); request.Header.SetHeaderValue("Authorization", authorization);
if (!string.IsNullOrEmpty(contentType)) if (!string.IsNullOrEmpty(contentType))
request.Header.ContentType = contentType; request.Header.ContentType = contentType;
request.Url.Parse(url); request.Url.Parse(url);
request.RequestType = (Crestron.SimplSharp.Net.Https.RequestType)requestType; request.RequestType = (Crestron.SimplSharp.Net.Https.RequestType)requestType;
response = client.Dispatch(request); response = client.Dispatch(request);
CrestronConsole.PrintLine(string.Format("SubmitRequestHttp Response[{0}]: {1}", response.Code, response.ContentString.ToString())); CrestronConsole.PrintLine(string.Format("SubmitRequestHttp Response[{0}]: {1}", response.Code, response.ContentString.ToString()));
if(!string.IsNullOrEmpty(response.ContentString.ToString())) if (!string.IsNullOrEmpty(response.ContentString.ToString()))
OnStringChange(response.ContentString.ToString(), 0, GenericRESTfulConstants.ResponseStringChange); OnStringChange(response.ContentString.ToString(), 0, GenericRESTfulConstants.ResponseStringChange);
if(response.Code > 0) if (response.Code > 0)
OnUshrtChange((ushort)response.Code, 0, GenericRESTfulConstants.ResponseCodeChange); OnUshrtChange((ushort)response.Code, 0, GenericRESTfulConstants.ResponseCodeChange);
} }
catch (Exception e) catch (Exception e)
{ {
//var msg = string.Format("SubmitRequestHttps({0}, {1}, {2}, {3}, {4}) failed:{5}", url, port, requestType, username, password, e.Message); //var msg = string.Format("SubmitRequestHttps({0}, {1}, {2}, {3}, {4}) failed:{5}", url, port, requestType, username, password, e.Message);
//CrestronConsole.PrintLine(msg); //CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
CrestronConsole.PrintLine(e.Message); CrestronConsole.PrintLine(e.Message);
OnStringChange(e.Message, 0, GenericRESTfulConstants.ErrorStringChange); OnStringChange(e.Message, 0, GenericRESTfulConstants.ErrorStringChange);
} }
} }
/// <summary> /// <summary>
/// Private method to encode username and password to Base64 string /// Private method to encode username and password to Base64 string
/// </summary> /// </summary>
/// <param name="username"></param> /// <param name="username"></param>
/// <param name="password"></param> /// <param name="password"></param>
/// <returns>authorization</returns> /// <returns>authorization</returns>
private string EncodeBase64(string username, string password) private string EncodeBase64(string username, string password)
{ {
var authorization = ""; var authorization = "";
try try
{ {
if (!string.IsNullOrEmpty(username)) if (!string.IsNullOrEmpty(username))
{ {
string base64String = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(string.Format("{0}:{1}", username, password))); string base64String = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(string.Format("{0}:{1}", username, password)));
authorization = string.Format("Basic {0}", base64String); authorization = string.Format("Basic {0}", base64String);
} }
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("EncodeBase64({0}, {1}) failed:\r{2}", username, password, e); var msg = string.Format("EncodeBase64({0}, {1}) failed:\r{2}", username, password, e);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
ErrorLog.Error(msg); ErrorLog.Error(msg);
return "" ; return "";
} }
return authorization; return authorization;
} }
/// <summary> /// <summary>
/// Protected method to handle boolean change events /// Protected method to handle boolean change events
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
var handler = BoolChange; var handler = BoolChange;
if (handler != null) if (handler != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected mehtod to handle ushort change events /// Protected mehtod to handle ushort change events
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnUshrtChange(ushort value, ushort index, ushort type) protected void OnUshrtChange(ushort value, ushort index, ushort type)
{ {
var handler = UshrtChange; var handler = UshrtChange;
if (handler != null) if (handler != null)
{ {
var args = new UshrtChangeEventArgs(value, type); var args = new UshrtChangeEventArgs(value, type);
args.Index = index; args.Index = index;
UshrtChange(this, args); UshrtChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected method to handle string change events /// Protected method to handle string change events
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
var handler = StringChange; var handler = StringChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
} }
} }

View File

@@ -1,77 +1,73 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.JsonStandardObjects namespace PepperDash.Core.JsonStandardObjects
{ {
/// <summary> /// <summary>
/// Constants for simpl modules /// Constants for simpl modules
/// </summary> /// </summary>
public class JsonStandardDeviceConstants public class JsonStandardDeviceConstants
{ {
/// <summary> /// <summary>
/// Json object evaluated constant /// Json object evaluated constant
/// </summary> /// </summary>
public const ushort JsonObjectEvaluated = 2; public const ushort JsonObjectEvaluated = 2;
/// <summary> /// <summary>
/// Json object changed constant /// Json object changed constant
/// </summary> /// </summary>
public const ushort JsonObjectChanged = 104; public const ushort JsonObjectChanged = 104;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class DeviceChangeEventArgs : EventArgs public class DeviceChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// Device change event args object /// Device change event args object
/// </summary> /// </summary>
public DeviceConfig Device { get; set; } public DeviceConfig Device { get; set; }
/// <summary> /// <summary>
/// Device change event args type /// Device change event args type
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// Device change event args index /// Device change event args index
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
public DeviceChangeEventArgs() public DeviceChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="device"></param> /// <param name="device"></param>
/// <param name="type"></param> /// <param name="type"></param>
public DeviceChangeEventArgs(DeviceConfig device, ushort type) public DeviceChangeEventArgs(DeviceConfig device, ushort type)
{ {
Device = device; Device = device;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="device"></param> /// <param name="device"></param>
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public DeviceChangeEventArgs(DeviceConfig device, ushort type, ushort index) public DeviceChangeEventArgs(DeviceConfig device, ushort type, ushort index)
{ {
Device = device; Device = device;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
} }

View File

@@ -1,187 +1,184 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core.JsonToSimpl; using PepperDash.Core.JsonToSimpl;
using PepperDash.Core.Logging;
using System;
using System.Linq;
namespace PepperDash.Core.JsonStandardObjects namespace PepperDash.Core.JsonStandardObjects
{ {
/// <summary> /// <summary>
/// Device class /// Device class
/// </summary> /// </summary>
public class DeviceConfig public class DeviceConfig
{ {
/// <summary> /// <summary>
/// JSON config key property /// JSON config key property
/// </summary> /// </summary>
public string key { get; set; } public string key { get; set; }
/// <summary> /// <summary>
/// JSON config name property /// JSON config name property
/// </summary> /// </summary>
public string name { get; set; } public string name { get; set; }
/// <summary> /// <summary>
/// JSON config type property /// JSON config type property
/// </summary> /// </summary>
public string type { get; set; } public string type { get; set; }
/// <summary> /// <summary>
/// JSON config properties /// JSON config properties
/// </summary> /// </summary>
public PropertiesConfig properties { get; set; } public PropertiesConfig properties { get; set; }
/// <summary> /// <summary>
/// Bool change event handler /// Bool change event handler
/// </summary> /// </summary>
public event EventHandler<BoolChangeEventArgs> BoolChange; public event EventHandler<BoolChangeEventArgs> BoolChange;
/// <summary> /// <summary>
/// Ushort change event handler /// Ushort change event handler
/// </summary> /// </summary>
public event EventHandler<UshrtChangeEventArgs> UshrtChange; public event EventHandler<UshrtChangeEventArgs> UshrtChange;
/// <summary> /// <summary>
/// String change event handler /// String change event handler
/// </summary> /// </summary>
public event EventHandler<StringChangeEventArgs> StringChange; public event EventHandler<StringChangeEventArgs> StringChange;
/// <summary> /// <summary>
/// Object change event handler /// Object change event handler
/// </summary> /// </summary>
public event EventHandler<DeviceChangeEventArgs> DeviceChange; public event EventHandler<DeviceChangeEventArgs> DeviceChange;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public DeviceConfig() public DeviceConfig()
{ {
properties = new PropertiesConfig(); properties = new PropertiesConfig();
} }
/// <summary> /// <summary>
/// Initialize method /// Initialize method
/// </summary> /// </summary>
/// <param name="uniqueID"></param> /// <param name="uniqueID"></param>
/// <param name="deviceKey"></param> /// <param name="deviceKey"></param>
public void Initialize(string uniqueID, string deviceKey) public void Initialize(string uniqueID, string deviceKey)
{ {
// S+ set EvaluateFb low // S+ set EvaluateFb low
OnBoolChange(false, 0, JsonStandardDeviceConstants.JsonObjectEvaluated); OnBoolChange(false, 0, JsonStandardDeviceConstants.JsonObjectEvaluated);
// validate parameters // validate parameters
if (string.IsNullOrEmpty(uniqueID) || string.IsNullOrEmpty(deviceKey)) if (string.IsNullOrEmpty(uniqueID) || string.IsNullOrEmpty(deviceKey))
{ {
Debug.Console(1, "UniqueID ({0} or key ({1} is null or empty", uniqueID, deviceKey); Debug.Console(1, "UniqueID ({0} or key ({1} is null or empty", uniqueID, deviceKey);
// S+ set EvaluteFb high // S+ set EvaluteFb high
OnBoolChange(true, 0, JsonStandardDeviceConstants.JsonObjectEvaluated); OnBoolChange(true, 0, JsonStandardDeviceConstants.JsonObjectEvaluated);
return; return;
} }
key = deviceKey; key = deviceKey;
try try
{ {
// get the file using the unique ID // get the file using the unique ID
JsonToSimplMaster jsonMaster = J2SGlobal.GetMasterByFile(uniqueID); JsonToSimplMaster jsonMaster = J2SGlobal.GetMasterByFile(uniqueID);
if (jsonMaster == null) if (jsonMaster == null)
{ {
Debug.Console(1, "Could not find JSON file with uniqueID {0}", uniqueID); Debug.Console(1, "Could not find JSON file with uniqueID {0}", uniqueID);
return; return;
} }
// get the device configuration using the key // get the device configuration using the key
var devices = jsonMaster.JsonObject.ToObject<RootObject>().devices; var devices = jsonMaster.JsonObject.ToObject<RootObject>().devices;
var device = devices.FirstOrDefault(d => d.key.Equals(key)); var device = devices.FirstOrDefault(d => d.key.Equals(key));
if (device == null) if (device == null)
{ {
Debug.Console(1, "Could not find device with key {0}", key); Debug.Console(1, "Could not find device with key {0}", key);
return; return;
} }
OnObjectChange(device, 0, JsonStandardDeviceConstants.JsonObjectChanged); OnObjectChange(device, 0, JsonStandardDeviceConstants.JsonObjectChanged);
var index = devices.IndexOf(device); var index = devices.IndexOf(device);
OnStringChange(string.Format("devices[{0}]", index), 0, JsonToSimplConstants.FullPathToArrayChange); OnStringChange(string.Format("devices[{0}]", index), 0, JsonToSimplConstants.FullPathToArrayChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("Device {0} lookup failed:\r{1}", key, e); var msg = string.Format("Device {0} lookup failed:\r{1}", key, e);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
ErrorLog.Error(msg); ErrorLog.Error(msg);
} }
finally finally
{ {
// S+ set EvaluteFb high // S+ set EvaluteFb high
OnBoolChange(true, 0, JsonStandardDeviceConstants.JsonObjectEvaluated); OnBoolChange(true, 0, JsonStandardDeviceConstants.JsonObjectEvaluated);
} }
} }
#region EventHandler Helpers #region EventHandler Helpers
/// <summary> /// <summary>
/// BoolChange event handler helper /// BoolChange event handler helper
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
var handler = BoolChange; var handler = BoolChange;
if (handler != null) if (handler != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
/// <summary> /// <summary>
/// UshrtChange event handler helper /// UshrtChange event handler helper
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnUshrtChange(ushort state, ushort index, ushort type) protected void OnUshrtChange(ushort state, ushort index, ushort type)
{ {
var handler = UshrtChange; var handler = UshrtChange;
if (handler != null) if (handler != null)
{ {
var args = new UshrtChangeEventArgs(state, type); var args = new UshrtChangeEventArgs(state, type);
args.Index = index; args.Index = index;
UshrtChange(this, args); UshrtChange(this, args);
} }
} }
/// <summary> /// <summary>
/// StringChange event handler helper /// StringChange event handler helper
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
var handler = StringChange; var handler = StringChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
/// <summary> /// <summary>
/// ObjectChange event handler helper /// ObjectChange event handler helper
/// </summary> /// </summary>
/// <param name="device"></param> /// <param name="device"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnObjectChange(DeviceConfig device, ushort index, ushort type) protected void OnObjectChange(DeviceConfig device, ushort index, ushort type)
{ {
if (DeviceChange != null) if (DeviceChange != null)
{ {
var args = new DeviceChangeEventArgs(device, type); var args = new DeviceChangeEventArgs(device, type);
args.Index = index; args.Index = index;
DeviceChange(this, args); DeviceChange(this, args);
} }
} }
#endregion EventHandler Helpers #endregion EventHandler Helpers
} }
} }

View File

@@ -1,12 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.JsonStandardObjects namespace PepperDash.Core.JsonStandardObjects
{ {
/* /*
Convert JSON snippt to C#: http://json2csharp.com/# Convert JSON snippt to C#: http://json2csharp.com/#
JSON Snippet: JSON Snippet:
@@ -47,11 +44,11 @@ namespace PepperDash.Core.JsonStandardObjects
] ]
} }
*/ */
/// <summary> /// <summary>
/// Device communication parameter class /// Device communication parameter class
/// </summary> /// </summary>
public class ComParamsConfig public class ComParamsConfig
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -85,11 +82,11 @@ namespace PepperDash.Core.JsonStandardObjects
/// </summary> /// </summary>
public int pacing { get; set; } public int pacing { get; set; }
// convert properties for simpl // convert properties for simpl
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort simplBaudRate { get { return Convert.ToUInt16(baudRate); } } public ushort simplBaudRate { get { return Convert.ToUInt16(baudRate); } }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -103,20 +100,20 @@ namespace PepperDash.Core.JsonStandardObjects
/// </summary> /// </summary>
public ushort simplPacing { get { return Convert.ToUInt16(pacing); } } public ushort simplPacing { get { return Convert.ToUInt16(pacing); } }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ComParamsConfig() public ComParamsConfig()
{ {
} }
} }
/// <summary> /// <summary>
/// Device TCP/SSH properties class /// Device TCP/SSH properties class
/// </summary> /// </summary>
public class TcpSshPropertiesConfig public class TcpSshPropertiesConfig
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -142,11 +139,11 @@ namespace PepperDash.Core.JsonStandardObjects
/// </summary> /// </summary>
public int autoReconnectIntervalMs { get; set; } public int autoReconnectIntervalMs { get; set; }
// convert properties for simpl // convert properties for simpl
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort simplPort { get { return Convert.ToUInt16(port); } } public ushort simplPort { get { return Convert.ToUInt16(port); } }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -156,20 +153,20 @@ namespace PepperDash.Core.JsonStandardObjects
/// </summary> /// </summary>
public ushort simplAutoReconnectIntervalMs { get { return Convert.ToUInt16(autoReconnectIntervalMs); } } public ushort simplAutoReconnectIntervalMs { get { return Convert.ToUInt16(autoReconnectIntervalMs); } }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public TcpSshPropertiesConfig() public TcpSshPropertiesConfig()
{ {
} }
} }
/// <summary> /// <summary>
/// Device control class /// Device control class
/// </summary> /// </summary>
public class ControlConfig public class ControlConfig
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -191,27 +188,27 @@ namespace PepperDash.Core.JsonStandardObjects
/// </summary> /// </summary>
public TcpSshPropertiesConfig tcpSshProperties { get; set; } public TcpSshPropertiesConfig tcpSshProperties { get; set; }
// convert properties for simpl // convert properties for simpl
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort simplControlPortNumber { get { return Convert.ToUInt16(controlPortNumber); } } public ushort simplControlPortNumber { get { return Convert.ToUInt16(controlPortNumber); } }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ControlConfig() public ControlConfig()
{ {
comParams = new ComParamsConfig(); comParams = new ComParamsConfig();
tcpSshProperties = new TcpSshPropertiesConfig(); tcpSshProperties = new TcpSshPropertiesConfig();
} }
} }
/// <summary> /// <summary>
/// Device properties class /// Device properties class
/// </summary> /// </summary>
public class PropertiesConfig public class PropertiesConfig
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -225,33 +222,33 @@ namespace PepperDash.Core.JsonStandardObjects
/// </summary> /// </summary>
public ControlConfig control { get; set; } public ControlConfig control { get; set; }
// convert properties for simpl // convert properties for simpl
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort simplDeviceId { get { return Convert.ToUInt16(deviceId); } } public ushort simplDeviceId { get { return Convert.ToUInt16(deviceId); } }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort simplEnabled { get { return (ushort)(enabled ? 1 : 0); } } public ushort simplEnabled { get { return (ushort)(enabled ? 1 : 0); } }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public PropertiesConfig() public PropertiesConfig()
{ {
control = new ControlConfig(); control = new ControlConfig();
} }
} }
/// <summary> /// <summary>
/// Root device class /// Root device class
/// </summary> /// </summary>
public class RootObject public class RootObject
{ {
/// <summary> /// <summary>
/// The collection of devices /// The collection of devices
/// </summary> /// </summary>
public List<DeviceConfig> devices { get; set; } public List<DeviceConfig> devices { get; set; }
} }
} }

View File

@@ -1,16 +1,10 @@
using System; namespace PepperDash.Core.JsonToSimpl
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.JsonToSimpl
{ {
/// <summary> /// <summary>
/// Constants for Simpl modules /// Constants for Simpl modules
/// </summary> /// </summary>
public class JsonToSimplConstants public class JsonToSimplConstants
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -43,7 +37,7 @@ namespace PepperDash.Core.JsonToSimpl
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort StringValueChange = 201; public const ushort StringValueChange = 201;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -76,18 +70,18 @@ namespace PepperDash.Core.JsonToSimpl
/// Reports the room name change /// Reports the room name change
/// </summary> /// </summary>
public const ushort RoomNameChange = 208; public const ushort RoomNameChange = 208;
} }
/// <summary> /// <summary>
/// S+ values delegate /// S+ values delegate
/// </summary> /// </summary>
public delegate void SPlusValuesDelegate(); public delegate void SPlusValuesDelegate();
/// <summary> /// <summary>
/// S+ values wrapper /// S+ values wrapper
/// </summary> /// </summary>
public class SPlusValueWrapper public class SPlusValueWrapper
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -108,7 +102,7 @@ namespace PepperDash.Core.JsonToSimpl
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public SPlusValueWrapper() {} public SPlusValueWrapper() { }
/// <summary> /// <summary>
/// ///
@@ -116,17 +110,17 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public SPlusValueWrapper(SPlusType type, ushort index) public SPlusValueWrapper(SPlusType type, ushort index)
{ {
ValueType = type; ValueType = type;
Index = index; Index = index;
} }
} }
/// <summary> /// <summary>
/// S+ types enum /// S+ types enum
/// </summary> /// </summary>
public enum SPlusType public enum SPlusType
{ {
/// <summary> /// <summary>
/// Digital /// Digital
/// </summary> /// </summary>
@@ -139,5 +133,5 @@ namespace PepperDash.Core.JsonToSimpl
/// String /// String
/// </summary> /// </summary>
String String
} }
} }

View File

@@ -1,8 +1,8 @@
using System; using Crestron.SimplSharp;
using PepperDash.Core.Logging;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
//using PepperDash.Core; //using PepperDash.Core;
@@ -12,48 +12,48 @@ namespace PepperDash.Core.JsonToSimpl
/// The global class to manage all the instances of JsonToSimplMaster /// The global class to manage all the instances of JsonToSimplMaster
/// </summary> /// </summary>
public class J2SGlobal public class J2SGlobal
{ {
static List<JsonToSimplMaster> Masters = new List<JsonToSimplMaster>(); static List<JsonToSimplMaster> Masters = new List<JsonToSimplMaster>();
/// <summary> /// <summary>
/// Adds a file master. If the master's key or filename is equivalent to any existing /// Adds a file master. If the master's key or filename is equivalent to any existing
/// master, this will fail /// master, this will fail
/// </summary> /// </summary>
/// <param name="master">New master to add</param> /// <param name="master">New master to add</param>
/// ///
public static void AddMaster(JsonToSimplMaster master) public static void AddMaster(JsonToSimplMaster master)
{ {
if (master == null) if (master == null)
throw new ArgumentNullException("master"); throw new ArgumentNullException("master");
if (string.IsNullOrEmpty(master.UniqueID)) if (string.IsNullOrEmpty(master.UniqueID))
throw new InvalidOperationException("JSON Master cannot be added with a null UniqueId"); throw new InvalidOperationException("JSON Master cannot be added with a null UniqueId");
Debug.Console(1, "JSON Global adding master {0}", master.UniqueID); Debug.Console(1, "JSON Global adding master {0}", master.UniqueID);
if (Masters.Contains(master)) return; if (Masters.Contains(master)) return;
var existing = Masters.FirstOrDefault(m => var existing = Masters.FirstOrDefault(m =>
m.UniqueID.Equals(master.UniqueID, StringComparison.OrdinalIgnoreCase)); m.UniqueID.Equals(master.UniqueID, StringComparison.OrdinalIgnoreCase));
if (existing == null) if (existing == null)
{ {
Masters.Add(master); Masters.Add(master);
} }
else else
{ {
var msg = string.Format("Cannot add JSON Master with unique ID '{0}'.\rID is already in use on another master.", master.UniqueID); var msg = string.Format("Cannot add JSON Master with unique ID '{0}'.\rID is already in use on another master.", master.UniqueID);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
ErrorLog.Warn(msg); ErrorLog.Warn(msg);
} }
} }
/// <summary> /// <summary>
/// Gets a master by its key. Case-insensitive /// Gets a master by its key. Case-insensitive
/// </summary> /// </summary>
public static JsonToSimplMaster GetMasterByFile(string file) public static JsonToSimplMaster GetMasterByFile(string file)
{ {
return Masters.FirstOrDefault(m => m.UniqueID.Equals(file, StringComparison.OrdinalIgnoreCase)); return Masters.FirstOrDefault(m => m.UniqueID.Equals(file, StringComparison.OrdinalIgnoreCase));
} }
} }
} }

View File

@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core.Logging;
using System;
using System.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
@@ -13,7 +10,7 @@ namespace PepperDash.Core.JsonToSimpl
/// Used to interact with an array of values with the S+ modules /// Used to interact with an array of values with the S+ modules
/// </summary> /// </summary>
public class JsonToSimplArrayLookupChild : JsonToSimplChildObjectBase public class JsonToSimplArrayLookupChild : JsonToSimplChildObjectBase
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -23,144 +20,144 @@ namespace PepperDash.Core.JsonToSimpl
/// </summary> /// </summary>
public string SearchPropertyValue { get; set; } public string SearchPropertyValue { get; set; }
int ArrayIndex; int ArrayIndex;
/// <summary> /// <summary>
/// For gt2.4.1 array lookups /// For gt2.4.1 array lookups
/// </summary> /// </summary>
/// <param name="file"></param> /// <param name="file"></param>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="pathPrefix"></param> /// <param name="pathPrefix"></param>
/// <param name="pathSuffix"></param> /// <param name="pathSuffix"></param>
/// <param name="searchPropertyName"></param> /// <param name="searchPropertyName"></param>
/// <param name="searchPropertyValue"></param> /// <param name="searchPropertyValue"></param>
public void Initialize(string file, string key, string pathPrefix, string pathSuffix, public void Initialize(string file, string key, string pathPrefix, string pathSuffix,
string searchPropertyName, string searchPropertyValue) string searchPropertyName, string searchPropertyValue)
{ {
base.Initialize(file, key, pathPrefix, pathSuffix); base.Initialize(file, key, pathPrefix, pathSuffix);
SearchPropertyName = searchPropertyName; SearchPropertyName = searchPropertyName;
SearchPropertyValue = searchPropertyValue; SearchPropertyValue = searchPropertyValue;
} }
/// <summary> /// <summary>
/// For newer >=2.4.1 array lookups. /// For newer >=2.4.1 array lookups.
/// </summary> /// </summary>
/// <param name="file"></param> /// <param name="file"></param>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="pathPrefix"></param> /// <param name="pathPrefix"></param>
/// <param name="pathAppend"></param> /// <param name="pathAppend"></param>
/// <param name="pathSuffix"></param> /// <param name="pathSuffix"></param>
/// <param name="searchPropertyName"></param> /// <param name="searchPropertyName"></param>
/// <param name="searchPropertyValue"></param> /// <param name="searchPropertyValue"></param>
public void InitializeWithAppend(string file, string key, string pathPrefix, string pathAppend, public void InitializeWithAppend(string file, string key, string pathPrefix, string pathAppend,
string pathSuffix, string searchPropertyName, string searchPropertyValue) string pathSuffix, string searchPropertyName, string searchPropertyValue)
{ {
string pathPrefixWithAppend = (pathPrefix != null ? pathPrefix : "") + GetPathAppend(pathAppend); string pathPrefixWithAppend = (pathPrefix != null ? pathPrefix : "") + GetPathAppend(pathAppend);
base.Initialize(file, key, pathPrefixWithAppend, pathSuffix); base.Initialize(file, key, pathPrefixWithAppend, pathSuffix);
SearchPropertyName = searchPropertyName; SearchPropertyName = searchPropertyName;
SearchPropertyValue = searchPropertyValue; SearchPropertyValue = searchPropertyValue;
} }
//PathPrefix+ArrayName+[x]+path+PathSuffix //PathPrefix+ArrayName+[x]+path+PathSuffix
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <returns></returns> /// <returns></returns>
protected override string GetFullPath(string path) protected override string GetFullPath(string path)
{ {
return string.Format("{0}[{1}].{2}{3}", return string.Format("{0}[{1}].{2}{3}",
PathPrefix == null ? "" : PathPrefix, PathPrefix == null ? "" : PathPrefix,
ArrayIndex, ArrayIndex,
path, path,
PathSuffix == null ? "" : PathSuffix); PathSuffix == null ? "" : PathSuffix);
} }
/// <summary> /// <summary>
/// Process all values /// Process all values
/// </summary> /// </summary>
public override void ProcessAll() public override void ProcessAll()
{ {
if (FindInArray()) if (FindInArray())
base.ProcessAll(); base.ProcessAll();
} }
/// <summary> /// <summary>
/// Provides the path append for GetFullPath /// Provides the path append for GetFullPath
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
string GetPathAppend(string a) string GetPathAppend(string a)
{ {
if (string.IsNullOrEmpty(a)) if (string.IsNullOrEmpty(a))
{ {
return ""; return "";
} }
if (a.StartsWith(".")) if (a.StartsWith("."))
{ {
return a; return a;
} }
else else
{ {
return "." + a; return "." + a;
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
bool FindInArray() bool FindInArray()
{ {
if (Master == null) if (Master == null)
throw new InvalidOperationException("Cannot do operations before master is linked"); throw new InvalidOperationException("Cannot do operations before master is linked");
if (Master.JsonObject == null) if (Master.JsonObject == null)
throw new InvalidOperationException("Cannot do operations before master JSON has read"); throw new InvalidOperationException("Cannot do operations before master JSON has read");
if (PathPrefix == null) if (PathPrefix == null)
throw new InvalidOperationException("Cannot do operations before PathPrefix is set"); throw new InvalidOperationException("Cannot do operations before PathPrefix is set");
var token = Master.JsonObject.SelectToken(PathPrefix); var token = Master.JsonObject.SelectToken(PathPrefix);
if (token is JArray) if (token is JArray)
{ {
var array = token as JArray; var array = token as JArray;
try try
{ {
var item = array.FirstOrDefault(o => var item = array.FirstOrDefault(o =>
{ {
var prop = o[SearchPropertyName]; var prop = o[SearchPropertyName];
return prop != null && prop.Value<string>() return prop != null && prop.Value<string>()
.Equals(SearchPropertyValue, StringComparison.OrdinalIgnoreCase); .Equals(SearchPropertyValue, StringComparison.OrdinalIgnoreCase);
}); });
if (item == null) if (item == null)
{ {
Debug.Console(1, "JSON Child[{0}] Array '{1}' '{2}={3}' not found: ", Key, Debug.Console(1, "JSON Child[{0}] Array '{1}' '{2}={3}' not found: ", Key,
PathPrefix, SearchPropertyName, SearchPropertyValue); PathPrefix, SearchPropertyName, SearchPropertyValue);
this.LinkedToObject = false; this.LinkedToObject = false;
return false; return false;
} }
this.LinkedToObject = true; this.LinkedToObject = true;
ArrayIndex = array.IndexOf(item); ArrayIndex = array.IndexOf(item);
OnStringChange(string.Format("{0}[{1}]", PathPrefix, ArrayIndex), 0, JsonToSimplConstants.FullPathToArrayChange); OnStringChange(string.Format("{0}[{1}]", PathPrefix, ArrayIndex), 0, JsonToSimplConstants.FullPathToArrayChange);
Debug.Console(1, "JSON Child[{0}] Found array match at index {1}", Key, ArrayIndex); Debug.Console(1, "JSON Child[{0}] Found array match at index {1}", Key, ArrayIndex);
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(1, "JSON Child[{0}] Array '{1}' lookup error: '{2}={3}'\r{4}", Key, Debug.Console(1, "JSON Child[{0}] Array '{1}' lookup error: '{2}={3}'\r{4}", Key,
PathPrefix, SearchPropertyName, SearchPropertyValue, e); PathPrefix, SearchPropertyName, SearchPropertyValue, e);
} }
} }
else else
{ {
Debug.Console(1, "JSON Child[{0}] Path '{1}' is not an array", Key, PathPrefix); Debug.Console(1, "JSON Child[{0}] Path '{1}' is not an array", Key, PathPrefix);
} }
return false; return false;
} }
} }
} }

View File

@@ -1,11 +1,10 @@
using Newtonsoft.Json.Linq;
using PepperDash.Core.Interfaces;
using PepperDash.Core.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
@@ -13,7 +12,7 @@ namespace PepperDash.Core.JsonToSimpl
/// Base class for JSON objects /// Base class for JSON objects
/// </summary> /// </summary>
public abstract class JsonToSimplChildObjectBase : IKeyed public abstract class JsonToSimplChildObjectBase : IKeyed
{ {
/// <summary> /// <summary>
/// Notifies of bool change /// Notifies of bool change
/// </summary> /// </summary>
@@ -32,26 +31,26 @@ namespace PepperDash.Core.JsonToSimpl
/// </summary> /// </summary>
public SPlusValuesDelegate GetAllValuesDelegate { get; set; } public SPlusValuesDelegate GetAllValuesDelegate { get; set; }
/// <summary> /// <summary>
/// Use a callback to reduce task switch/threading /// Use a callback to reduce task switch/threading
/// </summary> /// </summary>
public SPlusValuesDelegate SetAllPathsDelegate { get; set; } public SPlusValuesDelegate SetAllPathsDelegate { get; set; }
/// <summary> /// <summary>
/// Unique identifier for instance /// Unique identifier for instance
/// </summary> /// </summary>
public string Key { get; protected set; } public string Key { get; protected set; }
/// <summary> /// <summary>
/// This will be prepended to all paths to allow path swapping or for more organized /// This will be prepended to all paths to allow path swapping or for more organized
/// sub-paths /// sub-paths
/// </summary> /// </summary>
public string PathPrefix { get; protected set; } public string PathPrefix { get; protected set; }
/// <summary> /// <summary>
/// This is added to the end of all paths /// This is added to the end of all paths
/// </summary> /// </summary>
public string PathSuffix { get; protected set; } public string PathSuffix { get; protected set; }
/// <summary> /// <summary>
/// Indicates if the instance is linked to an object /// Indicates if the instance is linked to an object
@@ -76,107 +75,109 @@ namespace PepperDash.Core.JsonToSimpl
/// </summary> /// </summary>
protected Dictionary<ushort, string> StringPaths = new Dictionary<ushort, string>(); protected Dictionary<ushort, string> StringPaths = new Dictionary<ushort, string>();
/// <summary> /// <summary>
/// Call this before doing anything else /// Call this before doing anything else
/// </summary> /// </summary>
/// <param name="masterUniqueId"></param> /// <param name="masterUniqueId"></param>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="pathPrefix"></param> /// <param name="pathPrefix"></param>
/// <param name="pathSuffix"></param> /// <param name="pathSuffix"></param>
public void Initialize(string masterUniqueId, string key, string pathPrefix, string pathSuffix) public void Initialize(string masterUniqueId, string key, string pathPrefix, string pathSuffix)
{ {
Key = key; Key = key;
PathPrefix = pathPrefix; PathPrefix = pathPrefix;
PathSuffix = pathSuffix; PathSuffix = pathSuffix;
Master = J2SGlobal.GetMasterByFile(masterUniqueId); Master = J2SGlobal.GetMasterByFile(masterUniqueId);
if (Master != null) if (Master != null)
Master.AddChild(this); Master.AddChild(this);
else else
Debug.Console(1, "JSON Child [{0}] cannot link to master {1}", key, masterUniqueId); Debug.Console(1, "JSON Child [{0}] cannot link to master {1}", key, masterUniqueId);
} }
/// <summary> /// <summary>
/// Sets the path prefix for the object /// Sets the path prefix for the object
/// </summary> /// </summary>
/// <param name="pathPrefix"></param> /// <param name="pathPrefix"></param>
public void SetPathPrefix(string pathPrefix) public void SetPathPrefix(string pathPrefix)
{ {
PathPrefix = pathPrefix; PathPrefix = pathPrefix;
} }
/// <summary> /// <summary>
/// Set the JPath to evaluate for a given bool out index. /// Set the JPath to evaluate for a given bool out index.
/// </summary> /// </summary>
public void SetBoolPath(ushort index, string path) public void SetBoolPath(ushort index, string path)
{ {
Debug.Console(1, "JSON Child[{0}] SetBoolPath {1}={2}", Key, index, path); Debug.Console(1, "JSON Child[{0}] SetBoolPath {1}={2}", Key, index, path);
if (path == null || path.Trim() == string.Empty) return; if (path == null || path.Trim() == string.Empty) return;
BoolPaths[index] = path; BoolPaths[index] = path;
} }
/// <summary> /// <summary>
/// Set the JPath for a ushort out index. /// Set the JPath for a ushort out index.
/// </summary> /// </summary>
public void SetUshortPath(ushort index, string path) public void SetUshortPath(ushort index, string path)
{ {
Debug.Console(1, "JSON Child[{0}] SetUshortPath {1}={2}", Key, index, path); Debug.Console(1, "JSON Child[{0}] SetUshortPath {1}={2}", Key, index, path);
if (path == null || path.Trim() == string.Empty) return; if (path == null || path.Trim() == string.Empty) return;
UshortPaths[index] = path; UshortPaths[index] = path;
} }
/// <summary> /// <summary>
/// Set the JPath for a string output index. /// Set the JPath for a string output index.
/// </summary> /// </summary>
public void SetStringPath(ushort index, string path) public void SetStringPath(ushort index, string path)
{ {
Debug.Console(1, "JSON Child[{0}] SetStringPath {1}={2}", Key, index, path); Debug.Console(1, "JSON Child[{0}] SetStringPath {1}={2}", Key, index, path);
if (path == null || path.Trim() == string.Empty) return; if (path == null || path.Trim() == string.Empty) return;
StringPaths[index] = path; StringPaths[index] = path;
} }
/// <summary> /// <summary>
/// Evalutates all outputs with defined paths. called by S+ when paths are ready to process /// Evalutates all outputs with defined paths. called by S+ when paths are ready to process
/// and by Master when file is read. /// and by Master when file is read.
/// </summary> /// </summary>
public virtual void ProcessAll() public virtual void ProcessAll()
{ {
if (!LinkedToObject) if (!LinkedToObject)
{ {
Debug.Console(1, this, "Not linked to object in file. Skipping"); Debug.Console(1, this, "Not linked to object in file. Skipping");
return; return;
} }
if (SetAllPathsDelegate == null) if (SetAllPathsDelegate == null)
{ {
Debug.Console(1, this, "No SetAllPathsDelegate set. Ignoring ProcessAll"); Debug.Console(1, this, "No SetAllPathsDelegate set. Ignoring ProcessAll");
return; return;
} }
SetAllPathsDelegate(); SetAllPathsDelegate();
foreach (var kvp in BoolPaths) foreach (var kvp in BoolPaths)
ProcessBoolPath(kvp.Key); ProcessBoolPath(kvp.Key);
foreach (var kvp in UshortPaths) foreach (var kvp in UshortPaths)
ProcessUshortPath(kvp.Key); ProcessUshortPath(kvp.Key);
foreach (var kvp in StringPaths) foreach (var kvp in StringPaths)
ProcessStringPath(kvp.Key); ProcessStringPath(kvp.Key);
} }
/// <summary> /// <summary>
/// Processes a bool property, converting to bool, firing off a BoolChange event /// Processes a bool property, converting to bool, firing off a BoolChange event
/// </summary> /// </summary>
void ProcessBoolPath(ushort index) void ProcessBoolPath(ushort index)
{ {
string response;
if (Process(BoolPaths[index], out response))
OnBoolChange(response.Equals("true", StringComparison.OrdinalIgnoreCase),
index, JsonToSimplConstants.BoolValueChange);
else { }
// OnBoolChange(false, index, JsonToSimplConstants.BoolValueChange);
}
// Processes the path to a ushort, converting to ushort if able, twos complement if necessary, firing off UshrtChange event
void ProcessUshortPath(ushort index) {
string response; string response;
if (Process(UshortPaths[index], out response)) { if (Process(BoolPaths[index], out response))
OnBoolChange(response.Equals("true", StringComparison.OrdinalIgnoreCase),
index, JsonToSimplConstants.BoolValueChange);
else { }
// OnBoolChange(false, index, JsonToSimplConstants.BoolValueChange);
}
// Processes the path to a ushort, converting to ushort if able, twos complement if necessary, firing off UshrtChange event
void ProcessUshortPath(ushort index)
{
string response;
if (Process(UshortPaths[index], out response))
{
ushort val; ushort val;
try { val = Convert.ToInt32(response) < 0 ? (ushort)(Convert.ToInt16(response) + 65536) : Convert.ToUInt16(response); } try { val = Convert.ToInt32(response) < 0 ? (ushort)(Convert.ToInt16(response) + 65536) : Convert.ToUInt16(response); }
catch { val = 0; } catch { val = 0; }
@@ -187,94 +188,94 @@ namespace PepperDash.Core.JsonToSimpl
// OnUShortChange(0, index, JsonToSimplConstants.UshortValueChange); // OnUShortChange(0, index, JsonToSimplConstants.UshortValueChange);
} }
// Processes the path to a string property and fires of a StringChange event. // Processes the path to a string property and fires of a StringChange event.
void ProcessStringPath(ushort index) void ProcessStringPath(ushort index)
{ {
string response; string response;
if (Process(StringPaths[index], out response)) if (Process(StringPaths[index], out response))
OnStringChange(response, index, JsonToSimplConstants.StringValueChange); OnStringChange(response, index, JsonToSimplConstants.StringValueChange);
else { } else { }
// OnStringChange("", index, JsonToSimplConstants.StringValueChange); // OnStringChange("", index, JsonToSimplConstants.StringValueChange);
} }
/// <summary> /// <summary>
/// Processes the given path. /// Processes the given path.
/// </summary> /// </summary>
/// <param name="path">JPath formatted path to the desired property</param> /// <param name="path">JPath formatted path to the desired property</param>
/// <param name="response">The string value of the property, or a default value if it /// <param name="response">The string value of the property, or a default value if it
/// doesn't exist</param> /// doesn't exist</param>
/// <returns> This will return false in the case that EvaulateAllOnJsonChange /// <returns> This will return false in the case that EvaulateAllOnJsonChange
/// is false and the path does not evaluate to a property in the incoming JSON. </returns> /// is false and the path does not evaluate to a property in the incoming JSON. </returns>
bool Process(string path, out string response) bool Process(string path, out string response)
{ {
path = GetFullPath(path); path = GetFullPath(path);
Debug.Console(1, "JSON Child[{0}] Processing {1}", Key, path); Debug.Console(1, "JSON Child[{0}] Processing {1}", Key, path);
response = ""; response = "";
if (Master == null) if (Master == null)
{ {
Debug.Console(1, "JSONChild[{0}] cannot process without Master attached", Key); Debug.Console(1, "JSONChild[{0}] cannot process without Master attached", Key);
return false; return false;
} }
if (Master.JsonObject != null && path != string.Empty) if (Master.JsonObject != null && path != string.Empty)
{ {
bool isCount = false; bool isCount = false;
path = path.Trim(); path = path.Trim();
if (path.EndsWith(".Count")) if (path.EndsWith(".Count"))
{ {
path = path.Remove(path.Length - 6, 6); path = path.Remove(path.Length - 6, 6);
isCount = true; isCount = true;
} }
try // Catch a strange cast error on a bad path try // Catch a strange cast error on a bad path
{ {
var t = Master.JsonObject.SelectToken(path); var t = Master.JsonObject.SelectToken(path);
if (t != null) if (t != null)
{ {
// return the count of children objects - if any // return the count of children objects - if any
if (isCount) if (isCount)
response = (t.HasValues ? t.Children().Count() : 0).ToString(); response = (t.HasValues ? t.Children().Count() : 0).ToString();
else else
response = t.Value<string>(); response = t.Value<string>();
Debug.Console(1, " ='{0}'", response); Debug.Console(1, " ='{0}'", response);
return true; return true;
} }
} }
catch catch
{ {
response = ""; response = "";
} }
} }
// If the path isn't found, return this to determine whether to pass out the non-value or not. // If the path isn't found, return this to determine whether to pass out the non-value or not.
return false; return false;
} }
//************************************************************************************************ //************************************************************************************************
// Save-related functions // Save-related functions
/// <summary> /// <summary>
/// Called from Master to read inputs and update their values in master JObject /// Called from Master to read inputs and update their values in master JObject
/// Callback should hit one of the following four methods /// Callback should hit one of the following four methods
/// </summary> /// </summary>
public void UpdateInputsForMaster() public void UpdateInputsForMaster()
{ {
if (!LinkedToObject) if (!LinkedToObject)
{ {
Debug.Console(1, this, "Not linked to object in file. Skipping"); Debug.Console(1, this, "Not linked to object in file. Skipping");
return; return;
} }
if (SetAllPathsDelegate == null) if (SetAllPathsDelegate == null)
{ {
Debug.Console(1, this, "No SetAllPathsDelegate set. Ignoring UpdateInputsForMaster"); Debug.Console(1, this, "No SetAllPathsDelegate set. Ignoring UpdateInputsForMaster");
return; return;
} }
SetAllPathsDelegate(); SetAllPathsDelegate();
var del = GetAllValuesDelegate; var del = GetAllValuesDelegate;
if (del != null) if (del != null)
GetAllValuesDelegate(); GetAllValuesDelegate();
} }
/// <summary> /// <summary>
/// ///
@@ -282,9 +283,9 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="theValue"></param> /// <param name="theValue"></param>
public void USetBoolValue(ushort key, ushort theValue) public void USetBoolValue(ushort key, ushort theValue)
{ {
SetBoolValue(key, theValue == 1); SetBoolValue(key, theValue == 1);
} }
/// <summary> /// <summary>
/// ///
@@ -292,10 +293,10 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="theValue"></param> /// <param name="theValue"></param>
public void SetBoolValue(ushort key, bool theValue) public void SetBoolValue(ushort key, bool theValue)
{ {
if (BoolPaths.ContainsKey(key)) if (BoolPaths.ContainsKey(key))
SetValueOnMaster(BoolPaths[key], new JValue(theValue)); SetValueOnMaster(BoolPaths[key], new JValue(theValue));
} }
/// <summary> /// <summary>
/// ///
@@ -303,10 +304,10 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="theValue"></param> /// <param name="theValue"></param>
public void SetUShortValue(ushort key, ushort theValue) public void SetUShortValue(ushort key, ushort theValue)
{ {
if (UshortPaths.ContainsKey(key)) if (UshortPaths.ContainsKey(key))
SetValueOnMaster(UshortPaths[key], new JValue(theValue)); SetValueOnMaster(UshortPaths[key], new JValue(theValue));
} }
/// <summary> /// <summary>
/// ///
@@ -314,10 +315,10 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="theValue"></param> /// <param name="theValue"></param>
public void SetStringValue(ushort key, string theValue) public void SetStringValue(ushort key, string theValue)
{ {
if (StringPaths.ContainsKey(key)) if (StringPaths.ContainsKey(key))
SetValueOnMaster(StringPaths[key], new JValue(theValue)); SetValueOnMaster(StringPaths[key], new JValue(theValue));
} }
/// <summary> /// <summary>
/// ///
@@ -325,68 +326,68 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="keyPath"></param> /// <param name="keyPath"></param>
/// <param name="valueToSave"></param> /// <param name="valueToSave"></param>
public void SetValueOnMaster(string keyPath, JValue valueToSave) public void SetValueOnMaster(string keyPath, JValue valueToSave)
{ {
var path = GetFullPath(keyPath); var path = GetFullPath(keyPath);
try try
{ {
Debug.Console(1, "JSON Child[{0}] Queueing value on master {1}='{2}'", Key, path, valueToSave); Debug.Console(1, "JSON Child[{0}] Queueing value on master {1}='{2}'", Key, path, valueToSave);
//var token = Master.JsonObject.SelectToken(path); //var token = Master.JsonObject.SelectToken(path);
//if (token != null) // The path exists in the file //if (token != null) // The path exists in the file
Master.AddUnsavedValue(path, valueToSave); Master.AddUnsavedValue(path, valueToSave);
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(1, "JSON Child[{0}] Failed setting value for path '{1}'\r{2}", Key, path, e); Debug.Console(1, "JSON Child[{0}] Failed setting value for path '{1}'\r{2}", Key, path, e);
} }
} }
/// <summary> /// <summary>
/// Called during Process(...) to get the path to a given property. By default, /// Called during Process(...) to get the path to a given property. By default,
/// returns PathPrefix+path+PathSuffix. Override to change the way path is built. /// returns PathPrefix+path+PathSuffix. Override to change the way path is built.
/// </summary> /// </summary>
protected virtual string GetFullPath(string path) protected virtual string GetFullPath(string path)
{ {
return (PathPrefix != null ? PathPrefix : "") + return (PathPrefix != null ? PathPrefix : "") +
path + (PathSuffix != null ? PathSuffix : ""); path + (PathSuffix != null ? PathSuffix : "");
} }
// Helpers for events // Helpers for events
//****************************************************************************************** //******************************************************************************************
/// <summary> /// <summary>
/// Event helper /// Event helper
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
var handler = BoolChange; var handler = BoolChange;
if (handler != null) if (handler != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
//****************************************************************************************** //******************************************************************************************
/// <summary> /// <summary>
/// Event helper /// Event helper
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnUShortChange(ushort state, ushort index, ushort type) protected void OnUShortChange(ushort state, ushort index, ushort type)
{ {
var handler = UShortChange; var handler = UShortChange;
if (handler != null) if (handler != null)
{ {
var args = new UshrtChangeEventArgs(state, type); var args = new UshrtChangeEventArgs(state, type);
args.Index = index; args.Index = index;
UShortChange(this, args); UShortChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Event helper /// Event helper
@@ -395,14 +396,14 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
var handler = StringChange; var handler = StringChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
} }
} }

View File

@@ -1,14 +1,13 @@
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json.Linq;
using PepperDash.Core.Logging;
using System; using System;
//using System.IO; //using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {

View File

@@ -1,14 +1,4 @@
//using System.IO;
using System;
//using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
@@ -16,13 +6,13 @@ namespace PepperDash.Core.JsonToSimpl
/// ///
/// </summary> /// </summary>
public class JsonToSimplFixedPathObject : JsonToSimplChildObjectBase public class JsonToSimplFixedPathObject : JsonToSimplChildObjectBase
{ {
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public JsonToSimplFixedPathObject() public JsonToSimplFixedPathObject()
{ {
this.LinkedToObject = true; this.LinkedToObject = true;
} }
} }
} }

View File

@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core.Logging;
using System;
using System.Collections.Generic;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
@@ -12,109 +13,109 @@ namespace PepperDash.Core.JsonToSimpl
/// </summary> /// </summary>
public class JsonToSimplGenericMaster : JsonToSimplMaster public class JsonToSimplGenericMaster : JsonToSimplMaster
{ {
/*****************************************************************************************/ /*****************************************************************************************/
/** Privates **/ /** Privates **/
// The JSON file in JObject form // The JSON file in JObject form
// For gathering the incoming data // For gathering the incoming data
object StringBuilderLock = new object(); object StringBuilderLock = new object();
// To prevent multiple same-file access // To prevent multiple same-file access
static object WriteLock = new object(); static object WriteLock = new object();
/// <summary> /// <summary>
/// Callback action for saving /// Callback action for saving
/// </summary> /// </summary>
public Action<string> SaveCallback { get; set; } public Action<string> SaveCallback { get; set; }
/*****************************************************************************************/ /*****************************************************************************************/
/// <summary> /// <summary>
/// SIMPL+ default constructor. /// SIMPL+ default constructor.
/// </summary> /// </summary>
public JsonToSimplGenericMaster() public JsonToSimplGenericMaster()
{ {
} }
/// <summary> /// <summary>
/// Loads in JSON and triggers evaluation on all children /// Loads in JSON and triggers evaluation on all children
/// </summary> /// </summary>
/// <param name="json"></param> /// <param name="json"></param>
public void LoadWithJson(string json) public void LoadWithJson(string json)
{ {
OnBoolChange(false, 0, JsonToSimplConstants.JsonIsValidBoolChange); OnBoolChange(false, 0, JsonToSimplConstants.JsonIsValidBoolChange);
try try
{ {
JsonObject = JObject.Parse(json); JsonObject = JObject.Parse(json);
foreach (var child in Children) foreach (var child in Children)
child.ProcessAll(); child.ProcessAll();
OnBoolChange(true, 0, JsonToSimplConstants.JsonIsValidBoolChange); OnBoolChange(true, 0, JsonToSimplConstants.JsonIsValidBoolChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("JSON parsing failed:\r{0}", e); var msg = string.Format("JSON parsing failed:\r{0}", e);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
ErrorLog.Error(msg); ErrorLog.Error(msg);
} }
} }
/// <summary> /// <summary>
/// Loads JSON into JsonObject, but does not trigger evaluation by children /// Loads JSON into JsonObject, but does not trigger evaluation by children
/// </summary> /// </summary>
/// <param name="json"></param> /// <param name="json"></param>
public void SetJsonWithoutEvaluating(string json) public void SetJsonWithoutEvaluating(string json)
{ {
try try
{ {
JsonObject = JObject.Parse(json); JsonObject = JObject.Parse(json);
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(0, this, "JSON parsing failed:\r{0}", e); Debug.Console(0, this, "JSON parsing failed:\r{0}", e);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public override void Save() public override void Save()
{ {
// this code is duplicated in the other masters!!!!!!!!!!!!! // this code is duplicated in the other masters!!!!!!!!!!!!!
UnsavedValues = new Dictionary<string, JValue>(); UnsavedValues = new Dictionary<string, JValue>();
// Make each child update their values into master object // Make each child update their values into master object
foreach (var child in Children) foreach (var child in Children)
{ {
Debug.Console(1, this, "Master. checking child [{0}] for updates to save", child.Key); Debug.Console(1, this, "Master. checking child [{0}] for updates to save", child.Key);
child.UpdateInputsForMaster(); child.UpdateInputsForMaster();
} }
if (UnsavedValues == null || UnsavedValues.Count == 0) if (UnsavedValues == null || UnsavedValues.Count == 0)
{ {
Debug.Console(1, this, "Master. No updated values to save. Skipping"); Debug.Console(1, this, "Master. No updated values to save. Skipping");
return; return;
} }
lock (WriteLock) lock (WriteLock)
{ {
Debug.Console(1, this, "Saving"); Debug.Console(1, this, "Saving");
foreach (var path in UnsavedValues.Keys) foreach (var path in UnsavedValues.Keys)
{ {
var tokenToReplace = JsonObject.SelectToken(path); var tokenToReplace = JsonObject.SelectToken(path);
if (tokenToReplace != null) if (tokenToReplace != null)
{// It's found {// It's found
tokenToReplace.Replace(UnsavedValues[path]); tokenToReplace.Replace(UnsavedValues[path]);
Debug.Console(1, this, "Master Updating '{0}'", path); Debug.Console(1, this, "Master Updating '{0}'", path);
} }
else // No token. Let's make one else // No token. Let's make one
{ {
Debug.Console(1, "Master Cannot write value onto missing property: '{0}'", path); Debug.Console(1, "Master Cannot write value onto missing property: '{0}'", path);
} }
} }
} }
if (SaveCallback != null) if (SaveCallback != null)
SaveCallback(JsonObject.ToString()); SaveCallback(JsonObject.ToString());
else else
Debug.Console(0, this, "WARNING: No save callback defined."); Debug.Console(0, this, "WARNING: No save callback defined.");
} }
} }
} }

View File

@@ -1,14 +1,13 @@
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core.Interfaces;
using PepperDash.Core.Logging;
using System; using System;
//using System.IO; //using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
@@ -16,7 +15,7 @@ namespace PepperDash.Core.JsonToSimpl
/// Abstract base class for JsonToSimpl interactions /// Abstract base class for JsonToSimpl interactions
/// </summary> /// </summary>
public abstract class JsonToSimplMaster : IKeyed public abstract class JsonToSimplMaster : IKeyed
{ {
/// <summary> /// <summary>
/// Notifies of bool change /// Notifies of bool change
/// </summary> /// </summary>
@@ -35,116 +34,116 @@ namespace PepperDash.Core.JsonToSimpl
/// </summary> /// </summary>
protected List<JsonToSimplChildObjectBase> Children = new List<JsonToSimplChildObjectBase>(); protected List<JsonToSimplChildObjectBase> Children = new List<JsonToSimplChildObjectBase>();
/*****************************************************************************************/ /*****************************************************************************************/
/// <summary> /// <summary>
/// Mirrors the Unique ID for now. /// Mirrors the Unique ID for now.
/// </summary> /// </summary>
public string Key { get { return UniqueID; } } public string Key { get { return UniqueID; } }
/// <summary> /// <summary>
/// A unique ID /// A unique ID
/// </summary> /// </summary>
public string UniqueID { get; protected set; } public string UniqueID { get; protected set; }
/// <summary> /// <summary>
/// Merely for use in debug messages /// Merely for use in debug messages
/// </summary> /// </summary>
public string DebugName public string DebugName
{ {
get { return _DebugName; } get { return _DebugName; }
set { if (DebugName == null) _DebugName = ""; else _DebugName = value; } set { if (DebugName == null) _DebugName = ""; else _DebugName = value; }
} }
string _DebugName = ""; string _DebugName = "";
/// <summary> /// <summary>
/// This will be prepended to all paths to allow path swapping or for more organized /// This will be prepended to all paths to allow path swapping or for more organized
/// sub-paths /// sub-paths
/// </summary> /// </summary>
public string PathPrefix { get; set; } public string PathPrefix { get; set; }
/// <summary> /// <summary>
/// This is added to the end of all paths /// This is added to the end of all paths
/// </summary> /// </summary>
public string PathSuffix { get; set; } public string PathSuffix { get; set; }
/// <summary> /// <summary>
/// Enables debugging output to the console. Certain error messages will be logged to the /// Enables debugging output to the console. Certain error messages will be logged to the
/// system's error log regardless of this setting /// system's error log regardless of this setting
/// </summary> /// </summary>
public bool DebugOn { get; set; } public bool DebugOn { get; set; }
/// <summary> /// <summary>
/// Ushort helper for Debug property /// Ushort helper for Debug property
/// </summary> /// </summary>
public ushort UDebug public ushort UDebug
{ {
get { return (ushort)(DebugOn ? 1 : 0); } get { return (ushort)(DebugOn ? 1 : 0); }
set set
{ {
DebugOn = (value == 1); DebugOn = (value == 1);
CrestronConsole.PrintLine("JsonToSimpl debug={0}", DebugOn); CrestronConsole.PrintLine("JsonToSimpl debug={0}", DebugOn);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public JObject JsonObject { get; protected set; } public JObject JsonObject { get; protected set; }
/*****************************************************************************************/ /*****************************************************************************************/
/** Privates **/ /** Privates **/
// The JSON file in JObject form // The JSON file in JObject form
// For gathering the incoming data // For gathering the incoming data
protected Dictionary<string, JValue> UnsavedValues = new Dictionary<string, JValue>(); protected Dictionary<string, JValue> UnsavedValues = new Dictionary<string, JValue>();
/*****************************************************************************************/ /*****************************************************************************************/
/// <summary> /// <summary>
/// SIMPL+ default constructor. /// SIMPL+ default constructor.
/// </summary> /// </summary>
public JsonToSimplMaster() public JsonToSimplMaster()
{ {
} }
/// <summary> /// <summary>
/// Sets up class - overriding methods should always call this. /// Sets up class - overriding methods should always call this.
/// </summary> /// </summary>
/// <param name="uniqueId"></param> /// <param name="uniqueId"></param>
public virtual void Initialize(string uniqueId) public virtual void Initialize(string uniqueId)
{ {
UniqueID = uniqueId; UniqueID = uniqueId;
J2SGlobal.AddMaster(this); // Should not re-add J2SGlobal.AddMaster(this); // Should not re-add
} }
/// <summary> /// <summary>
/// Adds a child "module" to this master /// Adds a child "module" to this master
/// </summary> /// </summary>
/// <param name="child"></param> /// <param name="child"></param>
public void AddChild(JsonToSimplChildObjectBase child) public void AddChild(JsonToSimplChildObjectBase child)
{ {
if (!Children.Contains(child)) if (!Children.Contains(child))
{ {
Children.Add(child); Children.Add(child);
} }
} }
/// <summary> /// <summary>
/// Called from the child to add changed or new values for saving /// Called from the child to add changed or new values for saving
/// </summary> /// </summary>
public void AddUnsavedValue(string path, JValue value) public void AddUnsavedValue(string path, JValue value)
{ {
if (UnsavedValues.ContainsKey(path)) if (UnsavedValues.ContainsKey(path))
{ {
Debug.Console(0, "Master[{0}] WARNING - Attempt to add duplicate value for path '{1}'.\r Ingoring. Please ensure that path does not exist on multiple modules.", UniqueID, path); Debug.Console(0, "Master[{0}] WARNING - Attempt to add duplicate value for path '{1}'.\r Ingoring. Please ensure that path does not exist on multiple modules.", UniqueID, path);
} }
else else
UnsavedValues.Add(path, value); UnsavedValues.Add(path, value);
//Debug.Console(0, "Master[{0}] Unsaved size={1}", UniqueID, UnsavedValues.Count); //Debug.Console(0, "Master[{0}] Unsaved size={1}", UniqueID, UnsavedValues.Count);
} }
/// <summary> /// <summary>
/// Saves the file /// Saves the file
@@ -152,27 +151,27 @@ namespace PepperDash.Core.JsonToSimpl
public abstract void Save(); public abstract void Save();
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public static class JsonFixes public static class JsonFixes
{ {
/// <summary> /// <summary>
/// Deserializes a string into a JObject /// Deserializes a string into a JObject
/// </summary> /// </summary>
/// <param name="json"></param> /// <param name="json"></param>
/// <returns></returns> /// <returns></returns>
public static JObject ParseObject(string json) public static JObject ParseObject(string json)
{ {
using (var reader = new JsonTextReader(new System.IO.StringReader(json))) using (var reader = new JsonTextReader(new System.IO.StringReader(json)))
{ {
var startDepth = reader.Depth; var startDepth = reader.Depth;
var obj = JObject.Load(reader); var obj = JObject.Load(reader);
if (startDepth != reader.Depth) if (startDepth != reader.Depth)
throw new JsonSerializationException("Unenclosed json found"); throw new JsonSerializationException("Unenclosed json found");
return obj; return obj;
} }
} }
/// <summary> /// <summary>
/// Deserializes a string into a JArray /// Deserializes a string into a JArray
@@ -180,49 +179,49 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="json"></param> /// <param name="json"></param>
/// <returns></returns> /// <returns></returns>
public static JArray ParseArray(string json) public static JArray ParseArray(string json)
{ {
using (var reader = new JsonTextReader(new System.IO.StringReader(json))) using (var reader = new JsonTextReader(new System.IO.StringReader(json)))
{ {
var startDepth = reader.Depth; var startDepth = reader.Depth;
var obj = JArray.Load(reader); var obj = JArray.Load(reader);
if (startDepth != reader.Depth) if (startDepth != reader.Depth)
throw new JsonSerializationException("Unenclosed json found"); throw new JsonSerializationException("Unenclosed json found");
return obj; return obj;
} }
} }
} }
/// <summary> /// <summary>
/// Helper event /// Helper event
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
if (BoolChange != null) if (BoolChange != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Helper event /// Helper event
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnUshrtChange(ushort state, ushort index, ushort type) protected void OnUshrtChange(ushort state, ushort index, ushort type)
{ {
if (UshrtChange != null) if (UshrtChange != null)
{ {
var args = new UshrtChangeEventArgs(state, type); var args = new UshrtChangeEventArgs(state, type);
args.Index = index; args.Index = index;
UshrtChange(this, args); UshrtChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Helper event /// Helper event
@@ -231,13 +230,13 @@ namespace PepperDash.Core.JsonToSimpl
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
if (StringChange != null) if (StringChange != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
} }
} }

View File

@@ -1,16 +1,14 @@
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json.Linq;
using PepperDash.Core.Config;
using PepperDash.Core.Logging;
using System; using System;
//using System.IO; //using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core.Config;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
@@ -19,179 +17,179 @@ namespace PepperDash.Core.JsonToSimpl
/// </summary> /// </summary>
public class JsonToSimplPortalFileMaster : JsonToSimplMaster public class JsonToSimplPortalFileMaster : JsonToSimplMaster
{ {
/// <summary> /// <summary>
/// Sets the filepath as well as registers this with the Global.Masters list /// Sets the filepath as well as registers this with the Global.Masters list
/// </summary> /// </summary>
public string PortalFilepath { get; private set; } public string PortalFilepath { get; private set; }
/// <summary> /// <summary>
/// File path of the actual file being read (Portal or local) /// File path of the actual file being read (Portal or local)
/// </summary> /// </summary>
public string ActualFilePath { get; private set; } public string ActualFilePath { get; private set; }
/*****************************************************************************************/ /*****************************************************************************************/
/** Privates **/ /** Privates **/
// To prevent multiple same-file access // To prevent multiple same-file access
object StringBuilderLock = new object(); object StringBuilderLock = new object();
static object FileLock = new object(); static object FileLock = new object();
/*****************************************************************************************/ /*****************************************************************************************/
/// <summary> /// <summary>
/// SIMPL+ default constructor. /// SIMPL+ default constructor.
/// </summary> /// </summary>
public JsonToSimplPortalFileMaster() public JsonToSimplPortalFileMaster()
{ {
} }
/// <summary> /// <summary>
/// Read, evaluate and udpate status /// Read, evaluate and udpate status
/// </summary> /// </summary>
public void EvaluateFile(string portalFilepath) public void EvaluateFile(string portalFilepath)
{ {
PortalFilepath = portalFilepath; PortalFilepath = portalFilepath;
OnBoolChange(false, 0, JsonToSimplConstants.JsonIsValidBoolChange); OnBoolChange(false, 0, JsonToSimplConstants.JsonIsValidBoolChange);
if (string.IsNullOrEmpty(PortalFilepath)) if (string.IsNullOrEmpty(PortalFilepath))
{ {
CrestronConsole.PrintLine("Cannot evaluate file. JSON file path not set"); CrestronConsole.PrintLine("Cannot evaluate file. JSON file path not set");
return; return;
} }
// Resolve possible wildcarded filename // Resolve possible wildcarded filename
// If the portal file is xyz.json, then // If the portal file is xyz.json, then
// the file we want to check for first will be called xyz.local.json // the file we want to check for first will be called xyz.local.json
var localFilepath = Path.ChangeExtension(PortalFilepath, "local.json"); var localFilepath = Path.ChangeExtension(PortalFilepath, "local.json");
Debug.Console(0, this, "Checking for local file {0}", localFilepath); Debug.Console(0, this, "Checking for local file {0}", localFilepath);
var actualLocalFile = GetActualFileInfoFromPath(localFilepath); var actualLocalFile = GetActualFileInfoFromPath(localFilepath);
if (actualLocalFile != null) if (actualLocalFile != null)
{ {
ActualFilePath = actualLocalFile.FullName; ActualFilePath = actualLocalFile.FullName;
OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange); OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange);
} }
// If the local file does not exist, then read the portal file xyz.json // If the local file does not exist, then read the portal file xyz.json
// and create the local. // and create the local.
else else
{ {
Debug.Console(1, this, "Local JSON file not found {0}\rLoading portal JSON file", localFilepath); Debug.Console(1, this, "Local JSON file not found {0}\rLoading portal JSON file", localFilepath);
var actualPortalFile = GetActualFileInfoFromPath(portalFilepath); var actualPortalFile = GetActualFileInfoFromPath(portalFilepath);
if (actualPortalFile != null) if (actualPortalFile != null)
{ {
var newLocalPath = Path.ChangeExtension(actualPortalFile.FullName, "local.json"); var newLocalPath = Path.ChangeExtension(actualPortalFile.FullName, "local.json");
// got the portal file, hand off to the merge / save method // got the portal file, hand off to the merge / save method
PortalConfigReader.ReadAndMergeFileIfNecessary(actualPortalFile.FullName, newLocalPath); PortalConfigReader.ReadAndMergeFileIfNecessary(actualPortalFile.FullName, newLocalPath);
ActualFilePath = newLocalPath; ActualFilePath = newLocalPath;
OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange); OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange);
} }
else else
{ {
var msg = string.Format("Portal JSON file not found: {0}", PortalFilepath); var msg = string.Format("Portal JSON file not found: {0}", PortalFilepath);
Debug.Console(1, this, msg); Debug.Console(1, this, msg);
ErrorLog.Error(msg); ErrorLog.Error(msg);
return; return;
} }
} }
// At this point we should have a local file. Do it. // At this point we should have a local file. Do it.
Debug.Console(1, "Reading local JSON file {0}", ActualFilePath); Debug.Console(1, "Reading local JSON file {0}", ActualFilePath);
string json = File.ReadToEnd(ActualFilePath, System.Text.Encoding.ASCII); string json = File.ReadToEnd(ActualFilePath, System.Text.Encoding.ASCII);
try try
{ {
JsonObject = JObject.Parse(json); JsonObject = JObject.Parse(json);
foreach (var child in Children) foreach (var child in Children)
child.ProcessAll(); child.ProcessAll();
OnBoolChange(true, 0, JsonToSimplConstants.JsonIsValidBoolChange); OnBoolChange(true, 0, JsonToSimplConstants.JsonIsValidBoolChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("JSON parsing failed:\r{0}", e); var msg = string.Format("JSON parsing failed:\r{0}", e);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
ErrorLog.Error(msg); ErrorLog.Error(msg);
return; return;
} }
} }
/// <summary> /// <summary>
/// Returns the FileInfo object for a given path, with possible wildcards /// Returns the FileInfo object for a given path, with possible wildcards
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <returns></returns> /// <returns></returns>
FileInfo GetActualFileInfoFromPath(string path) FileInfo GetActualFileInfoFromPath(string path)
{ {
var dir = Path.GetDirectoryName(path); var dir = Path.GetDirectoryName(path);
var localFilename = Path.GetFileName(path); var localFilename = Path.GetFileName(path);
var directory = new DirectoryInfo(dir); var directory = new DirectoryInfo(dir);
// search the directory for the file w/ wildcards // search the directory for the file w/ wildcards
return directory.GetFiles(localFilename).FirstOrDefault(); return directory.GetFiles(localFilename).FirstOrDefault();
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="level"></param> /// <param name="level"></param>
public void setDebugLevel(int level) public void setDebugLevel(int level)
{ {
Debug.SetDebugLevel(level); Debug.SetDebugLevel(level);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public override void Save() public override void Save()
{ {
// this code is duplicated in the other masters!!!!!!!!!!!!! // this code is duplicated in the other masters!!!!!!!!!!!!!
UnsavedValues = new Dictionary<string, JValue>(); UnsavedValues = new Dictionary<string, JValue>();
// Make each child update their values into master object // Make each child update their values into master object
foreach (var child in Children) foreach (var child in Children)
{ {
Debug.Console(1, "Master [{0}] checking child [{1}] for updates to save", UniqueID, child.Key); Debug.Console(1, "Master [{0}] checking child [{1}] for updates to save", UniqueID, child.Key);
child.UpdateInputsForMaster(); child.UpdateInputsForMaster();
} }
if (UnsavedValues == null || UnsavedValues.Count == 0) if (UnsavedValues == null || UnsavedValues.Count == 0)
{ {
Debug.Console(1, "Master [{0}] No updated values to save. Skipping", UniqueID); Debug.Console(1, "Master [{0}] No updated values to save. Skipping", UniqueID);
return; return;
} }
lock (FileLock) lock (FileLock)
{ {
Debug.Console(1, "Saving"); Debug.Console(1, "Saving");
foreach (var path in UnsavedValues.Keys) foreach (var path in UnsavedValues.Keys)
{ {
var tokenToReplace = JsonObject.SelectToken(path); var tokenToReplace = JsonObject.SelectToken(path);
if (tokenToReplace != null) if (tokenToReplace != null)
{// It's found {// It's found
tokenToReplace.Replace(UnsavedValues[path]); tokenToReplace.Replace(UnsavedValues[path]);
Debug.Console(1, "JSON Master[{0}] Updating '{1}'", UniqueID, path); Debug.Console(1, "JSON Master[{0}] Updating '{1}'", UniqueID, path);
} }
else // No token. Let's make one else // No token. Let's make one
{ {
//http://stackoverflow.com/questions/17455052/how-to-set-the-value-of-a-json-path-using-json-net //http://stackoverflow.com/questions/17455052/how-to-set-the-value-of-a-json-path-using-json-net
Debug.Console(1, "JSON Master[{0}] Cannot write value onto missing property: '{1}'", UniqueID, path); Debug.Console(1, "JSON Master[{0}] Cannot write value onto missing property: '{1}'", UniqueID, path);
} }
} }
using (StreamWriter sw = new StreamWriter(ActualFilePath)) using (StreamWriter sw = new StreamWriter(ActualFilePath))
{ {
try try
{ {
sw.Write(JsonObject.ToString()); sw.Write(JsonObject.ToString());
sw.Flush(); sw.Flush();
} }
catch (Exception e) catch (Exception e)
{ {
string err = string.Format("Error writing JSON file:\r{0}", e); string err = string.Format("Error writing JSON file:\r{0}", e);
Debug.Console(0, err); Debug.Console(0, err);
ErrorLog.Warn(err); ErrorLog.Warn(err);
return; return;
} }
} }
} }
} }
} }
} }

View File

@@ -1,16 +1,15 @@
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.CrestronLogger;
using Crestron.SimplSharp.Reflection;
using Newtonsoft.Json;
using PepperDash.Core.Interfaces;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharp.CrestronLogger;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using PepperDash.Core.DebugThings;
namespace PepperDash.Core.Logging
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Contains debug commands for use in various situations /// Contains debug commands for use in various situations
@@ -55,15 +54,15 @@ namespace PepperDash.Core
private static CTimer _saveTimer; private static CTimer _saveTimer;
/// <summary> /// <summary>
/// When true, the IncludedExcludedKeys dict will contain keys to include. /// When true, the IncludedExcludedKeys dict will contain keys to include.
/// When false (default), IncludedExcludedKeys will contain keys to exclude. /// When false (default), IncludedExcludedKeys will contain keys to exclude.
/// </summary> /// </summary>
private static bool _excludeAllMode; private static bool _excludeAllMode;
//static bool ExcludeNoKeyMessages; //static bool ExcludeNoKeyMessages;
private static readonly Dictionary<string, object> IncludedExcludedKeys; private static readonly Dictionary<string, object> IncludedExcludedKeys;
static Debug() static Debug()
{ {
@@ -85,7 +84,7 @@ namespace PepperDash.Core
LogError(ErrorLogLevel.Notice, msg); LogError(ErrorLogLevel.Notice, msg);
IncludedExcludedKeys = new Dictionary<string, object>(); IncludedExcludedKeys = new Dictionary<string, object>();
//CrestronDataStoreStatic.InitCrestronDataStore(); //CrestronDataStoreStatic.InitCrestronDataStore();
if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro) if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
@@ -103,8 +102,8 @@ namespace PepperDash.Core
CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear", CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
"appdebugclear:P Clears the current custom log", "appdebugclear:P Clears the current custom log",
ConsoleAccessLevelEnum.AccessOperator); ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter", CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator); "appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
} }
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
@@ -115,7 +114,7 @@ namespace PepperDash.Core
Level = context.Level; Level = context.Level;
DoNotLoadOnNextBoot = context.DoNotLoadOnNextBoot; DoNotLoadOnNextBoot = context.DoNotLoadOnNextBoot;
if(DoNotLoadOnNextBoot) if (DoNotLoadOnNextBoot)
CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber)); CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
try try
@@ -140,7 +139,7 @@ namespace PepperDash.Core
var assembly = Assembly.GetExecutingAssembly(); var assembly = Assembly.GetExecutingAssembly();
var ver = var ver =
assembly assembly
.GetCustomAttributes(typeof (AssemblyInformationalVersionAttribute), false); .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
if (ver != null && ver.Length > 0) if (ver != null && ver.Length > 0)
{ {
@@ -213,7 +212,7 @@ namespace PepperDash.Core
return; return;
} }
SetDoNotLoadOnNextBoot(Boolean.Parse(stateString)); SetDoNotLoadOnNextBoot(bool.Parse(stateString));
} }
catch catch
{ {
@@ -226,79 +225,79 @@ namespace PepperDash.Core
/// </summary> /// </summary>
/// <param name="items"></param> /// <param name="items"></param>
public static void SetDebugFilterFromConsole(string items) public static void SetDebugFilterFromConsole(string items)
{ {
var str = items.Trim(); var str = items.Trim();
if (str == "?") if (str == "?")
{ {
CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " + CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
"+all: at beginning puts filter into 'default include' mode\r" + "+all: at beginning puts filter into 'default include' mode\r" +
" All keys that follow will be excluded from output.\r" + " All keys that follow will be excluded from output.\r" +
"-all: at beginning puts filter into 'default excluse all' mode.\r" + "-all: at beginning puts filter into 'default excluse all' mode.\r" +
" All keys that follow will be the only keys that are shown\r" + " All keys that follow will be the only keys that are shown\r" +
"+nokey: Enables messages with no key (default)\r" + "+nokey: Enables messages with no key (default)\r" +
"-nokey: Disables messages with no key.\r" + "-nokey: Disables messages with no key.\r" +
"(nokey settings are independent of all other settings)"); "(nokey settings are independent of all other settings)");
return; return;
} }
var keys = Regex.Split(str, @"\s*"); var keys = Regex.Split(str, @"\s*");
foreach (var keyToken in keys) foreach (var keyToken in keys)
{ {
var lkey = keyToken.ToLower(); var lkey = keyToken.ToLower();
if (lkey == "+all") if (lkey == "+all")
{ {
IncludedExcludedKeys.Clear(); IncludedExcludedKeys.Clear();
_excludeAllMode = false; _excludeAllMode = false;
} }
else if (lkey == "-all") else if (lkey == "-all")
{ {
IncludedExcludedKeys.Clear(); IncludedExcludedKeys.Clear();
_excludeAllMode = true; _excludeAllMode = true;
} }
//else if (lkey == "+nokey") //else if (lkey == "+nokey")
//{ //{
// ExcludeNoKeyMessages = false; // ExcludeNoKeyMessages = false;
//} //}
//else if (lkey == "-nokey") //else if (lkey == "-nokey")
//{ //{
// ExcludeNoKeyMessages = true; // ExcludeNoKeyMessages = true;
//} //}
else else
{ {
string key; string key;
if (lkey.StartsWith("-")) if (lkey.StartsWith("-"))
{ {
key = lkey.Substring(1); key = lkey.Substring(1);
// if in exclude all mode, we need to remove this from the inclusions // if in exclude all mode, we need to remove this from the inclusions
if (_excludeAllMode) if (_excludeAllMode)
{ {
if (IncludedExcludedKeys.ContainsKey(key)) if (IncludedExcludedKeys.ContainsKey(key))
IncludedExcludedKeys.Remove(key); IncludedExcludedKeys.Remove(key);
} }
// otherwise include all mode, add to the exclusions // otherwise include all mode, add to the exclusions
else else
{ {
IncludedExcludedKeys[key] = new object(); IncludedExcludedKeys[key] = new object();
} }
} }
else if (lkey.StartsWith("+")) else if (lkey.StartsWith("+"))
{ {
key = lkey.Substring(1); key = lkey.Substring(1);
// if in exclude all mode, we need to add this as inclusion // if in exclude all mode, we need to add this as inclusion
if (_excludeAllMode) if (_excludeAllMode)
{ {
IncludedExcludedKeys[key] = new object(); IncludedExcludedKeys[key] = new object();
} }
// otherwise include all mode, remove this from exclusions // otherwise include all mode, remove this from exclusions
else else
{ {
if (IncludedExcludedKeys.ContainsKey(key)) if (IncludedExcludedKeys.ContainsKey(key))
IncludedExcludedKeys.Remove(key); IncludedExcludedKeys.Remove(key);
} }
} }
} }
} }
} }
/// <summary> /// <summary>
@@ -385,7 +384,7 @@ namespace PepperDash.Core
return; return;
} }
if(Level < level) if (Level < level)
{ {
return; return;
} }
@@ -421,9 +420,9 @@ namespace PepperDash.Core
} }
} }
/// <summary> /// <summary>
/// Logs to Console when at-level, and all messages to error log /// Logs to Console when at-level, and all messages to error log
/// </summary> /// </summary>
public static void Console(uint level, ErrorLogLevel errorLogLevel, public static void Console(uint level, ErrorLogLevel errorLogLevel,
string format, params object[] items) string format, params object[] items)
{ {
@@ -432,10 +431,10 @@ namespace PepperDash.Core
{ {
LogError(errorLogLevel, str); LogError(errorLogLevel, str);
} }
if (Level >= level) if (Level >= level)
{ {
Console(level, str); Console(level, str);
} }
} }
/// <summary> /// <summary>
@@ -558,19 +557,19 @@ namespace PepperDash.Core
return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber); return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
} }
return string.Format("{0}{1}user{1}debugSettings{1}{2}.json",Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId); return string.Format("{0}{1}user{1}debugSettings{1}{2}.json", Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
} }
private static void CheckForMigration() private static void CheckForMigration()
{ {
var oldFilePath = String.Format(@"\nvram\debugSettings\program{0}", InitialParametersClass.ApplicationNumber); var oldFilePath = string.Format(@"\nvram\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
var newFilePath = String.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber); var newFilePath = string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
//check for file at old path //check for file at old path
if (!File.Exists(oldFilePath)) if (!File.Exists(oldFilePath))
{ {
Console(0, ErrorLogLevel.Notice, Console(0, ErrorLogLevel.Notice,
String.Format( string.Format(
@"Debug settings file migration not necessary. Using file at \user\debugSettings\program{0}", @"Debug settings file migration not necessary. Using file at \user\debugSettings\program{0}",
InitialParametersClass.ApplicationNumber)); InitialParametersClass.ApplicationNumber));
@@ -584,7 +583,7 @@ namespace PepperDash.Core
} }
Console(0, ErrorLogLevel.Notice, Console(0, ErrorLogLevel.Notice,
String.Format( string.Format(
@"File found at \nvram\debugSettings\program{0}. Migrating to \user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber)); @"File found at \nvram\debugSettings\program{0}. Migrating to \user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber));
//Copy file from old path to new path, then delete it. This will overwrite the existing file //Copy file from old path to new path, then delete it. This will overwrite the existing file

View File

@@ -1,17 +1,14 @@
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using PepperDash.Core.Interfaces;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using PepperDash.Core.DebugThings;
namespace PepperDash.Core.Logging
namespace PepperDash.Core
{ {
/// <summary> /// <summary>
/// Represents a debugging context /// Represents a debugging context

View File

@@ -1,23 +1,22 @@
using System.Collections.Generic;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Collections.Generic;
namespace PepperDash.Core.DebugThings namespace PepperDash.Core.Logging
{ {
/// <summary> /// <summary>
/// Class to persist current Debug settings across program restarts /// Class to persist current Debug settings across program restarts
/// </summary> /// </summary>
public class DebugContextCollection public class DebugContextCollection
{ {
/// <summary> /// <summary>
/// To prevent threading issues with the DeviceDebugSettings collection /// To prevent threading issues with the DeviceDebugSettings collection
/// </summary> /// </summary>
private readonly CCriticalSection _deviceDebugSettingsLock; private readonly CCriticalSection _deviceDebugSettingsLock;
[JsonProperty("items")] private readonly Dictionary<string, DebugContextItem> _items; [JsonProperty("items")] private readonly Dictionary<string, DebugContextItem> _items;
/// <summary> /// <summary>
/// Collection of the debug settings for each device where the dictionary key is the device key /// Collection of the debug settings for each device where the dictionary key is the device key
@@ -26,40 +25,40 @@ namespace PepperDash.Core.DebugThings
private Dictionary<string, object> DeviceDebugSettings { get; set; } private Dictionary<string, object> DeviceDebugSettings { get; set; }
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
public DebugContextCollection() public DebugContextCollection()
{ {
_deviceDebugSettingsLock = new CCriticalSection(); _deviceDebugSettingsLock = new CCriticalSection();
DeviceDebugSettings = new Dictionary<string, object>(); DeviceDebugSettings = new Dictionary<string, object>();
_items = new Dictionary<string, DebugContextItem>(); _items = new Dictionary<string, DebugContextItem>();
} }
/// <summary> /// <summary>
/// Sets the level of a given context item, and adds that item if it does not /// Sets the level of a given context item, and adds that item if it does not
/// exist /// exist
/// </summary> /// </summary>
/// <param name="contextKey"></param> /// <param name="contextKey"></param>
/// <param name="level"></param> /// <param name="level"></param>
public void SetLevel(string contextKey, int level) public void SetLevel(string contextKey, int level)
{ {
if (level < 0 || level > 2) if (level < 0 || level > 2)
return; return;
GetOrCreateItem(contextKey).Level = level; GetOrCreateItem(contextKey).Level = level;
} }
/// <summary> /// <summary>
/// Gets a level or creates it if not existing /// Gets a level or creates it if not existing
/// </summary> /// </summary>
/// <param name="contextKey"></param> /// <param name="contextKey"></param>
/// <returns></returns> /// <returns></returns>
public DebugContextItem GetOrCreateItem(string contextKey) public DebugContextItem GetOrCreateItem(string contextKey)
{ {
if (!_items.ContainsKey(contextKey)) if (!_items.ContainsKey(contextKey))
_items[contextKey] = new DebugContextItem { Level = 0 }; _items[contextKey] = new DebugContextItem { Level = 0 };
return _items[contextKey]; return _items[contextKey];
} }
/// <summary> /// <summary>
@@ -96,23 +95,23 @@ namespace PepperDash.Core.DebugThings
{ {
return DeviceDebugSettings[deviceKey]; return DeviceDebugSettings[deviceKey];
} }
} }
/// <summary> /// <summary>
/// Contains information about /// Contains information about
/// </summary> /// </summary>
public class DebugContextItem public class DebugContextItem
{ {
/// <summary> /// <summary>
/// The level of debug messages to print /// The level of debug messages to print
/// </summary> /// </summary>
[JsonProperty("level")] [JsonProperty("level")]
public int Level { get; set; } public int Level { get; set; }
/// <summary> /// <summary>
/// Property to tell the program not to intitialize when it boots, if desired /// Property to tell the program not to intitialize when it boots, if desired
/// </summary> /// </summary>
[JsonProperty("doNotLoadOnNextBoot")] [JsonProperty("doNotLoadOnNextBoot")]
public bool DoNotLoadOnNextBoot { get; set; } public bool DoNotLoadOnNextBoot { get; set; }
} }
} }

View File

@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core
{
/// <summary>
/// Not in use
/// </summary>
public static class NetworkComm
{
/// <summary>
/// Not in use
/// </summary>
static NetworkComm()
{
}
}
}

View File

@@ -1,26 +1,20 @@
using System; namespace PepperDash.Core.PasswordManagement
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.PasswordManagement
{ {
/// <summary> /// <summary>
/// JSON password configuration /// JSON password configuration
/// </summary> /// </summary>
public class PasswordConfig public class PasswordConfig
{ {
/// <summary> /// <summary>
/// Password object configured password /// Password object configured password
/// </summary> /// </summary>
public string password { get; set; } public string password { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public PasswordConfig() public PasswordConfig()
{ {
} }
} }
} }

View File

@@ -1,57 +1,51 @@
using System; namespace PepperDash.Core.PasswordManagement
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.PasswordManagement
{ {
/// <summary> /// <summary>
/// Constants /// Constants
/// </summary> /// </summary>
public class PasswordManagementConstants public class PasswordManagementConstants
{ {
/// <summary> /// <summary>
/// Generic boolean value change constant /// Generic boolean value change constant
/// </summary> /// </summary>
public const ushort BoolValueChange = 1; public const ushort BoolValueChange = 1;
/// <summary> /// <summary>
/// Evaluated boolean change constant /// Evaluated boolean change constant
/// </summary> /// </summary>
public const ushort PasswordInitializedChange = 2; public const ushort PasswordInitializedChange = 2;
/// <summary> /// <summary>
/// Update busy change const /// Update busy change const
/// </summary> /// </summary>
public const ushort PasswordUpdateBusyChange = 3; public const ushort PasswordUpdateBusyChange = 3;
/// <summary> /// <summary>
/// Password is valid change constant /// Password is valid change constant
/// </summary> /// </summary>
public const ushort PasswordValidationChange = 4; public const ushort PasswordValidationChange = 4;
/// <summary> /// <summary>
/// Password LED change constant /// Password LED change constant
/// </summary> /// </summary>
public const ushort PasswordLedFeedbackChange = 5; public const ushort PasswordLedFeedbackChange = 5;
/// <summary> /// <summary>
/// Generic ushort value change constant /// Generic ushort value change constant
/// </summary> /// </summary>
public const ushort UshrtValueChange = 101; public const ushort UshrtValueChange = 101;
/// <summary> /// <summary>
/// Password count /// Password count
/// </summary> /// </summary>
public const ushort PasswordManagerCountChange = 102; public const ushort PasswordManagerCountChange = 102;
/// <summary> /// <summary>
/// Password selecte index change constant /// Password selecte index change constant
/// </summary> /// </summary>
public const ushort PasswordSelectIndexChange = 103; public const ushort PasswordSelectIndexChange = 103;
/// <summary> /// <summary>
/// Password length /// Password length
/// </summary> /// </summary>
public const ushort PasswordLengthChange = 104; public const ushort PasswordLengthChange = 104;
/// <summary> /// <summary>
/// Generic string value change constant /// Generic string value change constant
/// </summary> /// </summary>
public const ushort StringValueChange = 201; public const ushort StringValueChange = 201;
} }
} }

View File

@@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.PasswordManagement namespace PepperDash.Core.PasswordManagement
{ {
@@ -10,182 +6,182 @@ namespace PepperDash.Core.PasswordManagement
/// A class to allow user interaction with the PasswordManager /// A class to allow user interaction with the PasswordManager
/// </summary> /// </summary>
public class PasswordClient public class PasswordClient
{ {
/// <summary> /// <summary>
/// Password selected /// Password selected
/// </summary> /// </summary>
public string Password { get; set; } public string Password { get; set; }
/// <summary> /// <summary>
/// Password selected key /// Password selected key
/// </summary> /// </summary>
public ushort Key { get; set; } public ushort Key { get; set; }
/// <summary> /// <summary>
/// Used to build the password entered by the user /// Used to build the password entered by the user
/// </summary> /// </summary>
public string PasswordToValidate { get; set; } public string PasswordToValidate { get; set; }
/// <summary> /// <summary>
/// Boolean event /// Boolean event
/// </summary> /// </summary>
public event EventHandler<BoolChangeEventArgs> BoolChange; public event EventHandler<BoolChangeEventArgs> BoolChange;
/// <summary> /// <summary>
/// Ushort event /// Ushort event
/// </summary> /// </summary>
public event EventHandler<UshrtChangeEventArgs> UshrtChange; public event EventHandler<UshrtChangeEventArgs> UshrtChange;
/// <summary> /// <summary>
/// String event /// String event
/// </summary> /// </summary>
public event EventHandler<StringChangeEventArgs> StringChange; public event EventHandler<StringChangeEventArgs> StringChange;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public PasswordClient() public PasswordClient()
{ {
PasswordManager.PasswordChange += new EventHandler<StringChangeEventArgs>(PasswordManager_PasswordChange); PasswordManager.PasswordChange += new EventHandler<StringChangeEventArgs>(PasswordManager_PasswordChange);
} }
/// <summary> /// <summary>
/// Initialize method /// Initialize method
/// </summary> /// </summary>
public void Initialize() public void Initialize()
{ {
OnBoolChange(false, 0, PasswordManagementConstants.PasswordInitializedChange); OnBoolChange(false, 0, PasswordManagementConstants.PasswordInitializedChange);
Password = ""; Password = "";
PasswordToValidate = ""; PasswordToValidate = "";
OnUshrtChange((ushort)PasswordManager.Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange); OnUshrtChange((ushort)PasswordManager.Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange);
OnBoolChange(true, 0, PasswordManagementConstants.PasswordInitializedChange); OnBoolChange(true, 0, PasswordManagementConstants.PasswordInitializedChange);
} }
/// <summary> /// <summary>
/// Retrieve password by index /// Retrieve password by index
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
public void GetPasswordByIndex(ushort key) public void GetPasswordByIndex(ushort key)
{ {
OnUshrtChange((ushort)PasswordManager.Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange); OnUshrtChange((ushort)PasswordManager.Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange);
Key = key; Key = key;
var pw = PasswordManager.Passwords[Key]; var pw = PasswordManager.Passwords[Key];
if (pw == null) if (pw == null)
{ {
OnUshrtChange(0, 0, PasswordManagementConstants.PasswordLengthChange); OnUshrtChange(0, 0, PasswordManagementConstants.PasswordLengthChange);
return; return;
} }
Password = pw; Password = pw;
OnUshrtChange((ushort)Password.Length, 0, PasswordManagementConstants.PasswordLengthChange); OnUshrtChange((ushort)Password.Length, 0, PasswordManagementConstants.PasswordLengthChange);
OnUshrtChange(key, 0, PasswordManagementConstants.PasswordSelectIndexChange); OnUshrtChange(key, 0, PasswordManagementConstants.PasswordSelectIndexChange);
} }
/// <summary> /// <summary>
/// Password validation method /// Password validation method
/// </summary> /// </summary>
/// <param name="password"></param> /// <param name="password"></param>
public void ValidatePassword(string password) public void ValidatePassword(string password)
{ {
if (string.IsNullOrEmpty(password)) if (string.IsNullOrEmpty(password))
return; return;
if (string.Equals(Password, password)) if (string.Equals(Password, password))
OnBoolChange(true, 0, PasswordManagementConstants.PasswordValidationChange); OnBoolChange(true, 0, PasswordManagementConstants.PasswordValidationChange);
else else
OnBoolChange(false, 0, PasswordManagementConstants.PasswordValidationChange); OnBoolChange(false, 0, PasswordManagementConstants.PasswordValidationChange);
ClearPassword(); ClearPassword();
} }
/// <summary> /// <summary>
/// Builds the user entered passwrod string, will attempt to validate the user entered /// Builds the user entered passwrod string, will attempt to validate the user entered
/// password against the selected password when the length of the 2 are equal /// password against the selected password when the length of the 2 are equal
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
public void BuildPassword(string data) public void BuildPassword(string data)
{ {
PasswordToValidate = String.Concat(PasswordToValidate, data); PasswordToValidate = String.Concat(PasswordToValidate, data);
OnBoolChange(true, (ushort)PasswordToValidate.Length, PasswordManagementConstants.PasswordLedFeedbackChange); OnBoolChange(true, (ushort)PasswordToValidate.Length, PasswordManagementConstants.PasswordLedFeedbackChange);
if (PasswordToValidate.Length == Password.Length) if (PasswordToValidate.Length == Password.Length)
ValidatePassword(PasswordToValidate); ValidatePassword(PasswordToValidate);
} }
/// <summary> /// <summary>
/// Clears the user entered password and resets the LEDs /// Clears the user entered password and resets the LEDs
/// </summary> /// </summary>
public void ClearPassword() public void ClearPassword()
{ {
PasswordToValidate = ""; PasswordToValidate = "";
OnBoolChange(false, (ushort)PasswordToValidate.Length, PasswordManagementConstants.PasswordLedFeedbackChange); OnBoolChange(false, (ushort)PasswordToValidate.Length, PasswordManagementConstants.PasswordLedFeedbackChange);
} }
/// <summary> /// <summary>
/// Protected boolean change event handler /// Protected boolean change event handler
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
var handler = BoolChange; var handler = BoolChange;
if (handler != null) if (handler != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected ushort change event handler /// Protected ushort change event handler
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnUshrtChange(ushort value, ushort index, ushort type) protected void OnUshrtChange(ushort value, ushort index, ushort type)
{ {
var handler = UshrtChange; var handler = UshrtChange;
if (handler != null) if (handler != null)
{ {
var args = new UshrtChangeEventArgs(value, type); var args = new UshrtChangeEventArgs(value, type);
args.Index = index; args.Index = index;
UshrtChange(this, args); UshrtChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected string change event handler /// Protected string change event handler
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
var handler = StringChange; var handler = StringChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
/// <summary> /// <summary>
/// If password changes while selected change event will be notifed and update the client /// If password changes while selected change event will be notifed and update the client
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
protected void PasswordManager_PasswordChange(object sender, StringChangeEventArgs args) protected void PasswordManager_PasswordChange(object sender, StringChangeEventArgs args)
{ {
//throw new NotImplementedException(); //throw new NotImplementedException();
if (Key == args.Index) if (Key == args.Index)
{ {
//PasswordSelectedKey = args.Index; //PasswordSelectedKey = args.Index;
//PasswordSelected = args.StringValue; //PasswordSelected = args.StringValue;
GetPasswordByIndex(args.Index); GetPasswordByIndex(args.Index);
} }
} }
} }
} }

View File

@@ -1,14 +1,9 @@
using Crestron.SimplSharp;
using PepperDash.Core.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Crestron.SimplSharp;
using PepperDash.Core.JsonToSimpl;
using PepperDash.Core.JsonStandardObjects;
namespace PepperDash.Core.PasswordManagement namespace PepperDash.Core.PasswordManagement
{ {
@@ -16,234 +11,234 @@ namespace PepperDash.Core.PasswordManagement
/// Allows passwords to be stored and managed /// Allows passwords to be stored and managed
/// </summary> /// </summary>
public class PasswordManager public class PasswordManager
{ {
/// <summary> /// <summary>
/// Public dictionary of known passwords /// Public dictionary of known passwords
/// </summary> /// </summary>
public static Dictionary<uint, string> Passwords = new Dictionary<uint, string>(); public static Dictionary<uint, string> Passwords = new Dictionary<uint, string>();
/// <summary> /// <summary>
/// Private dictionary, used when passwords are updated /// Private dictionary, used when passwords are updated
/// </summary> /// </summary>
private Dictionary<uint, string> _passwords = new Dictionary<uint, string>(); private Dictionary<uint, string> _passwords = new Dictionary<uint, string>();
/// <summary> /// <summary>
/// Timer used to wait until password changes have stopped before updating the dictionary /// Timer used to wait until password changes have stopped before updating the dictionary
/// </summary> /// </summary>
CTimer PasswordTimer; CTimer PasswordTimer;
/// <summary> /// <summary>
/// Timer length /// Timer length
/// </summary> /// </summary>
public long PasswordTimerElapsedMs = 5000; public long PasswordTimerElapsedMs = 5000;
/// <summary> /// <summary>
/// Boolean event /// Boolean event
/// </summary> /// </summary>
public event EventHandler<BoolChangeEventArgs> BoolChange; public event EventHandler<BoolChangeEventArgs> BoolChange;
/// <summary> /// <summary>
/// Ushort event /// Ushort event
/// </summary> /// </summary>
public event EventHandler<UshrtChangeEventArgs> UshrtChange; public event EventHandler<UshrtChangeEventArgs> UshrtChange;
/// <summary> /// <summary>
/// String event /// String event
/// </summary> /// </summary>
public event EventHandler<StringChangeEventArgs> StringChange; public event EventHandler<StringChangeEventArgs> StringChange;
/// <summary> /// <summary>
/// Event to notify clients of an updated password at the specified index (uint) /// Event to notify clients of an updated password at the specified index (uint)
/// </summary> /// </summary>
public static event EventHandler<StringChangeEventArgs> PasswordChange; public static event EventHandler<StringChangeEventArgs> PasswordChange;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public PasswordManager() public PasswordManager()
{ {
} }
/// <summary> /// <summary>
/// Initialize password manager /// Initialize password manager
/// </summary> /// </summary>
public void Initialize() public void Initialize()
{ {
if (Passwords == null) if (Passwords == null)
Passwords = new Dictionary<uint, string>(); Passwords = new Dictionary<uint, string>();
if (_passwords == null) if (_passwords == null)
_passwords = new Dictionary<uint, string>(); _passwords = new Dictionary<uint, string>();
OnBoolChange(true, 0, PasswordManagementConstants.PasswordInitializedChange); OnBoolChange(true, 0, PasswordManagementConstants.PasswordInitializedChange);
} }
/// <summary> /// <summary>
/// Updates password stored in the dictonary /// Updates password stored in the dictonary
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="password"></param> /// <param name="password"></param>
public void UpdatePassword(ushort key, string password) public void UpdatePassword(ushort key, string password)
{ {
// validate the parameters // validate the parameters
if (key > 0 && string.IsNullOrEmpty(password)) if (key > 0 && string.IsNullOrEmpty(password))
{ {
Debug.Console(1, string.Format("PasswordManager.UpdatePassword: key [{0}] or password are not valid", key, password)); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: key [{0}] or password are not valid", key, password));
return; return;
} }
try try
{ {
// if key exists, update the value // if key exists, update the value
if(_passwords.ContainsKey(key)) if (_passwords.ContainsKey(key))
_passwords[key] = password; _passwords[key] = password;
// else add the key & value // else add the key & value
else else
_passwords.Add(key, password); _passwords.Add(key, password);
Debug.Console(1, string.Format("PasswordManager.UpdatePassword: _password[{0}] = {1}", key, _passwords[key])); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: _password[{0}] = {1}", key, _passwords[key]));
if (PasswordTimer == null) if (PasswordTimer == null)
{ {
PasswordTimer = new CTimer((o) => PasswordTimerElapsed(), PasswordTimerElapsedMs); PasswordTimer = new CTimer((o) => PasswordTimerElapsed(), PasswordTimerElapsedMs);
Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Started")); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Started"));
OnBoolChange(true, 0, PasswordManagementConstants.PasswordUpdateBusyChange); OnBoolChange(true, 0, PasswordManagementConstants.PasswordUpdateBusyChange);
} }
else else
{ {
PasswordTimer.Reset(PasswordTimerElapsedMs); PasswordTimer.Reset(PasswordTimerElapsedMs);
Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Reset")); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Reset"));
} }
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("PasswordManager.UpdatePassword key-value[{0}, {1}] failed:\r{2}", key, password, e); var msg = string.Format("PasswordManager.UpdatePassword key-value[{0}, {1}] failed:\r{2}", key, password, e);
Debug.Console(1, msg); Debug.Console(1, msg);
} }
} }
/// <summary> /// <summary>
/// CTimer callback function /// CTimer callback function
/// </summary> /// </summary>
private void PasswordTimerElapsed() private void PasswordTimerElapsed()
{ {
try try
{ {
PasswordTimer.Stop(); PasswordTimer.Stop();
Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: CTimer Stopped")); Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: CTimer Stopped"));
OnBoolChange(false, 0, PasswordManagementConstants.PasswordUpdateBusyChange); OnBoolChange(false, 0, PasswordManagementConstants.PasswordUpdateBusyChange);
foreach (var pw in _passwords) foreach (var pw in _passwords)
{ {
// if key exists, continue // if key exists, continue
if (Passwords.ContainsKey(pw.Key)) if (Passwords.ContainsKey(pw.Key))
{ {
Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: pw.key[{0}] = {1}", pw.Key, pw.Value)); Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: pw.key[{0}] = {1}", pw.Key, pw.Value));
if (Passwords[pw.Key] != _passwords[pw.Key]) if (Passwords[pw.Key] != _passwords[pw.Key])
{ {
Passwords[pw.Key] = _passwords[pw.Key]; Passwords[pw.Key] = _passwords[pw.Key];
Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: Updated Password[{0} = {1}", pw.Key, Passwords[pw.Key])); Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: Updated Password[{0} = {1}", pw.Key, Passwords[pw.Key]));
OnPasswordChange(Passwords[pw.Key], (ushort)pw.Key, PasswordManagementConstants.StringValueChange); OnPasswordChange(Passwords[pw.Key], (ushort)pw.Key, PasswordManagementConstants.StringValueChange);
} }
} }
// else add the key & value // else add the key & value
else else
{ {
Passwords.Add(pw.Key, pw.Value); Passwords.Add(pw.Key, pw.Value);
} }
} }
OnUshrtChange((ushort)Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange); OnUshrtChange((ushort)Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("PasswordManager.PasswordTimerElapsed failed:\r{0}", e); var msg = string.Format("PasswordManager.PasswordTimerElapsed failed:\r{0}", e);
Debug.Console(1, msg); Debug.Console(1, msg);
} }
} }
/// <summary> /// <summary>
/// Method to change the default timer value, (default 5000ms/5s) /// Method to change the default timer value, (default 5000ms/5s)
/// </summary> /// </summary>
/// <param name="time"></param> /// <param name="time"></param>
public void PasswordTimerMs(ushort time) public void PasswordTimerMs(ushort time)
{ {
PasswordTimerElapsedMs = Convert.ToInt64(time); PasswordTimerElapsedMs = Convert.ToInt64(time);
} }
/// <summary> /// <summary>
/// Helper method for debugging to see what passwords are in the lists /// Helper method for debugging to see what passwords are in the lists
/// </summary> /// </summary>
public void ListPasswords() public void ListPasswords()
{ {
Debug.Console(0, "PasswordManager.ListPasswords:\r"); Debug.Console(0, "PasswordManager.ListPasswords:\r");
foreach (var pw in Passwords) foreach (var pw in Passwords)
Debug.Console(0, "Passwords[{0}]: {1}\r", pw.Key, pw.Value); Debug.Console(0, "Passwords[{0}]: {1}\r", pw.Key, pw.Value);
Debug.Console(0, "\n"); Debug.Console(0, "\n");
foreach (var pw in _passwords) foreach (var pw in _passwords)
Debug.Console(0, "_passwords[{0}]: {1}\r", pw.Key, pw.Value); Debug.Console(0, "_passwords[{0}]: {1}\r", pw.Key, pw.Value);
} }
/// <summary> /// <summary>
/// Protected boolean change event handler /// Protected boolean change event handler
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
var handler = BoolChange; var handler = BoolChange;
if (handler != null) if (handler != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected ushort change event handler /// Protected ushort change event handler
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnUshrtChange(ushort value, ushort index, ushort type) protected void OnUshrtChange(ushort value, ushort index, ushort type)
{ {
var handler = UshrtChange; var handler = UshrtChange;
if (handler != null) if (handler != null)
{ {
var args = new UshrtChangeEventArgs(value, type); var args = new UshrtChangeEventArgs(value, type);
args.Index = index; args.Index = index;
UshrtChange(this, args); UshrtChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected string change event handler /// Protected string change event handler
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
var handler = StringChange; var handler = StringChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected password change event handler /// Protected password change event handler
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnPasswordChange(string value, ushort index, ushort type) protected void OnPasswordChange(string value, ushort index, ushort type)
{ {
var handler = PasswordChange; var handler = PasswordChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
PasswordChange(this, args); PasswordChange(this, args);
} }
} }
} }
} }

View File

@@ -1,53 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>PepperDash.Core</RootNamespace>
<AssemblyName>PepperDashCore</AssemblyName>
<TargetFramework>net472</TargetFramework>
<Deterministic>false</Deterministic>
<NeutralLanguage>en</NeutralLanguage>
<OutputPath>bin\$(Configuration)\</OutputPath>
<SignAssembly>False</SignAssembly>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>PepperDash Core</Title>
<Company>PepperDash Technologies</Company>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/PepperDash/PepperDashCore</RepositoryUrl>
<PackageTags>crestron;4series;</PackageTags>
<Version>$(Version)</Version>
<PackageOutputPath>../../package</PackageOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
<DefineConstants>TRACE;DEBUG;SERIES4</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DocumentationFile>bin\4Series\$(Configuration)\PepperDashCore.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Crestron.SimplSharp.SDK.Library" Version="2.19.35" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2">
<Aliases></Aliases>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Remove="Comm\._GenericSshClient.cs" />
<Compile Remove="Comm\._GenericTcpIpClient.cs" />
<Compile Remove="Comm\DynamicTCPServer.cs" />
<Compile Remove="PasswordManagement\OLD-ARRAY-Config.cs" />
<Compile Remove="PasswordManagement\OLD-ARRAY-PasswordClient.cs" />
<Compile Remove="PasswordManagement\OLD-ARRAY-PasswordManager.cs" />
</ItemGroup>
<Target Name="SimplSharpNewtonsoft" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
<ItemGroup>
<ReferencePath Condition="'%(FileName)' == 'SimplSharpNewtonsoft'">
<Aliases>crestron</Aliases>
</ReferencePath>
</ItemGroup>
</Target>
</Project>

View File

@@ -1,264 +1,260 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.SystemInfo namespace PepperDash.Core.SystemInfo
{ {
/// <summary> /// <summary>
/// Constants /// Constants
/// </summary> /// </summary>
public class SystemInfoConstants public class SystemInfoConstants
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort BoolValueChange = 1; public const ushort BoolValueChange = 1;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort CompleteBoolChange = 2; public const ushort CompleteBoolChange = 2;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort BusyBoolChange = 3; public const ushort BusyBoolChange = 3;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort UshortValueChange = 101; public const ushort UshortValueChange = 101;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort StringValueChange = 201; public const ushort StringValueChange = 201;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ConsoleResponseChange = 202; public const ushort ConsoleResponseChange = 202;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ProcessorUptimeChange = 203; public const ushort ProcessorUptimeChange = 203;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ProgramUptimeChange = 204; public const ushort ProgramUptimeChange = 204;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ObjectChange = 301; public const ushort ObjectChange = 301;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ProcessorConfigChange = 302; public const ushort ProcessorConfigChange = 302;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort EthernetConfigChange = 303; public const ushort EthernetConfigChange = 303;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ControlSubnetConfigChange = 304; public const ushort ControlSubnetConfigChange = 304;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public const ushort ProgramConfigChange = 305; public const ushort ProgramConfigChange = 305;
} }
/// <summary> /// <summary>
/// Processor Change Event Args Class /// Processor Change Event Args Class
/// </summary> /// </summary>
public class ProcessorChangeEventArgs : EventArgs public class ProcessorChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ProcessorInfo Processor { get; set; } public ProcessorInfo Processor { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ProcessorChangeEventArgs() public ProcessorChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
public ProcessorChangeEventArgs(ProcessorInfo processor, ushort type) public ProcessorChangeEventArgs(ProcessorInfo processor, ushort type)
{ {
Processor = processor; Processor = processor;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ProcessorChangeEventArgs(ProcessorInfo processor, ushort type, ushort index) public ProcessorChangeEventArgs(ProcessorInfo processor, ushort type, ushort index)
{ {
Processor = processor; Processor = processor;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
/// <summary> /// <summary>
/// Ethernet Change Event Args Class /// Ethernet Change Event Args Class
/// </summary> /// </summary>
public class EthernetChangeEventArgs : EventArgs public class EthernetChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public EthernetInfo Adapter { get; set; } public EthernetInfo Adapter { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public EthernetChangeEventArgs() public EthernetChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="ethernet"></param> /// <param name="ethernet"></param>
/// <param name="type"></param> /// <param name="type"></param>
public EthernetChangeEventArgs(EthernetInfo ethernet, ushort type) public EthernetChangeEventArgs(EthernetInfo ethernet, ushort type)
{ {
Adapter = ethernet; Adapter = ethernet;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="ethernet"></param> /// <param name="ethernet"></param>
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public EthernetChangeEventArgs(EthernetInfo ethernet, ushort type, ushort index) public EthernetChangeEventArgs(EthernetInfo ethernet, ushort type, ushort index)
{ {
Adapter = ethernet; Adapter = ethernet;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
/// <summary> /// <summary>
/// Control Subnet Chage Event Args Class /// Control Subnet Chage Event Args Class
/// </summary> /// </summary>
public class ControlSubnetChangeEventArgs : EventArgs public class ControlSubnetChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ControlSubnetInfo Adapter { get; set; } public ControlSubnetInfo Adapter { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ControlSubnetChangeEventArgs() public ControlSubnetChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
public ControlSubnetChangeEventArgs(ControlSubnetInfo controlSubnet, ushort type) public ControlSubnetChangeEventArgs(ControlSubnetInfo controlSubnet, ushort type)
{ {
Adapter = controlSubnet; Adapter = controlSubnet;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
public ControlSubnetChangeEventArgs(ControlSubnetInfo controlSubnet, ushort type, ushort index) public ControlSubnetChangeEventArgs(ControlSubnetInfo controlSubnet, ushort type, ushort index)
{ {
Adapter = controlSubnet; Adapter = controlSubnet;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
/// <summary> /// <summary>
/// Program Change Event Args Class /// Program Change Event Args Class
/// </summary> /// </summary>
public class ProgramChangeEventArgs : EventArgs public class ProgramChangeEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ProgramInfo Program { get; set; } public ProgramInfo Program { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Type { get; set; } public ushort Type { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ushort Index { get; set; } public ushort Index { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ProgramChangeEventArgs() public ProgramChangeEventArgs()
{ {
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="program"></param> /// <param name="program"></param>
/// <param name="type"></param> /// <param name="type"></param>
public ProgramChangeEventArgs(ProgramInfo program, ushort type) public ProgramChangeEventArgs(ProgramInfo program, ushort type)
{ {
Program = program; Program = program;
Type = type; Type = type;
} }
/// <summary> /// <summary>
/// Constructor overload /// Constructor overload
/// </summary> /// </summary>
/// <param name="program"></param> /// <param name="program"></param>
/// <param name="type"></param> /// <param name="type"></param>
/// <param name="index"></param> /// <param name="index"></param>
public ProgramChangeEventArgs(ProgramInfo program, ushort type, ushort index) public ProgramChangeEventArgs(ProgramInfo program, ushort type, ushort index)
{ {
Program = program; Program = program;
Type = type; Type = type;
Index = index; Index = index;
} }
} }
} }

View File

@@ -1,16 +1,10 @@
using System; namespace PepperDash.Core.SystemInfo
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.SystemInfo
{ {
/// <summary> /// <summary>
/// Processor info class /// Processor info class
/// </summary> /// </summary>
public class ProcessorInfo public class ProcessorInfo
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -52,20 +46,20 @@ namespace PepperDash.Core.SystemInfo
/// </summary> /// </summary>
public string ProgramIdTag { get; set; } public string ProgramIdTag { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ProcessorInfo() public ProcessorInfo()
{ {
} }
} }
/// <summary> /// <summary>
/// Ethernet info class /// Ethernet info class
/// </summary> /// </summary>
public class EthernetInfo public class EthernetInfo
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -107,20 +101,20 @@ namespace PepperDash.Core.SystemInfo
/// </summary> /// </summary>
public string Domain { get; set; } public string Domain { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public EthernetInfo() public EthernetInfo()
{ {
} }
} }
/// <summary> /// <summary>
/// Control subnet info class /// Control subnet info class
/// </summary> /// </summary>
public class ControlSubnetInfo public class ControlSubnetInfo
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -146,20 +140,20 @@ namespace PepperDash.Core.SystemInfo
/// </summary> /// </summary>
public string RouterPrefix { get; set; } public string RouterPrefix { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ControlSubnetInfo() public ControlSubnetInfo()
{ {
} }
} }
/// <summary> /// <summary>
/// Program info class /// Program info class
/// </summary> /// </summary>
public class ProgramInfo public class ProgramInfo
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -193,12 +187,12 @@ namespace PepperDash.Core.SystemInfo
/// </summary> /// </summary>
public string Programmer { get; set; } public string Programmer { get; set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public ProgramInfo() public ProgramInfo()
{ {
} }
} }
} }

View File

@@ -1,16 +1,13 @@
using System; using Crestron.SimplSharp;
using System.Collections.Generic; using System;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.SystemInfo namespace PepperDash.Core.SystemInfo
{ {
/// <summary> /// <summary>
/// System Info class /// System Info class
/// </summary> /// </summary>
public class SystemInfoToSimpl public class SystemInfoToSimpl
{ {
/// <summary> /// <summary>
/// Notifies of bool change /// Notifies of bool change
/// </summary> /// </summary>
@@ -37,426 +34,426 @@ namespace PepperDash.Core.SystemInfo
/// </summary> /// </summary>
public event EventHandler<ProgramChangeEventArgs> ProgramChange; public event EventHandler<ProgramChangeEventArgs> ProgramChange;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public SystemInfoToSimpl() public SystemInfoToSimpl()
{ {
} }
/// <summary> /// <summary>
/// Gets the current processor info /// Gets the current processor info
/// </summary> /// </summary>
public void GetProcessorInfo() public void GetProcessorInfo()
{ {
OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange);
try try
{ {
var processor = new ProcessorInfo(); var processor = new ProcessorInfo();
processor.Model = InitialParametersClass.ControllerPromptName; processor.Model = InitialParametersClass.ControllerPromptName;
processor.SerialNumber = CrestronEnvironment.SystemInfo.SerialNumber; processor.SerialNumber = CrestronEnvironment.SystemInfo.SerialNumber;
processor.ModuleDirectory = InitialParametersClass.ProgramDirectory.ToString(); processor.ModuleDirectory = InitialParametersClass.ProgramDirectory.ToString();
processor.ProgramIdTag = InitialParametersClass.ProgramIDTag; processor.ProgramIdTag = InitialParametersClass.ProgramIDTag;
processor.DevicePlatform = CrestronEnvironment.DevicePlatform.ToString(); processor.DevicePlatform = CrestronEnvironment.DevicePlatform.ToString();
processor.OsVersion = CrestronEnvironment.OSVersion.Version.ToString(); processor.OsVersion = CrestronEnvironment.OSVersion.Version.ToString();
processor.RuntimeEnvironment = CrestronEnvironment.RuntimeEnvironment.ToString(); processor.RuntimeEnvironment = CrestronEnvironment.RuntimeEnvironment.ToString();
processor.LocalTimeZone = CrestronEnvironment.GetTimeZone().Offset; processor.LocalTimeZone = CrestronEnvironment.GetTimeZone().Offset;
// Does not return firmware version matching a "ver" command // Does not return firmware version matching a "ver" command
// returns the "ver -v" 'CAB' version // returns the "ver -v" 'CAB' version
// example return ver -v: // example return ver -v:
// RMC3 Cntrl Eng [v1.503.3568.25373 (Oct 09 2018), #4001E302] @E-00107f4420f0 // RMC3 Cntrl Eng [v1.503.3568.25373 (Oct 09 2018), #4001E302] @E-00107f4420f0
// Build: 14:05:46 Oct 09 2018 (3568.25373) // Build: 14:05:46 Oct 09 2018 (3568.25373)
// Cab: 1.503.0070 // Cab: 1.503.0070
// Applications: 1.0.6855.21351 // Applications: 1.0.6855.21351
// Updater: 1.4.24 // Updater: 1.4.24
// Bootloader: 1.22.00 // Bootloader: 1.22.00
// RMC3-SetupProgram: 1.003.0011 // RMC3-SetupProgram: 1.003.0011
// IOPVersion: FPGA [v09] slot:7 // IOPVersion: FPGA [v09] slot:7
// PUF: Unknown // PUF: Unknown
//Firmware = CrestronEnvironment.OSVersion.Firmware; //Firmware = CrestronEnvironment.OSVersion.Firmware;
//Firmware = InitialParametersClass.FirmwareVersion; //Firmware = InitialParametersClass.FirmwareVersion;
// Use below logic to get actual firmware ver, not the 'CAB' returned by the above // Use below logic to get actual firmware ver, not the 'CAB' returned by the above
// matches console return of a "ver" and on SystemInfo page // matches console return of a "ver" and on SystemInfo page
// example return ver: // example return ver:
// RMC3 Cntrl Eng [v1.503.3568.25373 (Oct 09 2018), #4001E302] @E-00107f4420f0 // RMC3 Cntrl Eng [v1.503.3568.25373 (Oct 09 2018), #4001E302] @E-00107f4420f0
var response = ""; var response = "";
CrestronConsole.SendControlSystemCommand("ver", ref response); CrestronConsole.SendControlSystemCommand("ver", ref response);
processor.Firmware = ParseConsoleResponse(response, "Cntrl Eng", "[", "("); processor.Firmware = ParseConsoleResponse(response, "Cntrl Eng", "[", "(");
processor.FirmwareDate = ParseConsoleResponse(response, "Cntrl Eng", "(", ")"); processor.FirmwareDate = ParseConsoleResponse(response, "Cntrl Eng", "(", ")");
OnProcessorChange(processor, 0, SystemInfoConstants.ProcessorConfigChange); OnProcessorChange(processor, 0, SystemInfoConstants.ProcessorConfigChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("GetProcessorInfo failed: {0}", e.Message); var msg = string.Format("GetProcessorInfo failed: {0}", e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange);
} }
/// <summary> /// <summary>
/// Gets the current ethernet info /// Gets the current ethernet info
/// </summary> /// </summary>
public void GetEthernetInfo() public void GetEthernetInfo()
{ {
OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange);
var adapter = new EthernetInfo(); var adapter = new EthernetInfo();
try try
{ {
// get lan adapter id // get lan adapter id
var adapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter); var adapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter);
// get lan adapter info // get lan adapter info
var dhcpState = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterId); var dhcpState = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterId);
if (!string.IsNullOrEmpty(dhcpState)) if (!string.IsNullOrEmpty(dhcpState))
adapter.DhcpIsOn = (ushort)(dhcpState.ToLower().Contains("on") ? 1 : 0); adapter.DhcpIsOn = (ushort)(dhcpState.ToLower().Contains("on") ? 1 : 0);
adapter.Hostname = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterId); adapter.Hostname = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterId);
adapter.MacAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterId); adapter.MacAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterId);
adapter.IpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterId); adapter.IpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterId);
adapter.Subnet = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterId); adapter.Subnet = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterId);
adapter.Gateway = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterId); adapter.Gateway = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterId);
adapter.Domain = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterId); adapter.Domain = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterId);
// returns comma seperate list of dns servers with trailing comma // returns comma seperate list of dns servers with trailing comma
// example return: "8.8.8.8 (DHCP),8.8.4.4 (DHCP)," // example return: "8.8.8.8 (DHCP),8.8.4.4 (DHCP),"
string dns = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterId); string dns = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterId);
if (dns.Contains(",")) if (dns.Contains(","))
{ {
string[] dnsList = dns.Split(','); string[] dnsList = dns.Split(',');
for (var i = 0; i < dnsList.Length; i++) for (var i = 0; i < dnsList.Length; i++)
{ {
if(i == 0) if (i == 0)
adapter.Dns1 = !string.IsNullOrEmpty(dnsList[0]) ? dnsList[0] : "0.0.0.0"; adapter.Dns1 = !string.IsNullOrEmpty(dnsList[0]) ? dnsList[0] : "0.0.0.0";
if(i == 1) if (i == 1)
adapter.Dns2 = !string.IsNullOrEmpty(dnsList[1]) ? dnsList[1] : "0.0.0.0"; adapter.Dns2 = !string.IsNullOrEmpty(dnsList[1]) ? dnsList[1] : "0.0.0.0";
if(i == 2) if (i == 2)
adapter.Dns3 = !string.IsNullOrEmpty(dnsList[2]) ? dnsList[2] : "0.0.0.0"; adapter.Dns3 = !string.IsNullOrEmpty(dnsList[2]) ? dnsList[2] : "0.0.0.0";
} }
} }
else else
{ {
adapter.Dns1 = !string.IsNullOrEmpty(dns) ? dns : "0.0.0.0"; adapter.Dns1 = !string.IsNullOrEmpty(dns) ? dns : "0.0.0.0";
adapter.Dns2 = "0.0.0.0"; adapter.Dns2 = "0.0.0.0";
adapter.Dns3 = "0.0.0.0"; adapter.Dns3 = "0.0.0.0";
} }
OnEthernetInfoChange(adapter, 0, SystemInfoConstants.EthernetConfigChange); OnEthernetInfoChange(adapter, 0, SystemInfoConstants.EthernetConfigChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("GetEthernetInfo failed: {0}", e.Message); var msg = string.Format("GetEthernetInfo failed: {0}", e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange);
} }
/// <summary> /// <summary>
/// Gets the current control subnet info /// Gets the current control subnet info
/// </summary> /// </summary>
public void GetControlSubnetInfo() public void GetControlSubnetInfo()
{ {
OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange);
var adapter = new ControlSubnetInfo(); var adapter = new ControlSubnetInfo();
try try
{ {
// get cs adapter id // get cs adapter id
var adapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter); var adapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
if (!adapterId.Equals(EthernetAdapterType.EthernetUnknownAdapter)) if (!adapterId.Equals(EthernetAdapterType.EthernetUnknownAdapter))
{ {
adapter.Enabled = 1; adapter.Enabled = 1;
adapter.IsInAutomaticMode = (ushort)(CrestronEthernetHelper.IsControlSubnetInAutomaticMode ? 1 : 0); adapter.IsInAutomaticMode = (ushort)(CrestronEthernetHelper.IsControlSubnetInAutomaticMode ? 1 : 0);
adapter.MacAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterId); adapter.MacAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterId);
adapter.IpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterId); adapter.IpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterId);
adapter.Subnet = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterId); adapter.Subnet = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterId);
adapter.RouterPrefix = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CONTROL_SUBNET_ROUTER_PREFIX, adapterId); adapter.RouterPrefix = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CONTROL_SUBNET_ROUTER_PREFIX, adapterId);
} }
} }
catch (Exception e) catch (Exception e)
{ {
adapter.Enabled = 0; adapter.Enabled = 0;
adapter.IsInAutomaticMode = 0; adapter.IsInAutomaticMode = 0;
adapter.MacAddress = "NA"; adapter.MacAddress = "NA";
adapter.IpAddress = "NA"; adapter.IpAddress = "NA";
adapter.Subnet = "NA"; adapter.Subnet = "NA";
adapter.RouterPrefix = "NA"; adapter.RouterPrefix = "NA";
var msg = string.Format("GetControlSubnetInfo failed: {0}", e.Message); var msg = string.Format("GetControlSubnetInfo failed: {0}", e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
OnControlSubnetInfoChange(adapter, 0, SystemInfoConstants.ControlSubnetConfigChange); OnControlSubnetInfoChange(adapter, 0, SystemInfoConstants.ControlSubnetConfigChange);
OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange);
} }
/// <summary> /// <summary>
/// Gets the program info by index /// Gets the program info by index
/// </summary> /// </summary>
/// <param name="index"></param> /// <param name="index"></param>
public void GetProgramInfoByIndex(ushort index) public void GetProgramInfoByIndex(ushort index)
{ {
if (index < 1 || index > 10) if (index < 1 || index > 10)
return; return;
OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(true, 0, SystemInfoConstants.BusyBoolChange);
var program = new ProgramInfo(); var program = new ProgramInfo();
try try
{ {
var response = ""; var response = "";
CrestronConsole.SendControlSystemCommand(string.Format("progcomments:{0}", index), ref response); CrestronConsole.SendControlSystemCommand(string.Format("progcomments:{0}", index), ref response);
// no program loaded or running // no program loaded or running
if (response.Contains("Bad or Incomplete Command")) if (response.Contains("Bad or Incomplete Command"))
{ {
program.Name = ""; program.Name = "";
program.System = ""; program.System = "";
program.Programmer = ""; program.Programmer = "";
program.CompileTime = ""; program.CompileTime = "";
program.Database = ""; program.Database = "";
program.Environment = ""; program.Environment = "";
} }
else else
{ {
// SIMPL returns // SIMPL returns
program.Name = ParseConsoleResponse(response, "Program File", ":", "\x0D"); program.Name = ParseConsoleResponse(response, "Program File", ":", "\x0D");
program.System = ParseConsoleResponse(response, "System Name", ":", "\x0D"); program.System = ParseConsoleResponse(response, "System Name", ":", "\x0D");
program.ProgramIdTag = ParseConsoleResponse(response, "Friendly Name", ":", "\x0D"); program.ProgramIdTag = ParseConsoleResponse(response, "Friendly Name", ":", "\x0D");
program.Programmer = ParseConsoleResponse(response, "Programmer", ":", "\x0D"); program.Programmer = ParseConsoleResponse(response, "Programmer", ":", "\x0D");
program.CompileTime = ParseConsoleResponse(response, "Compiled On", ":", "\x0D"); program.CompileTime = ParseConsoleResponse(response, "Compiled On", ":", "\x0D");
program.Database = ParseConsoleResponse(response, "CrestronDB", ":", "\x0D"); program.Database = ParseConsoleResponse(response, "CrestronDB", ":", "\x0D");
program.Environment = ParseConsoleResponse(response, "Source Env", ":", "\x0D"); program.Environment = ParseConsoleResponse(response, "Source Env", ":", "\x0D");
// S# returns // S# returns
if (program.System.Length == 0) if (program.System.Length == 0)
program.System = ParseConsoleResponse(response, "Application Name", ":", "\x0D"); program.System = ParseConsoleResponse(response, "Application Name", ":", "\x0D");
if (program.Database.Length == 0) if (program.Database.Length == 0)
program.Database = ParseConsoleResponse(response, "PlugInVersion", ":", "\x0D"); program.Database = ParseConsoleResponse(response, "PlugInVersion", ":", "\x0D");
if (program.Environment.Length == 0) if (program.Environment.Length == 0)
program.Environment = ParseConsoleResponse(response, "Program Tool", ":", "\x0D"); program.Environment = ParseConsoleResponse(response, "Program Tool", ":", "\x0D");
} }
OnProgramChange(program, index, SystemInfoConstants.ProgramConfigChange); OnProgramChange(program, index, SystemInfoConstants.ProgramConfigChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("GetProgramInfoByIndex failed: {0}", e.Message); var msg = string.Format("GetProgramInfoByIndex failed: {0}", e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange); OnBoolChange(false, 0, SystemInfoConstants.BusyBoolChange);
} }
/// <summary> /// <summary>
/// Gets the processor uptime and passes it to S+ /// Gets the processor uptime and passes it to S+
/// </summary> /// </summary>
public void RefreshProcessorUptime() public void RefreshProcessorUptime()
{ {
try try
{ {
string response = ""; string response = "";
CrestronConsole.SendControlSystemCommand("uptime", ref response); CrestronConsole.SendControlSystemCommand("uptime", ref response);
var uptime = ParseConsoleResponse(response, "running for", "running for", "\x0D"); var uptime = ParseConsoleResponse(response, "running for", "running for", "\x0D");
OnStringChange(uptime, 0, SystemInfoConstants.ProcessorUptimeChange); OnStringChange(uptime, 0, SystemInfoConstants.ProcessorUptimeChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("RefreshProcessorUptime failed:\r{0}", e.Message); var msg = string.Format("RefreshProcessorUptime failed:\r{0}", e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
} }
/// <summary> /// <summary>
/// Gets the program uptime, by index, and passes it to S+ /// Gets the program uptime, by index, and passes it to S+
/// </summary> /// </summary>
/// <param name="index"></param> /// <param name="index"></param>
public void RefreshProgramUptimeByIndex(int index) public void RefreshProgramUptimeByIndex(int index)
{ {
try try
{ {
string response = ""; string response = "";
CrestronConsole.SendControlSystemCommand(string.Format("proguptime:{0}", index), ref response); CrestronConsole.SendControlSystemCommand(string.Format("proguptime:{0}", index), ref response);
string uptime = ParseConsoleResponse(response, "running for", "running for", "\x0D"); string uptime = ParseConsoleResponse(response, "running for", "running for", "\x0D");
OnStringChange(uptime, (ushort)index, SystemInfoConstants.ProgramUptimeChange); OnStringChange(uptime, (ushort)index, SystemInfoConstants.ProgramUptimeChange);
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("RefreshProgramUptimebyIndex({0}) failed:\r{1}", index, e.Message); var msg = string.Format("RefreshProgramUptimebyIndex({0}) failed:\r{1}", index, e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
} }
/// <summary> /// <summary>
/// Sends command to console, passes response back using string change event /// Sends command to console, passes response back using string change event
/// </summary> /// </summary>
/// <param name="cmd"></param> /// <param name="cmd"></param>
public void SendConsoleCommand(string cmd) public void SendConsoleCommand(string cmd)
{ {
if (string.IsNullOrEmpty(cmd)) if (string.IsNullOrEmpty(cmd))
return; return;
string response = ""; string response = "";
CrestronConsole.SendControlSystemCommand(cmd, ref response); CrestronConsole.SendControlSystemCommand(cmd, ref response);
if (!string.IsNullOrEmpty(response)) if (!string.IsNullOrEmpty(response))
{ {
if (response.EndsWith("\x0D\\x0A")) if (response.EndsWith("\x0D\\x0A"))
response.Trim('\n'); response.Trim('\n');
OnStringChange(response, 0, SystemInfoConstants.ConsoleResponseChange); OnStringChange(response, 0, SystemInfoConstants.ConsoleResponseChange);
} }
} }
/// <summary> /// <summary>
/// private method to parse console messages /// private method to parse console messages
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="line"></param> /// <param name="line"></param>
/// <param name="dataStart"></param> /// <param name="dataStart"></param>
/// <param name="dataEnd"></param> /// <param name="dataEnd"></param>
/// <returns></returns> /// <returns></returns>
private string ParseConsoleResponse(string data, string line, string dataStart, string dataEnd) private string ParseConsoleResponse(string data, string line, string dataStart, string dataEnd)
{ {
var response = ""; var response = "";
if (string.IsNullOrEmpty(data) || string.IsNullOrEmpty(line) || string.IsNullOrEmpty(dataStart) || string.IsNullOrEmpty(dataEnd)) if (string.IsNullOrEmpty(data) || string.IsNullOrEmpty(line) || string.IsNullOrEmpty(dataStart) || string.IsNullOrEmpty(dataEnd))
return response; return response;
try try
{ {
var linePos = data.IndexOf(line); var linePos = data.IndexOf(line);
var startPos = data.IndexOf(dataStart, linePos) + dataStart.Length; var startPos = data.IndexOf(dataStart, linePos) + dataStart.Length;
var endPos = data.IndexOf(dataEnd, startPos); var endPos = data.IndexOf(dataEnd, startPos);
response = data.Substring(startPos, endPos - startPos).Trim(); response = data.Substring(startPos, endPos - startPos).Trim();
} }
catch (Exception e) catch (Exception e)
{ {
var msg = string.Format("ParseConsoleResponse failed: {0}", e.Message); var msg = string.Format("ParseConsoleResponse failed: {0}", e.Message);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
//ErrorLog.Error(msg); //ErrorLog.Error(msg);
} }
return response; return response;
} }
/// <summary> /// <summary>
/// Protected boolean change event handler /// Protected boolean change event handler
/// </summary> /// </summary>
/// <param name="state"></param> /// <param name="state"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnBoolChange(bool state, ushort index, ushort type) protected void OnBoolChange(bool state, ushort index, ushort type)
{ {
var handler = BoolChange; var handler = BoolChange;
if (handler != null) if (handler != null)
{ {
var args = new BoolChangeEventArgs(state, type); var args = new BoolChangeEventArgs(state, type);
args.Index = index; args.Index = index;
BoolChange(this, args); BoolChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected string change event handler /// Protected string change event handler
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnStringChange(string value, ushort index, ushort type) protected void OnStringChange(string value, ushort index, ushort type)
{ {
var handler = StringChange; var handler = StringChange;
if (handler != null) if (handler != null)
{ {
var args = new StringChangeEventArgs(value, type); var args = new StringChangeEventArgs(value, type);
args.Index = index; args.Index = index;
StringChange(this, args); StringChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Protected processor config change event handler /// Protected processor config change event handler
/// </summary> /// </summary>
/// <param name="processor"></param> /// <param name="processor"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnProcessorChange(ProcessorInfo processor, ushort index, ushort type) protected void OnProcessorChange(ProcessorInfo processor, ushort index, ushort type)
{ {
var handler = ProcessorChange; var handler = ProcessorChange;
if (handler != null) if (handler != null)
{ {
var args = new ProcessorChangeEventArgs(processor, type); var args = new ProcessorChangeEventArgs(processor, type);
args.Index = index; args.Index = index;
ProcessorChange(this, args); ProcessorChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Ethernet change event handler /// Ethernet change event handler
/// </summary> /// </summary>
/// <param name="ethernet"></param> /// <param name="ethernet"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnEthernetInfoChange(EthernetInfo ethernet, ushort index, ushort type) protected void OnEthernetInfoChange(EthernetInfo ethernet, ushort index, ushort type)
{ {
var handler = EthernetChange; var handler = EthernetChange;
if (handler != null) if (handler != null)
{ {
var args = new EthernetChangeEventArgs(ethernet, type); var args = new EthernetChangeEventArgs(ethernet, type);
args.Index = index; args.Index = index;
EthernetChange(this, args); EthernetChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Control Subnet change event handler /// Control Subnet change event handler
/// </summary> /// </summary>
/// <param name="ethernet"></param> /// <param name="ethernet"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnControlSubnetInfoChange(ControlSubnetInfo ethernet, ushort index, ushort type) protected void OnControlSubnetInfoChange(ControlSubnetInfo ethernet, ushort index, ushort type)
{ {
var handler = ControlSubnetChange; var handler = ControlSubnetChange;
if (handler != null) if (handler != null)
{ {
var args = new ControlSubnetChangeEventArgs(ethernet, type); var args = new ControlSubnetChangeEventArgs(ethernet, type);
args.Index = index; args.Index = index;
ControlSubnetChange(this, args); ControlSubnetChange(this, args);
} }
} }
/// <summary> /// <summary>
/// Program change event handler /// Program change event handler
/// </summary> /// </summary>
/// <param name="program"></param> /// <param name="program"></param>
/// <param name="index"></param> /// <param name="index"></param>
/// <param name="type"></param> /// <param name="type"></param>
protected void OnProgramChange(ProgramInfo program, ushort index, ushort type) protected void OnProgramChange(ProgramInfo program, ushort index, ushort type)
{ {
var handler = ProgramChange; var handler = ProgramChange;
if (handler != null) if (handler != null)
{ {
var args = new ProgramChangeEventArgs(program, type); var args = new ProgramChangeEventArgs(program, type);
args.Index = index; args.Index = index;
ProgramChange(this, args); ProgramChange(this, args);
} }
} }
} }
} }

View File

@@ -1,12 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Core.WebApi.Presets namespace PepperDash.Core.WebApi.Presets
@@ -15,7 +9,7 @@ namespace PepperDash.Core.WebApi.Presets
/// Represents a preset /// Represents a preset
/// </summary> /// </summary>
public class Preset public class Preset
{ {
/// <summary> /// <summary>
/// ID of preset /// ID of preset
/// </summary> /// </summary>
@@ -50,18 +44,18 @@ namespace PepperDash.Core.WebApi.Presets
/// Constructor /// Constructor
/// </summary> /// </summary>
public Preset() public Preset()
{ {
PresetName = ""; PresetName = "";
PresetNumber = 1; PresetNumber = 1;
Data = "{}"; Data = "{}";
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class PresetReceivedEventArgs : EventArgs public class PresetReceivedEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// True when the preset is found /// True when the preset is found
/// </summary> /// </summary>
@@ -77,10 +71,10 @@ namespace PepperDash.Core.WebApi.Presets
/// </summary> /// </summary>
public Preset Preset { get; private set; } public Preset Preset { get; private set; }
/// <summary> /// <summary>
/// For Simpl+ /// For Simpl+
/// </summary> /// </summary>
public PresetReceivedEventArgs() { } public PresetReceivedEventArgs() { }
/// <summary> /// <summary>
/// Constructor /// Constructor
@@ -88,9 +82,9 @@ namespace PepperDash.Core.WebApi.Presets
/// <param name="preset"></param> /// <param name="preset"></param>
/// <param name="success"></param> /// <param name="success"></param>
public PresetReceivedEventArgs(Preset preset, bool success) public PresetReceivedEventArgs(Preset preset, bool success)
{ {
LookupSuccess = success; LookupSuccess = success;
Preset = preset; Preset = preset;
} }
} }
} }

View File

@@ -1,16 +1,12 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.WebApi.Presets namespace PepperDash.Core.WebApi.Presets
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class User public class User
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -19,7 +15,7 @@ namespace PepperDash.Core.WebApi.Presets
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string ExternalId { get; set; } public string ExternalId { get; set; }
/// <summary> /// <summary>
/// ///
@@ -30,14 +26,14 @@ namespace PepperDash.Core.WebApi.Presets
/// ///
/// </summary> /// </summary>
public string LastName { get; set; } public string LastName { get; set; }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class UserReceivedEventArgs : EventArgs public class UserReceivedEventArgs : EventArgs
{ {
/// <summary> /// <summary>
/// True when user is found /// True when user is found
/// </summary> /// </summary>
@@ -53,10 +49,10 @@ namespace PepperDash.Core.WebApi.Presets
/// </summary> /// </summary>
public User User { get; private set; } public User User { get; private set; }
/// <summary> /// <summary>
/// For Simpl+ /// For Simpl+
/// </summary> /// </summary>
public UserReceivedEventArgs() { } public UserReceivedEventArgs() { }
/// <summary> /// <summary>
/// Constructor /// Constructor
@@ -64,17 +60,17 @@ namespace PepperDash.Core.WebApi.Presets
/// <param name="user"></param> /// <param name="user"></param>
/// <param name="success"></param> /// <param name="success"></param>
public UserReceivedEventArgs(User user, bool success) public UserReceivedEventArgs(User user, bool success)
{ {
LookupSuccess = success; LookupSuccess = success;
User = user; User = user;
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class UserAndRoomMessage public class UserAndRoomMessage
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -89,5 +85,5 @@ namespace PepperDash.Core.WebApi.Presets
/// ///
/// </summary> /// </summary>
public int PresetNumber { get; set; } public int PresetNumber { get; set; }
} }
} }

View File

@@ -1,17 +1,15 @@
using System;
using System.Text;
using Crestron.SimplSharp; // For Basic SIMPL# Classes using Crestron.SimplSharp; // For Basic SIMPL# Classes
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Net;
using Crestron.SimplSharp.Net.Http; using Crestron.SimplSharp.Net.Http;
using Crestron.SimplSharp.Net.Https; using Crestron.SimplSharp.Net.Https;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core.Interfaces;
using PepperDash.Core;
using PepperDash.Core.JsonToSimpl; using PepperDash.Core.JsonToSimpl;
using PepperDash.Core.Logging;
using System;
namespace PepperDash.Core.WebApi.Presets namespace PepperDash.Core.WebApi.Presets
@@ -20,7 +18,7 @@ namespace PepperDash.Core.WebApi.Presets
/// Passcode client for the WebApi /// Passcode client for the WebApi
/// </summary> /// </summary>
public class WebApiPasscodeClient : IKeyed public class WebApiPasscodeClient : IKeyed
{ {
/// <summary> /// <summary>
/// Notifies when user received /// Notifies when user received
/// </summary> /// </summary>
@@ -36,29 +34,29 @@ namespace PepperDash.Core.WebApi.Presets
/// </summary> /// </summary>
public string Key { get; private set; } public string Key { get; private set; }
//string JsonMasterKey; //string JsonMasterKey;
/// <summary> /// <summary>
/// An embedded JsonToSimpl master object. /// An embedded JsonToSimpl master object.
/// </summary> /// </summary>
JsonToSimplGenericMaster J2SMaster; JsonToSimplGenericMaster J2SMaster;
string UrlBase; string UrlBase;
string DefaultPresetJsonFilePath; string DefaultPresetJsonFilePath;
User CurrentUser; User CurrentUser;
Preset CurrentPreset; Preset CurrentPreset;
/// <summary> /// <summary>
/// SIMPL+ can only execute the default constructor. If you have variables that require initialization, please /// SIMPL+ can only execute the default constructor. If you have variables that require initialization, please
/// use an Initialize method /// use an Initialize method
/// </summary> /// </summary>
public WebApiPasscodeClient() public WebApiPasscodeClient()
{ {
} }
/// <summary> /// <summary>
/// Initializes the instance /// Initializes the instance
@@ -68,23 +66,23 @@ namespace PepperDash.Core.WebApi.Presets
/// <param name="urlBase"></param> /// <param name="urlBase"></param>
/// <param name="defaultPresetJsonFilePath"></param> /// <param name="defaultPresetJsonFilePath"></param>
public void Initialize(string key, string jsonMasterKey, string urlBase, string defaultPresetJsonFilePath) public void Initialize(string key, string jsonMasterKey, string urlBase, string defaultPresetJsonFilePath)
{ {
Key = key; Key = key;
//JsonMasterKey = jsonMasterKey; //JsonMasterKey = jsonMasterKey;
UrlBase = urlBase; UrlBase = urlBase;
DefaultPresetJsonFilePath = defaultPresetJsonFilePath; DefaultPresetJsonFilePath = defaultPresetJsonFilePath;
J2SMaster = new JsonToSimplGenericMaster(); J2SMaster = new JsonToSimplGenericMaster();
J2SMaster.SaveCallback = this.SaveCallback; J2SMaster.SaveCallback = this.SaveCallback;
J2SMaster.Initialize(jsonMasterKey); J2SMaster.Initialize(jsonMasterKey);
} }
/// <summary> /// <summary>
/// Gets the user for a passcode /// Gets the user for a passcode
/// </summary> /// </summary>
/// <param name="passcode"></param> /// <param name="passcode"></param>
public void GetUserForPasscode(string passcode) public void GetUserForPasscode(string passcode)
{ {
// Bullshit duplicate code here... These two cases should be the same // Bullshit duplicate code here... These two cases should be the same
// except for https/http and the certificate ignores // except for https/http and the certificate ignores
if (!UrlBase.StartsWith("https")) if (!UrlBase.StartsWith("https"))
@@ -113,32 +111,32 @@ namespace PepperDash.Core.WebApi.Presets
} }
else else
if (handler != null) if (handler != null)
UserReceived(this, new UserReceivedEventArgs(null, false)); UserReceived(this, new UserReceivedEventArgs(null, false));
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="roomTypeId"></param> /// <param name="roomTypeId"></param>
/// <param name="presetNumber"></param> /// <param name="presetNumber"></param>
public void GetPresetForThisUser(int roomTypeId, int presetNumber) public void GetPresetForThisUser(int roomTypeId, int presetNumber)
{ {
if (CurrentUser == null) if (CurrentUser == null)
{ {
CrestronConsole.PrintLine("GetPresetForThisUser no user loaded"); CrestronConsole.PrintLine("GetPresetForThisUser no user loaded");
return; return;
} }
var msg = new UserAndRoomMessage var msg = new UserAndRoomMessage
{ {
UserId = CurrentUser.Id, UserId = CurrentUser.Id,
RoomTypeId = roomTypeId, RoomTypeId = roomTypeId,
PresetNumber = presetNumber PresetNumber = presetNumber
}; };
var handler = PresetReceived; var handler = PresetReceived;
try try
{ {
if (!UrlBase.StartsWith("https")) if (!UrlBase.StartsWith("https"))
return; return;
var req = new HttpsClientRequest(); var req = new HttpsClientRequest();
@@ -179,101 +177,101 @@ namespace PepperDash.Core.WebApi.Presets
if (handler != null) if (handler != null)
PresetReceived(this, new PresetReceivedEventArgs(null, false)); PresetReceived(this, new PresetReceivedEventArgs(null, false));
} }
} }
catch (HttpException e) catch (HttpException e)
{ {
var resp = e.Response; var resp = e.Response;
Debug.Console(1, this, "No preset received (code {0}). Loading default template", resp.Code); Debug.Console(1, this, "No preset received (code {0}). Loading default template", resp.Code);
LoadDefaultPresetData(); LoadDefaultPresetData();
if (handler != null) if (handler != null)
PresetReceived(this, new PresetReceivedEventArgs(null, false)); PresetReceived(this, new PresetReceivedEventArgs(null, false));
} }
} }
void LoadDefaultPresetData() void LoadDefaultPresetData()
{ {
CurrentPreset = null; CurrentPreset = null;
if (!File.Exists(DefaultPresetJsonFilePath)) if (!File.Exists(DefaultPresetJsonFilePath))
{ {
Debug.Console(0, this, "Cannot load default preset file. Saving will not work"); Debug.Console(0, this, "Cannot load default preset file. Saving will not work");
return; return;
} }
using (StreamReader sr = new StreamReader(DefaultPresetJsonFilePath)) using (StreamReader sr = new StreamReader(DefaultPresetJsonFilePath))
{ {
try try
{ {
var data = sr.ReadToEnd(); var data = sr.ReadToEnd();
J2SMaster.SetJsonWithoutEvaluating(data); J2SMaster.SetJsonWithoutEvaluating(data);
CurrentPreset = new Preset() { Data = data, UserId = CurrentUser.Id }; CurrentPreset = new Preset() { Data = data, UserId = CurrentUser.Id };
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(0, this, "Error reading default preset JSON: \r{0}", e); Debug.Console(0, this, "Error reading default preset JSON: \r{0}", e);
} }
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="roomTypeId"></param> /// <param name="roomTypeId"></param>
/// <param name="presetNumber"></param> /// <param name="presetNumber"></param>
public void SavePresetForThisUser(int roomTypeId, int presetNumber) public void SavePresetForThisUser(int roomTypeId, int presetNumber)
{ {
if (CurrentPreset == null) if (CurrentPreset == null)
LoadDefaultPresetData(); LoadDefaultPresetData();
//return; //return;
//// A new preset needs to have its numbers set //// A new preset needs to have its numbers set
//if (CurrentPreset.IsNewPreset) //if (CurrentPreset.IsNewPreset)
//{ //{
CurrentPreset.UserId = CurrentUser.Id; CurrentPreset.UserId = CurrentUser.Id;
CurrentPreset.RoomTypeId = roomTypeId; CurrentPreset.RoomTypeId = roomTypeId;
CurrentPreset.PresetNumber = presetNumber; CurrentPreset.PresetNumber = presetNumber;
//} //}
J2SMaster.Save(); // Will trigger callback when ready J2SMaster.Save(); // Will trigger callback when ready
} }
/// <summary> /// <summary>
/// After save operation on JSON master happens, send it to server /// After save operation on JSON master happens, send it to server
/// </summary> /// </summary>
/// <param name="json"></param> /// <param name="json"></param>
void SaveCallback(string json) void SaveCallback(string json)
{ {
CurrentPreset.Data = json; CurrentPreset.Data = json;
if (!UrlBase.StartsWith("https")) if (!UrlBase.StartsWith("https"))
return; return;
var req = new HttpsClientRequest(); var req = new HttpsClientRequest();
req.RequestType = Crestron.SimplSharp.Net.Https.RequestType.Post; req.RequestType = Crestron.SimplSharp.Net.Https.RequestType.Post;
req.Url = new UrlParser(string.Format("{0}/api/presets/addorchange", UrlBase)); req.Url = new UrlParser(string.Format("{0}/api/presets/addorchange", UrlBase));
req.Header.AddHeader(new HttpsHeader("Content-Type", "application/json")); req.Header.AddHeader(new HttpsHeader("Content-Type", "application/json"));
req.Header.AddHeader(new HttpsHeader("Accept", "application/json")); req.Header.AddHeader(new HttpsHeader("Accept", "application/json"));
req.ContentString = JsonConvert.SerializeObject(CurrentPreset); req.ContentString = JsonConvert.SerializeObject(CurrentPreset);
var client = new HttpsClient(); var client = new HttpsClient();
client.HostVerification = false; client.HostVerification = false;
client.PeerVerification = false; client.PeerVerification = false;
try try
{ {
var resp = client.Dispatch(req); var resp = client.Dispatch(req);
// 201=created // 201=created
// 204=empty content // 204=empty content
if (resp.Code == 201) if (resp.Code == 201)
CrestronConsole.PrintLine("Preset added"); CrestronConsole.PrintLine("Preset added");
else if (resp.Code == 204) else if (resp.Code == 204)
CrestronConsole.PrintLine("Preset updated"); CrestronConsole.PrintLine("Preset updated");
else if (resp.Code == 209) else if (resp.Code == 209)
CrestronConsole.PrintLine("Preset already exists. Cannot save as new."); CrestronConsole.PrintLine("Preset already exists. Cannot save as new.");
else else
CrestronConsole.PrintLine("Preset save failed: {0}\r", resp.Code, resp.ContentString); CrestronConsole.PrintLine("Preset save failed: {0}\r", resp.Code, resp.ContentString);
} }
catch (HttpException e) catch (HttpException e)
{ {
CrestronConsole.PrintLine("Preset save exception {0}", e.Response.Code); CrestronConsole.PrintLine("Preset save exception {0}", e.Response.Code);
} }
} }
} }
} }

View File

@@ -1,7 +1,7 @@
using PepperDash.Core.XSigUtility.Tokens;
using System.Collections.Generic; using System.Collections.Generic;
using PepperDash.Core.Intersystem.Tokens;
namespace PepperDash.Core.Intersystem.Serialization namespace PepperDash.Core.XSigUtility.Serialization
{ {
/// <summary> /// <summary>
/// Interface to determine XSig serialization for an object. /// Interface to determine XSig serialization for an object.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace PepperDash.Core.Intersystem.Serialization namespace PepperDash.Core.XSigUtility.Serialization
{ {
/// <summary> /// <summary>
/// Class to handle this specific exception type /// Class to handle this specific exception type

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace PepperDash.Core.Intersystem.Tokens namespace PepperDash.Core.XSigUtility.Tokens
{ {
/// <summary> /// <summary>
/// Represents an XSigAnalogToken /// Represents an XSigAnalogToken
@@ -47,8 +47,8 @@ namespace PepperDash.Core.Intersystem.Tokens
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
return new[] { return new[] {
(byte)(0xC0 | ((Value & 0xC000) >> 10) | (Index - 1 >> 7)), (byte)(0xC0 | (Value & 0xC000) >> 10 | Index - 1 >> 7),
(byte)((Index - 1) & 0x7F), (byte)(Index - 1 & 0x7F),
(byte)((Value & 0x3F80) >> 7), (byte)((Value & 0x3F80) >> 7),
(byte)(Value & 0x7F) (byte)(Value & 0x7F)
}; };

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace PepperDash.Core.Intersystem.Tokens namespace PepperDash.Core.XSigUtility.Tokens
{ {
/// <summary> /// <summary>
/// Represents an XSigDigitalToken /// Represents an XSigDigitalToken
@@ -47,8 +47,8 @@ namespace PepperDash.Core.Intersystem.Tokens
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
return new[] { return new[] {
(byte)(0x80 | (Value ? 0 : 0x20) | ((Index - 1) >> 7)), (byte)(0x80 | (Value ? 0 : 0x20) | Index - 1 >> 7),
(byte)((Index - 1) & 0x7F) (byte)(Index - 1 & 0x7F)
}; };
} }

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Text; using System.Text;
namespace PepperDash.Core.Intersystem.Tokens namespace PepperDash.Core.XSigUtility.Tokens
{ {
/// <summary> /// <summary>
/// Represents an XSigSerialToken /// Represents an XSigSerialToken
@@ -47,11 +47,11 @@ namespace PepperDash.Core.Intersystem.Tokens
/// <returns></returns> /// <returns></returns>
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
var serialBytes = String.IsNullOrEmpty(Value) ? new byte[0] : Encoding.GetEncoding(28591).GetBytes(Value); var serialBytes = string.IsNullOrEmpty(Value) ? new byte[0] : Encoding.GetEncoding(28591).GetBytes(Value);
var xsig = new byte[serialBytes.Length + 3]; var xsig = new byte[serialBytes.Length + 3];
xsig[0] = (byte)(0xC8 | (Index - 1 >> 7)); xsig[0] = (byte)(0xC8 | Index - 1 >> 7);
xsig[1] = (byte)((Index - 1) & 0x7F); xsig[1] = (byte)(Index - 1 & 0x7F);
xsig[xsig.Length - 1] = 0xFF; xsig[xsig.Length - 1] = 0xFF;
Buffer.BlockCopy(serialBytes, 0, xsig, 2, serialBytes.Length); Buffer.BlockCopy(serialBytes, 0, xsig, 2, serialBytes.Length);

View File

@@ -1,4 +1,4 @@
namespace PepperDash.Core.Intersystem.Tokens namespace PepperDash.Core.XSigUtility.Tokens
{ {
/// <summary> /// <summary>
/// Represents the base class for all XSig datatypes. /// Represents the base class for all XSig datatypes.

View File

@@ -1,4 +1,4 @@
namespace PepperDash.Core.Intersystem.Tokens namespace PepperDash.Core.XSigUtility.Tokens
{ {
/// <summary> /// <summary>
/// XSig token types. /// XSig token types.

View File

@@ -1,8 +1,7 @@
using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core.XSigUtility.Serialization;
using System; using System;
using System.Linq; using System.Linq;
using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core.Intersystem.Serialization;
using PepperDash.Core.Intersystem.Tokens;
/* /*
Digital (2 bytes) Digital (2 bytes)
@@ -18,7 +17,7 @@ using PepperDash.Core.Intersystem.Tokens;
11111111 <- denotes end of data 11111111 <- denotes end of data
*/ */
namespace PepperDash.Core.Intersystem namespace PepperDash.Core.XSigUtility
{ {
/// <summary> /// <summary>
/// Helper methods for creating XSig byte sequences compatible with the Intersystem Communications (ISC) symbol. /// Helper methods for creating XSig byte sequences compatible with the Intersystem Communications (ISC) symbol.

View File

@@ -1,10 +1,10 @@
using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core.XSigUtility.Serialization;
using PepperDash.Core.XSigUtility.Tokens;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core.Intersystem.Serialization;
using PepperDash.Core.Intersystem.Tokens;
namespace PepperDash.Core.Intersystem namespace PepperDash.Core.XSigUtility
{ {
/// <summary> /// <summary>
/// XSigToken stream reader. /// XSigToken stream reader.
@@ -56,7 +56,7 @@ namespace PepperDash.Core.Intersystem
var buffer = new byte[2]; var buffer = new byte[2];
stream.Read(buffer, 0, 2); stream.Read(buffer, 0, 2);
value = (ushort)((buffer[0] << 8) | buffer[1]); value = (ushort)(buffer[0] << 8 | buffer[1]);
return true; return true;
} }
@@ -73,7 +73,7 @@ namespace PepperDash.Core.Intersystem
if ((prefix & 0xF880) == 0xC800) // Serial data if ((prefix & 0xF880) == 0xC800) // Serial data
{ {
var index = ((prefix & 0x0700) >> 1) | (prefix & 0x7F); var index = (prefix & 0x0700) >> 1 | prefix & 0x7F;
var n = 0; var n = 0;
const int maxSerialDataLength = 252; const int maxSerialDataLength = 252;
var chars = new char[maxSerialDataLength]; var chars = new char[maxSerialDataLength];
@@ -95,14 +95,14 @@ namespace PepperDash.Core.Intersystem
if (!TryReadUInt16BE(_stream, out data)) if (!TryReadUInt16BE(_stream, out data))
return null; return null;
var index = ((prefix & 0x0700) >> 1) | (prefix & 0x7F); var index = (prefix & 0x0700) >> 1 | prefix & 0x7F;
var value = ((prefix & 0x3000) << 2) | ((data & 0x7F00) >> 1) | (data & 0x7F); var value = (prefix & 0x3000) << 2 | (data & 0x7F00) >> 1 | data & 0x7F;
return new XSigAnalogToken((ushort)(index + 1), (ushort)value); return new XSigAnalogToken((ushort)(index + 1), (ushort)value);
} }
if ((prefix & 0xC080) == 0x8000) // Digital data if ((prefix & 0xC080) == 0x8000) // Digital data
{ {
var index = ((prefix & 0x1F00) >> 1) | (prefix & 0x7F); var index = (prefix & 0x1F00) >> 1 | prefix & 0x7F;
var value = (prefix & 0x2000) == 0; var value = (prefix & 0x2000) == 0;
return new XSigDigitalToken((ushort)(index + 1), value); return new XSigDigitalToken((ushort)(index + 1), value);
} }

View File

@@ -1,11 +1,11 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core.Intersystem.Serialization; using PepperDash.Core.XSigUtility.Serialization;
using PepperDash.Core.Intersystem.Tokens; using PepperDash.Core.XSigUtility.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Core.Intersystem namespace PepperDash.Core.XSigUtility
{ {
/// <summary> /// <summary>
/// XSigToken stream writer. /// XSigToken stream writer.