From f0d10fb1f962f0ab3cdb8351781b55fcc4d153b7 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Mon, 17 Aug 2020 14:52:49 -0400 Subject: [PATCH] Finalized IHasExternalSourceSwitching adding method for setting the ExternalSource State Adds arguments for External Source type it the AddExternalSource() Adds subscription and parsing for External Source events --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 9 +- .../Devices/IrOutputPortController.cs | 240 +++++++++--------- .../Codec/IHasExternalSourceSwitching.cs | 5 +- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 44 +++- .../VideoCodec/CiscoCodec/xEvent.cs | 31 ++- 5 files changed, 193 insertions(+), 136 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 06ad71cd..0c048ed1 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -695,6 +695,10 @@ namespace PepperDash.Essentials (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); } + + /// + /// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch + /// private void SetCodecExternalSources() { @@ -707,12 +711,13 @@ namespace PepperDash.Essentials foreach (var kvp in srcList) { var srcConfig = kvp.Value; - Debug.Console(1, "**** KEY {0}", kvp.Key); if (kvp.Key != "codecOsd" && kvp.Key != "roomOff") { - (VideoCodec as IHasExternalSourceSwitching).AddExternalSource(codecTieLine, srcConfig.PreferredName); + (VideoCodec as IHasExternalSourceSwitching).AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop); + (VideoCodec as IHasExternalSourceSwitching).SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready); + } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs index ecfca4f8..83241e79 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs @@ -1,45 +1,45 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; +using System; +using System.Collections.Generic; +using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json.Linq; -using PepperDash.Essentials.Core.Config; - - -using PepperDash.Core; - -namespace PepperDash.Essentials.Core -{ - - /// - /// IR port wrapper. May act standalone - /// - public class IrOutputPortController : Device - { - uint IrPortUid; - IROutputPort IrPort; - - public ushort StandardIrPulseTime { get; set; } - public string DriverFilepath { get; private set; } - public bool DriverIsLoaded { get; private set; } - - /// - /// Constructor for IrDevice base class. If a null port is provided, this class will - /// still function without trying to talk to a port. - /// - public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath) - : base(key) - { - //if (port == null) throw new ArgumentNullException("port"); - IrPort = port; - if (port == null) - { - Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function"); - return; - } - LoadDriver(irDriverFilepath); +using PepperDash.Essentials.Core.Config; + + +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + + /// + /// IR port wrapper. May act standalone + /// + public class IrOutputPortController : Device + { + uint IrPortUid; + IROutputPort IrPort; + + public ushort StandardIrPulseTime { get; set; } + public string DriverFilepath { get; private set; } + public bool DriverIsLoaded { get; private set; } + + /// + /// Constructor for IrDevice base class. If a null port is provided, this class will + /// still function without trying to talk to a port. + /// + public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath) + : base(key) + { + //if (port == null) throw new ArgumentNullException("port"); + IrPort = port; + if (port == null) + { + Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function"); + return; + } + LoadDriver(irDriverFilepath); } public IrOutputPortController(string key, Func postActivationFunc, @@ -54,85 +54,85 @@ namespace PepperDash.Essentials.Core - /// - /// Loads the IR driver at path - /// - /// - public void LoadDriver(string path) - { - if (string.IsNullOrEmpty(path)) path = DriverFilepath; - try - { - IrPortUid = IrPort.LoadIRDriver(path); - DriverFilepath = path; - StandardIrPulseTime = 200; - DriverIsLoaded = true; - } - catch - { - DriverIsLoaded = false; - var message = string.Format("WARNING IR Driver '{0}' failed to load", path); - Debug.Console(0, this, message); - ErrorLog.Error(message); - } - } - - - /// - /// Starts and stops IR command on driver. Safe for missing commands - /// - public virtual void PressRelease(string command, bool state) - { - Debug.Console(2, this, "IR:'{0}'={1}", command, state); - if (IrPort == null) - { - Debug.Console(2, this, "WARNING No IR Port assigned to controller"); - return; - } - if (!DriverIsLoaded) - { - Debug.Console(2, this, "WARNING IR driver is not loaded"); - return; - } - if (state) - { - if (IrPort.IsIRCommandAvailable(IrPortUid, command)) - IrPort.Press(IrPortUid, command); - else - NoIrCommandError(command); - } - else - IrPort.Release(); - } - - /// - /// Pulses a command on driver. Safe for missing commands - /// - public virtual void Pulse(string command, ushort time) - { - if (IrPort == null) - { - Debug.Console(2, this, "WARNING No IR Port assigned to controller"); - return; - } - if (!DriverIsLoaded) - { - Debug.Console(2, this, "WARNING IR driver is not loaded"); - return; - } - if (IrPort.IsIRCommandAvailable(IrPortUid, command)) - IrPort.PressAndRelease(IrPortUid, command, time); - else - NoIrCommandError(command); - } - - /// - /// Notifies the console when a bad command is used. - /// - protected void NoIrCommandError(string command) - { - Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}", - Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command); + /// + /// Loads the IR driver at path + /// + /// + public void LoadDriver(string path) + { + if (string.IsNullOrEmpty(path)) path = DriverFilepath; + try + { + IrPortUid = IrPort.LoadIRDriver(path); + DriverFilepath = path; + StandardIrPulseTime = 200; + DriverIsLoaded = true; + } + catch + { + DriverIsLoaded = false; + var message = string.Format("WARNING IR Driver '{0}' failed to load", path); + Debug.Console(0, this, message); + ErrorLog.Error(message); + } } - } + + + /// + /// Starts and stops IR command on driver. Safe for missing commands + /// + public virtual void PressRelease(string command, bool state) + { + Debug.Console(2, this, "IR:'{0}'={1}", command, state); + if (IrPort == null) + { + Debug.Console(2, this, "WARNING No IR Port assigned to controller"); + return; + } + if (!DriverIsLoaded) + { + Debug.Console(2, this, "WARNING IR driver is not loaded"); + return; + } + if (state) + { + if (IrPort.IsIRCommandAvailable(IrPortUid, command)) + IrPort.Press(IrPortUid, command); + else + NoIrCommandError(command); + } + else + IrPort.Release(); + } + + /// + /// Pulses a command on driver. Safe for missing commands + /// + public virtual void Pulse(string command, ushort time) + { + if (IrPort == null) + { + Debug.Console(2, this, "WARNING No IR Port assigned to controller"); + return; + } + if (!DriverIsLoaded) + { + Debug.Console(2, this, "WARNING IR driver is not loaded"); + return; + } + if (IrPort.IsIRCommandAvailable(IrPortUid, command)) + IrPort.PressAndRelease(IrPortUid, command, time); + else + NoIrCommandError(command); + } + + /// + /// Notifies the console when a bad command is used. + /// + protected void NoIrCommandError(string command) + { + Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}", + Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs index 1870e756..d86f628e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasExternalSourceSwitching.cs @@ -4,12 +4,15 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; + namespace PepperDash.Essentials.Devices.Common.Codec { public interface IHasExternalSourceSwitching { bool ExternalSourceListEnabled { get; } - void AddExternalSource(string connectorId, string name); + void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type); + void SetExternalSourceState(string key, eExternalSourceMode mode); void ClearExternalSources(); Action RunRouteAction { set;} } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index b90ab896..108aab0b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -21,6 +21,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other} + public enum eExternalSourceMode {Ready, NotReady, Hiddon, Error} public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, @@ -636,11 +637,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } } - //TODO JTA FInish Parsing for External Sources - if (args.Text == "ExternalSource") - { - RunRouteAction("", ""); - } + } @@ -865,6 +862,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { GetBookings(null); } + + else if (response.IndexOf("\"UserInterface\":{") > -1 || response.IndexOf("\"UserInterface\": {") > -1) // External Source Trigger + { + CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject(); + JsonConvert.PopulateObject(response, eventReceived); + Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value); + RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null); + } } else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1) { @@ -1818,7 +1823,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco #region IHasExternalSourceSwitching Members /// - /// + /// Weather the Cisco supports External Source Lists or not /// public bool ExternalSourceListEnabled { @@ -1826,20 +1831,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco private set; } - public void AddExternalSource(string connectorId, string name) + /// + /// Adds an external source to the Cisco + /// + /// + /// + /// + public void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type) { int id = 2; if (connectorId.ToLower() == "hdmiin3") { id = 3; } - SendText(string.Format("xCommand UserInterface Presentation ExternalSource Add ConnectorId: {0} SourceIdentifier: \"{1}\" Name: \"{2}\" Type: desktop", id, name, name)); + SendText(string.Format("xCommand UserInterface Presentation ExternalSource Add ConnectorId: {0} SourceIdentifier: \"{1}\" Name: \"{2}\" Type: {3}", id, key, name, type.ToString())); + // SendText(string.Format("xCommand UserInterface Presentation ExternalSource State Set SourceIdentifier: \"{0}\" State: Ready", key)); Debug.Console(2, this, "Adding ExternalSource {0} {1}", connectorId, name); } + /// - /// + /// Sets the state of the External Source + /// + /// + /// + public void SetExternalSourceState(string key, eExternalSourceMode mode) + { + SendText(string.Format("xCommand UserInterface Presentation ExternalSource State Set SourceIdentifier: \"{0}\" State: {1}", key, mode.ToString())); + } + /// + /// Clears all external sources on the codec /// public void ClearExternalSources() { @@ -1847,7 +1869,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } - + /// + /// Action that will run when the External Source is selected. + /// public Action RunRouteAction { private get; set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs index 342a8848..23594ce2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xEvent.cs @@ -126,11 +126,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Encryption Encryption { get; set; } public RequestedURI RequestedURI { get; set; } public PeopleCountAverage PeopleCountAverage { get; set; } - } - + } + public class UserInterface + { + public string id { get; set; } + public Presentation Presentation { get; set; } + } + public class Presentation + { + public string id { get; set; } + public ExternalSource ExternalSource { get; set; } + } + public class ExternalSource + { + public string id { get; set; } + public Selected Selected { get; set; } + } + public class Selected + { + public string id { get; set; } + public SourceIdentifier SourceIdentifier { get; set; } + } + public class SourceIdentifier + { + public string id { get; set; } + public string Value { get; set; } + } public class Event { - public CallDisconnect CallDisconnect { get; set; } + public CallDisconnect CallDisconnect { get; set; } + public UserInterface UserInterface { get; set; } } public class RootObject