Pulling in 670 branch changes

This commit is contained in:
Heath Volmer
2018-02-08 12:35:08 -07:00
54 changed files with 58842 additions and 9907 deletions

View File

@@ -1,178 +1,198 @@
using System;
using Crestron.SimplSharp;
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 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
/// </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.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.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>
/// 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
{
// ****** All of these things, except for #Pro-specific com stuff, were
// moved into PepperDash.Core to help non-pro PortalSync.
//public eControlMethod Method { get; set; }
//public string ControlPortDevKey { get; set; }
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // In case "null" is present in config on this value
//public uint ControlPortNumber { get; set; }
//public TcpSshPropertiesConfig TcpSshProperties { get; set; }
//public string IrFile { get; set; }
//public ComPortConfig ComParams { get; set; }
[JsonConverter(typeof(ComSpecJsonConverter))]
public ComPort.ComPortSpec ComParams { get; set; }
//public string IpId { get; set; }
//[JsonIgnore]
//public uint IpIdInt { get { return Convert.ToUInt32(IpId, 16); } }
//public char EndOfLineChar { get; set; }
///// <summary>
///// Defaults to Environment.NewLine;
///// </summary>
//public string EndOfLineString { get; set; }
//public string DeviceReadyResponsePattern { get; set; }
//public EssentialsControlPropertiesConfig()
//{
// EndOfLineString = CrestronEnvironment.NewLine;
//}
}
public class IrControlSpec
{
public string PortDeviceKey { get; set; }
public uint PortNumber { get; set; }
public string File { get; set; }
}
//public enum eControlMethod
//{
// None = 0, Com, IpId, IR, Ssh, Tcpip, Telnet
//}
using System;
using Crestron.SimplSharp;
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 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
/// </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.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.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>
/// 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
{
// ****** All of these things, except for #Pro-specific com stuff, were
// moved into PepperDash.Core to help non-pro PortalSync.
//public eControlMethod Method { get; set; }
//public string ControlPortDevKey { get; set; }
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // In case "null" is present in config on this value
//public uint ControlPortNumber { get; set; }
//public TcpSshPropertiesConfig TcpSshProperties { get; set; }
//public string IrFile { get; set; }
//public ComPortConfig ComParams { get; set; }
[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 string IpId { get; set; }
//[JsonIgnore]
//public uint IpIdInt { get { return Convert.ToUInt32(IpId, 16); } }
//public char EndOfLineChar { get; set; }
///// <summary>
///// Defaults to Environment.NewLine;
///// </summary>
//public string EndOfLineString { get; set; }
//public string DeviceReadyResponsePattern { get; set; }
//public EssentialsControlPropertiesConfig()
//{
// EndOfLineString = CrestronEnvironment.NewLine;
//}
}
public class IrControlSpec
{
public string PortDeviceKey { get; set; }
public uint PortNumber { get; set; }
public string File { get; set; }
}
//public enum eControlMethod
//{
// None = 0, Com, IpId, IR, Ssh, Tcpip, Telnet
//}
}

View File

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

View File

@@ -10,6 +10,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
{
public string PortDeviceKey { get; set; }
public uint PortNumber { get; set; }
public bool DisablePullUpResistor { get; set; }
}
}

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </summary>
public class GenericVersiportInputDevice : Device, IDigitalInput
public class GenericVersiportDigitalInputDevice : Device, IDigitalInput
{
public Versiport InputPort { get; private set; }
@@ -26,28 +26,25 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
}
public GenericVersiportInputDevice(string key, Versiport inputPort):
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)
{
InputStateFeedback.FireUpdate();
Debug.Console(1, this, "Versiport change: {0}", args.Event);
if(args.Event == eVersiportEvent.DigitalInChange)
InputStateFeedback.FireUpdate();
}
}
public class GenericVersiportInputDeviceConfigProperties
{
}
}

View File

@@ -38,16 +38,16 @@ namespace PepperDash.Essentials.Core
/// </summary>
public override bool CustomActivate()
{
new CTimer(o =>
Debug.Console(0, this, "Activating");
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(1, this, "Activating");
var response = Hardware.RegisterWithLogging(Key);
if (response == eDeviceRegistrationUnRegistrationResponse.Success)
{
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
}
}, 0);
Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
return true;
}

View File

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

View File

@@ -56,8 +56,6 @@ namespace PepperDash.Essentials.Core
System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
object ret = method.Invoke(obj, convertedParams);
//Debug.Console(0, JsonConvert.SerializeObject(ret));
// return something?
}
/// <summary>

View File

@@ -29,10 +29,6 @@ namespace PepperDash.Essentials.Core
public static void Initialize(CrestronControlSystem cs)
{
//CrestronConsole.AddNewConsoleCommand(ListDeviceCommands, "devcmdlist", "Lists commands",
// ConsoleAccessLevelEnum.AccessOperator);
//CrestronConsole.AddNewConsoleCommand(DoDeviceCommand, "devcmd", "Runs a command on device - key Name value",
// ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
@@ -64,8 +60,15 @@ namespace PepperDash.Essentials.Core
{
foreach (var d in Devices.Values)
{
if (d is Device)
(d as Device).Activate();
try
{
if (d is Device)
(d as Device).Activate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device activation failure:\r{0}", e);
}
}
}

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

@@ -68,6 +68,8 @@ namespace PepperDash.Essentials.Core
public string VolumeControlKey { get; set; }
public eSourceListItemType Type { get; set; }
public List<SourceRouteListItem> RouteList { get; set; }
public bool DisableCodecSharing { get; set; }
public bool DisableRoutedSharing { get; set; }
public SourceListItem()
{

View File

@@ -19,6 +19,14 @@ namespace PepperDash.Essentials.Core
public abstract eCueType Type { get; }
/// <summary>
///
/// </summary>
public bool InTestMode { get; protected set; }
/// <summary>
/// Base Constructor - empty
/// </summary>
protected Feedback()
{
}
@@ -28,6 +36,15 @@ namespace PepperDash.Essentials.Core
Cue = cue;
}
/// <summary>
/// Clears test mode and fires update.
/// </summary>
public void ClearTestValue()
{
InTestMode = false;
FireUpdate();
}
/// <summary>
/// Fires an update synchronously
/// </summary>
@@ -60,11 +77,16 @@ namespace PepperDash.Essentials.Core
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; }
/// <summary>
/// The last value delivered on FireUpdate
/// </summary>
//public bool PreviousValue { get; private set; }
List<BoolInputSig> LinkedInputSigs = new List<BoolInputSig>();
List<BoolInputSig> LinkedComplementInputSigs = new List<BoolInputSig>();
@@ -82,7 +104,7 @@ namespace PepperDash.Essentials.Core
public override void FireUpdate()
{
var newValue = ValueFunc.Invoke();
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
if (newValue != _BoolValue)
{
_BoolValue = newValue;
@@ -116,9 +138,20 @@ namespace PepperDash.Essentials.Core
public override string ToString()
{
return BoolValue.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;
@@ -137,8 +170,12 @@ namespace PepperDash.Essentials.Core
int _IntValue;
public ushort UShortValue { get { return (ushort)_IntValue; } }
public override eCueType Type { get { return eCueType.Int; } }
//public int PreviousValue { get; private set; }
public int TestValue { get; private set; }
/// <summary>
/// Func evaluated on FireUpdate
/// </summary>
Func<int> ValueFunc;
List<UShortInputSig> LinkedInputSigs = new List<UShortInputSig>();
@@ -156,7 +193,7 @@ namespace PepperDash.Essentials.Core
public override void FireUpdate()
{
var newValue = ValueFunc.Invoke();
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
if (newValue != _IntValue)
{
_IntValue = newValue;
@@ -178,9 +215,20 @@ namespace PepperDash.Essentials.Core
public override string ToString()
{
return IntValue.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;
@@ -194,7 +242,15 @@ namespace PepperDash.Essentials.Core
public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } }
string _StringValue;
public override eCueType Type { get { return eCueType.String; } }
//public string PreviousValue { get; private set; }
/// <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>();
@@ -213,7 +269,7 @@ namespace PepperDash.Essentials.Core
public override void FireUpdate()
{
var newValue = ValueFunc.Invoke();
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
if (newValue != _StringValue)
{
_StringValue = newValue;
@@ -235,9 +291,20 @@ namespace PepperDash.Essentials.Core
public override string ToString()
{
return StringValue;
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;

View File

@@ -103,6 +103,7 @@
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
<Compile Include="Crestron IO\Inputs\GenericDigitalInputDevice.cs" />
<Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" />
<Compile Include="Crestron IO\Inputs\IDigitalInput.cs" />

View File

@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DM;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM.Chassis
{
public class HdMdNxM4kEController : Device, IRoutingInputsOutputs, IRouting
{
public HdMdNxM Chassis { get; private set; }
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="chassis"></param>
public HdMdNxM4kEController(string key, string name, HdMdNxM chassis,
HdMdNxM4kEPropertiesConfig props)
: base(key, name)
{
Chassis = chassis;
// logical ports
InputPorts = new RoutingPortCollection<RoutingInputPort>();
for (uint i = 1; i <= 4; i++)
{
InputPorts.Add(new RoutingInputPort("hdmiIn" + i, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, i, this));
}
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, null, this));
// physical settings
if (props != null && props.Inputs != null)
{
foreach (var kvp in props.Inputs)
{
// strip "hdmiIn"
var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
var port = chassis.HdmiInputs[inputNum].HdmiInputPort;
// set hdcp disables
if (kvp.Value.DisableHdcp)
{
Debug.Console(0, this, "Configuration disables HDCP support on {0}", kvp.Key);
port.HdcpSupportOff();
}
else
port.HdcpSupportOn();
}
}
}
public override bool CustomActivate()
{
var result = Chassis.Register();
if (result != Crestron.SimplSharpPro.eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(0, this, "Device registration failed: {0}", result);
return false;
}
return base.CustomActivate();
}
#region IRouting Members
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
Chassis.HdmiOutputs[1].VideoOut = Chassis.HdmiInputs[(uint)inputSelector];
}
#endregion
/////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="type"></param>
/// <param name="properties"></param>
/// <returns></returns>
public static HdMdNxM4kEController GetController(string key, string name,
string type, HdMdNxM4kEPropertiesConfig properties)
{
try
{
var ipid = properties.Control.IpIdInt;
var address = properties.Control.TcpSshProperties.Address;
type = type.ToLower();
if (type == "hdmd4x14ke")
{
var chassis = new HdMd4x14kE(ipid, address, Global.ControlSystem);
return new HdMdNxM4kEController(key, name, chassis, properties);
}
return null;
}
catch (Exception e)
{
Debug.Console(0, "ERROR Creating device key {0}: \r{1}", key, e);
return null;
}
}
}
}

View File

@@ -47,6 +47,13 @@ namespace PepperDash.Essentials.DM
return PepperDash.Essentials.DM.DmRmcHelper.GetDmRmcController(key, name, type, props);
}
else if (typeName.Equals("hdmd4x14ke"))
{
var props = JsonConvert.DeserializeObject
<PepperDash.Essentials.DM.Config.HdMdNxM4kEPropertiesConfig>(properties.ToString());
return PepperDash.Essentials.DM.Chassis.HdMdNxM4kEController.GetController(key, name, type, props);
}
return null;
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
namespace PepperDash.Essentials.DM.Config
{
/// <summary>
/// Defines the properties section of HdMdNxM boxes
/// </summary>
public class HdMdNxM4kEPropertiesConfig
{
[JsonProperty("control")]
public ControlPropertiesConfig Control { get; set; }
[JsonProperty("inputs")]
public Dictionary<string, InputPropertiesConfig> Inputs { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.DM.Config
{
public class InputPropertiesConfig
{
public string Name { get; set; }
public bool DisableHdcp { get; set; }
}
}

View File

@@ -91,9 +91,12 @@
<Compile Include="Cards REMOVE\DmInputCardBase.cs" />
<Compile Include="Chassis\DmCardAudioOutput.cs" />
<Compile Include="Chassis\DmChassisController.cs" />
<Compile Include="Chassis\HdMdNxM4kEController.cs" />
<Compile Include="Config\DmRmcConfig.cs" />
<Compile Include="Config\DmTxConfig.cs" />
<Compile Include="Config\DMChassisConfig.cs" />
<Compile Include="Config\HdMdNxM4kEPropertiesConfig.cs" />
<Compile Include="Config\InputPropertiesConfig.cs" />
<Compile Include="DmPortName.cs" />
<Compile Include="Endpoints\Receivers\DmRmc4KScalerCController.cs" />
<Compile Include="Endpoints\Receivers\DmRmcScalerCController.cs" />

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -13,9 +14,11 @@ using PepperDash.Essentials.Core.CrestronIO;
using PepperDash.Essentials.Devices.Common.DSP;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.Occupancy;
using PepperDash.Essentials.Devices.Common;
namespace PepperDash.Essentials.Devices.Common
{
public class DeviceFactory
@@ -26,6 +29,8 @@ namespace PepperDash.Essentials.Devices.Common
var name = dc.Name;
var type = dc.Type;
var properties = dc.Properties;
var propAnon = new {};
JsonConvert.DeserializeAnonymousType(dc.Properties.ToString(), propAnon);
var typeName = dc.Type.ToLower();
var groupName = dc.Group.ToLower();
@@ -117,46 +122,46 @@ namespace PepperDash.Essentials.Devices.Common
return new PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec(key, name, comm, props);
}
else if (typeName == "versiportinput")
{
var props = JsonConvert.DeserializeObject<IOPortConfig>(properties.ToString());
//else if (typeName == "versiportinput")
//{
// var props = JsonConvert.DeserializeObject<IOPortConfig>(properties.ToString());
IIOPorts portDevice;
// IIOPorts portDevice;
if (props.PortDeviceKey == "processor")
portDevice = Global.ControlSystem as IIOPorts;
else
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IIOPorts;
// if (props.PortDeviceKey == "processor")
// portDevice = Global.ControlSystem as IIOPorts;
// else
// portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IIOPorts;
if(portDevice == null)
Debug.Console(0, "Unable to add versiport device with key '{0}'. Port Device does not support versiports", key);
else
{
var cs = (portDevice as CrestronControlSystem);
// if(portDevice == null)
// Debug.Console(0, "Unable to add versiport device with key '{0}'. Port Device does not support versiports", key);
// else
// {
// var cs = (portDevice as CrestronControlSystem);
if (cs != null)
if (cs.SupportsVersiport && props.PortNumber <= cs.NumberOfVersiPorts)
{
Versiport versiport = cs.VersiPorts[props.PortNumber];
// if (cs != null)
// if (cs.SupportsVersiport && props.PortNumber <= cs.NumberOfVersiPorts)
// {
// Versiport versiport = cs.VersiPorts[props.PortNumber];
if(!versiport.Registered)
{
if (versiport.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
return new GenericVersiportInputDevice(key, versiport);
else
Debug.Console(0, "Attempt to register versiport {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
}
}
// if(!versiport.Registered)
// {
// if (versiport.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
// return new GenericVersiportInputDevice(key, versiport);
// else
// Debug.Console(0, "Attempt to register versiport {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
// }
// }
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
// // Future: Check if portDevice is 3-series card or other non control system that supports versiports
}
}
// }
//}
else if (typeName == "digitalinput")
{
var props = JsonConvert.DeserializeObject<IOPortConfig>(properties.ToString());
IDigitalInputPorts portDevice;
if (props.PortDeviceKey == "processor")
@@ -165,25 +170,70 @@ namespace PepperDash.Essentials.Devices.Common
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IDigitalInputPorts;
if (portDevice == null)
Debug.Console(0, "Unable to add digital input device with key '{0}'. Port Device does not support digital inputs", key);
Debug.Console(0, "ERROR: Unable to add digital input device with key '{0}'. Port Device does not support digital inputs", key);
else
{
var cs = (portDevice as CrestronControlSystem);
if (cs == null)
{
Debug.Console(0, "ERROR: Port device for [{0}] is not control system", props.PortDeviceKey);
return null;
}
if (cs != null)
if (cs.SupportsDigitalInput && props.PortNumber <= cs.NumberOfDigitalInputPorts)
if (cs.SupportsVersiport)
{
Debug.Console(1, "Attempting to add Digital Input device to Versiport port '{0}'", props.PortNumber);
if (props.PortNumber > cs.NumberOfVersiPorts)
{
Debug.Console(0, "WARNING: Cannot add Vesiport {0} on {1}. Out of range",
props.PortNumber, props.PortDeviceKey);
return null;
}
Versiport vp = cs.VersiPorts[props.PortNumber];
if (!vp.Registered)
{
var regSuccess = vp.Register();
if (regSuccess == eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(1, "Successfully Created Digital Input Device on Versiport");
return new GenericVersiportDigitalInputDevice(key, vp, props);
}
else
{
Debug.Console(0, "WARNING: Attempt to register versiport {0} on device with key '{1}' failed: {2}",
props.PortNumber, props.PortDeviceKey, regSuccess);
return null;
}
}
}
else if (cs.SupportsDigitalInput)
{
Debug.Console(1, "Attempting to add Digital Input device to Digital Input port '{0}'", props.PortNumber);
if (props.PortNumber > cs.NumberOfDigitalInputPorts)
{
Debug.Console(0, "WARNING: Cannot register DIO port {0} on {1}. Out of range",
props.PortNumber, props.PortDeviceKey);
return null;
}
DigitalInput digitalInput = cs.DigitalInputPorts[props.PortNumber];
if (!digitalInput.Registered)
{
if(digitalInput.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
if (digitalInput.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(1, "Successfully Created Digital Input Device on Digital Input");
return new GenericDigitalInputDevice(key, digitalInput);
}
else
Debug.Console(0, "Attempt to register digital input {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
Debug.Console(0, "WARNING: Attempt to register digital input {0} on device with key '{1}' failed.",
props.PortNumber, props.PortDeviceKey);
}
}
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
}
}
@@ -204,14 +254,14 @@ namespace PepperDash.Essentials.Devices.Common
{
var cs = (portDevice as CrestronControlSystem);
if(cs != null)
if (cs != null)
if (cs.SupportsRelay && props.PortNumber <= cs.NumberOfRelayPorts)
{
Relay relay = cs.RelayPorts[props.PortNumber];
if (!relay.Registered)
{
if(relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
return new GenericRelayDevice(key, relay);
else
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
@@ -248,6 +298,34 @@ namespace PepperDash.Essentials.Devices.Common
return new Roku2(key, name, irCont);
}
else if (typeName == "glsoirccn")
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
GlsOccupancySensorBase occSensor = null;
occSensor = new GlsOirCCn(comm.CresnetIdInt, Global.ControlSystem);
if (occSensor != null)
return new EssentialsGlsOccupancySensorBaseController(key, name, occSensor);
else
Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key);
}
else if (typeName == "glsodtccn")
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
GlsOccupancySensorBase occSensor = null;
occSensor = new GlsOdtCCn(comm.CresnetIdInt, Global.ControlSystem);
if (occSensor != null)
return new EssentialsGlsOccupancySensorBaseController(key, name, occSensor);
else
Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key);
}
return null;
}
}

View File

@@ -103,6 +103,7 @@ namespace PepperDash.Essentials.Devices.Common.Microphones
void PrivacyModeIsOnFeedback_OutputChange(object sender, EventArgs e)
{
Debug.Console(1, this, "Privacy mode change: {0}", sender as BoolFeedback);
CheckPrivacyMode();
}
@@ -160,7 +161,7 @@ namespace PepperDash.Essentials.Devices.Common.Microphones
/// <summary>
/// Toggles the state of the privacy mute
/// </summary>
void TogglePrivacyMute()
public void TogglePrivacyMute()
{
PrivacyDevice.PrivacyModeToggle();
}

View File

@@ -5,6 +5,7 @@ using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Occupancy
@@ -15,15 +16,50 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
public EssentialsGlsOccupancySensorBaseController(string key, string name, GlsOccupancySensorBase sensor, GlsOccupancySensorConfigurationProperties props)
// Debug properties
public bool InTestMode { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
}
}
public EssentialsGlsOccupancySensorBaseController(string key, string name, GlsOccupancySensorBase sensor)
: base(key, name, sensor)
{
OccSensor = sensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
OccSensor.GlsOccupancySensorChange += new GlsOccupancySensorChangeEventHandler(sensor_GlsOccupancySensorChange);
}
void sensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
RoomIsOccupiedFeedback.FireUpdate();
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
}
public class GlsOccupancySensorConfigurationProperties
{
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Occupancy
{
public class EssentialsGlsOccupancySensorBaseController : CrestronGenericBaseDevice, IOccupancyStatusProvider
{
public GlsOccupancySensorBase OccSensor { get; private set; }
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
<<<<<<< HEAD
/// <summary>
/// Set by debugging functions
/// </summary>
public bool InMockMode { get; private set; }
public bool MockRoomIsOccupiedFeedback { get; private set; }
=======
// Debug properties
public bool InTestMode { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
>>>>>>> origin/feature/ecs-342-neil
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
<<<<<<< HEAD
return () => InMockMode ? MockRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
=======
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
>>>>>>> origin/feature/ecs-342-neil
}
}
public EssentialsGlsOccupancySensorBaseController(string key, string name, GlsOccupancySensorBase sensor, GlsOccupancySensorConfigurationProperties props)
: base(key, name, sensor)
{
OccSensor = sensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
OccSensor.GlsOccupancySensorChange += new GlsOccupancySensorChangeEventHandler(sensor_GlsOccupancySensorChange);
}
void sensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
RoomIsOccupiedFeedback.FireUpdate();
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
}
/// <summary>
///
/// </summary>
public class GlsOccupancySensorConfigurationProperties
{
public string CresnetId { get; set; }
public string Model { get; set; }
}
}

View File

@@ -8,7 +8,7 @@ using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common
{
public class SetTopBoxPropertiesConfig
public class SetTopBoxPropertiesConfig : PepperDash.Essentials.Core.Config.SourceDevicePropertiesConfigBase
{
public bool HasPresets { get; set; }
public bool HasDvr { get; set; }

View File

@@ -18,7 +18,7 @@ namespace PepperDash.Essentials
public static bool LoadConfig2()
{
Debug.Console(0, "Using unmerged system/template configs.");
Debug.Console(0, "Loading unmerged system/template portal configuration file.");
try
{
var filePath = string.Format(@"\NVRAM\program{0}\ConfigurationFile.json",
@@ -35,7 +35,7 @@ namespace PepperDash.Essentials
var doubleObj = JObject.Parse(fs.ReadToEnd());
ConfigObject = MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
// Extract SystemUrl and TemplateUrl
// Extract SystemUrl and TemplateUrl into final config output
if (doubleObj["system_url"] != null)
{
@@ -83,7 +83,7 @@ namespace PepperDash.Essentials
else
merged.Add("sourceLists", Merge(template["sourceLists"], system["sourceLists"]));
// Template tie lines take precdence. Config tool probably can't do them at system
// Template tie lines take precdence. Config tool doesn't do them at system
// level anyway...
if (template["tieLines"] != null)
merged.Add("tieLines", template["tieLines"]);
@@ -92,7 +92,7 @@ namespace PepperDash.Essentials
else
merged.Add("tieLines", new JArray());
//Debug.Console(0, "MERGED RESULT: \x0d\x0a{0}", merged);
Debug.Console(2, "MERGED CONFIG RESULT: \x0d\x0a{0}", merged);
return merged;
}
@@ -141,7 +141,6 @@ namespace PepperDash.Essentials
/// <param name="b"></param>
static JObject Merge(JObject o1, JObject o2)
{
//Console.WriteLine("Merging {0}\ronto {1}", o2, o1);
foreach (var o2Prop in o2)
{
var o1Value = o1[o2Prop.Key];
@@ -160,6 +159,11 @@ namespace PepperDash.Essentials
return o1;
}
/// <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));

View File

@@ -69,10 +69,24 @@ namespace PepperDash.Essentials
return new CotijaSystemController(key, name, props);
}
else if (typeName == "cotijaddvc01room")
else if (typeName == "cotijaddvc01roombridge")
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
return new PepperDash.Essentials.Room.Cotija.CotijaDdvc01RoomBridge(key, name, comm.IpIdInt);
var bridge = new PepperDash.Essentials.Room.Cotija.CotijaDdvc01RoomBridge(key, name, comm.IpIdInt);
bridge.AddPreActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "cotijaServer") as CotijaSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.CotijaRooms.Add(bridge);
});
return bridge;
}
return null;

View File

@@ -22,7 +22,7 @@ namespace PepperDash.Essentials
[JsonProperty("template_url")]
public string TemplateUrl { get; set; }
public CotijaConfig Cotija { get; private set; }
//public CotijaConfig Cotija { get; private set; }
public string SystemUuid
{
@@ -49,7 +49,7 @@ namespace PepperDash.Essentials
}
[JsonProperty("rooms")]
public List<EssentialsRoomConfig> Rooms { get; private set; }
public List<EssentialsRoomConfig> Rooms { get; set; }
}
/// <summary>
@@ -60,7 +60,5 @@ namespace PepperDash.Essentials
public EssentialsConfig System { get; set; }
public EssentialsConfig Template { get; set; }
//public CotijaConfig Cotija { get; set; }
}
}

View File

@@ -10,6 +10,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Cotija;
namespace PepperDash.Essentials
{
@@ -42,6 +43,21 @@ namespace PepperDash.Essentials
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse
("Current running configuration. This is the merged system and template configuration");
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
GoWithLoad();
}
@@ -67,8 +83,6 @@ namespace PepperDash.Essentials
return;
Load();
DeviceManager.ActivateAll();
Debug.Console(0, "Essentials load complete\r" +
"-------------------------------------------------------------");
}
@@ -147,6 +161,8 @@ namespace PepperDash.Essentials
LoadTieLines();
LoadRooms();
LoadLogoServer();
DeviceManager.ActivateAll();
}
@@ -157,28 +173,35 @@ namespace PepperDash.Essentials
{
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
Debug.Console(0, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
try
{
Debug.Console(0, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, "WARNING: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
}
/// <summary>
@@ -204,6 +227,12 @@ namespace PepperDash.Essentials
/// </summary>
public void LoadRooms()
{
if (ConfigReader.ConfigObject.Rooms == null)
{
Debug.Console(0, "WARNING: Configuration contains no rooms");
return;
}
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = roomConfig.GetRoomObject();
@@ -216,12 +245,9 @@ namespace PepperDash.Essentials
Debug.Console(1, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
var cotija = DeviceManager.GetDeviceForKey("cotijaServer") as CotijaSystemController;
if (cotija != null)
{
cotija.CotijaRooms.Add(new CotijaEssentialsHuddleSpaceRoomBridge(cotija, room as EssentialsHuddleSpaceRoom));
}
Debug.Console(0, "******* RE-ENABLE COTIJA PROPERLY *******");
//var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
//AddBridgePostActivationHelper(bridge);
}
else if (room is EssentialsHuddleVtc1Room)
{
@@ -229,7 +255,7 @@ namespace PepperDash.Essentials
Debug.Console(1, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
}
}
else
{
Debug.Console(1, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion");
@@ -242,12 +268,30 @@ namespace PepperDash.Essentials
}
}
/// <summary>
/// Helps add the post activation steps that link bridges to main controller
/// </summary>
/// <param name="bridge"></param>
void AddBridgePostActivationHelper(CotijaBridgeBase bridge)
{
bridge.AddPostActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "cotijaServer") as CotijaSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.CotijaRooms.Add(bridge);
});
}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
try
{
LogoServer = new HttpLogoServer(8080, @"\html\logo");

View File

@@ -0,0 +1,276 @@
using System;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using PepperDash.Core;
using PepperDash.Core.PortalSync;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
namespace PepperDash.Essentials
{
public class ControlSystem : CrestronControlSystem
{
PepperDashPortalSyncClient PortalSync;
HttpLogoServer LogoServer;
public ControlSystem()
: base()
{
Thread.MaxNumberOfUserThreads = 400;
Global.ControlSystem = this;
DeviceManager.Initialize(this);
}
/// <summary>
/// Git 'er goin'
/// </summary>
public override void InitializeSystem()
{
//CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Reloads configuration file",
//ConsoleAccessLevelEnum.AccessOperator);
//CrestronConsole.AddNewConsoleCommand(s => TearDown(), "ungo", "Unloads configuration file",
// ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
GoWithLoad();
}
/// <summary>
/// Do it, yo
/// </summary>
public void GoWithLoad()
{
try
{
CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync",
ConsoleAccessLevelEnum.AccessOperator);
//PortalSync = new PepperDashPortalSyncClient();
Debug.Console(0, "Starting Essentials load from configuration");
var filesReady = SetupFilesystem();
if (filesReady)
{
Debug.Console(0, "Folder structure verified. Loading config...");
if (!ConfigReader.LoadConfig2())
return;
Load();
<<<<<<< HEAD
=======
>>>>>>> origin/feature/ecs-342-neil
Debug.Console(0, "Essentials load complete\r" +
"-------------------------------------------------------------");
}
else
{
Debug.Console(0,
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"Essentials file structure setup completed.\r" +
"Please load config, sgd and ir files and\r" +
"restart program.\r" +
"------------------------------------------------\r" +
"------------------------------------------------\r" +
"------------------------------------------------");
}
}
catch (Exception e)
{
Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e);
}
}
/// <summary>
/// Verifies filesystem is set up. IR, SGD, and program1 folders
/// </summary>
bool SetupFilesystem()
{
Debug.Console(0, "Verifying and/or creating folder structure");
var appNum = InitialParametersClass.ApplicationNumber;
var configDir = @"\NVRAM\Program" + appNum;
var configExists = Directory.Exists(configDir);
if (!configExists)
Directory.Create(configDir);
var irDir = string.Format(@"\NVRAM\Program{0}\ir", appNum);
if (!Directory.Exists(irDir))
Directory.Create(irDir);
var sgdDir = string.Format(@"\NVRAM\Program{0}\sgd", appNum);
if (!Directory.Exists(sgdDir))
Directory.Create(sgdDir);
return configExists;
}
public void EnablePortalSync(string s)
{
if (s.ToLower() == "enable")
{
CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled");
PortalSync = new PepperDashPortalSyncClient();
}
}
public void TearDown()
{
Debug.Console(0, "Tearing down existing system");
DeviceManager.DeactivateAll();
TieLineCollection.Default.Clear();
foreach (var key in DeviceManager.GetDevices())
DeviceManager.RemoveDevice(key);
Debug.Console(0, "Tear down COMPLETE");
}
/// <summary>
///
/// </summary>
void Load()
{
LoadDevices();
LoadTieLines();
LoadRooms();
LoadLogoServer();
<<<<<<< HEAD
DeviceManager.ActivateAll();
=======
DeviceManager.ActivateAll();
>>>>>>> origin/feature/ecs-342-neil
}
/// <summary>
/// Reads all devices from config and adds them to DeviceManager
/// </summary>
public void LoadDevices()
{
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
try
{
Debug.Console(0, "Creating device '{0}'", devConf.Key);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
continue;
// Try local factory first
var newDev = DeviceFactory.GetDevice(devConf);
// Then associated library factories
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf);
if (newDev == null)
newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
}
/// <summary>
/// Helper method to load tie lines. This should run after devices have loaded
/// </summary>
public void LoadTieLines()
{
// In the future, we can't necessarily just clear here because devices
// might be making their own internal sources/tie lines
var tlc = TieLineCollection.Default;
//tlc.Clear();
foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines)
{
var newTL = tieLineConfig.GetTieLine();
if (newTL != null)
tlc.Add(newTL);
}
}
/// <summary>
/// Reads all rooms from config and adds them to DeviceManager
/// </summary>
public void LoadRooms()
{
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = roomConfig.GetRoomObject();
if (room != null)
{
if (room is EssentialsHuddleSpaceRoom)
{
DeviceManager.AddDevice(room);
Debug.Console(1, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
var cotija = DeviceManager.GetDeviceForKey("cotijaServer") as CotijaSystemController;
if (cotija != null)
{
cotija.CotijaRooms.Add(new CotijaEssentialsHuddleSpaceRoomBridge(cotija, room as EssentialsHuddleSpaceRoom));
}
}
else if (room is EssentialsHuddleVtc1Room)
{
DeviceManager.AddDevice(room);
Debug.Console(1, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
}
else
{
Debug.Console(1, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
}
else
Debug.Console(0, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);
}
}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
try
{
LogoServer = new HttpLogoServer(8080, @"\html\logo");
}
catch (Exception)
{
Debug.Console(0, "NOTICE: Logo server cannot be started. Likely already running in another program");
}
}
}
}

View File

@@ -1208,14 +1208,23 @@ namespace PepperDash.Essentials.Fusion
{
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
FusionRoom.FusionAssetStateChange += new FusionAssetStateEventHandler(FusionRoom_FusionAssetStateChange);
// Build Occupancy Asset?
// Link sigs?
Room.SetRoomOccupancy(this);
//Room.SetRoomOccupancy(this as IOccupancyStatusProvider, 0);
}
void FusionRoom_FusionAssetStateChange(FusionBase device, FusionAssetStateEventArgs args)
{
if (args.EventId == FusionAssetEventId.RoomOccupiedReceivedEventId || args.EventId == FusionAssetEventId.RoomUnoccupiedReceivedEventId)
RoomIsOccupiedFeedback.FireUpdate();
}
/// <summary>
/// Sets up remote occupancy that will relay the occupancy status determined by local system devices to Fusion
/// </summary>

View File

@@ -75,9 +75,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\pepperdash-portal-sync\SspPortalSync\SspPortalSync\bin\PepperDashCorePortalSync.dll</HintPath>
</Reference>
<Reference Include="PepperDash_Core, Version=1.0.1.20241, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="PepperDash_Core, Version=1.0.3.27452, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\pepperdash-simplsharp-core\Pepperdash Core\CLZ Builds\PepperDash_Core.dll</HintPath>
<HintPath>..\..\Release Package\PepperDash_Core.dll</HintPath>
</Reference>
<Reference Include="PepperDash_Essentials_DM, Version=1.0.0.19343, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -134,11 +134,14 @@
<Compile Include="OTHER\Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="HttpApiHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Room\Config\DDVC01RoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
<Compile Include="Room\Cotija\CotijaConfig.cs" />
<Compile Include="Room\Cotija\Interfaces.cs" />
<Compile Include="Room\Cotija\RoomBridges\CotijaBridgeBase.cs" />
<Compile Include="Room\Cotija\RoomBridges\CotijaDdvc01RoomBridge.cs" />
<Compile Include="Room\Cotija\RoomBridges\CotijaEssentialsHuddleSpaceRoomBridge.cs" />
<Compile Include="Room\Cotija\DeviceTypeInterfaces\IChannelExtensions.cs" />
@@ -193,6 +196,9 @@
<Compile Include="UI\SubpageReferenceListSourceItem.cs" />
<None Include="app.config" />
<None Include="Properties\ControlSystem.cfg" />
<EmbeddedResource Include="SGD\PepperDash Essentials iPad.sgd" />
<EmbeddedResource Include="SGD\PepperDash Essentials TSW-560.sgd" />
<EmbeddedResource Include="SGD\PepperDash Essentials TSW-760.sgd" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Essentials Core\PepperDashEssentialsBase\PepperDash_Essentials_Core.csproj">

View File

@@ -4,5 +4,5 @@
[assembly: AssemblyCompany("PepperDash Technology Corp")]
[assembly: AssemblyProduct("PepperDashEssentials")]
[assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2017")]
[assembly: AssemblyVersion("1.0.17.*")]
[assembly: AssemblyVersion("1.0.36.*")]

View File

@@ -5,8 +5,8 @@
[assembly: AssemblyProduct("PepperDashEssentials")]
[assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2017")]
<<<<<<< HEAD
[assembly: AssemblyVersion("1.0.8.*")]
[assembly: AssemblyVersion("1.0.31.*")]
=======
[assembly: AssemblyVersion("1.0.10.*")]
>>>>>>> development
[assembly: AssemblyVersion("1.0.33.*")]
>>>>>>> origin/feature/ecs-342-neil

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Room.Config
{
public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
{
public string RoomPhoneNumber { get; set; }
public string RoomURI { get; set; }
public List<DDVC01SpeedDial> SpeedDials { get; set; }
public List<string> VolumeSliderNames { get; set; }
}
public class DDVC01SpeedDial
{
public string Name { get; set; }
public string Number { get; set; }
}
}

View File

@@ -29,6 +29,10 @@ namespace PepperDash.Essentials.Room.Config
var disp = DeviceManager.GetDeviceForKey(props.DefaultDisplayKey) as IRoutingSinkWithSwitching;
var audio = DeviceManager.GetDeviceForKey(props.DefaultAudioKey) as IRoutingSinkNoSwitching;
var huddle = new EssentialsHuddleSpaceRoom(Key, Name, disp, audio, props);
if (props.Occupancy != null)
huddle.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, props.Occupancy.TimoutMinutes);
huddle.LogoUrl = props.Logo.GetUrl();
huddle.SourceListKey = props.SourceListKey;
huddle.DefaultSourceItem = props.DefaultSourceItem;
@@ -67,7 +71,8 @@ namespace PepperDash.Essentials.Room.Config
// Add Occupancy object from config
if (props.Occupancy != null)
rm.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider);
rm.SetRoomOccupancy(DeviceManager.GetDeviceForKey(props.Occupancy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Occupancy.IOccupancyStatusProvider, props.Occupancy.TimoutMinutes);
rm.LogoUrl = props.Logo.GetUrl();
rm.SourceListKey = props.SourceListKey;
rm.DefaultSourceItem = props.DefaultSourceItem;
@@ -79,6 +84,10 @@ namespace PepperDash.Essentials.Room.Config
return rm;
}
else if (typeName == "ddvc01Bridge")
{
return new Device(Key, Name); // placeholder device that does nothing.
}
return null;
}
@@ -100,57 +109,69 @@ namespace PepperDash.Essentials.Room.Config
return null;
}
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController GetMicrophonePrivacy(EssentialsRoomPropertiesConfig props, EssentialsHuddleVtc1Room room)
{
var microphonePrivacy = props.MicrophonePrivacy;
if (microphonePrivacy != null)
{
// Get the MicrophonePrivacy device from the device manager
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController);
// Set this room as the IPrivacy device
if (mP != null)
{
mP.SetPrivacyDevice(room);
/// <summary>
///
/// </summary>
/// <param name="props"></param>
/// <param name="room"></param>
/// <returns></returns>
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController GetMicrophonePrivacy(
EssentialsRoomPropertiesConfig props, EssentialsHuddleVtc1Room room)
{
var microphonePrivacy = props.MicrophonePrivacy;
if (microphonePrivacy == null)
{
Debug.Console(0, "ERROR: Cannot create microphone privacy with null properties");
return null;
}
// Get the MicrophonePrivacy device from the device manager
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as
PepperDash.Essentials.Devices.Common.Microphones.MicrophonePrivacyController);
// Set this room as the IPrivacy device
if (mP == null)
{
Debug.Console(0, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
return null;
}
mP.SetPrivacyDevice(room);
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
if (behaviour != null)
{
if (behaviour == "trackroomstate")
{
// Tie LED enable to room power state
room.OnFeedback.OutputChange += (o, a) =>
{
if (room.OnFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
if (behaviour == null)
{
Debug.Console(0, "WARNING: No behaviour defined for MicrophonePrivacyController");
return null;
}
if (behaviour == "trackroomstate")
{
// Tie LED enable to room power state
room.OnFeedback.OutputChange += (o, a) =>
{
if (room.OnFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
mP.EnableLeds = room.OnFeedback.BoolValue;
}
else if (behaviour == "trackcallstate")
{
// Tie LED enable to room power state
room.InCallFeedback.OutputChange += (o, a) =>
{
if (room.InCallFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
mP.EnableLeds = room.OnFeedback.BoolValue;
}
else if (behaviour == "trackcallstate")
{
// Tie LED enable to room power state
room.InCallFeedback.OutputChange += (o, a) =>
{
if (room.InCallFeedback.BoolValue)
mP.EnableLeds = true;
else
mP.EnableLeds = false;
};
mP.EnableLeds = room.InCallFeedback.BoolValue;
}
}
else
Debug.Console(0, "No behaviour defined for MicrophonePrivacyController");
mP.EnableLeds = room.InCallFeedback.BoolValue;
}
return mP;
}
}
return null;
}
return mP;
}
}
/// <summary>
@@ -171,6 +192,7 @@ namespace PepperDash.Essentials.Room.Config
public EssentialsLogoPropertiesConfig Logo { get; set; }
public EssentialsRoomTechConfig Tech { get; set; }
public EssentialsRoomVolumesConfig Volumes { get; set; }
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
}
public class EssentialsRoomMicrophonePrivacyConfig
@@ -239,6 +261,7 @@ namespace PepperDash.Essentials.Room.Config
public class EssentialsRoomOccSensorConfig
{
public string DeviceKey { get; set; }
public int TimoutMinutes { get; set; }
}
public class EssentialsRoomTechConfig

View File

@@ -19,7 +19,7 @@ namespace PepperDash.Essentials
{
GenericHttpSseClient SseClient;
CCriticalSection FileLock;
//CCriticalSection FileLock;
/// <summary>
/// Prevents post operations from stomping on each other and getting lost
@@ -44,7 +44,7 @@ namespace PepperDash.Essentials
string SystemUuid;
public List<CotijaEssentialsHuddleSpaceRoomBridge> CotijaRooms { get; private set; }
public List<CotijaBridgeBase> CotijaRooms { get; private set; }
long ButtonHeartbeatInterval = 1000;
@@ -60,7 +60,7 @@ namespace PepperDash.Essentials
Config = config;
Debug.Console(0, this, "Mobile UI controller initializing for server:{0}", config.ServerUrl);
CotijaRooms = new List<CotijaEssentialsHuddleSpaceRoomBridge>();
CotijaRooms = new List<CotijaBridgeBase>();
//CrestronConsole.AddNewConsoleCommand(s => RegisterSystemToServer(),
// "CotiInitializeHttpClient", "Initializes a new HTTP client connection to a specified URL", ConsoleAccessLevelEnum.AccessOperator);
@@ -153,34 +153,37 @@ namespace PepperDash.Essentials
/// <param name="url">URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port"</param>
void RegisterSystemToServer()
{
#warning THIS SHOULD NOT GO until the config is ready - in cases of config populated from elsewhere (DDVC)
try
{
string filePath = string.Format(@"\NVRAM\Program{0}\configurationFile.json", Global.ControlSystem.ProgramNumber);
string postBody = null;
var confObject = ConfigReader.ConfigObject;
string postBody = JsonConvert.SerializeObject(confObject);
SystemUuid = confObject.SystemUuid;
if (string.IsNullOrEmpty(filePath))
{
Debug.Console(0, this, "Error reading file. No path specified.");
return;
}
//if (string.IsNullOrEmpty(filePath))
//{
// Debug.Console(0, this, "Error reading file. No path specified.");
// return;
//}
FileLock = new CCriticalSection();
#warning NEIL I think we need to review this usage. Don't think it ever blocks
// FileLock = new CCriticalSection();
//#warning NEIL I think we need to review this usage. Don't think it ever blocks
if (FileLock.TryEnter())
{
Debug.Console(1, this, "Reading configuration file to extract system UUID...");
// if (FileLock.TryEnter())
// {
// Debug.Console(1, this, "Reading configuration file to extract system UUID...");
postBody = File.ReadToEnd(filePath, Encoding.ASCII);
// postBody = File.ReadToEnd(filePath, Encoding.ASCII);
Debug.Console(2, this, "{0}", postBody);
// Debug.Console(2, this, "{0}", postBody);
FileLock.Leave();
}
// FileLock.Leave();
// }
if (string.IsNullOrEmpty(postBody))
{
Debug.Console(1, "Post Body is null or empty");
Debug.Console(1, this, "ERROR: Config post body is empty. Cannot register with server.");
}
else
{
@@ -188,11 +191,9 @@ namespace PepperDash.Essentials
Client = new HttpClient();
Client.Verbose = true;
Client.KeepAlive = true;
SystemUuid = Essentials.ConfigReader.ConfigObject.SystemUuid;
string url = string.Format("http://{0}/api/system/join/{1}", Config.ServerUrl, SystemUuid);
Debug.Console(1, this, "Sending config to {0}", url);
string url = string.Format("http://{0}/api/system/join/{1}", Config.ServerUrl, SystemUuid);
Debug.Console(1, this, "Joining server at {0}", url);
HttpClientRequest request = new HttpClientRequest();
request.Url.Parse(url);
@@ -200,13 +201,13 @@ namespace PepperDash.Essentials
request.Header.SetHeaderValue("Content-Type", "application/json");
request.ContentString = postBody;
Client.DispatchAsync(request, PostConnectionCallback);
var err = Client.DispatchAsync(request, PostConnectionCallback);
}
}
catch (Exception e)
{
Debug.Console(0, this, "Error Initilizing Room: {0}", e);
Debug.Console(0, this, "ERROR: Initilizing Room: {0}", e);
}
}
@@ -316,6 +317,7 @@ namespace PepperDash.Essentials
/// <param name="err"></param>
void PostConnectionCallback(HttpClientResponse resp, HTTP_CALLBACK_ERROR err)
{
Debug.Console(1, this, "PostConnectionCallback err: {0}", err);
try
{
if (resp != null && resp.Code == 200)
@@ -326,11 +328,7 @@ namespace PepperDash.Essentials
ServerReconnectTimer = null;
}
#warning The SSE Client from a previous session might need to be killed...
//if (SseClient == null)
//{
ConnectSseClient(null);
//}
ConnectSseClient(null);
}
else
{

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Room.Cotija
{
public interface IDelayedConfiguration
{
event EventHandler<EventArgs> ConfigurationIsReady;
}
}

View File

@@ -0,0 +1,33 @@
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
{
/// <summary>
///
/// </summary>
public abstract class CotijaBridgeBase: Device
{
public CotijaSystemController Parent { get; private set; }
public CotijaBridgeBase(string key, string name)
: base(key, name)
{
}
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
public void AddParent(CotijaSystemController parent)
{
Parent = parent;
}
}
}

View File

@@ -10,10 +10,13 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials.Room.Cotija
{
public class CotijaDdvc01RoomBridge : Device
public class CotijaDdvc01RoomBridge : CotijaBridgeBase, IDelayedConfiguration
{
public class BoolJoin
{
@@ -108,17 +111,28 @@ namespace PepperDash.Essentials.Room.Cotija
public const uint ConfigRoomURI = 505;
}
/// <summary>
/// Fires when the config is ready, to be used by the controller class to forward config to server
/// </summary>
public event EventHandler<EventArgs> ConfigurationIsReady;
public ThreeSeriesTcpIpEthernetIntersystemCommunications EISC { get; private set; }
CotijaSystemController Parent;
/// <summary>
///
/// </summary>
public bool ConfigIsLoaded { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ipId"></param>
public CotijaDdvc01RoomBridge(string key, string name, uint ipId)
: base(key, name)
{
Key = key;
try
{
EISC = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipId, "127.0.0.2", Global.ControlSystem);
@@ -133,22 +147,23 @@ namespace PepperDash.Essentials.Room.Cotija
}
/// <summary>
/// Finish wiring up everything after all devices are created
/// Finish wiring up everything after all devices are created. The base class will hunt down the related
/// parent controller and link them up.
/// </summary>
/// <returns></returns>
public override bool CustomActivate()
{
Parent = DeviceManager.AllDevices.FirstOrDefault(d => d is CotijaSystemController) as CotijaSystemController;
if (Parent == null)
{
Debug.Console(0, this, "ERROR: Cannot build CotijaDdvc01RoomBridge. System controller not present");
return false;
}
SetupFunctions();
SetupFeedbacks();
EISC.SigChange += EISC_SigChange;
EISC.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
LoadConfigValues();
};
// load config if it's already there
if (EISC.IsOnline) // || EISC.BooleanInput[BoolJoin.ConfigIsReady].BoolValue)
LoadConfigValues();
return base.CustomActivate();
}
@@ -234,8 +249,6 @@ namespace PepperDash.Essentials.Room.Cotija
// Config things
EISC.SetSigTrueAction(BoolJoin.ConfigIsReady, LoadConfigValues);
}
/// <summary>
@@ -243,7 +256,89 @@ namespace PepperDash.Essentials.Room.Cotija
/// </summary>
void LoadConfigValues()
{
Debug.Console(1, this, "Loading configuration from DDVC01 EISC bridge");
ConfigIsLoaded = false;
var co = ConfigReader.ConfigObject;
//Room
if (co.Rooms == null)
co.Rooms = new List<EssentialsRoomConfig>();
if (co.Rooms.Count == 0)
co.Rooms.Add(new EssentialsRoomConfig());
var rm = co.Rooms[0];
rm.Name = EISC.StringInput[501].StringValue;
rm.Key = "room1";
rm.Type = "ddvc01";
DDVC01RoomPropertiesConfig rmProps;
if (rm.Properties == null)
rmProps = new DDVC01RoomPropertiesConfig();
else
rmProps = JsonConvert.DeserializeObject<DDVC01RoomPropertiesConfig>(rm.Properties.ToString());
rmProps.Help = new EssentialsHelpPropertiesConfig();
rmProps.Help.Message = EISC.StringInput[502].StringValue;
rmProps.Help.CallButtonText = EISC.StringInput[503].StringValue;
rmProps.RoomPhoneNumber = EISC.StringInput[504].StringValue;
rmProps.RoomURI = EISC.StringInput[505].StringValue;
rmProps.SpeedDials = new List<DDVC01SpeedDial>();
// add speed dials as long as there are more - up to 4
for (uint i = 512; i <= 519; i = i + 2)
{
var num = EISC.StringInput[i].StringValue;
if (string.IsNullOrEmpty(num))
break;
var name = EISC.StringInput[i + 1].StringValue;
rmProps.SpeedDials.Add(new DDVC01SpeedDial { Number = num, Name = name});
}
// volume control names
var volCount = EISC.UShortInput[701].UShortValue;
rmProps.VolumeSliderNames = new List<string>();
for(uint i = 701; i <= 700 + volCount; i++)
{
rmProps.VolumeSliderNames.Add(EISC.StringInput[i].StringValue);
}
// There should be cotija devices in here, I think...
if(co.Devices == null)
co.Devices = new List<DeviceConfig>();
// Source list! This might be brutal!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
rmProps.SourceListKey = "default";
co.SourceLists = new Dictionary<string,Dictionary<string,SourceListItem>>();
var newSl = new Dictionary<string, SourceListItem>();
// add sources...
for (uint i = 0; i<= 19; i++)
{
var name = EISC.StringInput[601 + i].StringValue;
if(string.IsNullOrEmpty(name))
break;
var icon = EISC.StringInput[651 + i].StringValue;
var key = EISC.StringInput[671 + i].StringValue;
var type = EISC.StringInput[701 + i].StringValue;
var newSLI = new SourceListItem{
Icon = icon,
Name = name,
Order = (int)i + 1,
SourceKey = key,
};
// add dev to devices list
var devConf = new DeviceConfig {
Group = "ddvc01",
Key = key,
Name = name,
Type = type
};
co.Devices.Add(devConf);
}
co.SourceLists.Add("default", newSl);
Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
ConfigIsLoaded = true;
// send config changed status???

View File

@@ -10,15 +10,19 @@ using PepperDash.Essentials.Room.Cotija;
namespace PepperDash.Essentials
{
public class CotijaEssentialsHuddleSpaceRoomBridge
public class CotijaEssentialsHuddleSpaceRoomBridge : CotijaBridgeBase
{
CotijaSystemController Parent;
public EssentialsHuddleSpaceRoom Room { get; private set; }
public CotijaEssentialsHuddleSpaceRoomBridge(CotijaSystemController parent, EssentialsHuddleSpaceRoom room)
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
/// <param name="room"></param>
public CotijaEssentialsHuddleSpaceRoomBridge(EssentialsHuddleSpaceRoom room):
base("cotijaController", "Cotija Controller")
{
Parent = parent;
Room = room;
// we add actions to the messaging system with a path, and a related action. Custom action

View File

@@ -317,7 +317,9 @@ namespace PepperDash.Essentials
}
// Set volume control on room, using default if non provided
// Set volume control, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
@@ -334,7 +336,27 @@ namespace PepperDash.Essentials
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
CurrentVolumeControls = volDev;
if (volDev != CurrentVolumeControls)
{
// zero the volume on the device we are leaving.
// Set the volume to default on device we are entering
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
vd.SetVolume(0);
}
CurrentVolumeControls = volDev;
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
// store the name and UI info for routes
if (item.SourceKey == "$off")

View File

@@ -122,7 +122,8 @@ namespace PepperDash.Essentials
string LastSourceKey;
/// <summary>
///
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
/// tag to device.
/// </summary>
public IBasicVolumeControls CurrentVolumeControls
{
@@ -211,6 +212,7 @@ namespace PepperDash.Essentials
else if (defaultAudio is IHasVolumeDevice)
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
CurrentVolumeControls = DefaultVolumeControls;
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
@@ -270,7 +272,7 @@ namespace PepperDash.Essentials
RunDefaultPresentRoute();
CrestronEnvironment.Sleep(200);
CrestronEnvironment.Sleep(1000);
RunRouteAction("roomOff");
}
@@ -280,7 +282,7 @@ namespace PepperDash.Essentials
/// </summary>
public bool RunDefaultPresentRoute()
{
if (DefaultSourceItem != null)
//if (DefaultSourceItem != null)
RunRouteAction(DefaultSourceItem);
return DefaultSourceItem != null;
}
@@ -372,6 +374,52 @@ namespace PepperDash.Essentials
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
}
// See if this can be moved into common, base-class method -------------
// Set volume control, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
volDev = DefaultVolumeControls;
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
volDev = DefaultDisplay as IBasicVolumeControls;
// Or a specific device, probably rarely used.
else
{
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
if (dev is IBasicVolumeControls)
volDev = dev as IBasicVolumeControls;
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
if (volDev != CurrentVolumeControls)
{
// zero the volume on the device we are leaving.
// Set the volume to default on device we are entering
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
vd.SetVolume(0);
}
CurrentVolumeControls = volDev;
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
// -----------------------------------------------------------------------
// store the name and UI info for routes
if (item.SourceKey == "$off")
{

View File

@@ -74,6 +74,13 @@ namespace PepperDash.Essentials
/// </summary>
protected abstract Func<bool> OnFeedbackFunc { get; }
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
/// <summary>
/// When volume control devices change, should we zero the one that we are leaving?
/// </summary>
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
/// <summary>
///
/// </summary>
@@ -123,8 +130,11 @@ namespace PepperDash.Essentials
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
break;
case eVacancyMode.InShutdownWarning:
StartShutdown(eShutdownType.Vacancy);
break;
{
StartShutdown(eShutdownType.Vacancy);
Debug.Console(0, this, "Shutting Down due to vacancy.");
break;
}
default:
break;
}
@@ -154,6 +164,8 @@ namespace PepperDash.Essentials
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
VacancyMode = mode;
RoomVacancyShutdownTimer.Start();
Debug.Console(0, this, "Vacancy Timer Started.");
}
/// <summary>
@@ -181,12 +193,21 @@ namespace PepperDash.Essentials
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
/// </summary>
/// <param name="statusProvider"></param>
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider)
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
{
if (statusProvider == null)
{
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
return;
}
// If status provider is fusion, set flag to remote
if (statusProvider is PepperDash.Essentials.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
OccupancyStatusProviderIsRemote = true;
if(timeoutMinutes > 0)
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
RoomOccupancy = statusProvider;
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += new EventHandler<EventArgs>(RoomIsOccupiedFeedback_OutputChange);
@@ -194,19 +215,26 @@ namespace PepperDash.Essentials
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
{
if ((sender as IOccupancyStatusProvider).RoomIsOccupiedFeedback.BoolValue == false)
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
{
Debug.Console(1, this, "Notice: Vacancy Detected");
// Trigger the timer when the room is vacant
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
}
else
{
Debug.Console(1, this, "Notice: Occupancy Detected");
// Reset the timer when the room is occupied
if(RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
RoomVacancyShutdownTimer.Cancel();
}
}
//void SwapVolumeDevices(IBasicVolumeControls currentDevice, IBasicVolumeControls newDevice)
//{
//}
/// <summary>
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
/// </summary>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -87,8 +87,8 @@ namespace PepperDash.Essentials
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
}
new CTimer(o =>
{
//CrestronInvoke.BeginInvoke(o =>
// {
var regSuccess = Panel.Register();
if (regSuccess != eDeviceRegistrationUnRegistrationResponse.Success)
Debug.Console(0, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", regSuccess);
@@ -177,7 +177,7 @@ namespace PepperDash.Essentials
{
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
}
}, 0);
//}, 0);
});
}

View File

@@ -318,8 +318,6 @@ namespace PepperDash.Essentials
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
});
//TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusButtonPress, ShowActiveCallsList );
SetupNextMeetingTimer();
base.Show();
@@ -635,6 +633,7 @@ namespace PepperDash.Essentials
/// </summary>
void ActivityShareButtonPressed()
{
SetupSourceList();
if (VCDriver.IsVisible)
VCDriver.Hide();
HideNextMeetingPopup();
@@ -644,9 +643,12 @@ namespace PepperDash.Essentials
// Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue)
{
// If there's no default, show UI elements
if(!CurrentRoom.RunDefaultPresentRoute())
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
if (!CurrentRoom.OnFeedback.BoolValue)
{
// If there's no default, show UI elements
if (!CurrentRoom.RunDefaultPresentRoute())
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
}
}
else // room is on show what's active or select a source if nothing is yet active
{
@@ -903,6 +905,7 @@ namespace PepperDash.Essentials
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange;
_CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange;
}
_CurrentRoom = room;
@@ -910,27 +913,9 @@ namespace PepperDash.Essentials
if (_CurrentRoom != null)
{
// get the source list config and set up the source list
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
continue;
SetupSourceList();
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourceStagingSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
}
SourceStagingSrl.Count = (ushort)(i - 1);
}
// Name and logo
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
ShowLogo();
@@ -945,6 +930,8 @@ namespace PepperDash.Essentials
CurrentRoom_SyncOnFeedback();
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange += CurrentRoom_IsCoolingDownFeedback_OutputChange;
_CurrentRoom.InCallFeedback.OutputChange += CurrentRoom_InCallFeedback_OutputChange;
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
@@ -973,6 +960,62 @@ namespace PepperDash.Essentials
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CurrentRoom_InCallFeedback_OutputChange(object sender, EventArgs e)
{
var inCall = CurrentRoom.InCallFeedback.BoolValue;
if (inCall)
{
// Check if transitioning to in call - and non-sharable source is in use
if (CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
{
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
CurrentRoom.RunRouteAction("codecOsd");
}
}
SetupSourceList();
}
/// <summary>
///
/// </summary>
void SetupSourceList()
{
var inCall = CurrentRoom.InCallFeedback.BoolValue;
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
// Skip sources marked as not included, and filter list of non-sharable sources when in call
// or on share screen
if (!srcConfig.IncludeInSourceList || (inCall && srcConfig.DisableCodecSharing)
|| this.CurrentMode == UiDisplayMode.Call && srcConfig.DisableCodecSharing)
{
continue;
}
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourceStagingSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
}
SourceStagingSrl.Count = (ushort)(i - 1);
}
}
/// <summary>
/// If the schedule changes, this event will fire
/// </summary>

View File

@@ -79,9 +79,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
StringBuilder SearchStringBuilder = new StringBuilder();
BoolFeedback SearchStringBackspaceVisibleFeedback;
#warning WHAT THE HELL happened to this?????
BoolFeedback LayoutButtonEnableFeedback;
ModalDialog IncomingCallModal;
eKeypadMode KeypadMode;
@@ -197,13 +194,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
void Codec_IsReady()
{
string roomNumberSipUri = "";
#warning FIX PHONE FORMATTING TO ONLY SHOW WHEN APPROPRIATE - TALK TO NEIL
if (!string.IsNullOrEmpty(Codec.CodecInfo.SipUri)) // If both values are present, format the string with a pipe divider
roomNumberSipUri = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.SipPhoneNumber), Codec.CodecInfo.SipUri);
else // If only one value present, just show the phone number
roomNumberSipUri = Codec.CodecInfo.SipPhoneNumber;
if(string.IsNullOrEmpty(roomNumberSipUri))
roomNumberSipUri = string.Format("{0} | {1}", GetFormattedPhoneNumber(Codec.CodecInfo.E164Alias), Codec.CodecInfo.H323Id);
roomNumberSipUri = string.Format("{0} | {1}", Codec.CodecInfo.E164Alias, Codec.CodecInfo.H323Id);
TriList.SetString(UIStringJoin.RoomPhoneText, roomNumberSipUri);

View File

@@ -1,19 +0,0 @@
{
"RoomName": "Neil Essentials Huddle Space",
"IpId": 241,
"RoomGuid": "1-00:10:7f:74:11:49-8bca1901-999e-47fa-9c48-d241d6",
"StaticAssets": [
{
"Number": 1,
"Name": "Test Asset 1",
"Type": "Test Asset 1",
"InstanceID": "f8a00507-fa3c-4c9d-acfd-1bc03a0bec60"
},
{
"Number": 2,
"Name": "Test Asset 2",
"Type": "Test Asset 2",
"InstanceID": "82f31b23-8572-4192-8631-8128e65959e3"
}
]
}

View File

@@ -1,355 +0,0 @@
{
"system": {},
"system_url": "http://example.com/systems/55bc5f25-1122-4a85-9ae1-9be21b95a7dc#/system_summary",
"template": {
"info": {
"lastModifiedDate": "2017-03-22T17:32:17.800Z",
"comment": "",
"lastUid": 13,
"processorType": "mc3",
"systemType": "presentation",
"requiredControlSofwareVersion": ""
},
"rooms": [
{
"properties": {
"helpMessage": "Help!!",
"volumes": {
"master": {
"label": "Volume",
"level": 50,
"deviceKey": "biampTesira-1--master"
},
"program": {
"label": "Volume",
"level": 50,
"deviceKey": "biampTesira-1--program"
}
},
"defaultVideoBehavior": "basic",
"defaultAudioKey": "amplifier-1",
"displayKeys": [
"display-1",
"display-2"
],
"hasDsp": true,
"defaultAudioBehavior": "audioFollowVideo",
"sourceListKey": "default",
"description": ""
},
"key": "room1",
"type": "presentation",
"name": "West Dungeon"
}
],
"sourceLists": {
"default": {
"source-2": {
"sourceKey": "laptop-2",
"includeInSourceList": true,
"volumeControlKey": "$defaultAudio",
"routeList": [
{
"sourceKey": "laptop-2",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"icon": "",
"order": 2,
"type": "route",
"altIcon": "Blank"
},
"roomOff": {
"routeList": [
{
"sourceKey": "$off",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"sourceKey": "$off",
"type": "off"
},
"source-1": {
"sourceKey": "laptop-1",
"includeInSourceList": true,
"volumeControlKey": "$defaultAudio",
"routeList": [
{
"sourceKey": "laptop-1",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"icon": "",
"order": 1,
"type": "route",
"altIcon": "Blank"
},
"source-3": {
"sourceKey": "sonyBdp-generic-1",
"includeInSourceList": true,
"volumeControlKey": "$defaultAudio",
"routeList": [
{
"sourceKey": "sonyBdp-generic-1",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"icon": "",
"order": 3,
"type": "route",
"altIcon": "Blank"
}
}
},
"tieLines": [
{
"destinationPort": "card2--hdmiIn",
"sourcePort": "HdmiOut",
"sourceKey": "sonyBdp-generic-1",
"type": "audioVideo",
"destinationKey": "dmMd8x8-1"
},
{
"destinationPort": "anyAudioIn",
"sourcePort": "card1--audioOut1",
"sourceKey": "dmMd8x8-1",
"type": "audio",
"destinationKey": "amplifier-1"
}
],
"devices": [
{
"group": "dmChassis",
"properties": {
"outputSlots": {
"1": "dmc4kHdo"
},
"inputNames": {},
"volumeControls": {
"1": {
"outLevel": -1,
"isVolumeControlPoint": true
},
"2": {
"outLevel": 65535,
"isVolumeControlPoint": false
}
},
"control": {
"method": "ipid",
"ipid": "03",
"params": {
"endOfLineString": "\n",
"deviceReadyResponsePattern": ".*>"
}
},
"inputSlots": {
"1": "dmc4kC",
"2": "dmc4kHd"
}
},
"uid": 9,
"key": "dmMd8x8-1",
"name": "DM-MD8x8",
"type": "dmMd8x8"
},
{
"group": "amplifier",
"properties": {},
"uid": 0,
"key": "amplifier-1",
"name": "Audio endpoint/Amplifier",
"type": "amplifier"
},
{
"group": "display",
"properties": {
"control": {
"method": "tcpIp",
"tcpSshProperties": {
"port": 123,
"address": "123"
}
}
},
"uid": 2,
"key": "display-1",
"name": "Display 1",
"type": "NecMPSX"
},
{
"group": "pc",
"properties": {
"hasAudio": true,
"hasControls": false
},
"uid": 3,
"key": "laptop-1",
"name": "Laptop AAA",
"type": "laptop"
},
{
"group": "pc",
"properties": {
"hasAudio": true,
"hasControls": false
},
"uid": 4,
"key": "laptop-2",
"name": "Laptop BBB",
"type": "laptop"
},
{
"group": "discPlayer",
"properties": {
"hasControls": true,
"hasTransport": true,
"control": {
"method": "ir",
"controlPortNumber": 1,
"controlPortDevKey": "processor",
"irFile": "Sony BDP Series.ir"
},
"hasAudio": true,
"hasNumeric": true,
"hasDpad": true
},
"uid": 5,
"key": "sonyBdp-generic-1",
"name": "LaserDisc player",
"type": "sonyBdp-generic"
},
{
"group": "processor",
"properties": {
"numberOfIrPorts": 5,
"numberOfComPorts": 2
},
"uid": 6,
"supportsCompliance": true,
"type": "mc3",
"name": "MC3",
"supportedSystemTypes": [
"custom",
"hudType",
"presType"
],
"key": "processor"
},
{
"group": "display",
"properties": {
"control": {
"method": "tcpIp",
"tcpSshProperties": {
"port": 123,
"address": "123"
}
}
},
"uid": 7,
"key": "display-2",
"name": "Display 2",
"type": "NecMPSX"
},
{
"group": "touchpanel",
"properties": {
"sourcesOverflowCount": 5,
"defaultRoomKey": "room1",
"control": {
"method": "ipid",
"ipid": "A1",
"params": {
"endOfLineString": "\n",
"deviceReadyResponsePattern": ".*>"
}
},
"showTime": true,
"roomListKey": "",
"showDate": true,
"sgdFile": "Essentials TSW.sgd",
"usesSplashPage": true,
"showVolumeGauge": true
},
"uid": 8,
"key": "tsw1052-1",
"name": "TSW 1050/1052 1",
"type": "tsw1052"
},
{
"group": "dsp",
"properties": {
"levelControlBlocks": {
"audioCallRx": {
"index1": 1,
"index2": 0,
"label": "Audio Call Receive",
"hasLevel": true,
"instanceTag": "VoIPRxLevel",
"hasMute": true
},
"audioCallTx": {
"index1": 1,
"index2": 0,
"label": "Audio Call Transmit",
"hasLevel": false,
"instanceTag": "VoIPTxLevel",
"hasMute": true
},
"master": {
"index1": 1,
"index2": 0,
"label": "Master",
"hasLevel": true,
"instanceTag": "RoomLevel",
"hasMute": true
},
"program": {
"index1": 1,
"index2": 0,
"label": "Program",
"hasLevel": true,
"instanceTag": "ProgramLevel",
"hasMute": true
}
},
"presenterMic": {
"enabled": false
},
"control": {
"method": "ssh",
"tcpSshProperties": {
"port": 22,
"address": "10.11.50.191",
"ipAutoReconnectInterval": 1000,
"username": "default"
},
"comParams": {
"stopBits": 1,
"hardwareHandshake": "None",
"baudRate": 38400,
"dataBits": 8,
"parity": "None",
"softwareHandshake": "None",
"protocol": "RS232"
},
"params": {
"endOfLineString": "\n",
"deviceReadyResponsePattern": "Welcome to the Tesira Text Protocol Server.*"
}
}
},
"uid": 12,
"type": "biampTesira",
"name": "Biamp Tesira 1",
"key": "biampTesira-1"
}
]
},
"template_url": "http://example.com/templates/9f143a56-a160-453a-a7cb-5854857fd220#/template_summary"
}

View File

@@ -1,388 +0,0 @@
{
"template": {
"info": {
"comment": "",
"lastUid": 9,
"requiredControlSofwareVersion": "",
"processorType": "rmc3",
"lastModifiedDate": "2017-07-07T16:58:43.621Z",
"systemType": "presentation"
},
"devices": [
{
"type": "dmMd8x8",
"properties": {
"inputNames": {},
"control": {
"params": {
"deviceReadyResponsePattern": ".*>",
"endOfLineString": "\n"
},
"method": "ipid",
"ipid": "04"
},
"inputSlots": {
"1": "dmc4kHd",
"2": "dmc4kHd",
"3": "dmc4kHd"
},
"volumeControls": {
"1": {
"outLevel": 65535,
"isVolumeControlPoint": false
},
"2": {
"outLevel": 65535,
"isVolumeControlPoint": false
}
},
"outputSlots": {
"1": "dmc4kHdo"
}
},
"key": "dmMd8x8-1",
"name": "DM-MD8x8 Chassis 1",
"uid": 4,
"group": "dmChassis"
},
{
"supportsCompliance": true,
"key": "processor",
"properties": {
"numberOfComPorts": 1,
"numberOfIrPorts": 2
},
"supportedSystemTypes": [
"hudType",
"presType",
"vtcType",
"custom"
],
"type": "rmc3",
"supportedConfigModes": [
"compliance",
"essentials"
],
"uid": 0,
"name": "RMC3",
"group": "processor"
},
{
"type": "sonyBdp-generic",
"properties": {
"control": {
"irFile": "Sony BDP Series.ir",
"method": "ir",
"controlPortDevKey": "processor",
"controlPortNumber": 1
},
"hasAudio": true,
"hasControls": true,
"hasTransport": true,
"hasDpad": true
},
"key": "sonyBdp-generic-1",
"group": "discPlayer",
"uid": 1,
"name": "Sony Bluray 1"
},
{
"type": "comcastMotorola-generic",
"properties": {
"control": {
"irFile": "Comcast Motorola DVR.ir",
"method": "ir",
"controlPortDevKey": "processor",
"controlPortNumber": 2
},
"hasAudio": true,
"hasControls": true,
"hasDvr": true,
"hasDpad": true,
"hasNumeric": true
},
"key": "comcastMotorola-generic-1",
"group": "setTopBox",
"uid": 2,
"name": "Comcast Motorola DVR 1"
},
{
"type": "laptop",
"properties": {
"hasAudio": true,
"hasControls": false
},
"key": "laptop-1",
"group": "pc",
"uid": 3,
"name": "Laptop 1"
},
{
"type": "biampTesira",
"properties": {
"control": {
"deviceReadyResponsePattern": "Welcome to the Tesira Text Protocol Server.*",
"tcpSshProperties": {
"port": 22,
"address": "0.0.0.0",
"username": "default"
},
"endOfLineString": "\r\n",
"method": "ssh"
},
"levelControlBlocks": {
"audioCallRx": {
"label": "Audio Call Receive",
"index1": 1,
"instanceTag": "VoIPRxLevel",
"hasMute": true,
"hasLevel": true,
"index2": 0
},
"audioCallTx": {
"label": "Audio Call Transmit",
"index1": 1,
"instanceTag": "VoIPTxLevel",
"hasMute": true,
"hasLevel": false,
"index2": 0
},
"master": {
"label": "Master",
"index1": 1,
"instanceTag": "RoomLevel",
"hasMute": true,
"hasLevel": true,
"index2": 0
},
"program": {
"label": "Program",
"index1": 1,
"instanceTag": "ProgramLevel",
"hasMute": true,
"hasLevel": true,
"index2": 0
}
},
"presenterMic": {
"enabled": false
}
},
"key": "biampTesira-1",
"name": "Biamp Tesira 1",
"uid": 5,
"group": "dsp"
},
{
"type": "NecMPSX",
"properties": {
"control": {
"tcpSshProperties": {
"address": "0.0.0.0",
"port": 23
},
"method": "tcpIp"
}
},
"key": "display-1",
"name": "Left Display",
"uid": 6,
"group": "display"
},
{
"type": "NecMPSX",
"properties": {
"control": {
"tcpSshProperties": {
"address": "0.0.0.0",
"port": 23
},
"method": "tcpIp"
}
},
"key": "display-2",
"name": "Right Display",
"uid": 7,
"group": "display"
},
{
"type": "tsw1052",
"properties": {
"defaultRoomKey": "room1",
"roomListKey": "",
"sourcesOverflowCount": 5,
"sgdFile": "Essentials TSW.sgd",
"control": {
"params": {
"deviceReadyResponsePattern": ".*>",
"endOfLineString": "\n"
},
"method": "ipid",
"ipid": "03"
},
"showTime": true,
"showVolumeGauge": true,
"showDate": true,
"usesSplashPage": true
},
"key": "tsw1052-1",
"name": "TSW 1050/1052 1",
"uid": 8,
"group": "touchpanel"
},
{
"type": "amplifier",
"key": "amplifier-1",
"uid": 9,
"name": "Amplifier"
}
],
"rooms": [
{
"properties": {
"defaultAudioBehavior": "audioFollowVideo",
"defaultVideoBehavior": "advanced",
"description": "",
"displayKeys": [
"display-1"
],
"hasDsp": true,
"defaultAudioKey": "biampTesira-1",
"volumes": {
"master": {
"label": "Volume",
"level": -10,
"deviceKey": "biampTesira-1--master"
},
"program": {
"label": "Volume",
"level": -10,
"deviceKey": "biampTesira-1--program"
}
},
"helpMessage": "",
"sourceListKey": "default"
},
"key": "room1",
"type": "presentation",
"name": "Neil's Test Presentation Template"
}
],
"sourceLists": {
"default": {
"roomOff": {
"routeList": [
{
"sourceKey": "$off",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"sourceKey": "$off",
"type": "off"
},
"source-1": {
"sourceKey": "laptop-1",
"includeInSourceList": true,
"volumeControlKey": "$defaultAudio",
"routeList": [
{
"sourceKey": "laptop-1",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"icon": "",
"order": 1,
"type": "route",
"altIcon": "Blank"
},
"source-2": {
"sourceKey": "sonyBdp-generic-1",
"includeInSourceList": true,
"volumeControlKey": "$defaultAudio",
"routeList": [
{
"sourceKey": "sonyBdp-generic-1",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"icon": "",
"order": 3,
"type": "route",
"altIcon": "Blank"
},
"source-3": {
"sourceKey": "comcastMotorola-generic-1",
"includeInSourceList": true,
"volumeControlKey": "$defaultAudio",
"routeList": [
{
"sourceKey": "comcastMotorola-generic-1",
"type": "audioVideo",
"destinationKey": "$defaultAll"
}
],
"icon": "",
"order": 3,
"type": "route",
"altIcon": "Blank"
}
}
},
"tieLines": [
{
"sourceKey": "sonyBdp-generic-1",
"destinationKey": "dmMd8x8-1",
"sourcePort": "HdmiOut",
"destinationPort": "card1--hdmiIn",
"type": "audioVideo"
},
{
"sourceKey": "comcastMotorola-generic-1",
"destinationKey": "dmMd8x8-1",
"sourcePort": "anyVideoOut",
"destinationPort": "card2--hdmiIn",
"type": "audioVideo"
},
{
"sourceKey": "laptop-1",
"destinationKey": "dmMd8x8-1",
"sourcePort": "anyOut",
"destinationPort": "card3--hdmiIn",
"type": "audioVideo"
},
{
"sourceKey": "dmMd8x8-1",
"destinationKey": "display-1",
"sourcePort": "card1--hdmiOut1",
"destinationPort": "HdmiIn1",
"type": "audioVideo"
},
{
"sourceKey": "dmMd8x8-1",
"destinationKey": "display-2",
"sourcePort": "card1--hdmiOut2",
"destinationPort": "HdmiIn1",
"type": "audioVideo"
},
{
"sourceKey": "dmMd8x8-1",
"destinationKey": "biampTesira-1",
"sourcePort": "card1--audioOut1",
"destinationPort": "anyAudioIn",
"type": "audio"
},
{
"sourceKey": "biampTesira-1",
"destinationKey": "amplifier-1",
"sourcePort": "anyAudioOut",
"destinationPort": "anyAudioIn",
"type": "audio"
}
]
},
"system": {},
"system_url": "http://portal-QA.devcloud.pepperdash.com/templates/0f50640b-bc89-42d5-998f-81d137d3fc98#/template_summary"
}

View File

@@ -22,4 +22,10 @@ devjson:1 {"deviceKey":"mockVc-1", "methodName":"TestIncomingVideoCall", "params
devjson:1 {"deviceKey":"mockVc-1", "methodName":"ListCalls"}
devjson:1 {"deviceKey":"room1-emergency", "methodName":"RunEmergencyBehavior"}
devjson:1 {"deviceKey":"room1-emergency", "methodName":"RunEmergencyBehavior"}
devjson:1 {"deviceKey":"microphonePrivacyController-1", "methodName":"TogglePrivacyMute"}
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"SetTestValue", "params": [ true ]}
devjson:1 {"deviceKey":"room1.InCallFeedback","methodName":"ClearTestValue", "params": []}

Binary file not shown.