mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 04:34:56 +00:00
Merged in maintenance/remove-essentials-framework-submodule (pull request #18)
Removes essentials-framework as a submodule and brings the files back into the main repo Approved-by: Neil Dorin <ndorin@pepperdash.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@ obj/
|
|||||||
_ReSharper*/
|
_ReSharper*/
|
||||||
SIMPLSharpLogs/
|
SIMPLSharpLogs/
|
||||||
*.projectinfo
|
*.projectinfo
|
||||||
|
essentials-framework/EssentialDMTestConfig/
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "essentials-framework"]
|
|
||||||
path = essentials-framework
|
|
||||||
url = https://bitbucket.org/Pepperdash_Products/essentials-framework.git
|
|
||||||
|
|||||||
Submodule essentials-framework deleted from 2e132f830f
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash_Essentials_Core", "PepperDashEssentialsBase\PepperDash_Essentials_Core.csproj", "{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class CecPortController : Device, IBasicCommunication
|
||||||
|
{
|
||||||
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
|
public bool IsConnected { get { return true; } }
|
||||||
|
|
||||||
|
ICec Port;
|
||||||
|
|
||||||
|
public CecPortController(string key, ICec port)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
Port = port;
|
||||||
|
|
||||||
|
Port.StreamCec.CecChange += new CecChangeEventHandler(StreamCec_CecChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamCec_CecChange(Cec cecDevice, CecEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.EventId == CecEventIds.CecMessageReceivedEventId)
|
||||||
|
OnDataReceived(cecDevice.Received.StringValue);
|
||||||
|
else if (args.EventId == CecEventIds.ErrorFeedbackEventId)
|
||||||
|
if(cecDevice.ErrorFeedback.BoolValue)
|
||||||
|
Debug.Console(2, this, "CEC NAK Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDataReceived(string s)
|
||||||
|
{
|
||||||
|
var bytesHandler = BytesReceived;
|
||||||
|
if (bytesHandler != null)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||||
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
|
}
|
||||||
|
var textHandler = TextReceived;
|
||||||
|
if (textHandler != null)
|
||||||
|
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IBasicCommunication Members
|
||||||
|
|
||||||
|
public void SendText(string text)
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
return;
|
||||||
|
Port.StreamCec.Send.StringValue = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
return;
|
||||||
|
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
|
Port.StreamCec.Send.StringValue = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Connect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
public void SimulateReceive(string s)
|
||||||
|
{
|
||||||
|
// split out hex chars and build string
|
||||||
|
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
foreach (var t in split)
|
||||||
|
{
|
||||||
|
if (t.StartsWith(@"\") && t.Length == 4)
|
||||||
|
b.Append((char)(Convert.ToByte(t.Substring(2, 2), 16)));
|
||||||
|
else
|
||||||
|
b.Append(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnDataReceived(b.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class ComPortController : Device, IBasicCommunication
|
||||||
|
{
|
||||||
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
|
public bool IsConnected { get { return true; } }
|
||||||
|
|
||||||
|
ComPort Port;
|
||||||
|
ComPort.ComPortSpec Spec;
|
||||||
|
|
||||||
|
public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
if (port == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "ERROR: Invalid com port, continuing but comms will not function");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Port = port;
|
||||||
|
Spec = spec;
|
||||||
|
//IsConnected = new BoolFeedback(CommonBoolCue.IsConnected, () => true);
|
||||||
|
|
||||||
|
if (Port.Parent is CrestronControlSystem)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var result = Port.Register();
|
||||||
|
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "ERROR: Cannot register Com port: {0}", result);
|
||||||
|
return; // false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var specResult = Port.SetComPortSpec(Spec);
|
||||||
|
if (specResult != 0)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "WARNING: Cannot set comspec");
|
||||||
|
return; // false
|
||||||
|
}
|
||||||
|
Port.SerialDataReceived += new ComPortDataReceivedEvent(Port_SerialDataReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ComPortController()
|
||||||
|
{
|
||||||
|
Port.SerialDataReceived -= Port_SerialDataReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
|
||||||
|
{
|
||||||
|
OnDataReceived(args.SerialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDataReceived(string s)
|
||||||
|
{
|
||||||
|
var bytesHandler = BytesReceived;
|
||||||
|
if (bytesHandler != null)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||||
|
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
|
}
|
||||||
|
var textHandler = TextReceived;
|
||||||
|
if (textHandler != null)
|
||||||
|
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IBasicCommunication Members
|
||||||
|
|
||||||
|
public void SendText(string text)
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
return;
|
||||||
|
Port.Send(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (Port == null)
|
||||||
|
return;
|
||||||
|
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
|
Port.Send(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Connect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
public void SimulateReceive(string s)
|
||||||
|
{
|
||||||
|
// split out hex chars and build string
|
||||||
|
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
foreach (var t in split)
|
||||||
|
{
|
||||||
|
if (t.StartsWith(@"\") && t.Length == 4)
|
||||||
|
b.Append((char)(Convert.ToByte(t.Substring(2, 2), 16)));
|
||||||
|
else
|
||||||
|
b.Append(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnDataReceived(b.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This converter creates a proper ComPort.ComPortSpec struct from more-friendly JSON values. It uses
|
||||||
|
/// ComSpecPropsJsonConverter to finish the individual properties.
|
||||||
|
/// </summary>
|
||||||
|
public class ComSpecJsonConverter : JsonConverter
|
||||||
|
{
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (objectType == typeof(ComPort.ComPortSpec))
|
||||||
|
{
|
||||||
|
var newSer = new JsonSerializer();
|
||||||
|
newSer.Converters.Add(new ComSpecPropsJsonConverter());
|
||||||
|
newSer.ObjectCreationHandling = ObjectCreationHandling.Replace;
|
||||||
|
return newSer.Deserialize<ComPort.ComPortSpec>(reader);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return objectType == typeof(ComPort.ComPortSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanRead { get { return true; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This converter will not be used for writing
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The gist of this converter: The comspec JSON comes in with normal values that need to be converted
|
||||||
|
/// into enum names. This converter takes the value and applies the appropriate enum's name prefix to the value
|
||||||
|
/// and then returns the enum value using Enum.Parse. NOTE: Does not write
|
||||||
|
/// </summary>
|
||||||
|
public class ComSpecPropsJsonConverter : JsonConverter
|
||||||
|
{
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return objectType == typeof(ComPort.eComBaudRates)
|
||||||
|
|| objectType == typeof(ComPort.eComDataBits)
|
||||||
|
|| objectType == typeof(ComPort.eComParityType)
|
||||||
|
|| objectType == typeof(ComPort.eComHardwareHandshakeType)
|
||||||
|
|| objectType == typeof(ComPort.eComSoftwareHandshakeType)
|
||||||
|
|| objectType == typeof(ComPort.eComProtocolType)
|
||||||
|
|| objectType == typeof(ComPort.eComStopBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanRead { get { return true; } }
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
//Debug.Console(2, "ReadJson type: " + objectType.Name);
|
||||||
|
if (objectType == typeof(ComPort.eComBaudRates))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComBaudRates), "ComspecBaudRate" + reader.Value, false);
|
||||||
|
else if (objectType == typeof(ComPort.eComDataBits))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComDataBits), "ComspecDataBits" + reader.Value, true);
|
||||||
|
else if (objectType == typeof(ComPort.eComHardwareHandshakeType))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComHardwareHandshakeType), "ComspecHardwareHandshake" + reader.Value, true);
|
||||||
|
else if (objectType == typeof(ComPort.eComParityType))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComParityType), "ComspecParity" + reader.Value, true);
|
||||||
|
else if (objectType == typeof(ComPort.eComProtocolType))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComProtocolType), "ComspecProtocol" + reader.Value, true);
|
||||||
|
else if (objectType == typeof(ComPort.eComSoftwareHandshakeType))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComSoftwareHandshakeType), "ComspecSoftwareHandshake" + reader.Value, true);
|
||||||
|
else if (objectType == typeof(ComPort.eComStopBits))
|
||||||
|
return Enum.Parse(typeof(ComPort.eComStopBits), "ComspecStopBits" + reader.Value, true);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
using System;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class CommFactory
|
||||||
|
{
|
||||||
|
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||||
|
(deviceConfig.Properties["control"].ToString());
|
||||||
|
//Debug.Console(2, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(0, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deviceConfig">The Device config object</param>
|
||||||
|
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||||
|
{
|
||||||
|
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||||
|
if (controlConfig == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IBasicCommunication comm = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var c = controlConfig.TcpSshProperties;
|
||||||
|
switch (controlConfig.Method)
|
||||||
|
{
|
||||||
|
case eControlMethod.Com:
|
||||||
|
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort(controlConfig), controlConfig.ComParams);
|
||||||
|
break;
|
||||||
|
case eControlMethod.Cec:
|
||||||
|
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort(controlConfig));
|
||||||
|
break;
|
||||||
|
case eControlMethod.IR:
|
||||||
|
break;
|
||||||
|
case eControlMethod.Ssh:
|
||||||
|
{
|
||||||
|
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
||||||
|
ssh.AutoReconnect = c.AutoReconnect;
|
||||||
|
if(ssh.AutoReconnect)
|
||||||
|
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
|
comm = ssh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eControlMethod.Tcpip:
|
||||||
|
{
|
||||||
|
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
||||||
|
tcp.AutoReconnect = c.AutoReconnect;
|
||||||
|
if (tcp.AutoReconnect)
|
||||||
|
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||||
|
comm = tcp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eControlMethod.Udp:
|
||||||
|
{
|
||||||
|
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||||
|
comm = udp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eControlMethod.Telnet:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
||||||
|
deviceConfig.Properties.ToString(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// put it in the device manager if it's the right flavor
|
||||||
|
var comDev = comm as Device;
|
||||||
|
if (comDev != null)
|
||||||
|
DeviceManager.AddDevice(comDev);
|
||||||
|
return comm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||||
|
{
|
||||||
|
var comPar = config.ComParams;
|
||||||
|
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||||
|
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||||
|
return dev.ComPorts[config.ControlPortNumber];
|
||||||
|
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
||||||
|
|
||||||
|
if (dev != null)
|
||||||
|
{
|
||||||
|
var inputPort = (dev as IRoutingInputsOutputs).InputPorts[config.ControlPortName];
|
||||||
|
|
||||||
|
if (inputPort != null)
|
||||||
|
if (inputPort.Port is ICec)
|
||||||
|
return inputPort.Port as ICec;
|
||||||
|
|
||||||
|
var outputPort = (dev as IRoutingInputsOutputs).OutputPorts[config.ControlPortName];
|
||||||
|
|
||||||
|
if (outputPort != null)
|
||||||
|
if (outputPort.Port is ICec)
|
||||||
|
return outputPort.Port as ICec;
|
||||||
|
}
|
||||||
|
Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called: '{1}'", config.ControlPortDevKey, config.ControlPortName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||||
|
/// return the ControlSystem object from the Global class.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||||
|
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||||
|
{
|
||||||
|
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
|
||||||
|
&& Global.ControlSystem is IComPorts)
|
||||||
|
return Global.ControlSystem;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
||||||
|
if (dev == null)
|
||||||
|
Debug.Console(0, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class EssentialsControlPropertiesConfig :
|
||||||
|
PepperDash.Core.ControlPropertiesConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||||
|
public ComPort.ComPortSpec ComParams { get; set; }
|
||||||
|
|
||||||
|
public string CresnetId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to provide uint conversion of string CresnetId
|
||||||
|
/// </summary>
|
||||||
|
public uint CresnetIdInt
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Convert.ToUInt32(CresnetId, 16);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IrControlSpec
|
||||||
|
{
|
||||||
|
public string PortDeviceKey { get; set; }
|
||||||
|
public uint PortNumber { get; set; }
|
||||||
|
public string File { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IComPortsDevice
|
||||||
|
{
|
||||||
|
IComPorts Device { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class ConsoleCommMockDevice : Device, ICommunicationMonitor
|
||||||
|
{
|
||||||
|
public IBasicCommunication Communication { get; private set; }
|
||||||
|
public CommunicationGather PortGather { get; private set; }
|
||||||
|
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defaults to \x0a
|
||||||
|
/// </summary>
|
||||||
|
public string LineEnding { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set to true to show responses in full hex
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowHexResponse { get; set; }
|
||||||
|
|
||||||
|
public ConsoleCommMockDevice(string key, string name, ConsoleCommMockDevicePropertiesConfig props, IBasicCommunication comm)
|
||||||
|
:base(key, name)
|
||||||
|
{
|
||||||
|
Communication = comm;
|
||||||
|
PortGather = new CommunicationGather(Communication, '\x0d');
|
||||||
|
PortGather.LineReceived += this.Port_LineReceived;
|
||||||
|
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
|
||||||
|
LineEnding = props.LineEnding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
Communication.Connect();
|
||||||
|
CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
|
||||||
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(SendLine, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
|
||||||
|
{
|
||||||
|
if (Debug.Level == 2)
|
||||||
|
Debug.Console(2, this, "RX: '{0}'",
|
||||||
|
ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendLine(string s)
|
||||||
|
{
|
||||||
|
//if (Debug.Level == 2)
|
||||||
|
// Debug.Console(2, this, " Send '{0}'", ComTextHelper.GetEscapedText(s));
|
||||||
|
Communication.SendText(s + LineEnding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConsoleCommMockDevicePropertiesConfig
|
||||||
|
{
|
||||||
|
public string LineEnding { get; set; }
|
||||||
|
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
||||||
|
|
||||||
|
public ConsoleCommMockDevicePropertiesConfig()
|
||||||
|
{
|
||||||
|
LineEnding = "\x0a";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class ComPortController : Device, IBasicCommunication
|
||||||
|
{
|
||||||
|
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||||
|
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||||
|
|
||||||
|
ComPort Port;
|
||||||
|
ComPort.ComPortSpec Spec;
|
||||||
|
|
||||||
|
public ComPortController(string key, IComPorts ComDevice, uint comPortNum, ComPort.ComPortSpec spec)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
Port = ComDevice.ComPorts[comPortNum];
|
||||||
|
Spec = spec;
|
||||||
|
|
||||||
|
Debug.Console(2, "Creating com port '{0}'", key);
|
||||||
|
Debug.Console(2, "Com port spec:\r{0}", JsonConvert.SerializeObject(spec));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a ComPort if the parameters are correct. Returns and logs errors if not
|
||||||
|
/// </summary>
|
||||||
|
public static ComPortController GetComPortController(string key,
|
||||||
|
IComPorts comDevice, uint comPortNum, ComPort.ComPortSpec spec)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Creating com port '{0}'", key);
|
||||||
|
if (comDevice == null)
|
||||||
|
throw new ArgumentNullException("comDevice");
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
throw new ArgumentNullException("key");
|
||||||
|
if (comPortNum > comDevice.NumberOfComPorts)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "[{0}] Com port {1} out of range on {2}",
|
||||||
|
key, comPortNum, comDevice.GetType().Name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var port = new ComPortController(key, comDevice, comPortNum, spec);
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers port and sends ComSpec
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>false if either register or comspec fails</returns>
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
var result = Port.Register();
|
||||||
|
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Cannot register Com port: {0}", result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var specResult = Port.SetComPortSpec(Spec);
|
||||||
|
if (specResult != 0)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Cannot set comspec");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Port.SerialDataReceived += new ComPortDataReceivedEvent(Port_SerialDataReceived);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
|
||||||
|
{
|
||||||
|
if (BytesReceived != null)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.GetEncoding(28591).GetBytes(args.SerialData);
|
||||||
|
BytesReceived(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||||
|
}
|
||||||
|
if(TextReceived != null)
|
||||||
|
TextReceived(this, new GenericCommMethodReceiveTextArgs(args.SerialData));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IBasicCommunication Members
|
||||||
|
|
||||||
|
public void SendText(string text)
|
||||||
|
{
|
||||||
|
Port.Send(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
|
||||||
|
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||||
|
Port.Send(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serves as a generic wrapper class for all styles of IBasicCommuncation ports
|
||||||
|
/// </summary>
|
||||||
|
public class
|
||||||
|
GenericComm : ReconfigurableDevice
|
||||||
|
{
|
||||||
|
EssentialsControlPropertiesConfig PropertiesConfig;
|
||||||
|
|
||||||
|
public IBasicCommunication CommPort { get; private set; }
|
||||||
|
|
||||||
|
public GenericComm(DeviceConfig config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
||||||
|
|
||||||
|
CommPort = CommFactory.CreateCommForDevice(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPortConfig(string portConfig)
|
||||||
|
{
|
||||||
|
// TODO: Deserialize new EssentialsControlPropertiesConfig and handle as necessary
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||||
|
(portConfig.ToString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Error deserializing port config: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CustomSetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
||||||
|
|
||||||
|
ConfigWriter.UpdateDeviceConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class IRPortHelper
|
||||||
|
{
|
||||||
|
public static string IrDriverPathPrefix
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Global.FilePathPrefix + "IR" + Global.DirectorySeparator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds either the ControlSystem or a device controller that contains IR ports and
|
||||||
|
/// returns a port from the hardware device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propsToken"></param>
|
||||||
|
/// <returns>IrPortConfig object. The port and or filename will be empty/null
|
||||||
|
/// if valid values don't exist on config</returns>
|
||||||
|
public static IrOutPortConfig GetIrPort(JToken propsToken)
|
||||||
|
{
|
||||||
|
var control = propsToken["control"];
|
||||||
|
if (control == null)
|
||||||
|
return null;
|
||||||
|
if (control["method"].Value<string>() != "ir")
|
||||||
|
{
|
||||||
|
Debug.Console(0, "IRPortHelper called with non-IR properties");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var port = new IrOutPortConfig();
|
||||||
|
|
||||||
|
var portDevKey = control.Value<string>("controlPortDevKey");
|
||||||
|
var portNum = control.Value<uint>("controlPortNumber");
|
||||||
|
if (portDevKey == null || portNum == 0)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "WARNING: Properties is missing port device or port number");
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
IIROutputPorts irDev = null;
|
||||||
|
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
||||||
|
irDev = Global.ControlSystem;
|
||||||
|
else
|
||||||
|
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
|
||||||
|
|
||||||
|
if (irDev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "[Config] Error, device with IR ports '{0}' not found", portDevKey);
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portNum <= irDev.NumberOfIROutputPorts) // success!
|
||||||
|
{
|
||||||
|
var file = IrDriverPathPrefix + control["irFile"].Value<string>();
|
||||||
|
port.Port = irDev.IROutputPorts[portNum];
|
||||||
|
port.FileName = file;
|
||||||
|
return port; // new IrOutPortConfig { Port = irDev.IROutputPorts[portNum], FileName = file };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, "[Config] Error, device '{0}' IR port {1} out of range",
|
||||||
|
portDevKey, portNum);
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a ready-to-go IrOutputPortController from a DeviceConfig object.
|
||||||
|
/// </summary>
|
||||||
|
public static IrOutputPortController GetIrOutputPortController(DeviceConfig devConf)
|
||||||
|
{
|
||||||
|
var irControllerKey = devConf.Key + "-ir";
|
||||||
|
if (devConf.Properties == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "[{0}] WARNING: Device config does not include properties. IR will not function.", devConf.Key);
|
||||||
|
return new IrOutputPortController(irControllerKey, null, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
var control = devConf.Properties["control"];
|
||||||
|
if (control == null)
|
||||||
|
{
|
||||||
|
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||||
|
Debug.Console(0, c, "WARNING: Device config does not include control properties. IR will not function");
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
var portDevKey = control.Value<string>("controlPortDevKey");
|
||||||
|
var portNum = control.Value<uint>("controlPortNumber");
|
||||||
|
IIROutputPorts irDev = null;
|
||||||
|
|
||||||
|
if (portDevKey == null)
|
||||||
|
{
|
||||||
|
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||||
|
Debug.Console(0, c, "WARNING: control properties is missing ir device");
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portNum == 0)
|
||||||
|
{
|
||||||
|
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||||
|
Debug.Console(0, c, "WARNING: control properties is missing ir port number");
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
||||||
|
irDev = Global.ControlSystem;
|
||||||
|
else
|
||||||
|
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
|
||||||
|
|
||||||
|
if (irDev == null)
|
||||||
|
{
|
||||||
|
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||||
|
Debug.Console(0, c, "WARNING: device with IR ports '{0}' not found", portDevKey);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portNum <= irDev.NumberOfIROutputPorts) // success!
|
||||||
|
return new IrOutputPortController(irControllerKey, irDev.IROutputPorts[portNum],
|
||||||
|
IrDriverPathPrefix + control["irFile"].Value<string>());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||||
|
Debug.Console(0, c, "WARNING: device '{0}' IR port {1} out of range",
|
||||||
|
portDevKey, portNum);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrapper to help in IR port creation
|
||||||
|
/// </summary>
|
||||||
|
public class IrOutPortConfig
|
||||||
|
{
|
||||||
|
public IROutputPort Port { get; set; }
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
public IrOutPortConfig()
|
||||||
|
{
|
||||||
|
FileName = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Override this and splice on specific room type behavior, as well as other properties
|
||||||
|
/// </summary>
|
||||||
|
public class BasicConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("info")]
|
||||||
|
public InfoConfig Info { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("devices")]
|
||||||
|
public List<DeviceConfig> Devices { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("sourceLists")]
|
||||||
|
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("tieLines")]
|
||||||
|
public List<TieLineConfig> TieLines { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, SourceListItem> GetSourceListForKey(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key) || !SourceLists.ContainsKey(key))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return SourceLists[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
public class ConfigPropertiesHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the value of properties.hasAudio, or false if not defined
|
||||||
|
/// </summary>
|
||||||
|
public static bool GetHasAudio(DeviceConfig deviceConfig)
|
||||||
|
{
|
||||||
|
return deviceConfig.Properties.Value<bool>("hasAudio");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the value of properties.hasControls, or false if not defined
|
||||||
|
/// </summary>
|
||||||
|
public static bool GetHasControls(DeviceConfig deviceConfig)
|
||||||
|
{
|
||||||
|
return deviceConfig.Properties.Value<bool>("hasControls");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
public class DeviceConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("uid")]
|
||||||
|
public int Uid { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("group")]
|
||||||
|
public string Group { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("properties")]
|
||||||
|
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||||
|
public JToken Properties { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class DevicePropertiesConverter : JsonConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return objectType == typeof(JToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
return JToken.ReadFrom(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("SOD OFF HOSER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the ConfigObject from the file
|
||||||
|
/// </summary>
|
||||||
|
public class ConfigReader
|
||||||
|
{
|
||||||
|
public static EssentialsConfig ConfigObject { get; private set; }
|
||||||
|
|
||||||
|
public static bool LoadConfig2()
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check for local config file first
|
||||||
|
var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
|
||||||
|
|
||||||
|
bool localConfigFound = false;
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
|
||||||
|
|
||||||
|
// Check for local config directory first
|
||||||
|
|
||||||
|
var configFiles = GetConfigFiles(filePath);
|
||||||
|
|
||||||
|
if (configFiles != null)
|
||||||
|
{
|
||||||
|
if (configFiles.Length > 1)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||||
|
"****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(configFiles.Length == 1)
|
||||||
|
{
|
||||||
|
localConfigFound = true;
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Local config file: '{0}'", filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||||
|
"Local Configuration file not present.", filePath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for Portal Config
|
||||||
|
if(!localConfigFound)
|
||||||
|
{
|
||||||
|
filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
|
||||||
|
|
||||||
|
configFiles = GetConfigFiles(filePath);
|
||||||
|
|
||||||
|
if (configFiles != null)
|
||||||
|
{
|
||||||
|
if (configFiles.Length > 1)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||||
|
"****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||||
|
"ERROR: Portal Configuration file not present. Please load file and reset program.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the actual file path
|
||||||
|
filePath = configFiles[0].FullName;
|
||||||
|
|
||||||
|
// Read the file
|
||||||
|
using (StreamReader fs = new StreamReader(filePath))
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
|
||||||
|
|
||||||
|
if (localConfigFound)
|
||||||
|
{
|
||||||
|
ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject<EssentialsConfig>();
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
||||||
|
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
||||||
|
|
||||||
|
// Extract SystemUrl and TemplateUrl into final config output
|
||||||
|
|
||||||
|
if (doubleObj["system_url"] != null)
|
||||||
|
{
|
||||||
|
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doubleObj["template_url"] != null)
|
||||||
|
{
|
||||||
|
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns all the files from the directory specified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static FileInfo[] GetConfigFiles(string filePath)
|
||||||
|
{
|
||||||
|
// Get the directory
|
||||||
|
var dir = Path.GetDirectoryName(filePath);
|
||||||
|
|
||||||
|
if (Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Searching in Directory '{0}'", dir);
|
||||||
|
// Get the directory info
|
||||||
|
var dirInfo = new DirectoryInfo(dir);
|
||||||
|
|
||||||
|
// Get the file name
|
||||||
|
var fileName = Path.GetFileName(filePath);
|
||||||
|
Debug.Console(1, "For Config Files matching: '{0}'", fileName);
|
||||||
|
|
||||||
|
// Get the files that match from the directory
|
||||||
|
return dirInfo.GetFiles(fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||||
|
"Directory not found: ", dir);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the group for a given device key in config
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetGroupForDeviceKey(string key)
|
||||||
|
{
|
||||||
|
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
return dev == null ? null : dev.Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Crestron.SimplSharp.Net.Http;
|
||||||
|
using Crestron.SimplSharpPro.Diagnostics;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
public static class ConfigUpdater
|
||||||
|
{
|
||||||
|
public static event EventHandler<ConfigStatusEventArgs> ConfigStatusChanged;
|
||||||
|
|
||||||
|
public static void GetConfigFromServer(string url)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to get new config from '{0}'", url);
|
||||||
|
|
||||||
|
// HTTP GET
|
||||||
|
var req = new HttpClientRequest();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
req.RequestType = RequestType.Get;
|
||||||
|
req.Url.Parse(url);
|
||||||
|
|
||||||
|
new HttpClient().DispatchAsync(req, (r, e) =>
|
||||||
|
{
|
||||||
|
if (e == HTTP_CALLBACK_ERROR.COMPLETED)
|
||||||
|
{
|
||||||
|
if (r.Code == 200)
|
||||||
|
{
|
||||||
|
var newConfig = r.ContentString;
|
||||||
|
|
||||||
|
OnStatusUpdate(eUpdateStatus.ConfigFileReceived);
|
||||||
|
|
||||||
|
ArchiveExistingPortalConfigs();
|
||||||
|
|
||||||
|
CheckForLocalConfigAndDelete();
|
||||||
|
|
||||||
|
WriteConfigToFile(newConfig);
|
||||||
|
|
||||||
|
RestartProgram();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Config Update Process Stopped. Failed to get config file from server: {0}", r.Code);
|
||||||
|
OnStatusUpdate(eUpdateStatus.UpdateFailed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Request for config from Server Failed: {0}", e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Error Getting Config from Server: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnStatusUpdate(eUpdateStatus status)
|
||||||
|
{
|
||||||
|
var handler = ConfigStatusChanged;
|
||||||
|
|
||||||
|
if(handler != null)
|
||||||
|
{
|
||||||
|
handler(typeof(ConfigUpdater), new ConfigStatusEventArgs(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteConfigToFile(string configData)
|
||||||
|
{
|
||||||
|
var filePath = Global.FilePathPrefix+ "configurationFile-updated.json";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var config = JObject.Parse(configData).ToObject<EssentialsConfig>();
|
||||||
|
|
||||||
|
ConfigWriter.WriteFile(filePath, configData);
|
||||||
|
|
||||||
|
OnStatusUpdate(eUpdateStatus.WritingConfigFile);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Error parsing new config: {0}", e);
|
||||||
|
|
||||||
|
OnStatusUpdate(eUpdateStatus.UpdateFailed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for any existing portal config files and archives them
|
||||||
|
/// </summary>
|
||||||
|
static void ArchiveExistingPortalConfigs()
|
||||||
|
{
|
||||||
|
var filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||||
|
|
||||||
|
var configFiles = ConfigReader.GetConfigFiles(filePath);
|
||||||
|
|
||||||
|
if (configFiles != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Existing config files found. Moving to Archive folder.");
|
||||||
|
|
||||||
|
OnStatusUpdate(eUpdateStatus.ArchivingConfigs);
|
||||||
|
|
||||||
|
MoveFilesToArchiveFolder(configFiles);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No Existing config files found in '{0}'. Nothing to archive", filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for presence of archive folder and if found deletes contents.
|
||||||
|
/// Moves any config files to the archive folder and adds a .bak suffix
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="files"></param>
|
||||||
|
static void MoveFilesToArchiveFolder(FileInfo[] files)
|
||||||
|
{
|
||||||
|
string archiveDirectoryPath = Global.FilePathPrefix + "archive";
|
||||||
|
|
||||||
|
if (!Directory.Exists(archiveDirectoryPath))
|
||||||
|
{
|
||||||
|
// Directory does not exist, create it
|
||||||
|
Directory.Create(archiveDirectoryPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Directory exists, first clear any contents
|
||||||
|
var archivedConfigFiles = ConfigReader.GetConfigFiles(archiveDirectoryPath + Global.DirectorySeparator + Global.ConfigFileName + ".bak");
|
||||||
|
|
||||||
|
if(archivedConfigFiles != null || archivedConfigFiles.Length > 0)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "{0} Existing files found in archive folder. Deleting.", archivedConfigFiles.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < archivedConfigFiles.Length; i++ )
|
||||||
|
{
|
||||||
|
var file = archivedConfigFiles[i];
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Deleting archived file: '{0}'", file.FullName);
|
||||||
|
file.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move any files from the program folder to the archive folder
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Moving config file '{0}' to archive folder", file.FullName);
|
||||||
|
|
||||||
|
// Moves the file and appends the .bak extension
|
||||||
|
var fileDest = archiveDirectoryPath + "/" + file.Name + ".bak";
|
||||||
|
if(!File.Exists(fileDest))
|
||||||
|
{
|
||||||
|
file.MoveTo(fileDest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Warning, "Cannot move file to archive folder. Existing file already exists with same name: '{0}'", fileDest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for LocalConfig folder in file system and deletes if found
|
||||||
|
/// </summary>
|
||||||
|
static void CheckForLocalConfigAndDelete()
|
||||||
|
{
|
||||||
|
var folderPath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder;
|
||||||
|
|
||||||
|
if (Directory.Exists(folderPath))
|
||||||
|
{
|
||||||
|
OnStatusUpdate(eUpdateStatus.DeletingLocalConfig);
|
||||||
|
Directory.Delete(folderPath);
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Local Config Found in '{0}'. Deleting.", folderPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connects to the processor via SSH and restarts the program
|
||||||
|
/// </summary>
|
||||||
|
static void RestartProgram()
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to Reset Program");
|
||||||
|
|
||||||
|
OnStatusUpdate(eUpdateStatus.RestartingProgram);
|
||||||
|
|
||||||
|
string response = string.Empty;
|
||||||
|
|
||||||
|
CrestronConsole.SendControlSystemCommand(string.Format("progreset -p:{0}", InitialParametersClass.ApplicationNumber), ref response);
|
||||||
|
|
||||||
|
Debug.Console(1, "Console Response: {0}", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum eUpdateStatus
|
||||||
|
{
|
||||||
|
UpdateStarted,
|
||||||
|
ConfigFileReceived,
|
||||||
|
ArchivingConfigs,
|
||||||
|
DeletingLocalConfig,
|
||||||
|
WritingConfigFile,
|
||||||
|
RestartingProgram,
|
||||||
|
UpdateSucceeded,
|
||||||
|
UpdateFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConfigStatusEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public eUpdateStatus UpdateStatus { get; private set; }
|
||||||
|
|
||||||
|
public ConfigStatusEventArgs(eUpdateStatus status)
|
||||||
|
{
|
||||||
|
UpdateStatus = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Responsible for updating config at runtime, and writing the updates out to a local file
|
||||||
|
/// </summary>
|
||||||
|
public class ConfigWriter
|
||||||
|
{
|
||||||
|
public const string LocalConfigFolder = "LocalConfig";
|
||||||
|
|
||||||
|
public const long WriteTimeout = 30000;
|
||||||
|
|
||||||
|
public static CTimer WriteTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the config properties of a device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deviceKey"></param>
|
||||||
|
/// <param name="properties"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
// Get the current device config
|
||||||
|
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
|
||||||
|
|
||||||
|
if (deviceConfig != null)
|
||||||
|
{
|
||||||
|
// Replace the current properties JToken with the new one passed into this method
|
||||||
|
deviceConfig.Properties = properties;
|
||||||
|
|
||||||
|
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetTimer();
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool UpdateDeviceConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
|
||||||
|
|
||||||
|
if (deviceConfig != null)
|
||||||
|
{
|
||||||
|
deviceConfig = config;
|
||||||
|
|
||||||
|
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetTimer();
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool UpdateRoomConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
|
||||||
|
|
||||||
|
if (deviceConfig != null)
|
||||||
|
{
|
||||||
|
deviceConfig = config;
|
||||||
|
|
||||||
|
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetTimer();
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets (or starts) the write timer
|
||||||
|
/// </summary>
|
||||||
|
static void ResetTimer()
|
||||||
|
{
|
||||||
|
if (WriteTimer == null)
|
||||||
|
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
|
||||||
|
|
||||||
|
WriteTimer.Reset(WriteTimeout);
|
||||||
|
|
||||||
|
Debug.Console(1, "Config File write timer has been reset.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes the current config to a file in the LocalConfig subfolder
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static void WriteConfigFile(object o)
|
||||||
|
{
|
||||||
|
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
|
||||||
|
|
||||||
|
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
|
||||||
|
|
||||||
|
WriteFile(filePath, configData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filepath"></param>
|
||||||
|
/// <param name="o"></param>
|
||||||
|
public static void WriteFile(string filePath, string configData)
|
||||||
|
{
|
||||||
|
if (WriteTimer != null)
|
||||||
|
WriteTimer.Stop();
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
|
||||||
|
|
||||||
|
var fileLock = new CCriticalSection();
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (fileLock.TryEnter())
|
||||||
|
{
|
||||||
|
using (StreamWriter sw = new StreamWriter(filePath))
|
||||||
|
{
|
||||||
|
sw.Write(configData);
|
||||||
|
sw.Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (fileLock != null && !fileLock.Disposed)
|
||||||
|
fileLock.Leave();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the ConfigObject from the file
|
||||||
|
/// </summary>
|
||||||
|
public class EssentialsConfig : BasicConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("system_url")]
|
||||||
|
public string SystemUrl { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("template_url")]
|
||||||
|
public string TemplateUrl { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
//public CotijaConfig Cotija { get; private set; }
|
||||||
|
|
||||||
|
[JsonProperty("systemUuid")]
|
||||||
|
public string SystemUuid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SystemUrl))
|
||||||
|
return "missing url";
|
||||||
|
|
||||||
|
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/(.*)\/#.*");
|
||||||
|
string uuid = result.Groups[1].Value;
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("templateUuid")]
|
||||||
|
public string TemplateUuid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(TemplateUrl))
|
||||||
|
return "missing template url";
|
||||||
|
|
||||||
|
var result = Regex.Match(TemplateUrl, @"https?:\/\/.*\/templates\/(.*)\/#.*");
|
||||||
|
string uuid = result.Groups[1].Value;
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("rooms")]
|
||||||
|
public List<DeviceConfig> Rooms { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class SystemTemplateConfigs
|
||||||
|
{
|
||||||
|
public EssentialsConfig System { get; set; }
|
||||||
|
|
||||||
|
public EssentialsConfig Template { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the info section of a Config file
|
||||||
|
/// </summary>
|
||||||
|
public class InfoConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("date")]
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("version")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("runtimeInfo")]
|
||||||
|
public RuntimeInfo RuntimeInfo { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("comment")]
|
||||||
|
public string Comment { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("hostname")]
|
||||||
|
public string HostName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("appNumber")]
|
||||||
|
public uint AppNumber { get; set; }
|
||||||
|
|
||||||
|
public InfoConfig()
|
||||||
|
{
|
||||||
|
Name = "";
|
||||||
|
Date = DateTime.Now;
|
||||||
|
Type = "";
|
||||||
|
Version = "";
|
||||||
|
Comment = "";
|
||||||
|
HostName = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
|
||||||
|
AppNumber = InitialParametersClass.ApplicationNumber;
|
||||||
|
|
||||||
|
RuntimeInfo = new RuntimeInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents runtime information about the program/processor
|
||||||
|
/// </summary>
|
||||||
|
public class RuntimeInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the running application
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("appName")]
|
||||||
|
public string AppName {get; set;}
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return Assembly.GetExecutingAssembly().GetName().Name;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Assembly version of the running application
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("assemblyVersion")]
|
||||||
|
public string AssemblyVersion {get; set;}
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// var version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
|
// return string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The OS Version of the processor (Firmware Version)
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("osVersion")]
|
||||||
|
public string OsVersion {get; set;}
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return Crestron.SimplSharp.CrestronEnvironment.OSVersion.Firmware;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Config
|
||||||
|
{
|
||||||
|
public class SourceDevicePropertiesConfigBase
|
||||||
|
{
|
||||||
|
public bool DisableSharing { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class CommonBoolCue
|
||||||
|
{
|
||||||
|
public static readonly Cue Power = new Cue("Power", 101, eCueType.Bool);
|
||||||
|
public static readonly Cue PowerOn = new Cue("PowerOn", 102, eCueType.Bool);
|
||||||
|
public static readonly Cue PowerOff = new Cue("PowerOff", 103, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue HasPowerFeedback = new Cue("HasPowerFeedback", 101, eCueType.Bool);
|
||||||
|
public static readonly Cue PowerOnFeedback = new Cue("PowerOnFeedback", 102, eCueType.Bool);
|
||||||
|
public static readonly Cue IsOnlineFeedback = new Cue("IsOnlineFeedback", 104, eCueType.Bool);
|
||||||
|
public static readonly Cue IsWarmingUp = new Cue("IsWarmingUp", 105, eCueType.Bool);
|
||||||
|
public static readonly Cue IsCoolingDown = new Cue("IsCoolingDown", 106, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue Dash = new Cue("Dash", 109, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit0 = new Cue("Digit0", 110, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit1 = new Cue("Digit1", 111, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit2 = new Cue("Digit2", 112, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit3 = new Cue("Digit3", 113, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit4 = new Cue("Digit4", 114, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit5 = new Cue("Digit5", 115, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit6 = new Cue("Digit6", 116, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit7 = new Cue("Digit7", 117, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit8 = new Cue("Digit8", 118, eCueType.Bool);
|
||||||
|
public static readonly Cue Digit9 = new Cue("Digit9", 119, eCueType.Bool);
|
||||||
|
public static readonly Cue KeypadMisc1 = new Cue("KeypadMisc1", 120, eCueType.Bool);
|
||||||
|
public static readonly Cue KeypadMisc2 = new Cue("KeypadMisc2", 121, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue NumericEnter = new Cue("Enter", 122, eCueType.Bool);
|
||||||
|
public static readonly Cue ChannelUp = new Cue("ChannelUp", 123, eCueType.Bool);
|
||||||
|
public static readonly Cue ChannelDown = new Cue("ChannelDown", 124, eCueType.Bool);
|
||||||
|
public static readonly Cue Last = new Cue("Last", 125, eCueType.Bool);
|
||||||
|
public static readonly Cue OpenClose = new Cue("OpenClose", 126, eCueType.Bool);
|
||||||
|
public static readonly Cue Subtitle = new Cue("Subtitle", 127, eCueType.Bool);
|
||||||
|
public static readonly Cue Audio = new Cue("Audio", 128, eCueType.Bool);
|
||||||
|
public static readonly Cue Info = new Cue("Info", 129, eCueType.Bool);
|
||||||
|
public static readonly Cue Menu = new Cue("Menu", 130, eCueType.Bool);
|
||||||
|
public static readonly Cue DeviceMenu = new Cue("DeviceMenu", 131, eCueType.Bool);
|
||||||
|
public static readonly Cue Return = new Cue("Return", 132, eCueType.Bool);
|
||||||
|
public static readonly Cue Back = new Cue("Back", 133, eCueType.Bool);
|
||||||
|
public static readonly Cue Exit = new Cue("Exit", 134, eCueType.Bool);
|
||||||
|
public static readonly Cue Clear = new Cue("Clear", 135, eCueType.Bool);
|
||||||
|
public static readonly Cue List = new Cue("List", 136, eCueType.Bool);
|
||||||
|
public static readonly Cue Guide = new Cue("Guide", 137, eCueType.Bool);
|
||||||
|
public static readonly Cue Am = new Cue("Am", 136, eCueType.Bool);
|
||||||
|
public static readonly Cue Fm = new Cue("Fm", 137, eCueType.Bool);
|
||||||
|
public static readonly Cue Up = new Cue("Up", 138, eCueType.Bool);
|
||||||
|
public static readonly Cue Down = new Cue("Down", 139, eCueType.Bool);
|
||||||
|
public static readonly Cue Left = new Cue("Left", 140, eCueType.Bool);
|
||||||
|
public static readonly Cue Right = new Cue("Right", 141, eCueType.Bool);
|
||||||
|
public static readonly Cue Select = new Cue("Select", 142, eCueType.Bool);
|
||||||
|
public static readonly Cue SmartApps = new Cue("SmartApps", 143, eCueType.Bool);
|
||||||
|
public static readonly Cue Dvr = new Cue("Dvr", 144, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue Play = new Cue("Play", 145, eCueType.Bool);
|
||||||
|
public static readonly Cue Pause = new Cue("Pause", 146, eCueType.Bool);
|
||||||
|
public static readonly Cue Stop = new Cue("Stop", 147, eCueType.Bool);
|
||||||
|
public static readonly Cue ChapNext = new Cue("ChapNext", 148, eCueType.Bool);
|
||||||
|
public static readonly Cue ChapPrevious = new Cue("ChapPrevious", 149, eCueType.Bool);
|
||||||
|
public static readonly Cue Rewind = new Cue("Rewind", 150, eCueType.Bool);
|
||||||
|
public static readonly Cue Ffwd = new Cue("Ffwd", 151, eCueType.Bool);
|
||||||
|
public static readonly Cue Replay = new Cue("Replay", 152, eCueType.Bool);
|
||||||
|
public static readonly Cue Advance = new Cue("Advance", 153, eCueType.Bool);
|
||||||
|
public static readonly Cue Record = new Cue("Record", 154, eCueType.Bool);
|
||||||
|
public static readonly Cue Red = new Cue("Red", 155, eCueType.Bool);
|
||||||
|
public static readonly Cue Green = new Cue("Green", 156, eCueType.Bool);
|
||||||
|
public static readonly Cue Yellow = new Cue("Yellow", 157, eCueType.Bool);
|
||||||
|
public static readonly Cue Blue = new Cue("Blue", 158, eCueType.Bool);
|
||||||
|
public static readonly Cue Home = new Cue("Home", 159, eCueType.Bool);
|
||||||
|
public static readonly Cue PopUp = new Cue("PopUp", 160, eCueType.Bool);
|
||||||
|
public static readonly Cue PageUp = new Cue("PageUp", 161, eCueType.Bool);
|
||||||
|
public static readonly Cue PageDown = new Cue("PageDown", 162, eCueType.Bool);
|
||||||
|
public static readonly Cue Search = new Cue("Search", 163, eCueType.Bool);
|
||||||
|
public static readonly Cue Setup = new Cue("Setup", 164, eCueType.Bool);
|
||||||
|
public static readonly Cue RStep = new Cue("RStep", 165, eCueType.Bool);
|
||||||
|
public static readonly Cue FStep = new Cue("FStep", 166, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue IsConnected = new Cue("IsConnected", 281, eCueType.Bool);
|
||||||
|
public static readonly Cue IsOk = new Cue("IsOk", 282, eCueType.Bool);
|
||||||
|
public static readonly Cue InWarning = new Cue("InWarning", 283, eCueType.Bool);
|
||||||
|
public static readonly Cue InError = new Cue("InError", 284, eCueType.Bool);
|
||||||
|
public static readonly Cue StatusUnknown = new Cue("StatusUnknown", 285, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue VolumeUp = new Cue("VolumeUp", 401, eCueType.Bool);
|
||||||
|
public static readonly Cue VolumeDown = new Cue("VolumeDown", 402, eCueType.Bool);
|
||||||
|
public static readonly Cue MuteOn = new Cue("MuteOn", 403, eCueType.Bool);
|
||||||
|
public static readonly Cue MuteOff = new Cue("MuteOff", 404, eCueType.Bool);
|
||||||
|
public static readonly Cue MuteToggle = new Cue("MuteToggle", 405, eCueType.Bool);
|
||||||
|
public static readonly Cue ShowVolumeButtons = new Cue("ShowVolumeButtons", 406, eCueType.Bool);
|
||||||
|
public static readonly Cue ShowVolumeSlider = new Cue("ShowVolumeSlider", 407, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue Hdmi1 = new Cue("Hdmi1", 451, eCueType.Bool);
|
||||||
|
public static readonly Cue Hdmi2 = new Cue("Hdmi2", 452, eCueType.Bool);
|
||||||
|
public static readonly Cue Hdmi3 = new Cue("Hdmi3", 453, eCueType.Bool);
|
||||||
|
public static readonly Cue Hdmi4 = new Cue("Hdmi4", 454, eCueType.Bool);
|
||||||
|
public static readonly Cue Hdmi5 = new Cue("Hdmi5", 455, eCueType.Bool);
|
||||||
|
public static readonly Cue Hdmi6 = new Cue("Hdmi6", 456, eCueType.Bool);
|
||||||
|
public static readonly Cue DisplayPort1 = new Cue("DisplayPort1", 457, eCueType.Bool);
|
||||||
|
public static readonly Cue DisplayPort2 = new Cue("DisplayPort2", 458, eCueType.Bool);
|
||||||
|
public static readonly Cue Dvi1 = new Cue("Dvi1", 459, eCueType.Bool);
|
||||||
|
public static readonly Cue Dvi2 = new Cue("Dvi2", 460, eCueType.Bool);
|
||||||
|
public static readonly Cue Video1 = new Cue("Video1", 461, eCueType.Bool);
|
||||||
|
public static readonly Cue Video2 = new Cue("Video2", 462, eCueType.Bool);
|
||||||
|
public static readonly Cue Component1 = new Cue("Component1", 463, eCueType.Bool);
|
||||||
|
public static readonly Cue Component2 = new Cue("Component2", 464, eCueType.Bool);
|
||||||
|
public static readonly Cue Vga1 = new Cue("Vga1", 465, eCueType.Bool);
|
||||||
|
public static readonly Cue Vga2 = new Cue("Vga2", 466, eCueType.Bool);
|
||||||
|
public static readonly Cue Rgb1 = new Cue("Rgb1", 467, eCueType.Bool);
|
||||||
|
public static readonly Cue Rgb2 = new Cue("Rgb2", 468, eCueType.Bool);
|
||||||
|
public static readonly Cue Antenna = new Cue("Antenna", 469, eCueType.Bool);
|
||||||
|
|
||||||
|
public static readonly Cue InCall = new Cue("InCall", 501, eCueType.Bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CommonIntCue
|
||||||
|
{
|
||||||
|
public static readonly Cue MainVolumeLevel = new Cue("MainVolumeLevel", 401, eCueType.Int);
|
||||||
|
public static readonly Cue MainVolumeLevelFeedback = new Cue("MainVolumeLevelFeedback", 401, eCueType.Int);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CommonStringCue
|
||||||
|
{
|
||||||
|
public static readonly Cue IpConnectionsText = new Cue("IpConnectionsText", 9999, eCueType.String);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
public class IOPortConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("portDeviceKey")]
|
||||||
|
public string PortDeviceKey { get; set; }
|
||||||
|
[JsonProperty("portNumber")]
|
||||||
|
public uint PortNumber { get; set; }
|
||||||
|
[JsonProperty("disablePullUpResistor")]
|
||||||
|
public bool DisablePullUpResistor { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
public class GenericDigitalInputDevice : Device, IDigitalInput
|
||||||
|
{
|
||||||
|
public DigitalInput InputPort { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback InputStateFeedback { get; private set; }
|
||||||
|
|
||||||
|
Func<bool> InputStateFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () => InputPort.State;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericDigitalInputDevice(string key, DigitalInput inputPort):
|
||||||
|
base(key)
|
||||||
|
{
|
||||||
|
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||||
|
|
||||||
|
InputPort = inputPort;
|
||||||
|
|
||||||
|
InputPort.StateChange += new DigitalInputEventHandler(InputPort_StateChange);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||||
|
{
|
||||||
|
InputStateFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a generic digital input deviced tied to a versiport
|
||||||
|
/// </summary>
|
||||||
|
public class GenericVersiportDigitalInputDevice : Device, IDigitalInput
|
||||||
|
{
|
||||||
|
public Versiport InputPort { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback InputStateFeedback { get; private set; }
|
||||||
|
|
||||||
|
Func<bool> InputStateFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () => InputPort.DigitalIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericVersiportDigitalInputDevice(string key, Versiport inputPort, IOPortConfig props):
|
||||||
|
base(key)
|
||||||
|
{
|
||||||
|
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||||
|
InputPort = inputPort;
|
||||||
|
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||||
|
if (props.DisablePullUpResistor)
|
||||||
|
InputPort.DisablePullUpResistor = true;
|
||||||
|
InputPort.VersiportChange += new VersiportEventHandler(InputPort_VersiportChange);
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", props.PortNumber, InputPort.DisablePullUpResistor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Versiport change: {0}", args.Event);
|
||||||
|
|
||||||
|
if(args.Event == eVersiportEvent.DigitalInChange)
|
||||||
|
InputStateFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a device that provides digital input
|
||||||
|
/// </summary>
|
||||||
|
public interface IDigitalInput
|
||||||
|
{
|
||||||
|
BoolFeedback InputStateFeedback { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a generic device controlled by relays
|
||||||
|
/// </summary>
|
||||||
|
public class GenericRelayDevice : Device, ISwitchedOutput
|
||||||
|
{
|
||||||
|
public Relay RelayOutput { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback OutputIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
public GenericRelayDevice(string key, Relay relay):
|
||||||
|
base(key)
|
||||||
|
{
|
||||||
|
OutputIsOnFeedback = new BoolFeedback(new Func<bool>(() => RelayOutput.State));
|
||||||
|
|
||||||
|
RelayOutput = relay;
|
||||||
|
RelayOutput.Register();
|
||||||
|
|
||||||
|
RelayOutput.StateChange += new RelayEventHandler(RelayOutput_StateChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
|
||||||
|
{
|
||||||
|
OutputIsOnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenRelay()
|
||||||
|
{
|
||||||
|
RelayOutput.State = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseRelay()
|
||||||
|
{
|
||||||
|
RelayOutput.State = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleRelayState()
|
||||||
|
{
|
||||||
|
if (RelayOutput.State == true)
|
||||||
|
OpenRelay();
|
||||||
|
else
|
||||||
|
CloseRelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ISwitchedOutput Members
|
||||||
|
|
||||||
|
void ISwitchedOutput.On()
|
||||||
|
{
|
||||||
|
CloseRelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISwitchedOutput.Off()
|
||||||
|
{
|
||||||
|
OpenRelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes an output capable of switching on and off
|
||||||
|
/// </summary>
|
||||||
|
public interface ISwitchedOutput
|
||||||
|
{
|
||||||
|
BoolFeedback OutputIsOnFeedback {get;}
|
||||||
|
|
||||||
|
void On();
|
||||||
|
void Off();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISwitchedOutputCollection
|
||||||
|
{
|
||||||
|
Dictionary<uint, ISwitchedOutput> SwitchedOutputs { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A bridge class to cover the basic features of GenericBase hardware
|
||||||
|
/// </summary>
|
||||||
|
public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
|
||||||
|
{
|
||||||
|
public virtual GenericBase Hardware { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list containing the Outputs that we want to expose.
|
||||||
|
/// </summary>
|
||||||
|
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback IsOnline { get; private set; }
|
||||||
|
public BoolFeedback IsRegistered { get; private set; }
|
||||||
|
public StringFeedback IpConnectionsText { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by implementing classes to prevent registration with Crestron TLDM. For
|
||||||
|
/// devices like RMCs and TXs attached to a chassis.
|
||||||
|
/// </summary>
|
||||||
|
public bool PreventRegistration { get; protected set; }
|
||||||
|
|
||||||
|
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Feedbacks = new FeedbackCollection<Feedback>();
|
||||||
|
|
||||||
|
Hardware = hardware;
|
||||||
|
IsOnline = new BoolFeedback("IsOnlineFeedback", () => Hardware.IsOnline);
|
||||||
|
IsRegistered = new BoolFeedback("IsRegistered", () => Hardware.Registered);
|
||||||
|
IpConnectionsText = new StringFeedback("IpConnectionsText", () =>
|
||||||
|
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
|
||||||
|
|
||||||
|
AddToFeedbackList(IsOnline, IsRegistered, IpConnectionsText);
|
||||||
|
|
||||||
|
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make sure that overriding classes call this!
|
||||||
|
/// Registers the Crestron device, connects up to the base events, starts communication monitor
|
||||||
|
/// </summary>
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Activating");
|
||||||
|
if (!PreventRegistration)
|
||||||
|
{
|
||||||
|
//Debug.Console(1, this, " Does not require registration. Skipping");
|
||||||
|
|
||||||
|
var response = Hardware.RegisterWithLogging(Key);
|
||||||
|
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
|
||||||
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This disconnects events and unregisters the base hardware device.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
CommunicationMonitor.Stop();
|
||||||
|
Hardware.OnlineStatusChange -= Hardware_OnlineStatusChange;
|
||||||
|
|
||||||
|
return Hardware.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds feedback(s) to the list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newFbs"></param>
|
||||||
|
public void AddToFeedbackList(params Feedback[] newFbs)
|
||||||
|
{
|
||||||
|
foreach (var f in newFbs)
|
||||||
|
{
|
||||||
|
if (f != null)
|
||||||
|
{
|
||||||
|
if (!Feedbacks.Contains(f))
|
||||||
|
{
|
||||||
|
Feedbacks.Add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.DeviceOnLine)
|
||||||
|
{
|
||||||
|
foreach (var feedback in Feedbacks)
|
||||||
|
{
|
||||||
|
if (feedback != null)
|
||||||
|
feedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IStatusMonitor Members
|
||||||
|
|
||||||
|
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IUsageTracking Members
|
||||||
|
|
||||||
|
public UsageTracking UsageTracker { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************************************************************
|
||||||
|
public class CrestronGenericBaseDeviceEventIds
|
||||||
|
{
|
||||||
|
public const uint IsOnline = 1;
|
||||||
|
public const uint IpConnectionsText =2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds logging to Register() failure
|
||||||
|
/// </summary>
|
||||||
|
public static class GenericBaseExtensions
|
||||||
|
{
|
||||||
|
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
|
||||||
|
{
|
||||||
|
var result = device.Register();
|
||||||
|
var level = result == eDeviceRegistrationUnRegistrationResponse.Success ?
|
||||||
|
Debug.ErrorLogLevel.Notice : Debug.ErrorLogLevel.Error;
|
||||||
|
Debug.Console(0, level, "Register device result: '{0}', type '{1}', result {2}", key, device, result);
|
||||||
|
//if (result != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
//{
|
||||||
|
// Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
|
||||||
|
//}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A bridge class to cover the basic features of GenericBase hardware
|
||||||
|
/// </summary>
|
||||||
|
public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
|
||||||
|
{
|
||||||
|
public virtual GenericBase Hardware { get; protected set; }
|
||||||
|
|
||||||
|
public BoolFeedback IsOnline { get; private set; }
|
||||||
|
public BoolFeedback IsRegistered { get; private set; }
|
||||||
|
public StringFeedback IpConnectionsText { get; private set; }
|
||||||
|
|
||||||
|
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Hardware = hardware;
|
||||||
|
IsOnline = new BoolFeedback(CommonBoolCue.IsOnlineFeedback, () => Hardware.IsOnline);
|
||||||
|
IsRegistered = new BoolFeedback(new Cue("IsRegistered", 0, eCueType.Bool), () => Hardware.Registered);
|
||||||
|
IpConnectionsText = new StringFeedback(CommonStringCue.IpConnectionsText, () =>
|
||||||
|
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
|
||||||
|
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make sure that overriding classes call this!
|
||||||
|
/// Registers the Crestron device, connects up to the base events, starts communication monitor
|
||||||
|
/// </summary>
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Activating");
|
||||||
|
var response = Hardware.RegisterWithLogging(Key);
|
||||||
|
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
=======
|
||||||
|
Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
>>>>>>> origin/feature/ecs-342-neil
|
||||||
|
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
|
||||||
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This disconnects events and unregisters the base hardware device.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
CommunicationMonitor.Stop();
|
||||||
|
Hardware.OnlineStatusChange -= Hardware_OnlineStatusChange;
|
||||||
|
|
||||||
|
return Hardware.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list containing the Outputs that we want to expose.
|
||||||
|
/// </summary>
|
||||||
|
public virtual List<Feedback> Feedbacks
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new List<Feedback>
|
||||||
|
{
|
||||||
|
IsOnline,
|
||||||
|
IsRegistered,
|
||||||
|
IpConnectionsText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||||
|
{
|
||||||
|
IsOnline.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IStatusMonitor Members
|
||||||
|
|
||||||
|
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IUsageTracking Members
|
||||||
|
|
||||||
|
public UsageTracking UsageTracker { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************************************************************
|
||||||
|
public class CrestronGenericBaseDeviceEventIds
|
||||||
|
{
|
||||||
|
public const uint IsOnline = 1;
|
||||||
|
public const uint IpConnectionsText =2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds logging to Register() failure
|
||||||
|
/// </summary>
|
||||||
|
public static class GenericBaseExtensions
|
||||||
|
{
|
||||||
|
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
|
||||||
|
{
|
||||||
|
var result = device.Register();
|
||||||
|
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Encapsulates a string-named, joined and typed command to a device
|
||||||
|
/// </summary>
|
||||||
|
[Obsolete()]
|
||||||
|
public class DevAction
|
||||||
|
{
|
||||||
|
public Cue Cue { get; private set; }
|
||||||
|
public Action<object> Action { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
public DevAction(Cue cue, Action<object> action)
|
||||||
|
{
|
||||||
|
Cue = cue;
|
||||||
|
Action = action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum eCueType
|
||||||
|
{
|
||||||
|
Bool, Int, String, Serial, Void, Other
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Cue class is a container to represent a name / join number / type for simplifying
|
||||||
|
/// commands coming into devices.
|
||||||
|
/// </summary>
|
||||||
|
public class Cue
|
||||||
|
{
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public uint Number { get; private set; }
|
||||||
|
public eCueType Type { get; private set; }
|
||||||
|
|
||||||
|
public Cue(string name, uint join, eCueType type)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Number = join;
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override that prints out the cue's data
|
||||||
|
/// </summary>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("{0} Cue '{1}'-{2}", Type, Name, Number);
|
||||||
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Returns a new Cue with JoinNumber offset
|
||||||
|
///// </summary>
|
||||||
|
//public Cue GetOffsetCopy(uint offset)
|
||||||
|
//{
|
||||||
|
// return new Cue(Name, Number + offset, Type);
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method to create a Cue of Bool type
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Cue</returns>
|
||||||
|
public static Cue BoolCue(string name, uint join)
|
||||||
|
{
|
||||||
|
return new Cue(name, join, eCueType.Bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method to create a Cue of ushort type
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Cue</returns>
|
||||||
|
public static Cue UShortCue(string name, uint join)
|
||||||
|
{
|
||||||
|
return new Cue(name, join, eCueType.Int);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method to create a Cue of string type
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Cue</returns>
|
||||||
|
public static Cue StringCue(string name, uint join)
|
||||||
|
{
|
||||||
|
return new Cue(name, join, eCueType.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Cue DefaultBoolCue = new Cue("-none-", 0, eCueType.Bool);
|
||||||
|
public static readonly Cue DefaultIntCue = new Cue("-none-", 0, eCueType.Int);
|
||||||
|
public static readonly Cue DefaultStringCue = new Cue("-none-", 0, eCueType.String);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//using System;
|
||||||
|
//using System.Collections.Generic;
|
||||||
|
//using Crestron.SimplSharpPro;
|
||||||
|
//using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
//using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
//namespace PepperDash.Essentials.Core
|
||||||
|
//{
|
||||||
|
// public interface IPresentationSource : IKeyed
|
||||||
|
// {
|
||||||
|
// string Name { get; }
|
||||||
|
// PresentationSourceType Type { get; }
|
||||||
|
// string IconName { get; set; }
|
||||||
|
// BoolFeedback HasPowerOnFeedback { get; }
|
||||||
|
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IChannel
|
||||||
|
{
|
||||||
|
void ChannelUp(bool pressRelease);
|
||||||
|
void ChannelDown(bool pressRelease);
|
||||||
|
void LastChannel(bool pressRelease);
|
||||||
|
void Guide(bool pressRelease);
|
||||||
|
void Info(bool pressRelease);
|
||||||
|
void Exit(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class IChannelExtensions
|
||||||
|
{
|
||||||
|
public static void LinkButtons(this IChannel dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.SetBoolSigAction(123, dev.ChannelUp);
|
||||||
|
triList.SetBoolSigAction(124, dev.ChannelDown);
|
||||||
|
triList.SetBoolSigAction(125, dev.LastChannel);
|
||||||
|
triList.SetBoolSigAction(137, dev.Guide);
|
||||||
|
triList.SetBoolSigAction(129, dev.Info);
|
||||||
|
triList.SetBoolSigAction(134, dev.Exit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this IChannel dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(123);
|
||||||
|
triList.ClearBoolSigAction(124);
|
||||||
|
triList.ClearBoolSigAction(125);
|
||||||
|
triList.ClearBoolSigAction(137);
|
||||||
|
triList.ClearBoolSigAction(129);
|
||||||
|
triList.ClearBoolSigAction(134);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IColor
|
||||||
|
{
|
||||||
|
void Red(bool pressRelease);
|
||||||
|
void Green(bool pressRelease);
|
||||||
|
void Yellow(bool pressRelease);
|
||||||
|
void Blue(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class IColorExtensions
|
||||||
|
{
|
||||||
|
public static void LinkButtons(this IColor dev, BasicTriList TriList)
|
||||||
|
{
|
||||||
|
TriList.SetBoolSigAction(155, dev.Red);
|
||||||
|
TriList.SetBoolSigAction(156, dev.Green);
|
||||||
|
TriList.SetBoolSigAction(157, dev.Yellow);
|
||||||
|
TriList.SetBoolSigAction(158, dev.Blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this IColor dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(155);
|
||||||
|
triList.ClearBoolSigAction(156);
|
||||||
|
triList.ClearBoolSigAction(157);
|
||||||
|
triList.ClearBoolSigAction(158);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IDPad
|
||||||
|
{
|
||||||
|
void Up(bool pressRelease);
|
||||||
|
void Down(bool pressRelease);
|
||||||
|
void Left(bool pressRelease);
|
||||||
|
void Right(bool pressRelease);
|
||||||
|
void Select(bool pressRelease);
|
||||||
|
void Menu(bool pressRelease);
|
||||||
|
void Exit(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class IDPadExtensions
|
||||||
|
{
|
||||||
|
public static void LinkButtons(this IDPad dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.SetBoolSigAction(138, dev.Up);
|
||||||
|
triList.SetBoolSigAction(139, dev.Down);
|
||||||
|
triList.SetBoolSigAction(140, dev.Left);
|
||||||
|
triList.SetBoolSigAction(141, dev.Right);
|
||||||
|
triList.SetBoolSigAction(142, dev.Select);
|
||||||
|
triList.SetBoolSigAction(130, dev.Menu);
|
||||||
|
triList.SetBoolSigAction(134, dev.Exit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this IDPad dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(138);
|
||||||
|
triList.ClearBoolSigAction(139);
|
||||||
|
triList.ClearBoolSigAction(140);
|
||||||
|
triList.ClearBoolSigAction(141);
|
||||||
|
triList.ClearBoolSigAction(142);
|
||||||
|
triList.ClearBoolSigAction(130);
|
||||||
|
triList.ClearBoolSigAction(134);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
|
||||||
|
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IPower, ITransport, IUiDisplayInfo
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Devices.DeviceTypeInterfaces
|
||||||
|
{
|
||||||
|
public interface IDisplayBasic
|
||||||
|
{
|
||||||
|
void InputHdmi1();
|
||||||
|
void InputHdmi2();
|
||||||
|
void InputHdmi3();
|
||||||
|
void InputHdmi4();
|
||||||
|
void InputDisplayPort1();
|
||||||
|
void InputDvi1();
|
||||||
|
void InputVideo1();
|
||||||
|
void InputVga1();
|
||||||
|
void InputVga2();
|
||||||
|
void InputRgb1();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IDumbSource
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IDvr : IDPad
|
||||||
|
{
|
||||||
|
void DvrList(bool pressRelease);
|
||||||
|
void Record(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class IDvrExtensions
|
||||||
|
{
|
||||||
|
public static void LinkButtons(this IDvr dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.SetBoolSigAction(136, dev.DvrList);
|
||||||
|
triList.SetBoolSigAction(152, dev.Record);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this IDvr dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(136);
|
||||||
|
triList.ClearBoolSigAction(152);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface INumericKeypad
|
||||||
|
{
|
||||||
|
void Digit0(bool pressRelease);
|
||||||
|
void Digit1(bool pressRelease);
|
||||||
|
void Digit2(bool pressRelease);
|
||||||
|
void Digit3(bool pressRelease);
|
||||||
|
void Digit4(bool pressRelease);
|
||||||
|
void Digit5(bool pressRelease);
|
||||||
|
void Digit6(bool pressRelease);
|
||||||
|
void Digit7(bool pressRelease);
|
||||||
|
void Digit8(bool pressRelease);
|
||||||
|
void Digit9(bool pressRelease);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to hide/show the button and/or text on the left-hand keypad button
|
||||||
|
/// </summary>
|
||||||
|
bool HasKeypadAccessoryButton1 { get; }
|
||||||
|
string KeypadAccessoryButton1Label { get; }
|
||||||
|
void KeypadAccessoryButton1(bool pressRelease);
|
||||||
|
|
||||||
|
bool HasKeypadAccessoryButton2 { get; }
|
||||||
|
string KeypadAccessoryButton2Label { get; }
|
||||||
|
void KeypadAccessoryButton2(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISetTopBoxNumericKeypad : INumericKeypad
|
||||||
|
{
|
||||||
|
void Dash(bool pressRelease);
|
||||||
|
void KeypadEnter(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class INumericExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Links to the smart object, and sets the misc button's labels on joins x and y
|
||||||
|
/// </summary>
|
||||||
|
public static void LinkButtons(this INumericKeypad dev, BasicTriList trilist)
|
||||||
|
{
|
||||||
|
trilist.SetBoolSigAction(110, dev.Digit0);
|
||||||
|
trilist.SetBoolSigAction(111, dev.Digit1);
|
||||||
|
trilist.SetBoolSigAction(112, dev.Digit2);
|
||||||
|
trilist.SetBoolSigAction(113, dev.Digit3);
|
||||||
|
trilist.SetBoolSigAction(114, dev.Digit4);
|
||||||
|
trilist.SetBoolSigAction(115, dev.Digit5);
|
||||||
|
trilist.SetBoolSigAction(116, dev.Digit6);
|
||||||
|
trilist.SetBoolSigAction(117, dev.Digit7);
|
||||||
|
trilist.SetBoolSigAction(118, dev.Digit8);
|
||||||
|
trilist.SetBoolSigAction(119, dev.Digit9);
|
||||||
|
trilist.SetBoolSigAction(120, dev.KeypadAccessoryButton1);
|
||||||
|
trilist.SetBoolSigAction(121, dev.KeypadAccessoryButton2);
|
||||||
|
trilist.StringInput[111].StringValue = dev.KeypadAccessoryButton1Label;
|
||||||
|
trilist.StringInput[111].StringValue = dev.KeypadAccessoryButton2Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this INumericKeypad dev, BasicTriList trilist)
|
||||||
|
{
|
||||||
|
trilist.ClearBoolSigAction(110);
|
||||||
|
trilist.ClearBoolSigAction(111);
|
||||||
|
trilist.ClearBoolSigAction(112);
|
||||||
|
trilist.ClearBoolSigAction(113);
|
||||||
|
trilist.ClearBoolSigAction(114);
|
||||||
|
trilist.ClearBoolSigAction(115);
|
||||||
|
trilist.ClearBoolSigAction(116);
|
||||||
|
trilist.ClearBoolSigAction(117);
|
||||||
|
trilist.ClearBoolSigAction(118);
|
||||||
|
trilist.ClearBoolSigAction(119);
|
||||||
|
trilist.ClearBoolSigAction(120);
|
||||||
|
trilist.ClearBoolSigAction(121);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.Fusion;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IPower
|
||||||
|
{
|
||||||
|
void PowerOn();
|
||||||
|
void PowerOff();
|
||||||
|
void PowerToggle();
|
||||||
|
BoolFeedback PowerIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class IPowerExtensions
|
||||||
|
{
|
||||||
|
public static void LinkButtons(this IPower dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.SetSigFalseAction(101, dev.PowerOn);
|
||||||
|
triList.SetSigFalseAction(102, dev.PowerOff);
|
||||||
|
triList.SetSigFalseAction(103, dev.PowerToggle);
|
||||||
|
dev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this IPower dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(101);
|
||||||
|
triList.ClearBoolSigAction(102);
|
||||||
|
triList.ClearBoolSigAction(103);
|
||||||
|
dev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface ISetTopBoxControls : IChannel, IColor, IDPad, ISetTopBoxNumericKeypad,
|
||||||
|
ITransport, IUiDisplayInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Show DVR controls?
|
||||||
|
/// </summary>
|
||||||
|
bool HasDvr { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show presets controls?
|
||||||
|
/// </summary>
|
||||||
|
bool HasPresets { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show number pad controls?
|
||||||
|
/// </summary>
|
||||||
|
bool HasNumeric { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show D-pad controls?
|
||||||
|
/// </summary>
|
||||||
|
bool HasDpad { get; }
|
||||||
|
|
||||||
|
PepperDash.Essentials.Core.Presets.DevicePresetsModel PresetsModel { get; }
|
||||||
|
void LoadPresets(string filePath);
|
||||||
|
|
||||||
|
void DvrList(bool pressRelease);
|
||||||
|
void Replay(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ISetTopBoxControlsExtensions
|
||||||
|
{
|
||||||
|
public static void LinkButtons(this ISetTopBoxControls dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.SetBoolSigAction(136, dev.DvrList);
|
||||||
|
triList.SetBoolSigAction(152, dev.Replay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this ISetTopBoxControls dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(136);
|
||||||
|
triList.ClearBoolSigAction(152);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface ITransport
|
||||||
|
{
|
||||||
|
void Play(bool pressRelease);
|
||||||
|
void Pause(bool pressRelease);
|
||||||
|
void Rewind(bool pressRelease);
|
||||||
|
void FFwd(bool pressRelease);
|
||||||
|
void ChapMinus(bool pressRelease);
|
||||||
|
void ChapPlus(bool pressRelease);
|
||||||
|
void Stop(bool pressRelease);
|
||||||
|
void Record(bool pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class ITransportExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attaches to trilist joins: Play:145, Pause:146, Stop:147, ChapPlus:148, ChapMinus:149, Rewind:150, Ffwd:151, Record:154
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static void LinkButtons(this ITransport dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.SetBoolSigAction(145, dev.Play);
|
||||||
|
triList.SetBoolSigAction(146, dev.Pause);
|
||||||
|
triList.SetBoolSigAction(147, dev.Stop);
|
||||||
|
triList.SetBoolSigAction(148, dev.ChapPlus);
|
||||||
|
triList.SetBoolSigAction(149, dev.ChapMinus);
|
||||||
|
triList.SetBoolSigAction(150, dev.Rewind);
|
||||||
|
triList.SetBoolSigAction(151, dev.FFwd);
|
||||||
|
triList.SetBoolSigAction(154, dev.Record);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnlinkButtons(this ITransport dev, BasicTriList triList)
|
||||||
|
{
|
||||||
|
triList.ClearBoolSigAction(145);
|
||||||
|
triList.ClearBoolSigAction(146);
|
||||||
|
triList.ClearBoolSigAction(147);
|
||||||
|
triList.ClearBoolSigAction(148);
|
||||||
|
triList.ClearBoolSigAction(149);
|
||||||
|
triList.ClearBoolSigAction(150);
|
||||||
|
triList.ClearBoolSigAction(151);
|
||||||
|
triList.ClearBoolSigAction(154);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes things needed to show on UI
|
||||||
|
/// </summary>
|
||||||
|
public interface IUiDisplayInfo : IKeyed
|
||||||
|
{
|
||||||
|
uint DisplayUiType { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a class that has warm up and cool down
|
||||||
|
/// </summary>
|
||||||
|
public interface IWarmingCooling
|
||||||
|
{
|
||||||
|
BoolFeedback IsWarmingUpFeedback { get; }
|
||||||
|
BoolFeedback IsCoolingDownFeedback { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.SmartObjects;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds control of codec receive volume
|
||||||
|
/// </summary>
|
||||||
|
public interface IReceiveVolume
|
||||||
|
{
|
||||||
|
// Break this out into 3 interfaces
|
||||||
|
void SetReceiveVolume(ushort level);
|
||||||
|
void ReceiveMuteOn();
|
||||||
|
void ReceiveMuteOff();
|
||||||
|
void ReceiveMuteToggle();
|
||||||
|
IntFeedback ReceiveLevelFeedback { get; }
|
||||||
|
BoolFeedback ReceiveMuteIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds control of codec transmit volume
|
||||||
|
/// </summary>
|
||||||
|
public interface ITransmitVolume
|
||||||
|
{
|
||||||
|
void SetTransmitVolume(ushort level);
|
||||||
|
void TransmitMuteOn();
|
||||||
|
void TransmitMuteOff();
|
||||||
|
void TransmitMuteToggle();
|
||||||
|
IntFeedback TransmitLevelFeedback { get; }
|
||||||
|
BoolFeedback TransmitMuteIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds control of codec privacy function (microphone mute)
|
||||||
|
/// </summary>
|
||||||
|
public interface IPrivacy
|
||||||
|
{
|
||||||
|
void PrivacyModeOn();
|
||||||
|
void PrivacyModeOff();
|
||||||
|
void PrivacyModeToggle();
|
||||||
|
BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Requirements for a device that has dialing capabilities
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasDialer
|
||||||
|
{
|
||||||
|
// Add requirements for Dialer functionality
|
||||||
|
|
||||||
|
void Dial(string number);
|
||||||
|
<<<<<<< HEAD
|
||||||
|
void EndCall(string number);
|
||||||
|
=======
|
||||||
|
void EndCall(object activeCall);
|
||||||
|
void EndAllCalls();
|
||||||
|
>>>>>>> origin/feature/cisco-spark-2
|
||||||
|
void AcceptCall();
|
||||||
|
void RejectCall();
|
||||||
|
void SendDtmf(string digit);
|
||||||
|
|
||||||
|
IntFeedback ActiveCallCountFeedback { get; }
|
||||||
|
BoolFeedback IncomingCallFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines minimum volume controls for a codec device with dialing capabilities
|
||||||
|
/// </summary>
|
||||||
|
public interface ICodecAudio : IBasicVolumeWithFeedback, IPrivacy
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds control of codec receive volume
|
||||||
|
/// </summary>
|
||||||
|
public interface IReceiveVolume
|
||||||
|
{
|
||||||
|
// Break this out into 3 interfaces
|
||||||
|
void SetReceiveVolume(ushort level);
|
||||||
|
void ReceiveMuteOn();
|
||||||
|
void ReceiveMuteOff();
|
||||||
|
void ReceiveMuteToggle();
|
||||||
|
IntFeedback ReceiveLevelFeedback { get; }
|
||||||
|
BoolFeedback ReceiveMuteIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds control of codec transmit volume
|
||||||
|
/// </summary>
|
||||||
|
public interface ITransmitVolume
|
||||||
|
{
|
||||||
|
void SetTransmitVolume(ushort level);
|
||||||
|
void TransmitMuteOn();
|
||||||
|
void TransmitMuteOff();
|
||||||
|
void TransmitMuteToggle();
|
||||||
|
IntFeedback TransmitLevelFeedback { get; }
|
||||||
|
BoolFeedback TransmitMuteIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds control of codec privacy function (microphone mute)
|
||||||
|
/// </summary>
|
||||||
|
public interface IPrivacy
|
||||||
|
{
|
||||||
|
void PrivacyModeOn();
|
||||||
|
void PrivacyModeOff();
|
||||||
|
void PrivacyModeToggle();
|
||||||
|
BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IHasCallHistory
|
||||||
|
{
|
||||||
|
// Add recent calls list
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IHasDirectory
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IHasObtp
|
||||||
|
{
|
||||||
|
|
||||||
|
// Upcoming Meeting warning event
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Devices
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This wrapper class is meant to allow interfaces to be applied to any Crestron processor
|
||||||
|
/// </summary>
|
||||||
|
public class CrestronProcessor : Device, ISwitchedOutputCollection
|
||||||
|
{
|
||||||
|
public Dictionary<uint, ISwitchedOutput> SwitchedOutputs { get; private set; }
|
||||||
|
|
||||||
|
public Crestron.SimplSharpPro.CrestronControlSystem Processor { get; private set; }
|
||||||
|
|
||||||
|
public CrestronProcessor(string key)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
SwitchedOutputs = new Dictionary<uint, ISwitchedOutput>();
|
||||||
|
Processor = Global.ControlSystem;
|
||||||
|
|
||||||
|
GetRelays();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a GenericRelayDevice for each relay on the processor and adds them to the SwitchedOutputs collection
|
||||||
|
/// </summary>
|
||||||
|
void GetRelays()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Processor.SupportsRelay)
|
||||||
|
{
|
||||||
|
for (uint i = 1; i <= Processor.NumberOfRelayPorts; i++)
|
||||||
|
{
|
||||||
|
var relay = new GenericRelayDevice(string.Format("{0}-relay-{1}", this.Key, i), Processor.RelayPorts[i]);
|
||||||
|
SwitchedOutputs.Add(i, relay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error Getting Relays from processor:\n '{0}'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Devices
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for all Device APIs
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DeviceApiBase
|
||||||
|
{
|
||||||
|
public Dictionary<string, Object> ActionApi { get; protected set; }
|
||||||
|
public Dictionary<string, Feedback> FeedbackApi { get; protected set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class DeviceJsonApi
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="json"></param>
|
||||||
|
public static void DoDeviceActionWithJson(string json)
|
||||||
|
{
|
||||||
|
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
|
||||||
|
DoDeviceAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
public static void DoDeviceAction(DeviceActionWrapper action)
|
||||||
|
{
|
||||||
|
var key = action.DeviceKey;
|
||||||
|
var obj = FindObjectOnPath(key);
|
||||||
|
if (obj == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CType t = obj.GetType();
|
||||||
|
var method = t.GetMethod(action.MethodName);
|
||||||
|
if (method == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Method '{0}' not found", action.MethodName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var mParams = method.GetParameters();
|
||||||
|
// Add empty params if not provided
|
||||||
|
if (action.Params == null) action.Params = new object[0];
|
||||||
|
if (mParams.Length > action.Params.Length)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
object[] convertedParams = mParams
|
||||||
|
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
|
||||||
|
System.Globalization.CultureInfo.InvariantCulture))
|
||||||
|
.ToArray();
|
||||||
|
object ret = method.Invoke(obj, convertedParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetProperties(string deviceObjectPath)
|
||||||
|
{
|
||||||
|
var obj = FindObjectOnPath(deviceObjectPath);
|
||||||
|
if (obj == null)
|
||||||
|
return "{ \"error\":\"No Device\"}";
|
||||||
|
|
||||||
|
CType t = obj.GetType();
|
||||||
|
// get the properties and set them into a new collection of NameType wrappers
|
||||||
|
var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
|
||||||
|
return JsonConvert.SerializeObject(props, Formatting.Indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetMethods(string deviceObjectPath)
|
||||||
|
{
|
||||||
|
var obj = FindObjectOnPath(deviceObjectPath);
|
||||||
|
if (obj == null)
|
||||||
|
return "{ \"error\":\"No Device\"}";
|
||||||
|
|
||||||
|
// Package up method names using helper objects
|
||||||
|
CType t = obj.GetType();
|
||||||
|
var methods = t.GetMethods()
|
||||||
|
.Where(m => !m.IsSpecialName)
|
||||||
|
.Select(p => new MethodNameParams(p));
|
||||||
|
return JsonConvert.SerializeObject(methods, Formatting.Indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetApiMethods(string deviceObjectPath)
|
||||||
|
{
|
||||||
|
var obj = FindObjectOnPath(deviceObjectPath);
|
||||||
|
if (obj == null)
|
||||||
|
return "{ \"error\":\"No Device\"}";
|
||||||
|
|
||||||
|
// Package up method names using helper objects
|
||||||
|
CType t = obj.GetType();
|
||||||
|
var methods = t.GetMethods()
|
||||||
|
.Where(m => !m.IsSpecialName)
|
||||||
|
.Where(m => m.GetCustomAttributes(typeof(ApiAttribute), true).Any())
|
||||||
|
.Select(p => new MethodNameParams(p));
|
||||||
|
return JsonConvert.SerializeObject(methods, Formatting.Indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Walks down a dotted object path, starting with a Device, and returns the object
|
||||||
|
/// at the end of the path
|
||||||
|
/// </summary>
|
||||||
|
public static object FindObjectOnPath(string deviceObjectPath)
|
||||||
|
{
|
||||||
|
var path = deviceObjectPath.Split('.');
|
||||||
|
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(path[0]);
|
||||||
|
if (dev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device {0} not found", path[0]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through any dotted properties
|
||||||
|
object obj = dev;
|
||||||
|
if (path.Length > 1)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < path.Length; i++)
|
||||||
|
{
|
||||||
|
var objName = path[i];
|
||||||
|
string indexStr = null;
|
||||||
|
var indexOpen = objName.IndexOf('[');
|
||||||
|
if (indexOpen != -1)
|
||||||
|
{
|
||||||
|
var indexClose = objName.IndexOf(']');
|
||||||
|
if (indexClose == -1)
|
||||||
|
{
|
||||||
|
Debug.Console(0, dev, "ERROR Unmatched index brackets");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Get the index and strip quotes if any
|
||||||
|
indexStr = objName.Substring(indexOpen + 1, indexClose - indexOpen - 1).Replace("\"", "");
|
||||||
|
objName = objName.Substring(0, indexOpen);
|
||||||
|
Debug.Console(0, dev, " Checking for collection '{0}', index '{1}'", objName, indexStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
CType oType = obj.GetType();
|
||||||
|
var prop = oType.GetProperty(objName);
|
||||||
|
if (prop == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, dev, "Property {0} not found on {1}", objName, path[i - 1]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// if there's an index, try to get the property
|
||||||
|
if (indexStr != null)
|
||||||
|
{
|
||||||
|
if (!typeof(ICollection).IsAssignableFrom(prop.PropertyType))
|
||||||
|
{
|
||||||
|
Debug.Console(0, dev, "Property {0} is not collection", objName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var collection = prop.GetValue(obj, null) as ICollection;
|
||||||
|
// Get the indexed items "property"
|
||||||
|
var indexedPropInfo = prop.PropertyType.GetProperty("Item");
|
||||||
|
// These are the parameters for the indexing. Only care about one
|
||||||
|
var indexParams = indexedPropInfo.GetIndexParameters();
|
||||||
|
if (indexParams.Length > 0)
|
||||||
|
{
|
||||||
|
Debug.Console(0, " Indexed, param type: {0}", indexParams[0].ParameterType.Name);
|
||||||
|
var properParam = Convert.ChangeType(indexStr, indexParams[0].ParameterType,
|
||||||
|
System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
obj = indexedPropInfo.GetValue(collection, new object[] { properParam });
|
||||||
|
}
|
||||||
|
// if the index is bad, catch it here.
|
||||||
|
catch (Crestron.SimplSharp.Reflection.TargetInvocationException e)
|
||||||
|
{
|
||||||
|
if (e.InnerException is ArgumentOutOfRangeException)
|
||||||
|
Debug.Console(0, " Index Out of range");
|
||||||
|
else if (e.InnerException is KeyNotFoundException)
|
||||||
|
Debug.Console(0, " Key not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
obj = prop.GetValue(obj, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a property on an object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deviceObjectPath"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string SetProperty(string deviceObjectPath)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("This could be really useful. Finish it please");
|
||||||
|
|
||||||
|
//var obj = FindObjectOnPath(deviceObjectPath);
|
||||||
|
//if (obj == null)
|
||||||
|
// return "{\"error\":\"No object found\"}";
|
||||||
|
|
||||||
|
//CType t = obj.GetType();
|
||||||
|
|
||||||
|
|
||||||
|
//// get the properties and set them into a new collection of NameType wrappers
|
||||||
|
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
|
||||||
|
//return JsonConvert.SerializeObject(props, Formatting.Indented);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeviceActionWrapper
|
||||||
|
{
|
||||||
|
public string DeviceKey { get; set; }
|
||||||
|
public string MethodName { get; set; }
|
||||||
|
public object[] Params { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PropertyNameType
|
||||||
|
{
|
||||||
|
object Parent;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public PropertyInfo PropInfo { get; private set; }
|
||||||
|
public string Name { get { return PropInfo.Name; } }
|
||||||
|
public string Type { get { return PropInfo.PropertyType.Name; } }
|
||||||
|
public string Value { get
|
||||||
|
{
|
||||||
|
if (PropInfo.CanRead)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return PropInfo.GetValue(Parent, null).ToString();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
} }
|
||||||
|
|
||||||
|
public bool CanRead { get { return PropInfo.CanRead; } }
|
||||||
|
public bool CanWrite { get { return PropInfo.CanWrite; } }
|
||||||
|
|
||||||
|
|
||||||
|
public PropertyNameType(PropertyInfo info, object parent)
|
||||||
|
{
|
||||||
|
PropInfo = info;
|
||||||
|
Parent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MethodNameParams
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public MethodInfo MethodInfo { get; private set; }
|
||||||
|
|
||||||
|
public string Name { get { return MethodInfo.Name; } }
|
||||||
|
public IEnumerable<NameType> Params { get {
|
||||||
|
return MethodInfo.GetParameters().Select(p =>
|
||||||
|
new NameType { Name = p.Name, Type = p.ParameterType.Name });
|
||||||
|
} }
|
||||||
|
|
||||||
|
public MethodNameParams(MethodInfo info)
|
||||||
|
{
|
||||||
|
MethodInfo = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NameType
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
|
public class ApiAttribute : CAttribute
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.UI;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class DeviceManager
|
||||||
|
{
|
||||||
|
//public static List<Device> Devices { get { return _Devices; } }
|
||||||
|
//static List<Device> _Devices = new List<Device>();
|
||||||
|
|
||||||
|
static Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a copy of all the devices in a list
|
||||||
|
/// </summary>
|
||||||
|
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
|
||||||
|
|
||||||
|
public static void Initialize(CrestronControlSystem cs)
|
||||||
|
{
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s));
|
||||||
|
}, "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s));
|
||||||
|
}, "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s));
|
||||||
|
}, "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||||
|
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls activate steps on all Device class items
|
||||||
|
/// </summary>
|
||||||
|
public static void ActivateAll()
|
||||||
|
{
|
||||||
|
// PreActivate all devices
|
||||||
|
foreach (var d in Devices.Values)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).PreActivate();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate all devices
|
||||||
|
foreach (var d in Devices.Values)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).Activate();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostActivate all devices
|
||||||
|
foreach (var d in Devices.Values)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).PostActivate();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls activate on all Device class items
|
||||||
|
/// </summary>
|
||||||
|
public static void DeactivateAll()
|
||||||
|
{
|
||||||
|
foreach (var d in Devices.Values)
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).Deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//static void ListMethods(string devKey)
|
||||||
|
//{
|
||||||
|
// var dev = GetDeviceForKey(devKey);
|
||||||
|
// if(dev != null)
|
||||||
|
// {
|
||||||
|
// var type = dev.GetType().GetCType();
|
||||||
|
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
|
||||||
|
// var sb = new StringBuilder();
|
||||||
|
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
|
||||||
|
// foreach (var m in methods)
|
||||||
|
// {
|
||||||
|
// sb.Append(string.Format("{0}(", m.Name));
|
||||||
|
// var pars = m.GetParameters();
|
||||||
|
// foreach (var p in pars)
|
||||||
|
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
|
||||||
|
// sb.AppendLine(")");
|
||||||
|
// }
|
||||||
|
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void ListDevices(string s)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "{0} Devices registered with Device Mangager:",Devices.Count);
|
||||||
|
var sorted = Devices.Values.ToList();
|
||||||
|
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||||
|
|
||||||
|
foreach (var d in sorted)
|
||||||
|
{
|
||||||
|
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||||
|
Debug.Console(0, " [{0}] {1}", d.Key, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListDeviceFeedbacks(string devKey)
|
||||||
|
{
|
||||||
|
var dev = GetDeviceForKey(devKey);
|
||||||
|
if(dev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device '{0}' not found", devKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var statusDev = dev as IHasFeedback;
|
||||||
|
if(statusDev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statusDev.DumpFeedbacksToConsole(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//static void ListDeviceCommands(string devKey)
|
||||||
|
//{
|
||||||
|
// var dev = GetDeviceForKey(devKey);
|
||||||
|
// if (dev == null)
|
||||||
|
// {
|
||||||
|
// Debug.Console(0, "Device '{0}' not found", devKey);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void ListDeviceCommStatuses(string input)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var dev in Devices.Values)
|
||||||
|
{
|
||||||
|
if (dev is ICommunicationMonitor)
|
||||||
|
sb.Append(string.Format("{0}: {1}\r", dev.Key, (dev as ICommunicationMonitor).CommunicationMonitor.Status));
|
||||||
|
}
|
||||||
|
CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//static void DoDeviceCommand(string command)
|
||||||
|
//{
|
||||||
|
// Debug.Console(0, "Not yet implemented. Stay tuned");
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static void AddDevice(IKeyed newDev)
|
||||||
|
{
|
||||||
|
// Check for device with same key
|
||||||
|
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
////// If it exists, remove or warn??
|
||||||
|
//if (existingDevice != null)
|
||||||
|
if(Devices.ContainsKey(newDev.Key))
|
||||||
|
{
|
||||||
|
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Devices.Add(newDev.Key, newDev);
|
||||||
|
//if (!(_Devices.Contains(newDev)))
|
||||||
|
// _Devices.Add(newDev);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveDevice(IKeyed newDev)
|
||||||
|
{
|
||||||
|
if(newDev == null)
|
||||||
|
return;
|
||||||
|
if (Devices.ContainsKey(newDev.Key))
|
||||||
|
Devices.Remove(newDev.Key);
|
||||||
|
//if (_Devices.Contains(newDev))
|
||||||
|
// _Devices.Remove(newDev);
|
||||||
|
else
|
||||||
|
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<string> GetDeviceKeys()
|
||||||
|
{
|
||||||
|
//return _Devices.Select(d => d.Key).ToList();
|
||||||
|
return Devices.Keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IKeyed> GetDevices()
|
||||||
|
{
|
||||||
|
//return _Devices.Select(d => d.Key).ToList();
|
||||||
|
return Devices.Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IKeyed GetDeviceForKey(string key)
|
||||||
|
{
|
||||||
|
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (key != null && Devices.ContainsKey(key))
|
||||||
|
return Devices[key];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Console handler that simulates com port data receive
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
public static void SimulateComReceiveOnDevice(string s)
|
||||||
|
{
|
||||||
|
// devcomsim:1 xyzabc
|
||||||
|
var match = Regex.Match(s, @"(\S*)\s*(.*)");
|
||||||
|
if (match.Groups.Count < 3)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
|
||||||
|
|
||||||
|
ComPortController com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
|
||||||
|
if (com == null)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
com.SimulateReceive(match.Groups[2].Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.UI;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class DeviceManager
|
||||||
|
{
|
||||||
|
//public static List<Device> Devices { get { return _Devices; } }
|
||||||
|
//static List<Device> _Devices = new List<Device>();
|
||||||
|
|
||||||
|
static Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a copy of all the devices in a list
|
||||||
|
/// </summary>
|
||||||
|
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
|
||||||
|
|
||||||
|
public static void Initialize(CrestronControlSystem cs)
|
||||||
|
{
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s));
|
||||||
|
}, "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s));
|
||||||
|
}, "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s));
|
||||||
|
}, "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||||
|
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls activate on all Device class items
|
||||||
|
/// </summary>
|
||||||
|
public static void ActivateAll()
|
||||||
|
{
|
||||||
|
foreach (var d in Devices.Values)
|
||||||
|
<<<<<<< HEAD
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).Activate();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, d, "ERROR: Device activation failure:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
=======
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).Activate();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, d, "ERROR: Device activation failure:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>>>>>> origin/feature/ecs-342-neil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls activate on all Device class items
|
||||||
|
/// </summary>
|
||||||
|
public static void DeactivateAll()
|
||||||
|
{
|
||||||
|
foreach (var d in Devices.Values)
|
||||||
|
{
|
||||||
|
if (d is Device)
|
||||||
|
(d as Device).Deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//static void ListMethods(string devKey)
|
||||||
|
//{
|
||||||
|
// var dev = GetDeviceForKey(devKey);
|
||||||
|
// if(dev != null)
|
||||||
|
// {
|
||||||
|
// var type = dev.GetType().GetCType();
|
||||||
|
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
|
||||||
|
// var sb = new StringBuilder();
|
||||||
|
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
|
||||||
|
// foreach (var m in methods)
|
||||||
|
// {
|
||||||
|
// sb.Append(string.Format("{0}(", m.Name));
|
||||||
|
// var pars = m.GetParameters();
|
||||||
|
// foreach (var p in pars)
|
||||||
|
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
|
||||||
|
// sb.AppendLine(")");
|
||||||
|
// }
|
||||||
|
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void ListDevices(string s)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "{0} Devices registered with Device Mangager:",Devices.Count);
|
||||||
|
var sorted = Devices.Values.ToList();
|
||||||
|
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||||
|
|
||||||
|
foreach (var d in sorted)
|
||||||
|
{
|
||||||
|
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||||
|
Debug.Console(0, " [{0}] {1}", d.Key, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListDeviceFeedbacks(string devKey)
|
||||||
|
{
|
||||||
|
var dev = GetDeviceForKey(devKey);
|
||||||
|
if(dev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device '{0}' not found", devKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var statusDev = dev as IHasFeedback;
|
||||||
|
if(statusDev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statusDev.DumpFeedbacksToConsole(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//static void ListDeviceCommands(string devKey)
|
||||||
|
//{
|
||||||
|
// var dev = GetDeviceForKey(devKey);
|
||||||
|
// if (dev == null)
|
||||||
|
// {
|
||||||
|
// Debug.Console(0, "Device '{0}' not found", devKey);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void ListDeviceCommStatuses(string input)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var dev in Devices.Values)
|
||||||
|
{
|
||||||
|
if (dev is ICommunicationMonitor)
|
||||||
|
sb.Append(string.Format("{0}: {1}\r", dev.Key, (dev as ICommunicationMonitor).CommunicationMonitor.Status));
|
||||||
|
}
|
||||||
|
CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//static void DoDeviceCommand(string command)
|
||||||
|
//{
|
||||||
|
// Debug.Console(0, "Not yet implemented. Stay tuned");
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static void AddDevice(IKeyed newDev)
|
||||||
|
{
|
||||||
|
// Check for device with same key
|
||||||
|
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
////// If it exists, remove or warn??
|
||||||
|
//if (existingDevice != null)
|
||||||
|
if(Devices.ContainsKey(newDev.Key))
|
||||||
|
{
|
||||||
|
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Devices.Add(newDev.Key, newDev);
|
||||||
|
//if (!(_Devices.Contains(newDev)))
|
||||||
|
// _Devices.Add(newDev);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveDevice(IKeyed newDev)
|
||||||
|
{
|
||||||
|
if(newDev == null)
|
||||||
|
return;
|
||||||
|
if (Devices.ContainsKey(newDev.Key))
|
||||||
|
Devices.Remove(newDev.Key);
|
||||||
|
//if (_Devices.Contains(newDev))
|
||||||
|
// _Devices.Remove(newDev);
|
||||||
|
else
|
||||||
|
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<string> GetDeviceKeys()
|
||||||
|
{
|
||||||
|
//return _Devices.Select(d => d.Key).ToList();
|
||||||
|
return Devices.Keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IKeyed> GetDevices()
|
||||||
|
{
|
||||||
|
//return _Devices.Select(d => d.Key).ToList();
|
||||||
|
return Devices.Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IKeyed GetDeviceForKey(string key)
|
||||||
|
{
|
||||||
|
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (key != null && Devices.ContainsKey(key))
|
||||||
|
return Devices[key];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Console handler that simulates com port data receive
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
public static void SimulateComReceiveOnDevice(string s)
|
||||||
|
{
|
||||||
|
// devcomsim:1 xyzabc
|
||||||
|
var match = Regex.Match(s, @"(\S*)\s*(.*)");
|
||||||
|
if (match.Groups.Count < 3)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
|
||||||
|
|
||||||
|
ComPortController com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
|
||||||
|
if (com == null)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
com.SimulateReceive(match.Groups[2].Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Integers that represent the "source type number" for given sources.
|
||||||
|
/// Primarily used by the UI to calculate subpage join offsets
|
||||||
|
/// Note, for UI, only values 1-49 are valid.
|
||||||
|
/// </summary>
|
||||||
|
public class DisplayUiConstants
|
||||||
|
{
|
||||||
|
public const uint TypeRadio = 1;
|
||||||
|
public const uint TypeDirecTv = 9;
|
||||||
|
public const uint TypeBluray = 13;
|
||||||
|
public const uint TypeChromeTv = 15;
|
||||||
|
public const uint TypeFireTv = 16;
|
||||||
|
public const uint TypeAppleTv = 17;
|
||||||
|
public const uint TypeRoku = 18;
|
||||||
|
public const uint TypeLaptop = 31;
|
||||||
|
public const uint TypePc = 32;
|
||||||
|
|
||||||
|
public const uint TypeNoControls = 49;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IOnline
|
||||||
|
{
|
||||||
|
BoolFeedback IsOnline { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// ** WANT THIS AND ALL ITS FRIENDS TO GO AWAY **
|
||||||
|
///// Defines a class that has a list of CueAction objects, typically
|
||||||
|
///// for linking functions to user interfaces or API calls
|
||||||
|
///// </summary>
|
||||||
|
//public interface IHasCueActionList
|
||||||
|
//{
|
||||||
|
// List<CueActionPair> CueActionList { get; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//public interface IHasComPortsHardware
|
||||||
|
//{
|
||||||
|
// IComPorts ComPortsDevice { get; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a device that can have a video sync providing device attached to it
|
||||||
|
/// </summary>
|
||||||
|
public interface IAttachVideoStatus : IKeyed
|
||||||
|
{
|
||||||
|
// Extension methods will depend on this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For display classes that can provide usage data
|
||||||
|
/// </summary>
|
||||||
|
public interface IDisplayUsage
|
||||||
|
{
|
||||||
|
IntFeedback LampHours { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IMakeModel : IKeyed
|
||||||
|
{
|
||||||
|
string DeviceMake { get; }
|
||||||
|
string DeviceModel { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Devices
|
||||||
|
{
|
||||||
|
public class GenericCommunicationMonitoredDevice : Device, ICommunicationMonitor
|
||||||
|
{
|
||||||
|
IBasicCommunication Client;
|
||||||
|
|
||||||
|
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||||
|
|
||||||
|
public GenericCommunicationMonitoredDevice(string key, string name, IBasicCommunication comm, string pollString,
|
||||||
|
long pollTime, long warningTime, long errorTime)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Client = comm;
|
||||||
|
CommunicationMonitor = new GenericCommunicationMonitor(this, Client, pollTime, warningTime, errorTime, pollString);
|
||||||
|
|
||||||
|
// ------------------------------------------------------DELETE THIS
|
||||||
|
CommunicationMonitor.StatusChange += (o, a) =>
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Communication monitor status change: {0}", a.Status);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericCommunicationMonitoredDevice(string key, string name, IBasicCommunication comm, string pollString)
|
||||||
|
: this(key, name, comm, pollString, 30000, 120000, 300000)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generic monitor for TCP reachability. Default with 30s poll, 120s warning and 300s error times
|
||||||
|
/// </summary>
|
||||||
|
[Obsolete]
|
||||||
|
public GenericCommunicationMonitoredDevice(string key, string name, string hostname, int port, string pollString)
|
||||||
|
: this(key, name, hostname, port, pollString, 30000, 120000, 300000)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Monitor for TCP reachability
|
||||||
|
/// </summary>
|
||||||
|
[Obsolete]
|
||||||
|
public GenericCommunicationMonitoredDevice(string key, string name, string hostname, int port, string pollString,
|
||||||
|
long pollTime, long warningTime, long errorTime)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Client = new GenericTcpIpClient(key + "-tcp", hostname, port, 512);
|
||||||
|
CommunicationMonitor = new GenericCommunicationMonitor(this, Client, pollTime, warningTime, errorTime, pollString);
|
||||||
|
|
||||||
|
// ------------------------------------------------------DELETE THIS
|
||||||
|
CommunicationMonitor.StatusChange += (o, a) =>
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Communication monitor status change: {0}", a.Status);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
CommunicationMonitor.Start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Deactivate()
|
||||||
|
{
|
||||||
|
CommunicationMonitor.Stop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class IAttachVideoStatusExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the VideoStatusOutputs for the device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attachDev"></param>
|
||||||
|
/// <returns>Attached VideoStatusOutputs or the default if none attached</returns>
|
||||||
|
public static VideoStatusOutputs GetVideoStatuses(this IAttachVideoStatus attachedDev)
|
||||||
|
{
|
||||||
|
// See if this device is connected to a status-providing port
|
||||||
|
var tl = TieLineCollection.Default.FirstOrDefault(t =>
|
||||||
|
t.SourcePort.ParentDevice == attachedDev
|
||||||
|
&& t.DestinationPort is RoutingInputPortWithVideoStatuses);
|
||||||
|
if (tl != null)
|
||||||
|
{
|
||||||
|
// if so, and it's got status, return it -- or null
|
||||||
|
var port = tl.DestinationPort as RoutingInputPortWithVideoStatuses;
|
||||||
|
if (port != null)
|
||||||
|
return port.VideoStatus;
|
||||||
|
}
|
||||||
|
return VideoStatusOutputs.NoStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HasVideoStatuses(this IAttachVideoStatus attachedDev)
|
||||||
|
{
|
||||||
|
return TieLineCollection.Default.FirstOrDefault(t =>
|
||||||
|
t.SourcePort.ParentDevice == attachedDev
|
||||||
|
&& t.DestinationPort is RoutingInputPortWithVideoStatuses) != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IHasFeedback : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This method shall return a list of all Output objects on a device,
|
||||||
|
/// including all "aggregate" devices.
|
||||||
|
/// </summary>
|
||||||
|
FeedbackCollection<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class IHasFeedbackExtensions
|
||||||
|
{
|
||||||
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
{
|
||||||
|
CType t = source.GetType();
|
||||||
|
// get the properties and set them into a new collection of NameType wrappers
|
||||||
|
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
if (feedbacks != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, source, "\n\nAvailable feedbacks:");
|
||||||
|
foreach (var f in feedbacks)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
string type = "";
|
||||||
|
if (getCurrentStates)
|
||||||
|
{
|
||||||
|
if (f is BoolFeedback)
|
||||||
|
{
|
||||||
|
val = f.BoolValue.ToString();
|
||||||
|
type = "boolean";
|
||||||
|
}
|
||||||
|
else if (f is IntFeedback)
|
||||||
|
{
|
||||||
|
val = f.IntValue.ToString();
|
||||||
|
type = "integer";
|
||||||
|
}
|
||||||
|
else if (f is StringFeedback)
|
||||||
|
{
|
||||||
|
val = f.StringValue;
|
||||||
|
type = "string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.Console(0, "{0,-12} {1, -25} {2}", type,
|
||||||
|
(string.IsNullOrEmpty(f.Key) ? "-no key-" : f.Key), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, source, "No available outputs:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IHasFeedback : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This method shall return a list of all Output objects on a device,
|
||||||
|
/// including all "aggregate" devices.
|
||||||
|
/// </summary>
|
||||||
|
List<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class IHasFeedbackExtensions
|
||||||
|
{
|
||||||
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
{
|
||||||
|
CType t = source.GetType();
|
||||||
|
// get the properties and set them into a new collection of NameType wrappers
|
||||||
|
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
if (feedbacks != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, source, "\n\nAvailable feedbacks:");
|
||||||
|
foreach (var f in feedbacks)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
string type = "";
|
||||||
|
if (getCurrentStates)
|
||||||
|
{
|
||||||
|
if (f is BoolFeedback)
|
||||||
|
{
|
||||||
|
val = f.BoolValue.ToString();
|
||||||
|
type = "boolean";
|
||||||
|
}
|
||||||
|
else if (f is IntFeedback)
|
||||||
|
{
|
||||||
|
val = f.IntValue.ToString();
|
||||||
|
type = "integer";
|
||||||
|
}
|
||||||
|
else if (f is StringFeedback)
|
||||||
|
{
|
||||||
|
val = f.StringValue;
|
||||||
|
type = "string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.Console(0, "{0,-12} {1, -25} {2}", type,
|
||||||
|
(string.IsNullOrEmpty(f.Cue.Name) ? "-no name-" : f.Cue.Name), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, source, "No available outputs:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
=======
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IHasFeedback : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This method shall return a list of all Output objects on a device,
|
||||||
|
/// including all "aggregate" devices.
|
||||||
|
/// </summary>
|
||||||
|
List<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class IHasFeedbackExtensions
|
||||||
|
{
|
||||||
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
{
|
||||||
|
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
if (feedbacks != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, source, "\n\nAvailable feedbacks:");
|
||||||
|
foreach (var f in feedbacks)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
if (getCurrentStates)
|
||||||
|
{
|
||||||
|
if (f is BoolFeedback)
|
||||||
|
val = " = " + f.BoolValue;
|
||||||
|
else if(f is IntFeedback)
|
||||||
|
val = " = " + f.IntValue;
|
||||||
|
else if(f is StringFeedback)
|
||||||
|
val = " = " + f.StringValue;
|
||||||
|
|
||||||
|
//switch (f.Type)
|
||||||
|
//{
|
||||||
|
// case eCueType.Bool:
|
||||||
|
// val = " = " + f.BoolValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.Int:
|
||||||
|
// val = " = " + f.IntValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.String:
|
||||||
|
// val = " = " + f.StringValue;
|
||||||
|
// break;
|
||||||
|
// //case eOutputType.Other:
|
||||||
|
// // break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
Debug.Console(0, "{0,-8} {1}{2}", f.GetType(),
|
||||||
|
(string.IsNullOrEmpty(f.Cue.Name) ? "-none-" : f.Cue.Name), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, source, "No available outputs:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IHasFeedbackFusionExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
>>>>>>> origin/feature/ecs-307
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IHasFeedback : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This method shall return a list of all Output objects on a device,
|
||||||
|
/// including all "aggregate" devices.
|
||||||
|
/// </summary>
|
||||||
|
List<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class IHasFeedbackExtensions
|
||||||
|
{
|
||||||
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
{
|
||||||
|
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
if (feedbacks != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, source, "\n\nAvailable feedbacks:");
|
||||||
|
foreach (var f in feedbacks)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
if (getCurrentStates)
|
||||||
|
{
|
||||||
|
if (f is BoolFeedback)
|
||||||
|
val = " = " + f.BoolValue;
|
||||||
|
else if(f is IntFeedback)
|
||||||
|
val = " = " + f.IntValue;
|
||||||
|
else if(f is StringFeedback)
|
||||||
|
val = " = " + f.StringValue;
|
||||||
|
|
||||||
|
//switch (f.Type)
|
||||||
|
//{
|
||||||
|
// case eCueType.Bool:
|
||||||
|
// val = " = " + f.BoolValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.Int:
|
||||||
|
// val = " = " + f.IntValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.String:
|
||||||
|
// val = " = " + f.StringValue;
|
||||||
|
// break;
|
||||||
|
// //case eOutputType.Other:
|
||||||
|
// // break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
Debug.Console(0, "{0,-8} {1}{2}", f.GetType(),
|
||||||
|
(string.IsNullOrEmpty(f.Cue.Name) ? "-none-" : f.Cue.Name), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, source, "No available outputs:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IHasFeedback : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This method shall return a list of all Output objects on a device,
|
||||||
|
/// including all "aggregate" devices.
|
||||||
|
/// </summary>
|
||||||
|
List<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class IHasFeedbackExtensions
|
||||||
|
{
|
||||||
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
{
|
||||||
|
CType t = source.GetType();
|
||||||
|
// get the properties and set them into a new collection of NameType wrappers
|
||||||
|
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
if (feedbacks != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, source, "\n\nAvailable feedbacks:");
|
||||||
|
foreach (var f in feedbacks)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
string type = "";
|
||||||
|
if (getCurrentStates)
|
||||||
|
{
|
||||||
|
if (f is BoolFeedback)
|
||||||
|
{
|
||||||
|
val = f.BoolValue.ToString();
|
||||||
|
type = "boolean";
|
||||||
|
}
|
||||||
|
else if (f is IntFeedback)
|
||||||
|
{
|
||||||
|
val = f.IntValue.ToString();
|
||||||
|
type = "integer";
|
||||||
|
}
|
||||||
|
else if (f is StringFeedback)
|
||||||
|
{
|
||||||
|
val = f.StringValue;
|
||||||
|
type = "string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.Console(0, "{0,-12} {1, -25} {2}", type,
|
||||||
|
(string.IsNullOrEmpty(f.Cue.Name) ? "-no name-" : f.Cue.Name), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, source, "No available outputs:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IHasFeedback : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This method shall return a list of all Output objects on a device,
|
||||||
|
/// including all "aggregate" devices.
|
||||||
|
/// </summary>
|
||||||
|
List<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class IHasFeedbackExtensions
|
||||||
|
{
|
||||||
|
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
{
|
||||||
|
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
if (feedbacks != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, source, "\n\nAvailable feedbacks:");
|
||||||
|
foreach (var f in feedbacks)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
if (getCurrentStates)
|
||||||
|
{
|
||||||
|
if (f is BoolFeedback)
|
||||||
|
val = " = " + f.BoolValue;
|
||||||
|
else if(f is IntFeedback)
|
||||||
|
val = " = " + f.IntValue;
|
||||||
|
else if(f is StringFeedback)
|
||||||
|
val = " = " + f.StringValue;
|
||||||
|
|
||||||
|
//switch (f.Type)
|
||||||
|
//{
|
||||||
|
// case eCueType.Bool:
|
||||||
|
// val = " = " + f.BoolValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.Int:
|
||||||
|
// val = " = " + f.IntValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.String:
|
||||||
|
// val = " = " + f.StringValue;
|
||||||
|
// break;
|
||||||
|
// //case eOutputType.Other:
|
||||||
|
// // break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
Debug.Console(0, "{0,-8} {1}{2}", f.GetType(),
|
||||||
|
(string.IsNullOrEmpty(f.Cue.Name) ? "-none-" : f.Cue.Name), val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, source, "No available outputs:");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IHasFeedbackFusionExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IUsageTracking
|
||||||
|
{
|
||||||
|
UsageTracking UsageTracker { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static class IUsageTrackingExtensions
|
||||||
|
//{
|
||||||
|
// public static void EnableUsageTracker(this IUsageTracking device)
|
||||||
|
// {
|
||||||
|
// device.UsageTracker = new UsageTracking();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public class UsageTracking
|
||||||
|
{
|
||||||
|
public event EventHandler<DeviceUsageEventArgs> DeviceUsageEnded;
|
||||||
|
|
||||||
|
public InUseTracking InUseTracker { get; protected set; }
|
||||||
|
|
||||||
|
public bool UsageIsTracked { get; set; }
|
||||||
|
|
||||||
|
public bool UsageTrackingStarted { get; protected set; }
|
||||||
|
public DateTime UsageStartTime { get; protected set; }
|
||||||
|
public DateTime UsageEndTime { get; protected set; }
|
||||||
|
|
||||||
|
public Device Parent { get; private set; }
|
||||||
|
|
||||||
|
public UsageTracking(Device parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
|
||||||
|
InUseTracker = new InUseTracking();
|
||||||
|
|
||||||
|
InUseTracker.InUseFeedback.OutputChange += InUseFeedback_OutputChange; //new EventHandler<EventArgs>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InUseFeedback_OutputChange(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(InUseTracker.InUseFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
StartDeviceUsage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EndDeviceUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the usage start time
|
||||||
|
/// </summary>
|
||||||
|
public void StartDeviceUsage()
|
||||||
|
{
|
||||||
|
UsageTrackingStarted = true;
|
||||||
|
UsageStartTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the difference between the usage start and end times, gets the total minutes used and fires an event to pass that info to a consumer
|
||||||
|
/// </summary>
|
||||||
|
public void EndDeviceUsage()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UsageTrackingStarted = false;
|
||||||
|
|
||||||
|
UsageEndTime = DateTime.Now;
|
||||||
|
|
||||||
|
if (UsageStartTime != null)
|
||||||
|
{
|
||||||
|
var timeUsed = UsageEndTime - UsageStartTime;
|
||||||
|
|
||||||
|
var handler = DeviceUsageEnded;
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Device Usage Ended for: {0} at {1}. In use for {2} minutes.", Parent.Name, UsageEndTime, timeUsed.Minutes);
|
||||||
|
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Error ending device usage: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeviceUsageEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public DateTime UsageEndTime { get; set; }
|
||||||
|
public int MinutesUsed { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface IUsageTracking
|
||||||
|
{
|
||||||
|
UsageTracking UsageTracker { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static class IUsageTrackingExtensions
|
||||||
|
//{
|
||||||
|
// public static void EnableUsageTracker(this IUsageTracking device)
|
||||||
|
// {
|
||||||
|
// device.UsageTracker = new UsageTracking();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public class UsageTracking
|
||||||
|
{
|
||||||
|
public event EventHandler<DeviceUsageEventArgs> DeviceUsageEnded;
|
||||||
|
|
||||||
|
public InUseTracking InUseTracker { get; protected set; }
|
||||||
|
|
||||||
|
public bool UsageIsTracked { get; set; }
|
||||||
|
public DateTime UsageStartTime { get; protected set; }
|
||||||
|
public DateTime UsageEndTime { get; protected set; }
|
||||||
|
|
||||||
|
public Device Parent { get; private set; }
|
||||||
|
|
||||||
|
public UsageTracking(Device parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
|
||||||
|
InUseTracker = new InUseTracking();
|
||||||
|
|
||||||
|
InUseTracker.InUseFeedback.OutputChange +=new EventHandler<EventArgs>(InUseFeedback_OutputChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InUseFeedback_OutputChange(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(InUseTracker.InUseFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
StartDeviceUsage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EndDeviceUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the usage start time
|
||||||
|
/// </summary>
|
||||||
|
public void StartDeviceUsage()
|
||||||
|
{
|
||||||
|
UsageStartTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the difference between the usage start and end times, gets the total minutes used and fires an event to pass that info to a consumer
|
||||||
|
/// </summary>
|
||||||
|
public void EndDeviceUsage()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UsageEndTime = DateTime.Now;
|
||||||
|
|
||||||
|
if (UsageStartTime != null)
|
||||||
|
{
|
||||||
|
var timeUsed = UsageEndTime - UsageStartTime;
|
||||||
|
|
||||||
|
var handler = DeviceUsageEnded;
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Device Usage Ended for: {0} at {1}. In use for {2} minutes.", Parent.Name, UsageEndTime, timeUsed.Minutes);
|
||||||
|
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
Debug.Console(1, "Device Usage Ended at {0}. In use for {1} minutes.", UsageEndTime, timeUsed.Minutes);
|
||||||
|
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
|
||||||
|
=======
|
||||||
|
Debug.Console(1, "Error ending device usage: {0}", e);
|
||||||
|
>>>>>>> origin/feature/fusion-nyu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeviceUsageEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public DateTime UsageEndTime { get; set; }
|
||||||
|
public int MinutesUsed { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines minimal volume control methods
|
||||||
|
/// </summary>
|
||||||
|
public interface IBasicVolumeControls
|
||||||
|
{
|
||||||
|
void VolumeUp(bool pressRelease);
|
||||||
|
void VolumeDown(bool pressRelease);
|
||||||
|
void MuteToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds feedback and direct volume level set to IBasicVolumeControls
|
||||||
|
/// </summary>
|
||||||
|
public interface IBasicVolumeWithFeedback : IBasicVolumeControls
|
||||||
|
{
|
||||||
|
void SetVolume(ushort level);
|
||||||
|
void MuteOn();
|
||||||
|
void MuteOff();
|
||||||
|
IntFeedback VolumeLevelFeedback { get; }
|
||||||
|
BoolFeedback MuteFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class that implements this contains a reference to a current IBasicVolumeControls device.
|
||||||
|
/// The class may have multiple IBasicVolumeControls.
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasCurrentVolumeControls
|
||||||
|
{
|
||||||
|
IBasicVolumeControls CurrentVolumeControls { get; }
|
||||||
|
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IFullAudioSettings : IBasicVolumeWithFeedback
|
||||||
|
{
|
||||||
|
void SetBalance(ushort level);
|
||||||
|
void BalanceLeft(bool pressRelease);
|
||||||
|
void BalanceRight(bool pressRelease);
|
||||||
|
|
||||||
|
void SetBass(ushort level);
|
||||||
|
void BassUp(bool pressRelease);
|
||||||
|
void BassDown(bool pressRelease);
|
||||||
|
|
||||||
|
void SetTreble(ushort level);
|
||||||
|
void TrebleUp(bool pressRelease);
|
||||||
|
void TrebleDown(bool pressRelease);
|
||||||
|
|
||||||
|
bool hasMaxVolume { get; }
|
||||||
|
void SetMaxVolume(ushort level);
|
||||||
|
void MaxVolumeUp(bool pressRelease);
|
||||||
|
void MaxVolumeDown(bool pressRelease);
|
||||||
|
|
||||||
|
bool hasDefaultVolume { get; }
|
||||||
|
void SetDefaultVolume(ushort level);
|
||||||
|
void DefaultVolumeUp(bool pressRelease);
|
||||||
|
void DefaultVolumeDown(bool pressRelease);
|
||||||
|
|
||||||
|
void LoudnessToggle();
|
||||||
|
void MonoToggle();
|
||||||
|
|
||||||
|
BoolFeedback LoudnessFeedback { get; }
|
||||||
|
BoolFeedback MonoFeedback { get; }
|
||||||
|
IntFeedback BalanceFeedback { get; }
|
||||||
|
IntFeedback BassFeedback { get; }
|
||||||
|
IntFeedback TrebleFeedback { get; }
|
||||||
|
IntFeedback MaxVolumeFeedback { get; }
|
||||||
|
IntFeedback DefaultVolumeFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class that implements this, contains a reference to an IBasicVolumeControls device.
|
||||||
|
/// For example, speakers attached to an audio zone. The speakers can provide reference
|
||||||
|
/// to their linked volume control.
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasVolumeDevice
|
||||||
|
{
|
||||||
|
IBasicVolumeControls VolumeDevice { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies a device that contains audio zones
|
||||||
|
/// </summary>
|
||||||
|
public interface IAudioZones : IRouting
|
||||||
|
{
|
||||||
|
Dictionary<uint, IAudioZone> Zone { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines minimum functionality for an audio zone
|
||||||
|
/// </summary>
|
||||||
|
public interface IAudioZone : IBasicVolumeWithFeedback
|
||||||
|
{
|
||||||
|
void SelectInput(ushort input);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IR port wrapper. May act standalone
|
||||||
|
/// </summary>
|
||||||
|
public class IrOutputPortController : Device
|
||||||
|
{
|
||||||
|
uint IrPortUid;
|
||||||
|
IROutputPort IrPort;
|
||||||
|
|
||||||
|
public ushort StandardIrPulseTime { get; set; }
|
||||||
|
public string DriverFilepath { get; private set; }
|
||||||
|
public bool DriverIsLoaded { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for IrDevice base class. If a null port is provided, this class will
|
||||||
|
/// still function without trying to talk to a port.
|
||||||
|
/// </summary>
|
||||||
|
public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
//if (port == null) throw new ArgumentNullException("port");
|
||||||
|
IrPort = port;
|
||||||
|
if (port == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LoadDriver(irDriverFilepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the IR driver at path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
public void LoadDriver(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path)) path = DriverFilepath;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IrPortUid = IrPort.LoadIRDriver(path);
|
||||||
|
DriverFilepath = path;
|
||||||
|
StandardIrPulseTime = 200;
|
||||||
|
DriverIsLoaded = true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DriverIsLoaded = false;
|
||||||
|
var message = string.Format("WARNING IR Driver '{0}' failed to load", path);
|
||||||
|
Debug.Console(0, this, message);
|
||||||
|
ErrorLog.Error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts and stops IR command on driver. Safe for missing commands
|
||||||
|
/// </summary>
|
||||||
|
public virtual void PressRelease(string command, bool state)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "IR:'{0}'={1}", command, state);
|
||||||
|
if (IrPort == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!DriverIsLoaded)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING IR driver is not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
|
||||||
|
IrPort.Press(IrPortUid, command);
|
||||||
|
else
|
||||||
|
NoIrCommandError(command);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IrPort.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pulses a command on driver. Safe for missing commands
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Pulse(string command, ushort time)
|
||||||
|
{
|
||||||
|
if (IrPort == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!DriverIsLoaded)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING IR driver is not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
|
||||||
|
IrPort.PressAndRelease(IrPortUid, command, time);
|
||||||
|
else
|
||||||
|
NoIrCommandError(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notifies the console when a bad command is used.
|
||||||
|
/// </summary>
|
||||||
|
protected void NoIrCommandError(string command)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}",
|
||||||
|
Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// When fed a dictionary of uint, string, will return UOs for each item,
|
||||||
|
///// attached to this IrOutputPort
|
||||||
|
///// </summary>
|
||||||
|
///// <param name="numStringDict"></param>
|
||||||
|
///// <returns></returns>
|
||||||
|
//public List<CueActionPair> GetUOsForIrCommands(Dictionary<Cue, string> numStringDict)
|
||||||
|
//{
|
||||||
|
// var funcs = new List<CueActionPair>(numStringDict.Count);
|
||||||
|
// foreach (var kvp in numStringDict)
|
||||||
|
// {
|
||||||
|
// // Have to assign these locally because of kvp's scope
|
||||||
|
// var cue = kvp.Key;
|
||||||
|
// var command = kvp.Value;
|
||||||
|
// funcs.Add(new BoolCueActionPair(cue, b => this.PressRelease(command, b)));
|
||||||
|
// }
|
||||||
|
// return funcs;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
//public interface IVolumeFunctions
|
||||||
|
//{
|
||||||
|
// BoolCueActionPair VolumeUpCueActionPair { get; }
|
||||||
|
// BoolCueActionPair VolumeDownCueActionPair { get; }
|
||||||
|
// BoolCueActionPair MuteToggleCueActionPair { get; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public interface IVolumeTwoWay : IVolumeFunctions
|
||||||
|
//{
|
||||||
|
// IntFeedback VolumeLevelFeedback { get; }
|
||||||
|
// UShortCueActionPair VolumeLevelCueActionPair { get; }
|
||||||
|
// BoolFeedback IsMutedFeedback { get; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
/////
|
||||||
|
///// </summary>
|
||||||
|
//public static class IFunctionListExtensions
|
||||||
|
//{
|
||||||
|
// public static string GetFunctionsConsoleList(this IHasCueActionList device)
|
||||||
|
// {
|
||||||
|
// var sb = new StringBuilder();
|
||||||
|
// var list = device.CueActionList;
|
||||||
|
// foreach (var cap in list)
|
||||||
|
// sb.AppendFormat("{0,-15} {1,4} {2}\r", cap.Cue.Name, cap.Cue.Number, cap.GetType().Name);
|
||||||
|
// return sb.ToString();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public enum AudioChangeType
|
||||||
|
{
|
||||||
|
Mute, Volume
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AudioChangeEventArgs
|
||||||
|
{
|
||||||
|
public AudioChangeType ChangeType { get; private set; }
|
||||||
|
public IBasicVolumeControls AudioDevice { get; private set; }
|
||||||
|
|
||||||
|
public AudioChangeEventArgs(IBasicVolumeControls device, AudioChangeType changeType)
|
||||||
|
{
|
||||||
|
ChangeType = changeType;
|
||||||
|
AudioDevice = device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.UI;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
//[Obsolete]
|
||||||
|
//public class PresentationDeviceType
|
||||||
|
//{
|
||||||
|
// public const ushort Default = 1;
|
||||||
|
// public const ushort CableSetTopBox = 2;
|
||||||
|
// public const ushort SatelliteSetTopBox = 3;
|
||||||
|
// public const ushort Dvd = 4;
|
||||||
|
// public const ushort Bluray = 5;
|
||||||
|
// public const ushort PC = 9;
|
||||||
|
// public const ushort Laptop = 10;
|
||||||
|
//}
|
||||||
|
|
||||||
|
public enum PresentationSourceType
|
||||||
|
{
|
||||||
|
None, Dvd, Laptop, PC, SetTopBox, VCR
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
//public interface IHasFeedback : IKeyed
|
||||||
|
//{
|
||||||
|
// /// <summary>
|
||||||
|
// /// This method shall return a list of all Output objects on a device,
|
||||||
|
// /// including all "aggregate" devices.
|
||||||
|
// /// </summary>
|
||||||
|
// List<Feedback> Feedbacks { get; }
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//public static class IHasFeedbackExtensions
|
||||||
|
//{
|
||||||
|
// public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||||
|
// {
|
||||||
|
// var outputs = source.Feedbacks.OrderBy(x => x.Type);
|
||||||
|
// if (outputs != null)
|
||||||
|
// {
|
||||||
|
// Debug.Console(0, source, "\n\nAvailable outputs:");
|
||||||
|
// foreach (var o in outputs)
|
||||||
|
// {
|
||||||
|
// string val = "";
|
||||||
|
// if (getCurrentStates)
|
||||||
|
// {
|
||||||
|
// switch (o.Type)
|
||||||
|
// {
|
||||||
|
// case eCueType.Bool:
|
||||||
|
// val = " = " + o.BoolValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.Int:
|
||||||
|
// val = " = " + o.IntValue;
|
||||||
|
// break;
|
||||||
|
// case eCueType.String:
|
||||||
|
// val = " = " + o.StringValue;
|
||||||
|
// break;
|
||||||
|
// //case eOutputType.Other:
|
||||||
|
// // break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Debug.Console(0, "{0,-8} {1,5} {2}{3}", o.Type, o.Cue.Number,
|
||||||
|
// (string.IsNullOrEmpty(o.Cue.Name) ? "-none-" : o.Cue.Name), val);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// Debug.Console(0, source, "No available outputs:");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Devices
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ReconfigurableDevice : Device
|
||||||
|
{
|
||||||
|
public event EventHandler<EventArgs> ConfigChanged;
|
||||||
|
|
||||||
|
public DeviceConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public ReconfigurableDevice(DeviceConfig config)
|
||||||
|
: base(config.Key)
|
||||||
|
{
|
||||||
|
SetNameHelper(config);
|
||||||
|
|
||||||
|
Config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the Config, calls CustomSetConfig and fires the ConfigChanged event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
public void SetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
|
||||||
|
SetNameHelper(config);
|
||||||
|
|
||||||
|
CustomSetConfig(config);
|
||||||
|
|
||||||
|
var handler = ConfigChanged;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, new EventArgs());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetNameHelper(DeviceConfig config)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(config.Name))
|
||||||
|
Name = config.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Config"></param>
|
||||||
|
protected virtual void CustomSetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
ConfigWriter.UpdateDeviceConfig(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class SmartObjectJoinOffsets
|
||||||
|
{
|
||||||
|
public const ushort Dpad = 1;
|
||||||
|
public const ushort Numpad = 2;
|
||||||
|
|
||||||
|
public const ushort PresetList = 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public enum eSourceListItemType
|
||||||
|
{
|
||||||
|
Route, Off, Other, SomethingAwesomerThanThese
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an item in a source list - can be deserialized into.
|
||||||
|
/// </summary>
|
||||||
|
public class SourceListItem
|
||||||
|
{
|
||||||
|
[JsonProperty("sourceKey")]
|
||||||
|
public string SourceKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the source Device for this, if it exists in DeviceManager
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public Device SourceDevice
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_SourceDevice == null)
|
||||||
|
_SourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as Device;
|
||||||
|
return _SourceDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Device _SourceDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets either the source's Name or this AlternateName property, if
|
||||||
|
/// defined. If source doesn't exist, returns "Missing source"
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("preferredName")]
|
||||||
|
public string PreferredName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Name))
|
||||||
|
{
|
||||||
|
if (SourceDevice == null)
|
||||||
|
return "---";
|
||||||
|
return SourceDevice.Name;
|
||||||
|
}
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A name that will override the source's name on the UI
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("icon")]
|
||||||
|
public string Icon { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("altIcon")]
|
||||||
|
public string AltIcon { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("includeInSourceList")]
|
||||||
|
public bool IncludeInSourceList { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("order")]
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("volumeControlKey")]
|
||||||
|
public string VolumeControlKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("type")]
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public eSourceListItemType Type { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("routeList")]
|
||||||
|
public List<SourceRouteListItem> RouteList { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("disableCodecSharing")]
|
||||||
|
public bool DisableCodecSharing { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("disableRoutedSharing")]
|
||||||
|
public bool DisableRoutedSharing { get; set; }
|
||||||
|
|
||||||
|
public SourceListItem()
|
||||||
|
{
|
||||||
|
Icon = "Blank";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SourceRouteListItem
|
||||||
|
{
|
||||||
|
[JsonProperty("sourceKey")]
|
||||||
|
public string SourceKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("destinationKey")]
|
||||||
|
public string DestinationKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("type")]
|
||||||
|
public eRoutingSignalType Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class VolumeDeviceChangeEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public IBasicVolumeControls OldDev { get; private set; }
|
||||||
|
public IBasicVolumeControls NewDev { get; private set; }
|
||||||
|
public ChangeType Type { get; private set; }
|
||||||
|
|
||||||
|
public VolumeDeviceChangeEventArgs(IBasicVolumeControls oldDev, IBasicVolumeControls newDev, ChangeType type)
|
||||||
|
{
|
||||||
|
OldDev = oldDev;
|
||||||
|
NewDev = newDev;
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public enum ChangeType
|
||||||
|
{
|
||||||
|
WillChange, DidChange
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IPower, IWarmingCooling, IRoutingSinkWithSwitching
|
||||||
|
{
|
||||||
|
public IrOutputPortController IrPort { get; private set; }
|
||||||
|
public ushort IrPulseTime { get; set; }
|
||||||
|
|
||||||
|
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||||
|
{
|
||||||
|
get { return () => _PowerIsOn; }
|
||||||
|
}
|
||||||
|
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||||
|
{
|
||||||
|
get { return () => _IsCoolingDown; }
|
||||||
|
}
|
||||||
|
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||||
|
{
|
||||||
|
get { return () => _IsWarmingUp; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _PowerIsOn;
|
||||||
|
bool _IsWarmingUp;
|
||||||
|
bool _IsCoolingDown;
|
||||||
|
|
||||||
|
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
|
||||||
|
DeviceManager.AddDevice(IrPort);
|
||||||
|
|
||||||
|
PowerIsOnFeedback.OutputChange += (o, a) => {
|
||||||
|
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||||
|
if (_PowerIsOn) StartWarmingTimer();
|
||||||
|
else StartCoolingTimer();
|
||||||
|
};
|
||||||
|
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
|
||||||
|
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
|
||||||
|
|
||||||
|
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
|
||||||
|
{
|
||||||
|
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
|
||||||
|
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
|
||||||
|
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
|
||||||
|
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
|
||||||
|
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
|
||||||
|
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
|
||||||
|
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hdmi1()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hdmi2()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hdmi3()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hdmi4()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Component1()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Video1()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Antenna()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPower Members
|
||||||
|
|
||||||
|
public override void PowerOn()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||||
|
_PowerIsOn = true;
|
||||||
|
PowerIsOnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PowerOff()
|
||||||
|
{
|
||||||
|
_PowerIsOn = false;
|
||||||
|
PowerIsOnFeedback.FireUpdate();
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PowerToggle()
|
||||||
|
{
|
||||||
|
_PowerIsOn = false;
|
||||||
|
PowerIsOnFeedback.FireUpdate();
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IBasicVolumeControls Members
|
||||||
|
|
||||||
|
public void VolumeUp(bool pressRelease)
|
||||||
|
{
|
||||||
|
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VolumeDown(bool pressRelease)
|
||||||
|
{
|
||||||
|
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MuteToggle()
|
||||||
|
{
|
||||||
|
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
void StartWarmingTimer()
|
||||||
|
{
|
||||||
|
_IsWarmingUp = true;
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
new CTimer(o => {
|
||||||
|
_IsWarmingUp = false;
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartCoolingTimer()
|
||||||
|
{
|
||||||
|
_IsCoolingDown = true;
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
_IsCoolingDown = false;
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
}, 7000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IRoutingSink Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Typically called by the discovery routing algorithm.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
||||||
|
public override void ExecuteSwitch(object inputSelector)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
|
||||||
|
|
||||||
|
Action finishSwitch = () =>
|
||||||
|
{
|
||||||
|
var action = inputSelector as Action;
|
||||||
|
if (action != null)
|
||||||
|
action();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
PowerOn();
|
||||||
|
EventHandler<FeedbackEventArgs> oneTimer = null;
|
||||||
|
oneTimer = (o, a) =>
|
||||||
|
{
|
||||||
|
if (IsWarmingUpFeedback.BoolValue) return; // Only catch done warming
|
||||||
|
IsWarmingUpFeedback.OutputChange -= oneTimer;
|
||||||
|
finishSwitch();
|
||||||
|
};
|
||||||
|
IsWarmingUpFeedback.OutputChange += oneTimer;
|
||||||
|
}
|
||||||
|
else // Do it!
|
||||||
|
finishSwitch();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
//using System;
|
||||||
|
//using System.Collections.Generic;
|
||||||
|
//using System.Linq;
|
||||||
|
//using System.Text;
|
||||||
|
//using Crestron.SimplSharp;
|
||||||
|
//using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
//namespace PepperDash.Essentials.Core
|
||||||
|
//{
|
||||||
|
// public abstract class IRDisplayBase : DisplayBase, IHasCueActionList
|
||||||
|
// {
|
||||||
|
// public IrOutputPortController IrPort { get; private set; }
|
||||||
|
// /// <summary>
|
||||||
|
// /// Default to 200ms
|
||||||
|
// /// </summary>
|
||||||
|
// public ushort IrPulseTime { get; set; }
|
||||||
|
// bool _PowerIsOn;
|
||||||
|
// bool _IsWarmingUp;
|
||||||
|
// bool _IsCoolingDown;
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// FunctionList is pre-defined to have power commands.
|
||||||
|
// /// </summary>
|
||||||
|
// public IRDisplayBase(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||||
|
// : base(key, name)
|
||||||
|
// {
|
||||||
|
// IrPort = new IrOutputPortController("ir-" + key, port, irDriverFilepath);
|
||||||
|
// IrPulseTime = 200;
|
||||||
|
// WarmupTime = 7000;
|
||||||
|
// CooldownTime = 10000;
|
||||||
|
|
||||||
|
// CueActionList = new List<CueActionPair>
|
||||||
|
// {
|
||||||
|
// new BoolCueActionPair(CommonBoolCue.Power, b=> PowerToggle()),
|
||||||
|
// new BoolCueActionPair(CommonBoolCue.PowerOn, b=> PowerOn()),
|
||||||
|
// new BoolCueActionPair(CommonBoolCue.PowerOff, b=> PowerOff()),
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void PowerOn()
|
||||||
|
// {
|
||||||
|
// if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||||
|
// {
|
||||||
|
// _IsWarmingUp = true;
|
||||||
|
// IsWarmingUpFeedback.FireUpdate();
|
||||||
|
// // Fake power-up cycle
|
||||||
|
// WarmupTimer = new CTimer(o =>
|
||||||
|
// {
|
||||||
|
// _IsWarmingUp = false;
|
||||||
|
// _PowerIsOn = true;
|
||||||
|
// IsWarmingUpFeedback.FireUpdate();
|
||||||
|
// PowerIsOnFeedback.FireUpdate();
|
||||||
|
// }, WarmupTime);
|
||||||
|
// }
|
||||||
|
// IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void PowerOff()
|
||||||
|
// {
|
||||||
|
// // If a display has unreliable-power off feedback, just override this and
|
||||||
|
// // remove this check.
|
||||||
|
// if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||||
|
// {
|
||||||
|
// _IsCoolingDown = true;
|
||||||
|
// _PowerIsOn = false;
|
||||||
|
// PowerIsOnFeedback.FireUpdate();
|
||||||
|
// IsCoolingDownFeedback.FireUpdate();
|
||||||
|
// // Fake cool-down cycle
|
||||||
|
// CooldownTimer = new CTimer(o =>
|
||||||
|
// {
|
||||||
|
// _IsCoolingDown = false;
|
||||||
|
// IsCoolingDownFeedback.FireUpdate();
|
||||||
|
// }, CooldownTime);
|
||||||
|
// }
|
||||||
|
// IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void PowerToggle()
|
||||||
|
// {
|
||||||
|
// // Not sure how to handle the feedback, but we should default to power off fb.
|
||||||
|
// // Does this need to trigger feedback??
|
||||||
|
// _PowerIsOn = false;
|
||||||
|
// IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #region IFunctionList Members
|
||||||
|
|
||||||
|
// public List<CueActionPair> CueActionList
|
||||||
|
// {
|
||||||
|
// get;
|
||||||
|
// private set;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// protected override Func<bool> PowerIsOnOutputFunc { get { return () => _PowerIsOn; } }
|
||||||
|
// protected override Func<bool> IsCoolingDownOutputFunc { get { return () => _IsCoolingDown; } }
|
||||||
|
// protected override Func<bool> IsWarmingUpOutputFunc { get { return () => _IsWarmingUp; } }
|
||||||
|
|
||||||
|
// public override void ExecuteSwitch(object selector)
|
||||||
|
// {
|
||||||
|
// IrPort.Pulse((string)selector, IrPulseTime);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DisplayBase : Device, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking
|
||||||
|
{
|
||||||
|
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||||
|
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||||
|
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||||
|
|
||||||
|
public UsageTracking UsageTracker { get; set; }
|
||||||
|
|
||||||
|
public uint WarmupTime { get; set; }
|
||||||
|
public uint CooldownTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||||
|
/// by concrete sub-classes
|
||||||
|
/// </summary>
|
||||||
|
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||||
|
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||||
|
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||||
|
|
||||||
|
|
||||||
|
protected CTimer WarmupTimer;
|
||||||
|
protected CTimer CooldownTimer;
|
||||||
|
|
||||||
|
#region IRoutingInputs Members
|
||||||
|
|
||||||
|
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public DisplayBase(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||||
|
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||||
|
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||||
|
|
||||||
|
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||||
|
|
||||||
|
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (UsageTracker != null)
|
||||||
|
{
|
||||||
|
if (PowerIsOnFeedback.BoolValue)
|
||||||
|
UsageTracker.StartDeviceUsage();
|
||||||
|
else
|
||||||
|
UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void PowerOn();
|
||||||
|
public abstract void PowerOff();
|
||||||
|
public abstract void PowerToggle();
|
||||||
|
|
||||||
|
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new FeedbackCollection<Feedback>
|
||||||
|
{
|
||||||
|
PowerIsOnFeedback,
|
||||||
|
IsCoolingDownFeedback,
|
||||||
|
IsWarmingUpFeedback
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void ExecuteSwitch(object selector);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public abstract class TwoWayDisplayBase : DisplayBase
|
||||||
|
{
|
||||||
|
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||||
|
|
||||||
|
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public static MockDisplay DefaultDisplay
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_DefaultDisplay == null)
|
||||||
|
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||||
|
return _DefaultDisplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static MockDisplay _DefaultDisplay;
|
||||||
|
|
||||||
|
public TwoWayDisplayBase(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||||
|
|
||||||
|
WarmupTime = 7000;
|
||||||
|
CooldownTime = 15000;
|
||||||
|
|
||||||
|
Feedbacks.Add(CurrentInputFeedback);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback
|
||||||
|
|
||||||
|
{
|
||||||
|
public RoutingInputPort HdmiIn1 { get; private set; }
|
||||||
|
public RoutingInputPort HdmiIn2 { get; private set; }
|
||||||
|
public RoutingInputPort HdmiIn3 { get; private set; }
|
||||||
|
public RoutingInputPort ComponentIn1 { get; private set; }
|
||||||
|
public RoutingInputPort VgaIn1 { get; private set; }
|
||||||
|
|
||||||
|
bool _PowerIsOn;
|
||||||
|
bool _IsWarmingUp;
|
||||||
|
bool _IsCoolingDown;
|
||||||
|
|
||||||
|
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
|
||||||
|
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
|
||||||
|
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
|
||||||
|
protected override Func<string> CurrentInputFeedbackFunc { get { return () => "Not Implemented"; } }
|
||||||
|
|
||||||
|
int VolumeHeldRepeatInterval = 200;
|
||||||
|
ushort VolumeInterval = 655;
|
||||||
|
ushort _FakeVolumeLevel = 31768;
|
||||||
|
bool _IsMuted;
|
||||||
|
|
||||||
|
public MockDisplay(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, null, this);
|
||||||
|
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, null, this);
|
||||||
|
HdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
|
||||||
|
eRoutingPortConnectionType.Hdmi, null, this);
|
||||||
|
ComponentIn1 = new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Video,
|
||||||
|
eRoutingPortConnectionType.Component, null, this);
|
||||||
|
VgaIn1 = new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
|
||||||
|
eRoutingPortConnectionType.Composite, null, this);
|
||||||
|
InputPorts.AddRange(new[] { HdmiIn1, HdmiIn2, HdmiIn3, ComponentIn1, VgaIn1 });
|
||||||
|
|
||||||
|
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
|
||||||
|
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PowerOn()
|
||||||
|
{
|
||||||
|
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||||
|
{
|
||||||
|
_IsWarmingUp = true;
|
||||||
|
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||||
|
// Fake power-up cycle
|
||||||
|
WarmupTimer = new CTimer(o =>
|
||||||
|
{
|
||||||
|
_IsWarmingUp = false;
|
||||||
|
_PowerIsOn = true;
|
||||||
|
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||||
|
PowerIsOnFeedback.InvokeFireUpdate();
|
||||||
|
}, WarmupTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PowerOff()
|
||||||
|
{
|
||||||
|
// If a display has unreliable-power off feedback, just override this and
|
||||||
|
// remove this check.
|
||||||
|
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
|
||||||
|
{
|
||||||
|
_IsCoolingDown = true;
|
||||||
|
_PowerIsOn = false;
|
||||||
|
PowerIsOnFeedback.InvokeFireUpdate();
|
||||||
|
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||||
|
// Fake cool-down cycle
|
||||||
|
CooldownTimer = new CTimer(o =>
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Cooldown timer ending");
|
||||||
|
_IsCoolingDown = false;
|
||||||
|
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||||
|
}, CooldownTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PowerToggle()
|
||||||
|
{
|
||||||
|
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
|
||||||
|
PowerOff();
|
||||||
|
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
|
||||||
|
PowerOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ExecuteSwitch(object selector)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "ExecuteSwitch: {0}", selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region IBasicVolumeWithFeedback Members
|
||||||
|
|
||||||
|
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||||
|
|
||||||
|
public void SetVolume(ushort level)
|
||||||
|
{
|
||||||
|
_FakeVolumeLevel = level;
|
||||||
|
VolumeLevelFeedback.InvokeFireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MuteOn()
|
||||||
|
{
|
||||||
|
_IsMuted = true;
|
||||||
|
MuteFeedback.InvokeFireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MuteOff()
|
||||||
|
{
|
||||||
|
_IsMuted = false;
|
||||||
|
MuteFeedback.InvokeFireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoolFeedback MuteFeedback { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IBasicVolumeControls Members
|
||||||
|
|
||||||
|
public void VolumeUp(bool pressRelease)
|
||||||
|
{
|
||||||
|
//while (pressRelease)
|
||||||
|
//{
|
||||||
|
Debug.Console(2, this, "Volume Down {0}", pressRelease);
|
||||||
|
if (pressRelease)
|
||||||
|
{
|
||||||
|
var newLevel = _FakeVolumeLevel + VolumeInterval;
|
||||||
|
SetVolume((ushort)newLevel);
|
||||||
|
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VolumeDown(bool pressRelease)
|
||||||
|
{
|
||||||
|
//while (pressRelease)
|
||||||
|
//{
|
||||||
|
Debug.Console(2, this, "Volume Up {0}", pressRelease);
|
||||||
|
if (pressRelease)
|
||||||
|
{
|
||||||
|
var newLevel = _FakeVolumeLevel - VolumeInterval;
|
||||||
|
SetVolume((ushort)newLevel);
|
||||||
|
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MuteToggle()
|
||||||
|
{
|
||||||
|
_IsMuted = !_IsMuted;
|
||||||
|
MuteFeedback.InvokeFireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Ethernet
|
||||||
|
{
|
||||||
|
public static class EthernetSettings
|
||||||
|
{
|
||||||
|
public static readonly BoolFeedback LinkActive = new BoolFeedback("LinkActive",
|
||||||
|
() => true);
|
||||||
|
public static readonly BoolFeedback DhcpActive = new BoolFeedback("DhcpActive",
|
||||||
|
() => CrestronEthernetHelper.GetEthernetParameter(
|
||||||
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, 0) == "ON");
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly StringFeedback Hostname = new StringFeedback("Hostname",
|
||||||
|
() => CrestronEthernetHelper.GetEthernetParameter(
|
||||||
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0));
|
||||||
|
public static readonly StringFeedback IpAddress0 = new StringFeedback("IpAddress0",
|
||||||
|
() => CrestronEthernetHelper.GetEthernetParameter(
|
||||||
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
||||||
|
public static readonly StringFeedback SubnetMask0 = new StringFeedback("SubnetMask0",
|
||||||
|
() => CrestronEthernetHelper.GetEthernetParameter(
|
||||||
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0));
|
||||||
|
public static readonly StringFeedback DefaultGateway0 = new StringFeedback("DefaultGateway0",
|
||||||
|
() => CrestronEthernetHelper.GetEthernetParameter(
|
||||||
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EthernetCue
|
||||||
|
{
|
||||||
|
public static readonly Cue LinkActive = Cue.BoolCue("LinkActive", 1);
|
||||||
|
public static readonly Cue DhcpActive = Cue.BoolCue("DhcpActive", 2);
|
||||||
|
|
||||||
|
public static readonly Cue Hostname = Cue.StringCue("Hostname", 1);
|
||||||
|
public static readonly Cue IpAddress0 = Cue.StringCue("IpAddress0", 2);
|
||||||
|
public static readonly Cue SubnetMask0 = Cue.StringCue("SubnetMask0", 3);
|
||||||
|
public static readonly Cue DefaultGateway0 = Cue.StringCue("DefaultGateway0", 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class DeviceFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A dictionary of factory methods, keyed by config types, added by plugins.
|
||||||
|
/// These methods are looked up and called by GetDevice in this class.
|
||||||
|
/// </summary>
|
||||||
|
static Dictionary<string, Func<DeviceConfig, IKeyed>> FactoryMethods =
|
||||||
|
new Dictionary<string, Func<DeviceConfig, IKeyed>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a plugin factory method
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dc"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static void AddFactoryForType(string type, Func<DeviceConfig, IKeyed> method)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", type);
|
||||||
|
DeviceFactory.FactoryMethods.Add(type, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The factory method for Core "things". Also iterates the Factory methods that have
|
||||||
|
/// been loaded from plugins
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dc"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IKeyed GetDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
var key = dc.Key;
|
||||||
|
var name = dc.Name;
|
||||||
|
var type = dc.Type;
|
||||||
|
var properties = dc.Properties;
|
||||||
|
|
||||||
|
var typeName = dc.Type.ToLower();
|
||||||
|
|
||||||
|
// Check "core" types first
|
||||||
|
if (typeName == "genericcomm")
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Factory Attempting to create new Generic Comm Device");
|
||||||
|
return new GenericComm(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// then check for types that have been added by plugin dlls.
|
||||||
|
if (FactoryMethods.ContainsKey(typeName))
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type);
|
||||||
|
return FactoryMethods[typeName](dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A Feedback whose output is derived from the return value of a provided Func.
|
||||||
|
/// </summary>
|
||||||
|
public class BoolFeedback : Feedback
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the current value of the feedback, derived from the ValueFunc. The ValueFunc is
|
||||||
|
/// evaluated whenever FireUpdate() is called
|
||||||
|
/// </summary>
|
||||||
|
public override bool BoolValue { get { return _BoolValue; } }
|
||||||
|
bool _BoolValue;
|
||||||
|
|
||||||
|
public override eCueType Type { get { return eCueType.Bool; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fake value to be used in test mode
|
||||||
|
/// </summary>
|
||||||
|
public bool TestValue { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Func that evaluates on FireUpdate
|
||||||
|
/// </summary>
|
||||||
|
public Func<bool> ValueFunc { get; private set; }
|
||||||
|
|
||||||
|
List<BoolInputSig> LinkedInputSigs = new List<BoolInputSig>();
|
||||||
|
List<BoolInputSig> LinkedComplementInputSigs = new List<BoolInputSig>();
|
||||||
|
|
||||||
|
public BoolFeedback(Func<bool> valueFunc)
|
||||||
|
: this(null, valueFunc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoolFeedback(string key, Func<bool> valueFunc)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
ValueFunc = valueFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public BoolFeedback(Cue cue, Func<bool> valueFunc)
|
||||||
|
// : base(cue)
|
||||||
|
//{
|
||||||
|
// if (cue == null) throw new ArgumentNullException("cue");
|
||||||
|
// ValueFunc = valueFunc;
|
||||||
|
//}
|
||||||
|
|
||||||
|
public override void FireUpdate()
|
||||||
|
{
|
||||||
|
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||||
|
if (newValue != _BoolValue)
|
||||||
|
{
|
||||||
|
_BoolValue = newValue;
|
||||||
|
LinkedInputSigs.ForEach(s => UpdateSig(s));
|
||||||
|
LinkedComplementInputSigs.ForEach(s => UpdateComplementSig(s));
|
||||||
|
OnOutputChange(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LinkInputSig(BoolInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Add(sig);
|
||||||
|
UpdateSig(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnlinkInputSig(BoolInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Remove(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LinkComplementInputSig(BoolInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedComplementInputSigs.Add(sig);
|
||||||
|
UpdateComplementSig(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnlinkComplementInputSig(BoolInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedComplementInputSigs.Remove(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return (InTestMode ? "TEST -- " : "") + BoolValue.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Puts this in test mode, sets the test value and fires an update.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public void SetTestValue(bool value)
|
||||||
|
{
|
||||||
|
TestValue = value;
|
||||||
|
InTestMode = true;
|
||||||
|
FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateSig(BoolInputSig sig)
|
||||||
|
{
|
||||||
|
sig.BoolValue = _BoolValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateComplementSig(BoolInputSig sig)
|
||||||
|
{
|
||||||
|
sig.BoolValue = !_BoolValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class BoolFeedbackPulse
|
||||||
|
{
|
||||||
|
public uint TimeoutMs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defaults to false
|
||||||
|
/// </summary>
|
||||||
|
public bool CanRetrigger { get; set; }
|
||||||
|
|
||||||
|
public BoolFeedback Feedback { get; private set; }
|
||||||
|
CTimer Timer;
|
||||||
|
|
||||||
|
bool _BoolValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a non-retriggering one shot
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedbackPulse(uint timeoutMs)
|
||||||
|
: this(timeoutMs, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a retriggerable one shot by setting canRetrigger true
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedbackPulse(uint timeoutMs, bool canRetrigger)
|
||||||
|
{
|
||||||
|
TimeoutMs = timeoutMs;
|
||||||
|
CanRetrigger = canRetrigger;
|
||||||
|
Feedback = new BoolFeedback(() => _BoolValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeout"></param>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
if (Timer == null)
|
||||||
|
{
|
||||||
|
_BoolValue = true;
|
||||||
|
Feedback.FireUpdate();
|
||||||
|
Timer = new CTimer(o =>
|
||||||
|
{
|
||||||
|
_BoolValue = false;
|
||||||
|
Feedback.FireUpdate();
|
||||||
|
Timer = null;
|
||||||
|
}, TimeoutMs);
|
||||||
|
}
|
||||||
|
// Timer is running, if retrigger is set, reset it.
|
||||||
|
else if (CanRetrigger)
|
||||||
|
Timer.Reset(TimeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cancel()
|
||||||
|
{
|
||||||
|
if(Timer != null)
|
||||||
|
Timer.Reset(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A class that wraps a BoolFeedback with logic that extends it's true state for
|
||||||
|
/// a time period after the value goes false.
|
||||||
|
/// </summary>
|
||||||
|
public class BoolFeedbackPulseExtender
|
||||||
|
{
|
||||||
|
public uint TimeoutMs { get; set; }
|
||||||
|
public BoolFeedback Feedback { get; private set; }
|
||||||
|
CTimer Timer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When set to true, will cause Feedback to go high, and cancel the timer.
|
||||||
|
/// When false, will start the timer, and after timeout, will go low and
|
||||||
|
/// feedback will go low.
|
||||||
|
/// </summary>
|
||||||
|
public bool BoolValue
|
||||||
|
{
|
||||||
|
get { return _BoolValue; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{ // if Timer is running and the value goes high, cancel it.
|
||||||
|
if (Timer != null)
|
||||||
|
{
|
||||||
|
Timer.Stop();
|
||||||
|
Timer = null;
|
||||||
|
}
|
||||||
|
// if it's already true, don't fire again
|
||||||
|
if (_BoolValue == true)
|
||||||
|
return;
|
||||||
|
_BoolValue = true;
|
||||||
|
Feedback.FireUpdate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Timer == null)
|
||||||
|
Timer = new CTimer(o => ClearFeedback(), TimeoutMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool _BoolValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeoutMs">The time which the true state will be extended after set to false</param>
|
||||||
|
public BoolFeedbackPulseExtender(uint timeoutMs)
|
||||||
|
{
|
||||||
|
TimeoutMs = timeoutMs;
|
||||||
|
Feedback = new BoolFeedback(() => this.BoolValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces the feedback to false regardless of timeout
|
||||||
|
/// </summary>
|
||||||
|
public void ClearNow()
|
||||||
|
{
|
||||||
|
if (Timer != null)
|
||||||
|
Timer.Stop();
|
||||||
|
ClearFeedback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearFeedback()
|
||||||
|
{
|
||||||
|
_BoolValue = false;
|
||||||
|
Feedback.FireUpdate();
|
||||||
|
Timer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class BoolFeedbackLogic
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Output representing the "and" value of all connected inputs
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback Output { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of all connected outputs
|
||||||
|
/// </summary>
|
||||||
|
protected List<BoolFeedback> OutputsIn = new List<BoolFeedback>();
|
||||||
|
|
||||||
|
protected bool ComputedValue;
|
||||||
|
|
||||||
|
public BoolFeedbackLogic()
|
||||||
|
{
|
||||||
|
Output = new BoolFeedback(() => ComputedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOutputIn(BoolFeedback output)
|
||||||
|
{
|
||||||
|
// Don't double up outputs
|
||||||
|
if(OutputsIn.Contains(output)) return;
|
||||||
|
|
||||||
|
OutputsIn.Add(output);
|
||||||
|
output.OutputChange += AnyInput_OutputChange;
|
||||||
|
Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOutputsIn(List<BoolFeedback> outputs)
|
||||||
|
{
|
||||||
|
foreach (var o in outputs)
|
||||||
|
{
|
||||||
|
// skip existing
|
||||||
|
if (OutputsIn.Contains(o)) continue;
|
||||||
|
|
||||||
|
OutputsIn.Add(o);
|
||||||
|
o.OutputChange += AnyInput_OutputChange;
|
||||||
|
}
|
||||||
|
Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOutputIn(BoolFeedback output)
|
||||||
|
{
|
||||||
|
// Don't double up outputs
|
||||||
|
if (OutputsIn.Contains(output)) return;
|
||||||
|
|
||||||
|
OutputsIn.Remove(output);
|
||||||
|
output.OutputChange -= AnyInput_OutputChange;
|
||||||
|
Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOutputsIn(List<BoolFeedback> outputs)
|
||||||
|
{
|
||||||
|
foreach (var o in outputs)
|
||||||
|
{
|
||||||
|
OutputsIn.Remove(o);
|
||||||
|
o.OutputChange -= AnyInput_OutputChange;
|
||||||
|
}
|
||||||
|
Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnyInput_OutputChange(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BoolFeedbackAnd : BoolFeedbackLogic
|
||||||
|
{
|
||||||
|
protected override void Evaluate()
|
||||||
|
{
|
||||||
|
var prevValue = ComputedValue;
|
||||||
|
var newValue = OutputsIn.All(o => o.BoolValue);
|
||||||
|
if (newValue != prevValue)
|
||||||
|
{
|
||||||
|
ComputedValue = newValue;
|
||||||
|
Output.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BoolFeedbackOr : BoolFeedbackLogic
|
||||||
|
{
|
||||||
|
protected override void Evaluate()
|
||||||
|
{
|
||||||
|
var prevValue = ComputedValue;
|
||||||
|
var newValue = OutputsIn.Any(o => o.BoolValue);
|
||||||
|
if (newValue != prevValue)
|
||||||
|
{
|
||||||
|
ComputedValue = newValue;
|
||||||
|
Output.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BoolFeedbackLinq : BoolFeedbackLogic
|
||||||
|
{
|
||||||
|
Func<IEnumerable<BoolFeedback>, bool> Predicate;
|
||||||
|
|
||||||
|
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
Predicate = predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Evaluate()
|
||||||
|
{
|
||||||
|
var prevValue = ComputedValue;
|
||||||
|
var newValue = Predicate(OutputsIn);
|
||||||
|
if (newValue != prevValue)
|
||||||
|
{
|
||||||
|
ComputedValue = newValue;
|
||||||
|
Output.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public abstract class Feedback : IKeyed
|
||||||
|
{
|
||||||
|
public event EventHandler<FeedbackEventArgs> OutputChange;
|
||||||
|
|
||||||
|
public string Key { get; private set; }
|
||||||
|
|
||||||
|
public virtual bool BoolValue { get { return false; } }
|
||||||
|
public virtual int IntValue { get { return 0; } }
|
||||||
|
public virtual string StringValue { get { return ""; } }
|
||||||
|
public virtual string SerialValue { get { return ""; } }
|
||||||
|
|
||||||
|
//public Cue Cue { get; private set; }
|
||||||
|
|
||||||
|
public abstract eCueType Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedbacks can be put into test mode for simulation of events without real data.
|
||||||
|
/// Using JSON debugging methods and the Set/ClearTestValue methods, we can simulate
|
||||||
|
/// Feedback behaviors
|
||||||
|
/// </summary>
|
||||||
|
public bool InTestMode { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base Constructor - empty
|
||||||
|
/// </summary>
|
||||||
|
protected Feedback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Feedback(string key)
|
||||||
|
{
|
||||||
|
if (key == null)
|
||||||
|
Key = "";
|
||||||
|
else
|
||||||
|
Key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
//protected Feedback(Cue cue)
|
||||||
|
//{
|
||||||
|
// Cue = cue;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears test mode and fires update.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearTestValue()
|
||||||
|
{
|
||||||
|
InTestMode = false;
|
||||||
|
FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires an update synchronously
|
||||||
|
/// </summary>
|
||||||
|
public abstract void FireUpdate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires the update asynchronously within a CrestronInvoke
|
||||||
|
/// </summary>
|
||||||
|
public void InvokeFireUpdate()
|
||||||
|
{
|
||||||
|
CrestronInvoke.BeginInvoke(o => FireUpdate());
|
||||||
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Helper method that fires event. Use this intstead of calling OutputChange
|
||||||
|
///// </summary>
|
||||||
|
//protected void OnOutputChange()
|
||||||
|
//{
|
||||||
|
// if (OutputChange != null) OutputChange(this, EventArgs.Empty);
|
||||||
|
//}
|
||||||
|
|
||||||
|
protected void OnOutputChange(bool value)
|
||||||
|
{
|
||||||
|
if (OutputChange != null) OutputChange(this, new FeedbackEventArgs(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnOutputChange(int value)
|
||||||
|
{
|
||||||
|
if (OutputChange != null) OutputChange(this, new FeedbackEventArgs(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void OnOutputChange(string value)
|
||||||
|
{
|
||||||
|
if (OutputChange != null) OutputChange(this, new FeedbackEventArgs(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Basically a List , with an indexer to find feedbacks by key name
|
||||||
|
/// </summary>
|
||||||
|
public class FeedbackCollection<T> : List<T> where T : Feedback
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Case-insensitive port lookup linked to feedbacks' keys
|
||||||
|
/// </summary>
|
||||||
|
public T this[string key]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.FirstOrDefault(i => i.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class FeedbackEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public bool BoolValue { get; private set; }
|
||||||
|
public int IntValue { get; private set; }
|
||||||
|
public ushort UShortValue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (ushort)IntValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string StringValue { get; private set; }
|
||||||
|
public eFeedbackEventType Type { get; private set; }
|
||||||
|
|
||||||
|
public FeedbackEventArgs(bool value)
|
||||||
|
{
|
||||||
|
BoolValue = value;
|
||||||
|
Type = eFeedbackEventType.TypeBool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeedbackEventArgs(int value)
|
||||||
|
{
|
||||||
|
IntValue = value;
|
||||||
|
Type = eFeedbackEventType.TypeInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeedbackEventArgs(string value)
|
||||||
|
{
|
||||||
|
StringValue = value;
|
||||||
|
Type = eFeedbackEventType.TypeString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum eFeedbackEventType
|
||||||
|
{
|
||||||
|
TypeBool,
|
||||||
|
TypeInt,
|
||||||
|
TypeString
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class IntFeedback : Feedback
|
||||||
|
{
|
||||||
|
public override int IntValue { get { return _IntValue; } } // ValueFunc.Invoke(); } }
|
||||||
|
int _IntValue;
|
||||||
|
public ushort UShortValue { get { return (ushort)_IntValue; } }
|
||||||
|
|
||||||
|
public override eCueType Type { get { return eCueType.Int; } }
|
||||||
|
|
||||||
|
public int TestValue { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Func evaluated on FireUpdate
|
||||||
|
/// </summary>
|
||||||
|
Func<int> ValueFunc;
|
||||||
|
List<UShortInputSig> LinkedInputSigs = new List<UShortInputSig>();
|
||||||
|
|
||||||
|
public IntFeedback(Func<int> valueFunc)
|
||||||
|
: this(null, valueFunc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntFeedback(string key, Func<int> valueFunc)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
ValueFunc = valueFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public IntFeedback(Cue cue, Func<int> valueFunc)
|
||||||
|
// : base(cue)
|
||||||
|
//{
|
||||||
|
// if (cue == null) throw new ArgumentNullException("cue");
|
||||||
|
// ValueFunc = valueFunc;
|
||||||
|
//}
|
||||||
|
|
||||||
|
public override void FireUpdate()
|
||||||
|
{
|
||||||
|
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||||
|
if (newValue != _IntValue)
|
||||||
|
{
|
||||||
|
_IntValue = newValue;
|
||||||
|
LinkedInputSigs.ForEach(s => UpdateSig(s));
|
||||||
|
OnOutputChange(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LinkInputSig(UShortInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Add(sig);
|
||||||
|
UpdateSig(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnlinkInputSig(UShortInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Remove(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return (InTestMode ? "TEST -- " : "") + IntValue.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Puts this in test mode, sets the test value and fires an update.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public void SetTestValue(int value)
|
||||||
|
{
|
||||||
|
TestValue = value;
|
||||||
|
InTestMode = true;
|
||||||
|
FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateSig(UShortInputSig sig)
|
||||||
|
{
|
||||||
|
sig.UShortValue = UShortValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// To be used for serial data feedback where the event chain / asynchronicity must be maintained
|
||||||
|
/// and calculating the value based on a Func when it is needed will not suffice.
|
||||||
|
/// </summary>
|
||||||
|
public class SerialFeedback : Feedback
|
||||||
|
{
|
||||||
|
public override string SerialValue { get { return _SerialValue; } }
|
||||||
|
string _SerialValue;
|
||||||
|
|
||||||
|
public override eCueType Type { get { return eCueType.Serial; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used in testing. Set/Clear functions
|
||||||
|
/// </summary>
|
||||||
|
public string TestValue { get; private set; }
|
||||||
|
|
||||||
|
List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
|
||||||
|
|
||||||
|
public SerialFeedback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerialFeedback(string key)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void FireUpdate()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("This feedback type does not use Funcs");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FireUpdate(string newValue)
|
||||||
|
{
|
||||||
|
_SerialValue = newValue;
|
||||||
|
LinkedInputSigs.ForEach(s => UpdateSig(s, newValue));
|
||||||
|
OnOutputChange(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LinkInputSig(StringInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Add(sig);
|
||||||
|
UpdateSig(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnlinkInputSig(StringInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Remove(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return (InTestMode ? "TEST -- " : "") + SerialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Puts this in test mode, sets the test value and fires an update.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public void SetTestValue(string value)
|
||||||
|
{
|
||||||
|
TestValue = value;
|
||||||
|
InTestMode = true;
|
||||||
|
FireUpdate(TestValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateSig(StringInputSig sig)
|
||||||
|
{
|
||||||
|
sig.StringValue = _SerialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateSig(StringInputSig sig, string value)
|
||||||
|
{
|
||||||
|
sig.StringValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class StringFeedback : Feedback
|
||||||
|
{
|
||||||
|
public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } }
|
||||||
|
string _StringValue;
|
||||||
|
|
||||||
|
public override eCueType Type { get { return eCueType.String; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used in testing. Set/Clear functions
|
||||||
|
/// </summary>
|
||||||
|
public string TestValue { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Evalutated on FireUpdate
|
||||||
|
/// </summary>
|
||||||
|
public Func<string> ValueFunc { get; private set; }
|
||||||
|
List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
|
||||||
|
|
||||||
|
public StringFeedback(Func<string> valueFunc)
|
||||||
|
: this(null, valueFunc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringFeedback(string key, Func<string> valueFunc)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
ValueFunc = valueFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public StringFeedback(Cue cue, Func<string> valueFunc)
|
||||||
|
// : base(cue)
|
||||||
|
//{
|
||||||
|
// if (cue == null) throw new ArgumentNullException("cue");
|
||||||
|
// ValueFunc = valueFunc;
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
public override void FireUpdate()
|
||||||
|
{
|
||||||
|
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||||
|
if (newValue != _StringValue)
|
||||||
|
{
|
||||||
|
_StringValue = newValue;
|
||||||
|
LinkedInputSigs.ForEach(s => UpdateSig(s));
|
||||||
|
OnOutputChange(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LinkInputSig(StringInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Add(sig);
|
||||||
|
UpdateSig(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnlinkInputSig(StringInputSig sig)
|
||||||
|
{
|
||||||
|
LinkedInputSigs.Remove(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return (InTestMode ? "TEST -- " : "") + StringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Puts this in test mode, sets the test value and fires an update.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public void SetTestValue(string value)
|
||||||
|
{
|
||||||
|
TestValue = value;
|
||||||
|
InTestMode = true;
|
||||||
|
FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateSig(StringInputSig sig)
|
||||||
|
{
|
||||||
|
sig.StringValue = _StringValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,377 @@
|
|||||||
|
//using System;
|
||||||
|
//using System.Collections.Generic;
|
||||||
|
//using System.Linq;
|
||||||
|
//using System.Text;
|
||||||
|
|
||||||
|
//using Crestron.SimplSharp;
|
||||||
|
//using Crestron.SimplSharpPro;
|
||||||
|
//using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
//using Crestron.SimplSharpPro.Fusion;
|
||||||
|
//using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
//using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
//namespace PepperDash.Essentials.Core.Fusion
|
||||||
|
//{
|
||||||
|
// public class EssentialsHuddleSpaceFusionSystemController : Device
|
||||||
|
// {
|
||||||
|
// FusionRoom FusionRoom;
|
||||||
|
// Room Room;
|
||||||
|
// Dictionary<IPresentationSource, BoolInputSig> SourceToFeedbackSigs = new Dictionary<IPresentationSource, BoolInputSig>();
|
||||||
|
|
||||||
|
// StatusMonitorCollection ErrorMessageRollUp;
|
||||||
|
|
||||||
|
// public EssentialsHuddleSpaceFusionSystemController(HuddleSpaceRoom room, uint ipId)
|
||||||
|
// : base(room.Key + "-fusion")
|
||||||
|
// {
|
||||||
|
// Room = room;
|
||||||
|
|
||||||
|
// FusionRoom = new FusionRoom(ipId, Global.ControlSystem, room.Name, "awesomeGuid-" + room.Key);
|
||||||
|
// FusionRoom.Register();
|
||||||
|
|
||||||
|
// FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange);
|
||||||
|
|
||||||
|
// // Room to fusion room
|
||||||
|
// room.RoomIsOn.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||||
|
// var srcName = FusionRoom.CreateOffsetStringSig(50, "Source - Name", eSigIoMask.InputSigOnly);
|
||||||
|
// room.CurrentSourceName.LinkInputSig(srcName.InputSig);
|
||||||
|
|
||||||
|
// FusionRoom.SystemPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (b) room.RoomOn(null); });
|
||||||
|
// FusionRoom.SystemPowerOff.OutputSig.UserObject = new Action<bool>(b => { if (b) room.RoomOff(); });
|
||||||
|
// // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
|
||||||
|
// FusionRoom.ErrorMessage.InputSig.StringValue = "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
|
||||||
|
|
||||||
|
// // Sources
|
||||||
|
// foreach (var src in room.Sources)
|
||||||
|
// {
|
||||||
|
// var srcNum = src.Key;
|
||||||
|
// var pSrc = src.Value as IPresentationSource;
|
||||||
|
// var keyNum = ExtractNumberFromKey(pSrc.Key);
|
||||||
|
// if (keyNum == -1)
|
||||||
|
// {
|
||||||
|
// Debug.Console(1, this, "WARNING: Cannot link source '{0}' to numbered Fusion attributes", pSrc.Key);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// string attrName = null;
|
||||||
|
// uint attrNum = Convert.ToUInt32(keyNum);
|
||||||
|
// switch (pSrc.Type)
|
||||||
|
// {
|
||||||
|
// case PresentationSourceType.None:
|
||||||
|
// break;
|
||||||
|
// case PresentationSourceType.SetTopBox:
|
||||||
|
// attrName = "Source - TV " + keyNum;
|
||||||
|
// attrNum += 115; // TV starts at 116
|
||||||
|
// break;
|
||||||
|
// case PresentationSourceType.Dvd:
|
||||||
|
// attrName = "Source - DVD " + keyNum;
|
||||||
|
// attrNum += 120; // DVD starts at 121
|
||||||
|
// break;
|
||||||
|
// case PresentationSourceType.PC:
|
||||||
|
// attrName = "Source - PC " + keyNum;
|
||||||
|
// attrNum += 110; // PC starts at 111
|
||||||
|
// break;
|
||||||
|
// case PresentationSourceType.Laptop:
|
||||||
|
// attrName = "Source - Laptop " + keyNum;
|
||||||
|
// attrNum += 100; // Laptops start at 101
|
||||||
|
// break;
|
||||||
|
// case PresentationSourceType.VCR:
|
||||||
|
// attrName = "Source - VCR " + keyNum;
|
||||||
|
// attrNum += 125; // VCRs start at 126
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// if (attrName == null)
|
||||||
|
// {
|
||||||
|
// Debug.Console(1, this, "Source type {0} does not have corresponsing Fusion attribute type, skipping", pSrc.Type);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", attrName, attrNum, pSrc.Key);
|
||||||
|
// var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
|
||||||
|
// // Need feedback when this source is selected
|
||||||
|
// // Event handler, added below, will compare source changes with this sig dict
|
||||||
|
// SourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
|
||||||
|
|
||||||
|
// // And respond to selection in Fusion
|
||||||
|
// sigD.OutputSig.UserObject = new Action<bool>(b => { if(b) room.SelectSource(pSrc); });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Attach to all room's devices with monitors.
|
||||||
|
// //foreach (var dev in DeviceManager.Devices)
|
||||||
|
// foreach (var dev in DeviceManager.GetDevices())
|
||||||
|
// {
|
||||||
|
// if (!(dev is ICommunicationMonitor))
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// var keyNum = ExtractNumberFromKey(dev.Key);
|
||||||
|
// if (keyNum == -1)
|
||||||
|
// {
|
||||||
|
// Debug.Console(1, this, "WARNING: Cannot link device '{0}' to numbered Fusion monitoring attributes", dev.Key);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// string attrName = null;
|
||||||
|
// uint attrNum = Convert.ToUInt32(keyNum);
|
||||||
|
|
||||||
|
// //if (dev is SmartGraphicsTouchpanelControllerBase)
|
||||||
|
// //{
|
||||||
|
// // if (attrNum > 10)
|
||||||
|
// // continue;
|
||||||
|
// // attrName = "Device Ok - Touch Panel " + attrNum;
|
||||||
|
// // attrNum += 200;
|
||||||
|
// //}
|
||||||
|
// //// add xpanel here
|
||||||
|
|
||||||
|
// //else
|
||||||
|
// if (dev is DisplayBase)
|
||||||
|
// {
|
||||||
|
// if (attrNum > 10)
|
||||||
|
// continue;
|
||||||
|
// attrName = "Device Ok - Display " + attrNum;
|
||||||
|
// attrNum += 240;
|
||||||
|
// }
|
||||||
|
// //else if (dev is DvdDeviceBase)
|
||||||
|
// //{
|
||||||
|
// // if (attrNum > 5)
|
||||||
|
// // continue;
|
||||||
|
// // attrName = "Device Ok - DVD " + attrNum;
|
||||||
|
// // attrNum += 260;
|
||||||
|
// //}
|
||||||
|
// // add set top box
|
||||||
|
|
||||||
|
// // add Cresnet roll-up
|
||||||
|
|
||||||
|
// // add DM-devices roll-up
|
||||||
|
|
||||||
|
// if (attrName != null)
|
||||||
|
// {
|
||||||
|
// // Link comm status to sig and update
|
||||||
|
// var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
|
||||||
|
// var smd = dev as ICommunicationMonitor;
|
||||||
|
// sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||||
|
// smd.CommunicationMonitor.StatusChange += (o, a) => { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
|
||||||
|
// Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Don't think we need to get current status of this as nothing should be alive yet.
|
||||||
|
// room.PresentationSourceChange += Room_PresentationSourceChange;
|
||||||
|
|
||||||
|
// // these get used in multiple places
|
||||||
|
// var display = room.Display;
|
||||||
|
// var dispPowerOnAction = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||||
|
// var dispPowerOffAction = new Action<bool>(b => { if (!b) display.PowerOff(); });
|
||||||
|
|
||||||
|
// // Display to fusion room sigs
|
||||||
|
// FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
|
// FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
|
// display.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||||
|
// if (display is IDisplayUsage)
|
||||||
|
// (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||||
|
|
||||||
|
// // Roll up ALL device errors
|
||||||
|
// ErrorMessageRollUp = new StatusMonitorCollection(this);
|
||||||
|
// foreach (var dev in DeviceManager.GetDevices())
|
||||||
|
// {
|
||||||
|
// var md = dev as ICommunicationMonitor;
|
||||||
|
// if (md != null)
|
||||||
|
// {
|
||||||
|
// ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor);
|
||||||
|
// Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ErrorMessageRollUp.Start();
|
||||||
|
// FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message;
|
||||||
|
// ErrorMessageRollUp.StatusChange += (o, a) => {
|
||||||
|
// FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; };
|
||||||
|
|
||||||
|
|
||||||
|
// // static assets --------------- testing
|
||||||
|
|
||||||
|
// // test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally.
|
||||||
|
// var ta1 = FusionRoom.CreateStaticAsset(1, "Test asset 1", "Awesome Asset", "Awesome123");
|
||||||
|
// ta1.AssetError.InputSig.StringValue = "This should be error";
|
||||||
|
|
||||||
|
|
||||||
|
// var ta2 = FusionRoom.CreateStaticAsset(2, "Test asset 2", "Awesome Asset", "Awesome1232");
|
||||||
|
// ta2.AssetUsage.InputSig.StringValue = "This should be usage";
|
||||||
|
|
||||||
|
|
||||||
|
// // Make a display asset
|
||||||
|
// var dispAsset = FusionRoom.CreateStaticAsset(3, display.Name, "Display", "awesomeDisplayId" + room.Key);
|
||||||
|
// dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
|
// dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
|
// display.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||||
|
// // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
||||||
|
// // Use extension methods
|
||||||
|
// dispAsset.TrySetMakeModel(display);
|
||||||
|
// dispAsset.TryLinkAssetErrorToCommunication(display);
|
||||||
|
|
||||||
|
|
||||||
|
// // Make it so!
|
||||||
|
// FusionRVI.GenerateFileForAllFusionDevices();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Helper to get the number from the end of a device's key string
|
||||||
|
// /// </summary>
|
||||||
|
// /// <returns>-1 if no number matched</returns>
|
||||||
|
// int ExtractNumberFromKey(string key)
|
||||||
|
// {
|
||||||
|
// var capture = System.Text.RegularExpressions.Regex.Match(key, @"\D+(\d+)");
|
||||||
|
// if (!capture.Success)
|
||||||
|
// return -1;
|
||||||
|
// else return Convert.ToInt32(capture.Groups[1].Value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void Room_PresentationSourceChange(object sender, EssentialsRoomSourceChangeEventArgs e)
|
||||||
|
// {
|
||||||
|
// if (e.OldSource != null)
|
||||||
|
// {
|
||||||
|
// if (SourceToFeedbackSigs.ContainsKey(e.OldSource))
|
||||||
|
// SourceToFeedbackSigs[e.OldSource].BoolValue = false;
|
||||||
|
// }
|
||||||
|
// if (e.NewSource != null)
|
||||||
|
// {
|
||||||
|
// if (SourceToFeedbackSigs.ContainsKey(e.NewSource))
|
||||||
|
// SourceToFeedbackSigs[e.NewSource].BoolValue = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
|
||||||
|
// // even though they all contain sigs.
|
||||||
|
|
||||||
|
// var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName);
|
||||||
|
// if (sigData != null)
|
||||||
|
// {
|
||||||
|
// var outSig = sigData.OutputSig;
|
||||||
|
// if (outSig.UserObject is Action<bool>)
|
||||||
|
// (outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
|
||||||
|
// else if (outSig.UserObject is Action<ushort>)
|
||||||
|
// (outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
|
||||||
|
// else if (outSig.UserObject is Action<string>)
|
||||||
|
// (outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var attrData = (args.UserConfiguredSigDetail as BooleanSigData);
|
||||||
|
// if (attrData != null)
|
||||||
|
// {
|
||||||
|
// var outSig = attrData.OutputSig;
|
||||||
|
// if (outSig.UserObject is Action<bool>)
|
||||||
|
// (outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
|
||||||
|
// else if (outSig.UserObject is Action<ushort>)
|
||||||
|
// (outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
|
||||||
|
// else if (outSig.UserObject is Action<string>)
|
||||||
|
// (outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// public static class FusionRoomExtensions
|
||||||
|
// {
|
||||||
|
// /// <summary>
|
||||||
|
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
|
||||||
|
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
|
||||||
|
// /// FusionRoom.AddSig with join number - 49
|
||||||
|
// /// </summary>
|
||||||
|
// /// <returns>The new attribute</returns>
|
||||||
|
// public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
||||||
|
// {
|
||||||
|
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
||||||
|
// number -= 49;
|
||||||
|
// fr.AddSig(eSigType.Bool, number, name, mask);
|
||||||
|
// return fr.UserDefinedBooleanSigDetails[number];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
|
||||||
|
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
|
||||||
|
// /// FusionRoom.AddSig with join number - 49
|
||||||
|
// /// </summary>
|
||||||
|
// /// <returns>The new attribute</returns>
|
||||||
|
// public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
||||||
|
// {
|
||||||
|
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
||||||
|
// number -= 49;
|
||||||
|
// fr.AddSig(eSigType.UShort, number, name, mask);
|
||||||
|
// return fr.UserDefinedUShortSigDetails[number];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
|
||||||
|
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
|
||||||
|
// /// FusionRoom.AddSig with join number - 49
|
||||||
|
// /// </summary>
|
||||||
|
// /// <returns>The new attribute</returns>
|
||||||
|
// public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
|
||||||
|
// {
|
||||||
|
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
|
||||||
|
// number -= 49;
|
||||||
|
// fr.AddSig(eSigType.String, number, name, mask);
|
||||||
|
// return fr.UserDefinedStringSigDetails[number];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Creates and returns a static asset
|
||||||
|
// /// </summary>
|
||||||
|
// /// <returns>the new asset</returns>
|
||||||
|
// public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId)
|
||||||
|
// {
|
||||||
|
// fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
|
||||||
|
// return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //************************************************************************************************
|
||||||
|
// /// <summary>
|
||||||
|
// /// Extensions to enhance Fusion room, asset and signal creation.
|
||||||
|
// /// </summary>
|
||||||
|
// public static class FusionStaticAssetExtensions
|
||||||
|
// {
|
||||||
|
// /// <summary>
|
||||||
|
// /// Tries to set a Fusion asset with the make and model of a device.
|
||||||
|
// /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset.
|
||||||
|
// /// Otherwise, does nothing.
|
||||||
|
// /// </summary>
|
||||||
|
// public static void TrySetMakeModel(this FusionStaticAsset asset, Device device)
|
||||||
|
// {
|
||||||
|
// var mm = device as IMakeModel;
|
||||||
|
// if (mm != null)
|
||||||
|
// {
|
||||||
|
// asset.ParamMake.Value = mm.DeviceMake;
|
||||||
|
// asset.ParamModel.Value = mm.DeviceModel;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Tries to attach the AssetError input on a Fusion asset to a Device's
|
||||||
|
// /// CommunicationMonitor.StatusChange event. Does nothing if the device is not
|
||||||
|
// /// IStatusMonitor
|
||||||
|
// /// </summary>
|
||||||
|
// /// <param name="asset"></param>
|
||||||
|
// /// <param name="device"></param>
|
||||||
|
// public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device)
|
||||||
|
// {
|
||||||
|
// if (device is ICommunicationMonitor)
|
||||||
|
// {
|
||||||
|
// var monitor = (device as ICommunicationMonitor).CommunicationMonitor;
|
||||||
|
// monitor.StatusChange += (o, a) =>
|
||||||
|
// {
|
||||||
|
// // Link connected and error inputs on asset
|
||||||
|
// asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
||||||
|
// asset.AssetError.InputSig.StringValue = a.Status.ToString();
|
||||||
|
// };
|
||||||
|
// // set current value
|
||||||
|
// asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk;
|
||||||
|
// asset.AssetError.InputSig.StringValue = monitor.Status.ToString();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronDataStore;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
|
||||||
|
//using PepperDash.Essentials.Core.Http;
|
||||||
|
using PepperDash.Essentials.License;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class Global
|
||||||
|
{
|
||||||
|
public static CrestronControlSystem ControlSystem { get; set; }
|
||||||
|
|
||||||
|
public static LicenseManager LicenseManager { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The file path prefix to the folder containing configuration files
|
||||||
|
/// </summary>
|
||||||
|
public static string FilePathPrefix { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the directory separator character based on the running OS
|
||||||
|
/// </summary>
|
||||||
|
public static char DirectorySeparator
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return System.IO.Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wildcarded config file name for global reference
|
||||||
|
/// </summary>
|
||||||
|
public const string ConfigFileName = "*configurationFile*.json";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the file path prefix
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefix"></param>
|
||||||
|
public static void SetFilePathPrefix(string prefix)
|
||||||
|
{
|
||||||
|
FilePathPrefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Global()
|
||||||
|
{
|
||||||
|
// Fire up CrestronDataStoreStatic
|
||||||
|
var err = CrestronDataStoreStatic.InitCrestronDataStore();
|
||||||
|
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||||
|
{
|
||||||
|
CrestronConsole.PrintLine("Error starting CrestronDataStoreStatic: {0}", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class JobTimer
|
||||||
|
{
|
||||||
|
static CTimer MinuteTimer;
|
||||||
|
|
||||||
|
static List<JobTimerItem> Items = new List<JobTimerItem>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="act"></param>
|
||||||
|
public static void AddAction(Action act)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="act"></param>
|
||||||
|
public static void AddJobTimerItem(JobTimerItem item)
|
||||||
|
{
|
||||||
|
var existing = Items.FirstOrDefault(i => i.Key == item.Key);
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
Items.Remove(existing);
|
||||||
|
}
|
||||||
|
Items.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckAndRunTimer()
|
||||||
|
{
|
||||||
|
if (Items.Count > 0 && MinuteTimer == null)
|
||||||
|
{
|
||||||
|
MinuteTimer = new CTimer(o => MinuteTimerCallback(), null, 60000, 60000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MinuteTimerCallback()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class JobTimerItem
|
||||||
|
{
|
||||||
|
public string Key { get; private set; }
|
||||||
|
public Action JobAction { get; private set; }
|
||||||
|
public eJobTimerCycleTypes CycleType { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public DateTime RunNextAt { get; set; }
|
||||||
|
|
||||||
|
public JobTimerItem(string key, eJobTimerCycleTypes cycle, Action act)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum eJobTimerCycleTypes
|
||||||
|
{
|
||||||
|
RunEveryDay,
|
||||||
|
RunEveryHour,
|
||||||
|
RunEveryHalfHour,
|
||||||
|
RunEveryMinute
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.Scheduler;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Global Scheduler for the system
|
||||||
|
/// </summary>
|
||||||
|
public static class Scheduler
|
||||||
|
{
|
||||||
|
private static Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||||
|
|
||||||
|
static Scheduler()
|
||||||
|
{
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears (deletes) all events from a group
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupName"></param>
|
||||||
|
static void ClearEventsFromGroup(string groupName)
|
||||||
|
{
|
||||||
|
var group = EventGroups[groupName];
|
||||||
|
|
||||||
|
if (group != null)
|
||||||
|
group.ClearAllEvents();
|
||||||
|
else
|
||||||
|
Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ListAllEventGroups(string command)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Event Groups:");
|
||||||
|
foreach (var group in EventGroups)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "{0}", group.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the event group to the global list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static void AddEventGroup(ScheduledEventGroup eventGroup)
|
||||||
|
{
|
||||||
|
// Add this group to the global collection
|
||||||
|
if (!EventGroups.ContainsKey(eventGroup.Name))
|
||||||
|
EventGroups.Add(eventGroup.Name, eventGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the event group from the global list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventGroup"></param>
|
||||||
|
public static void RemoveEventGroup(ScheduledEventGroup eventGroup)
|
||||||
|
{
|
||||||
|
if(!EventGroups.ContainsKey(eventGroup.Name))
|
||||||
|
EventGroups.Remove(eventGroup.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SchedulerUtilities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks the day of week in eventTime to see if it matches the weekdays defined in the recurrence enum.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventTime"></param>
|
||||||
|
/// <param name="recurrence"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool CheckIfDayOfWeekMatchesRecurrenceDays(DateTime eventTime, ScheduledEventCommon.eWeekDays recurrence)
|
||||||
|
{
|
||||||
|
bool isMatch = false;
|
||||||
|
|
||||||
|
var dayOfWeek = eventTime.DayOfWeek;
|
||||||
|
|
||||||
|
Debug.Console(1, "[Scheduler]: eventTime day of week is: {0}", dayOfWeek);
|
||||||
|
|
||||||
|
switch (dayOfWeek)
|
||||||
|
{
|
||||||
|
case DayOfWeek.Sunday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Sunday) == ScheduledEventCommon.eWeekDays.Sunday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DayOfWeek.Monday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Monday) == ScheduledEventCommon.eWeekDays.Monday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DayOfWeek.Tuesday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Tuesday) == ScheduledEventCommon.eWeekDays.Tuesday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DayOfWeek.Wednesday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Wednesday) == ScheduledEventCommon.eWeekDays.Wednesday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DayOfWeek.Thursday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Thursday) == ScheduledEventCommon.eWeekDays.Thursday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DayOfWeek.Friday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Friday) == ScheduledEventCommon.eWeekDays.Friday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DayOfWeek.Saturday:
|
||||||
|
{
|
||||||
|
if ((recurrence & ScheduledEventCommon.eWeekDays.Saturday) == ScheduledEventCommon.eWeekDays.Saturday)
|
||||||
|
isMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, "[Scheduler]: eventTime day of week matches recurrence days: {0}", isMatch);
|
||||||
|
|
||||||
|
return isMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a class that uses an InUseTracker
|
||||||
|
/// </summary>
|
||||||
|
public interface IInUseTracking
|
||||||
|
{
|
||||||
|
InUseTracking InUseTracker { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides in use tracking. Objects can register with this. InUseFeedback can provide
|
||||||
|
/// events when usage changes.
|
||||||
|
/// </summary>
|
||||||
|
public class InUseTracking
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a copied list of all users of this tracker.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<InUseTrackingObject> Users { get { return new List<InUseTrackingObject>(_Users); } }
|
||||||
|
List<InUseTrackingObject> _Users = new List<InUseTrackingObject>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that changes when this goes in/out of use
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback InUseFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that changes with the count of users
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback InUseCountFeedback { get; private set; }
|
||||||
|
|
||||||
|
public InUseTracking()
|
||||||
|
{
|
||||||
|
InUseFeedback = new BoolFeedback(() => _Users.Count > 0);
|
||||||
|
InUseCountFeedback = new IntFeedback(() => _Users.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a "user" object to this tracker. A user can be added to this tracker
|
||||||
|
/// multiple times, provided that the label is different
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">A label to identify the instance of the user. Treated like a "role", etc.</param>
|
||||||
|
public void AddUser(object objectToAdd, string label)
|
||||||
|
{
|
||||||
|
// check if an exact object/label pair exists and ignore if so. No double-registers.
|
||||||
|
var check = _Users.FirstOrDefault(u => u.Label == label && u.User == objectToAdd);
|
||||||
|
if (check != null) return;
|
||||||
|
|
||||||
|
var prevCount = _Users.Count;
|
||||||
|
_Users.Add(new InUseTrackingObject(objectToAdd, label));
|
||||||
|
// if this is the first add, fire an update
|
||||||
|
if (prevCount == 0 && _Users.Count > 0)
|
||||||
|
InUseFeedback.FireUpdate();
|
||||||
|
InUseCountFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a user object from this tracking
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveUser(object objectToRemove, string label)
|
||||||
|
{
|
||||||
|
// Find the user object if exists and remove it
|
||||||
|
var toRemove = _Users.FirstOrDefault(u => u.Label == label && u.User == objectToRemove);
|
||||||
|
if (toRemove != null)
|
||||||
|
{
|
||||||
|
_Users.Remove(toRemove);
|
||||||
|
if (_Users.Count == 0)
|
||||||
|
InUseFeedback.FireUpdate();
|
||||||
|
InUseCountFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrapper for label/object pair representing in-use status. Allows the same object to
|
||||||
|
/// register for in-use with different roles.
|
||||||
|
/// </summary>
|
||||||
|
public class InUseTrackingObject
|
||||||
|
{
|
||||||
|
public string Label { get; private set; }
|
||||||
|
public object User { get; private set; }
|
||||||
|
|
||||||
|
public InUseTrackingObject(object user, string label)
|
||||||
|
{
|
||||||
|
User = user;
|
||||||
|
Label = label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//public class InUseEventArgs
|
||||||
|
//{
|
||||||
|
// public int EventType { get; private set; }
|
||||||
|
// public InUseTracking Tracker { get; private set; }
|
||||||
|
|
||||||
|
// public InUseEventArgs(InUseTracking tracker, int eventType)
|
||||||
|
// {
|
||||||
|
// Tracker = tracker;
|
||||||
|
// EventType = eventType;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronDataStore;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.License
|
||||||
|
{
|
||||||
|
public abstract class LicenseManager
|
||||||
|
{
|
||||||
|
public BoolFeedback LicenseIsValid { get; protected set; }
|
||||||
|
public StringFeedback LicenseMessage { get; protected set; }
|
||||||
|
public StringFeedback LicenseLog { get; protected set; }
|
||||||
|
|
||||||
|
protected LicenseManager()
|
||||||
|
{
|
||||||
|
CrestronConsole.AddNewConsoleCommand(
|
||||||
|
s => CrestronConsole.ConsoleCommandResponse(GetStatusString()),
|
||||||
|
"licensestatus", "shows license and related data",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract string GetStatusString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MockEssentialsLicenseManager : LicenseManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the singleton mock license manager for this app
|
||||||
|
/// </summary>
|
||||||
|
public static MockEssentialsLicenseManager Manager
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_Manager == null)
|
||||||
|
_Manager = new MockEssentialsLicenseManager();
|
||||||
|
return _Manager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static MockEssentialsLicenseManager _Manager;
|
||||||
|
|
||||||
|
bool IsValid;
|
||||||
|
|
||||||
|
MockEssentialsLicenseManager() : base()
|
||||||
|
{
|
||||||
|
LicenseIsValid = new BoolFeedback("LicenseIsValid",
|
||||||
|
() => { return IsValid; });
|
||||||
|
CrestronConsole.AddNewConsoleCommand(
|
||||||
|
s => SetFromConsole(s.Equals("true", StringComparison.OrdinalIgnoreCase)),
|
||||||
|
"mocklicense", "true or false for testing", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
bool valid;
|
||||||
|
var err = CrestronDataStoreStatic.GetGlobalBoolValue("MockLicense", out valid);
|
||||||
|
if (err == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||||
|
SetIsValid(valid);
|
||||||
|
else if (err == CrestronDataStore.CDS_ERROR.CDS_RECORD_NOT_FOUND)
|
||||||
|
CrestronDataStoreStatic.SetGlobalBoolValue("MockLicense", false);
|
||||||
|
else
|
||||||
|
CrestronConsole.PrintLine("Error restoring Mock License setting: {0}", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIsValid(bool isValid)
|
||||||
|
{
|
||||||
|
IsValid = isValid;
|
||||||
|
CrestronDataStoreStatic.SetGlobalBoolValue("MockLicense", isValid);
|
||||||
|
Debug.Console(0, "Mock License is{0} valid", IsValid ? "" : " not");
|
||||||
|
LicenseIsValid.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFromConsole(bool isValid)
|
||||||
|
{
|
||||||
|
SetIsValid(isValid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string GetStatusString()
|
||||||
|
{
|
||||||
|
return string.Format("License Status: {0}", IsValid ? "Valid" : "Not Valid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EssentialsLicenseManager
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LicenseCue
|
||||||
|
{
|
||||||
|
public static Cue LicenseIsValid = Cue.BoolCue("LicenseIsValid", 15991);
|
||||||
|
|
||||||
|
public static Cue LicenseMessage = Cue.StringCue("LicenseMessage", 15991);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user