Removes essentials-framework as a submodule and brings the files back into the main repo

This commit is contained in:
Neil Dorin
2019-07-09 17:21:53 -06:00
parent 2cd68d40dc
commit 48c6bb78bc
362 changed files with 54624 additions and 5 deletions

View File

@@ -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; }
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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
{
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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; }
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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:");
}
}
}

View File

@@ -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
}

View File

@@ -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:");
}
}
}

View File

@@ -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:");
}
}
}

View File

@@ -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
{
}
}

View File

@@ -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; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
}
}

View File

@@ -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;
//}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
}
}

View File

@@ -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:");
// }
//}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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; }
}
}

View File

@@ -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
}
}