Merged in maintenance/PR-43 (pull request #33)

Maintenance/PR-43

Approved-by: Neil Dorin <ndorin@pepperdash.com>
This commit is contained in:
Neil Dorin
2019-10-15 21:50:56 +00:00
19 changed files with 2201 additions and 612 deletions

View File

@@ -76,6 +76,14 @@ namespace PepperDash.Core
public class GenericTcpServerCommMethodReceiveTextArgs : EventArgs public class GenericTcpServerCommMethodReceiveTextArgs : EventArgs
{ {
public uint ReceivedFromClientIndex { get; private set; } public uint ReceivedFromClientIndex { get; private set; }
public ushort ReceivedFromClientIndexShort
{
get
{
return (ushort)ReceivedFromClientIndex;
}
}
public string Text { get; private set; } public string Text { get; private set; }
public GenericTcpServerCommMethodReceiveTextArgs(string text) public GenericTcpServerCommMethodReceiveTextArgs(string text)

View File

@@ -221,7 +221,12 @@ namespace PepperDash.Core
Debug.Console(1, this, "Creating new SshClient"); Debug.Console(1, this, "Creating new SshClient");
ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth); ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth);
Client = new SshClient(connectionInfo);
if (Client == null)
{
Client = new SshClient(connectionInfo);
}
Client.ErrorOccurred -= Client_ErrorOccurred;
Client.ErrorOccurred += Client_ErrorOccurred; Client.ErrorOccurred += Client_ErrorOccurred;
//You can do it! //You can do it!

View File

@@ -273,8 +273,6 @@ namespace PepperDash.Core
if (Client == null) if (Client == null)
{ {
Client = new TCPClient(Hostname, Port, BufferSize); Client = new TCPClient(Hostname, Port, BufferSize);
Client.SocketStatusChange += Client_SocketStatusChange; Client.SocketStatusChange += Client_SocketStatusChange;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.JsonStandardObjects
{
/*
Convert JSON snippt to C#: http://json2csharp.com/#
JSON Snippet:
{
"devices": [
{
"key": "deviceKey",
"name": "deviceName",
"type": "deviceType",
"properties": {
"deviceId": 1,
"enabled": true,
"control": {
"method": "methodName",
"controlPortDevKey": "deviceControlPortDevKey",
"controlPortNumber": 1,
"comParams": {
"baudRate": 9600,
"dataBits": 8,
"stopBits": 1,
"parity": "None",
"protocol": "RS232",
"hardwareHandshake": "None",
"softwareHandshake": "None",
"pacing": 0
},
"tcpSshProperties": {
"address": "172.22.1.101",
"port": 23,
"username": "user01",
"password": "password01",
"autoReconnect": false,
"autoReconnectIntervalMs": 10000
}
}
}
}
]
}
*/
/// <summary>
/// Device communication parameter class
/// </summary>
public class ComParamsConfig
{
public int baudRate { get; set; }
public int dataBits { get; set; }
public int stopBits { get; set; }
public string parity { get; set; }
public string protocol { get; set; }
public string hardwareHandshake { get; set; }
public string softwareHandshake { get; set; }
public int pacing { get; set; }
// convert properties for simpl
public ushort simplBaudRate { get { return Convert.ToUInt16(baudRate); } }
public ushort simplDataBits { get { return Convert.ToUInt16(dataBits); } }
public ushort simplStopBits { get { return Convert.ToUInt16(stopBits); } }
public ushort simplPacing { get { return Convert.ToUInt16(pacing); } }
/// <summary>
/// Constructor
/// </summary>
public ComParamsConfig()
{
}
}
/// <summary>
/// Device TCP/SSH properties class
/// </summary>
public class TcpSshPropertiesConfig
{
public string address { get; set; }
public int port { get; set; }
public string username { get; set; }
public string password { get; set; }
public bool autoReconnect { get; set; }
public int autoReconnectIntervalMs { get; set; }
// convert properties for simpl
public ushort simplPort { get { return Convert.ToUInt16(port); } }
public ushort simplAutoReconnect { get { return (ushort)(autoReconnect ? 1 : 0); } }
public ushort simplAutoReconnectIntervalMs { get { return Convert.ToUInt16(autoReconnectIntervalMs); } }
/// <summary>
/// Constructor
/// </summary>
public TcpSshPropertiesConfig()
{
}
}
/// <summary>
/// Device control class
/// </summary>
public class ControlConfig
{
public string method { get; set; }
public string controlPortDevKey { get; set; }
public int controlPortNumber { get; set; }
public ComParamsConfig comParams { get; set; }
public TcpSshPropertiesConfig tcpSshProperties { get; set; }
// convert properties for simpl
public ushort simplControlPortNumber { get { return Convert.ToUInt16(controlPortNumber); } }
/// <summary>
/// Constructor
/// </summary>
public ControlConfig()
{
comParams = new ComParamsConfig();
tcpSshProperties = new TcpSshPropertiesConfig();
}
}
/// <summary>
/// Device properties class
/// </summary>
public class PropertiesConfig
{
public int deviceId { get; set; }
public bool enabled { get; set; }
public ControlConfig control { get; set; }
// convert properties for simpl
public ushort simplDeviceId { get { return Convert.ToUInt16(deviceId); } }
public ushort simplEnabled { get { return (ushort)(enabled ? 1 : 0); } }
/// <summary>
/// Constructor
/// </summary>
public PropertiesConfig()
{
control = new ControlConfig();
}
}
/// <summary>
/// Root device class
/// </summary>
public class RootObject
{
public List<DeviceConfig> devices { get; set; }
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.JsonToSimpl
{
/// <summary>
/// Constants for Simpl modules
/// </summary>
public class JsonToSimplConstants
{
public const ushort BoolValueChange = 1;
public const ushort JsonIsValidBoolChange = 2;
public const ushort UshortValueChange = 101;
public const ushort StringValueChange = 201;
public const ushort FullPathToArrayChange = 202;
public const ushort ActualFilePathChange = 203;
// TODO: pdc-20: Added below constants for passing file path and filename back to S+
public const ushort FilenameResolvedChange = 204;
public const ushort FilePathResolvedChange = 205;
}
/// <summary>
/// S+ values delegate
/// </summary>
public delegate void SPlusValuesDelegate();
/// <summary>
/// S+ values wrapper
/// </summary>
public class SPlusValueWrapper
{
public SPlusType ValueType { get; private set; }
public ushort Index { get; private set; }
public ushort BoolUShortValue { get; set; }
public string StringValue { get; set; }
public SPlusValueWrapper() { }
public SPlusValueWrapper(SPlusType type, ushort index)
{
ValueType = type;
Index = index;
}
}
/// <summary>
/// S+ types enum
/// </summary>
public enum SPlusType
{
Digital, Analog, String
}
}

View File

@@ -1,125 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.JsonToSimpl
{
/// <summary>
/// Constants for Simpl modules
/// </summary>
public class JsonToSimplConstants
{
public const ushort JsonIsValidBoolChange = 2;
public const ushort BoolValueChange = 1;
public const ushort UshortValueChange = 101;
public const ushort StringValueChange = 201;
public const ushort FullPathToArrayChange = 202;
public const ushort ActualFilePathChange = 203;
}
//**************************************************************************************************//
public delegate void SPlusValuesDelegate();
public class SPlusValueWrapper
{
public SPlusType ValueType { get; private set; }
public ushort Index { get; private set; }
public ushort BoolUShortValue { get; set; }
public string StringValue { get; set; }
public SPlusValueWrapper() { }
public SPlusValueWrapper(SPlusType type, ushort index)
{
ValueType = type;
Index = index;
}
}
public enum SPlusType
{
Digital, Analog, String
}
//**************************************************************************************************//
public class BoolChangeEventArgs : EventArgs
{
public bool State { get; set; }
public ushort IntValue { get { return (ushort)(State ? 1 : 0); } }
public ushort Type { get; set; }
public ushort Index { get; set; }
public BoolChangeEventArgs()
{
}
public BoolChangeEventArgs(bool state, ushort type)
{
State = state;
Type = type;
}
public BoolChangeEventArgs(bool state, ushort type, ushort index)
{
State = state;
Type = type;
Index = index;
}
}
//**************************************************************************************************//
public class UshrtChangeEventArgs : EventArgs
{
public ushort IntValue { get; set; }
public ushort Type { get; set; }
public ushort Index { get; set; }
public UshrtChangeEventArgs()
{
}
public UshrtChangeEventArgs(ushort intValue, ushort type)
{
IntValue = intValue;
Type = type;
}
public UshrtChangeEventArgs(ushort intValue, ushort type, ushort index)
{
IntValue = intValue;
Type = type;
Index = index;
}
}
//**************************************************************************************************//
public class StringChangeEventArgs : EventArgs
{
public string StringValue { get; set; }
public ushort Type { get; set; }
public ushort Index { get; set; }
public StringChangeEventArgs()
{
}
public StringChangeEventArgs(string stringValue, ushort type)
{
StringValue = stringValue;
Type = type;
}
public StringChangeEventArgs(string stringValue, ushort type, ushort index)
{
StringValue = stringValue;
Type = type;
Index = index;
}
}
}

View File

@@ -1,116 +1,116 @@
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;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
public class JsonToSimplArrayLookupChild : JsonToSimplChildObjectBase public class JsonToSimplArrayLookupChild : JsonToSimplChildObjectBase
{ {
public string SearchPropertyName { get; set; } public string SearchPropertyName { get; set; }
public string SearchPropertyValue { get; set; } public string SearchPropertyValue { get; set; }
int ArrayIndex; int ArrayIndex;
/// <summary> /// <summary>
/// For <2.4.1 array lookups /// For <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="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);
base.Initialize(file, key, pathPrefixWithAppend, pathSuffix);
SearchPropertyName = searchPropertyName;
SearchPropertyValue = searchPropertyValue;
}
//PathPrefix+ArrayName+[x]+path+PathSuffix
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
protected override string GetFullPath(string path)
{ {
string pathPrefixWithAppend = (pathPrefix != null ? pathPrefix : "") + GetPathAppend(pathAppend);
base.Initialize(file, key, pathPrefixWithAppend, pathSuffix);
SearchPropertyName = searchPropertyName;
SearchPropertyValue = searchPropertyValue;
}
//PathPrefix+ArrayName+[x]+path+PathSuffix
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
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);
} }
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;
@@ -139,15 +139,15 @@ namespace PepperDash.Core.JsonToSimpl
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,327 +1,327 @@
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;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
public abstract class JsonToSimplChildObjectBase: IKeyed public abstract class JsonToSimplChildObjectBase: IKeyed
{ {
public event EventHandler<BoolChangeEventArgs> BoolChange; public event EventHandler<BoolChangeEventArgs> BoolChange;
public event EventHandler<UshrtChangeEventArgs> UShortChange; public event EventHandler<UshrtChangeEventArgs> UShortChange;
public event EventHandler<StringChangeEventArgs> StringChange; public event EventHandler<StringChangeEventArgs> StringChange;
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; }
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; }
public bool LinkedToObject { get; protected set; } public bool LinkedToObject { get; protected set; }
protected JsonToSimplMaster Master; protected JsonToSimplMaster Master;
// The sent-in JPaths for the various types // The sent-in JPaths for the various types
protected Dictionary<ushort, string> BoolPaths = new Dictionary<ushort, string>(); protected Dictionary<ushort, string> BoolPaths = new Dictionary<ushort, string>();
protected Dictionary<ushort, string> UshortPaths = new Dictionary<ushort, string>(); protected Dictionary<ushort, string> UshortPaths = new Dictionary<ushort, string>();
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="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>
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);
} }
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; string response;
if (Process(BoolPaths[index], out response)) if (Process(BoolPaths[index], out response))
OnBoolChange(response.Equals("true", StringComparison.OrdinalIgnoreCase), OnBoolChange(response.Equals("true", StringComparison.OrdinalIgnoreCase),
index, JsonToSimplConstants.BoolValueChange); index, JsonToSimplConstants.BoolValueChange);
else { } else { }
// OnBoolChange(false, index, JsonToSimplConstants.BoolValueChange); // OnBoolChange(false, index, JsonToSimplConstants.BoolValueChange);
} }
// Processes the path to a ushort, converting to ushort if able, firing off UshrtChange event // Processes the path to a ushort, converting to ushort if able, firing off UshrtChange event
void ProcessUshortPath(ushort index) void ProcessUshortPath(ushort index)
{ {
string response; string response;
if (Process(UshortPaths[index], out response)) { if (Process(UshortPaths[index], out response)) {
ushort val; ushort val;
try { val = Convert.ToUInt16(response); } catch { val = 0; } try { val = Convert.ToUInt16(response); } catch { val = 0; }
OnUShortChange(val, index, JsonToSimplConstants.UshortValueChange); OnUShortChange(val, index, JsonToSimplConstants.UshortValueChange);
} }
else { } else { }
// 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();
} }
public void USetBoolValue(ushort key, ushort theValue) public void USetBoolValue(ushort key, ushort theValue)
{ {
SetBoolValue(key, theValue == 1); SetBoolValue(key, theValue == 1);
} }
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));
} }
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));
} }
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));
} }
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
//****************************************************************************************** //******************************************************************************************
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);
} }
} }
//****************************************************************************************** //******************************************************************************************
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);
} }
} }
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

@@ -10,8 +10,8 @@ using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
public class JsonToSimplFileMaster : JsonToSimplMaster public class JsonToSimplFileMaster : 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>
@@ -19,10 +19,14 @@ namespace PepperDash.Core.JsonToSimpl
public string ActualFilePath { get; private set; } public string ActualFilePath { get; private set; }
// TODO: pdc-20: added to return filename back to SIMPL
public string Filename { get; private set; }
public string FilePathName { get; private 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
object StringBuilderLock = new object(); object StringBuilderLock = new object();
@@ -32,10 +36,10 @@ namespace PepperDash.Core.JsonToSimpl
/*****************************************************************************************/ /*****************************************************************************************/
/// <summary> /// <summary>
/// SIMPL+ default constructor. /// SIMPL+ default constructor.
/// </summary> /// </summary>
public JsonToSimplFileMaster() public JsonToSimplFileMaster()
{ {
} }
/// <summary> /// <summary>
@@ -49,7 +53,7 @@ namespace PepperDash.Core.JsonToSimpl
if (string.IsNullOrEmpty(Filepath)) if (string.IsNullOrEmpty(Filepath))
{ {
CrestronConsole.PrintLine("Cannot evaluate file. JSON file path not set"); CrestronConsole.PrintLine("Cannot evaluate file. JSON file path not set");
return; return;
} }
// Resolve wildcard // Resolve wildcard
@@ -59,18 +63,28 @@ namespace PepperDash.Core.JsonToSimpl
var directory = new DirectoryInfo(dir); var directory = new DirectoryInfo(dir);
var actualFile = directory.GetFiles(fileName).FirstOrDefault(); var actualFile = directory.GetFiles(fileName).FirstOrDefault();
if(actualFile == null) if (actualFile == null)
{ {
var msg = string.Format("JSON file not found: {0}", Filepath); var msg = string.Format("JSON file not found: {0}", Filepath);
CrestronConsole.PrintLine(msg); CrestronConsole.PrintLine(msg);
ErrorLog.Error(msg); ErrorLog.Error(msg);
return; return;
} }
//var actualFileName = actualFile.FullName;
// \xSE\xR\PDT000-Template_Main_Config-Combined_DSP_v00.02.json
// \USER\PDT000-Template_Main_Config-Combined_DSP_v00.02.json
ActualFilePath = actualFile.FullName; ActualFilePath = actualFile.FullName;
OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange); OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange);
Debug.Console(1, "Actual JSON file is {0}", ActualFilePath); Debug.Console(1, "Actual JSON file is {0}", ActualFilePath);
Filename = actualFile.Name;
OnStringChange(Filename, 0, JsonToSimplConstants.FilenameResolvedChange);
Debug.Console(1, "JSON Filename is {0}", Filename);
FilePathName = string.Format(@"{0}\", actualFile.DirectoryName);
OnStringChange(FilePathName, 0, JsonToSimplConstants.FilePathResolvedChange);
Debug.Console(1, "JSON File Path is {0}", FilePathName);
string json = File.ReadToEnd(ActualFilePath, System.Text.Encoding.ASCII); string json = File.ReadToEnd(ActualFilePath, System.Text.Encoding.ASCII);
try try
@@ -87,10 +101,11 @@ namespace PepperDash.Core.JsonToSimpl
ErrorLog.Error(msg); ErrorLog.Error(msg);
return; return;
} }
} }
public void setDebugLevel(int level) { public void setDebugLevel(int level)
Debug.SetDebugLevel(level); {
} Debug.SetDebugLevel(level);
}
public override void Save() public override void Save()
{ {
// this code is duplicated in the other masters!!!!!!!!!!!!! // this code is duplicated in the other masters!!!!!!!!!!!!!
@@ -122,39 +137,39 @@ namespace PepperDash.Core.JsonToSimpl
{ {
//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);
// JContainer jpart = JsonObject;
// // walk down the path and find where it goes
//#warning Does not handle arrays.
// foreach (var part in path.Split('.'))
// {
// var openPos = part.IndexOf('['); // JContainer jpart = JsonObject;
// if (openPos > -1) // // walk down the path and find where it goes
// { //#warning Does not handle arrays.
// openPos++; // move to number // foreach (var part in path.Split('.'))
// var closePos = part.IndexOf(']'); // {
// var arrayName = part.Substring(0, openPos - 1); // get the name
// var index = Convert.ToInt32(part.Substring(openPos, closePos - openPos));
// // Check if the array itself exists and add the item if so // var openPos = part.IndexOf('[');
// if (jpart[arrayName] != null) // if (openPos > -1)
// { // {
// var arrayObj = jpart[arrayName] as JArray; // openPos++; // move to number
// var item = arrayObj[index]; // var closePos = part.IndexOf(']');
// if (item == null) // var arrayName = part.Substring(0, openPos - 1); // get the name
// arrayObj.Add(new JObject()); // var index = Convert.ToInt32(part.Substring(openPos, closePos - openPos));
// }
// // Check if the array itself exists and add the item if so
// Debug.Console(0, "IGNORING MISSING ARRAY VALUE FOR NOW"); // if (jpart[arrayName] != null)
// continue; // {
// } // var arrayObj = jpart[arrayName] as JArray;
// // Build the // var item = arrayObj[index];
// if (jpart[part] == null) // if (item == null)
// jpart.Add(new JProperty(part, new JObject())); // arrayObj.Add(new JObject());
// jpart = jpart[part] as JContainer; // }
// }
// jpart.Replace(UnsavedValues[path]); // Debug.Console(0, "IGNORING MISSING ARRAY VALUE FOR NOW");
// continue;
// }
// // Build the
// if (jpart[part] == null)
// jpart.Add(new JProperty(part, new JObject()));
// jpart = jpart[part] as JContainer;
// }
// jpart.Replace(UnsavedValues[path]);
} }
} }
using (StreamWriter sw = new StreamWriter(ActualFilePath)) using (StreamWriter sw = new StreamWriter(ActualFilePath))

View File

@@ -86,6 +86,12 @@
<Compile Include="Comm\TcpServerConfigObject.cs" /> <Compile Include="Comm\TcpServerConfigObject.cs" />
<Compile Include="Config\PortalConfigReader.cs" /> <Compile Include="Config\PortalConfigReader.cs" />
<Compile Include="CoreInterfaces.cs" /> <Compile Include="CoreInterfaces.cs" />
<Compile Include="EventArgs.cs" />
<Compile Include="GenericRESTfulCommunications\Constants.cs" />
<Compile Include="GenericRESTfulCommunications\GenericRESTfulClient.cs" />
<Compile Include="JsonStandardObjects\EventArgs and Constants.cs" />
<Compile Include="JsonStandardObjects\JsonToSimplDeviceConfig.cs" />
<Compile Include="JsonStandardObjects\JsonToSimplDevice.cs" />
<Compile Include="JsonToSimpl\JsonToSimplPortalFileMaster.cs" /> <Compile Include="JsonToSimpl\JsonToSimplPortalFileMaster.cs" />
<Compile Include="Logging\Debug.cs" /> <Compile Include="Logging\Debug.cs" />
<Compile Include="Logging\DebugContext.cs" /> <Compile Include="Logging\DebugContext.cs" />
@@ -94,7 +100,7 @@
<Compile Include="Comm\GenericTcpIpServer.cs" /> <Compile Include="Comm\GenericTcpIpServer.cs" />
<Compile Include="EthernetHelper.cs" /> <Compile Include="EthernetHelper.cs" />
<Compile Include="Comm\GenericTcpIpClient.cs" /> <Compile Include="Comm\GenericTcpIpClient.cs" />
<Compile Include="JsonToSimpl\EventArgs and Constants.cs" /> <Compile Include="JsonToSimpl\Constants.cs" />
<Compile Include="JsonToSimpl\Global.cs" /> <Compile Include="JsonToSimpl\Global.cs" />
<Compile Include="JsonToSimpl\JsonToSimplArrayLookupChild.cs" /> <Compile Include="JsonToSimpl\JsonToSimplArrayLookupChild.cs" />
<Compile Include="JsonToSimpl\JsonToSimplChildObjectBase.cs" /> <Compile Include="JsonToSimpl\JsonToSimplChildObjectBase.cs" />
@@ -104,7 +110,10 @@
<Compile Include="JsonToSimpl\JsonToSimplGenericMaster.cs" /> <Compile Include="JsonToSimpl\JsonToSimplGenericMaster.cs" />
<Compile Include="JsonToSimpl\JsonToSimplMaster.cs" /> <Compile Include="JsonToSimpl\JsonToSimplMaster.cs" />
<Compile Include="Network\DiscoveryThings.cs" /> <Compile Include="Network\DiscoveryThings.cs" />
<Compile Include="SystemInfo\EventArgs and Constants.cs" />
<Compile Include="SystemInfo\SystemInfoConfig.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SystemInfo\SystemInfoToSimpl.cs" />
<Compile Include="WebApi\Presets\Preset.cs" /> <Compile Include="WebApi\Presets\Preset.cs" />
<Compile Include="WebApi\Presets\User.cs" /> <Compile Include="WebApi\Presets\User.cs" />
<Compile Include="WebApi\Presets\WebApiPasscodeClient.cs" /> <Compile Include="WebApi\Presets\WebApiPasscodeClient.cs" />
@@ -117,5 +126,7 @@
</ProjectExtensions> </ProjectExtensions>
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>rem S# preparation will execute after these operations</PostBuildEvent> <PostBuildEvent>rem S# preparation will execute after these operations</PostBuildEvent>
<PreBuildEvent>del "$(TargetDir)PepperDash_Core.*" /q
</PreBuildEvent>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@@ -24,6 +24,7 @@ function Update-AllAssemblyInfoFiles ( $version )
$r= [System.Text.RegularExpressions.Regex]::Match($args[0], "^\d+\.\d+\.\d+$"); $r= [System.Text.RegularExpressions.Regex]::Match($args[0], "^\d+\.\d+\.\d+$");
if ($r.Success) if ($r.Success)
{ {
echo "Updating Assembly Version...";
Update-AllAssemblyInfoFiles $args[0]; Update-AllAssemblyInfoFiles $args[0];
} }
else else

View File

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

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Core.SystemInfo
{
/// <summary>
/// Processor info class
/// </summary>
public class ProcessorInfo
{
public string Model { get; set; }
public string SerialNumber { get; set; }
public string Firmware { get; set; }
public string FirmwareDate { get; set; }
public string OsVersion { get; set; }
public string RuntimeEnvironment { get; set; }
public string DevicePlatform { get; set; }
public string ModuleDirectory { get; set; }
public string LocalTimeZone { get; set; }
public string ProgramIdTag { get; set; }
/// <summary>
/// Constructor
/// </summary>
public ProcessorInfo()
{
}
}
/// <summary>
/// Ethernet info class
/// </summary>
public class EthernetInfo
{
public ushort DhcpIsOn { get; set; }
public string Hostname { get; set; }
public string MacAddress { get; set; }
public string IpAddress { get; set; }
public string Subnet { get; set; }
public string Gateway { get; set; }
public string Dns1 { get; set; }
public string Dns2 { get; set; }
public string Dns3 { get; set; }
public string Domain { get; set; }
/// <summary>
/// Constructor
/// </summary>
public EthernetInfo()
{
}
}
/// <summary>
/// Control subnet info class
/// </summary>
public class ControlSubnetInfo
{
public ushort Enabled { get; set; }
public ushort IsInAutomaticMode { get; set; }
public string MacAddress { get; set; }
public string IpAddress { get; set; }
public string Subnet { get; set; }
public string RouterPrefix { get; set; }
/// <summary>
/// Constructor
/// </summary>
public ControlSubnetInfo()
{
}
}
/// <summary>
/// Program info class
/// </summary>
public class ProgramInfo
{
public string Name { get; set; }
public string Header { get; set; }
public string System { get; set; }
public string ProgramIdTag { get; set; }
public string CompileTime { get; set; }
public string Database { get; set; }
public string Environment { get; set; }
public string Programmer { get; set; }
/// <summary>
/// Constructor
/// </summary>
public ProgramInfo()
{
}
}
}

View File

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