diff --git a/src/PepperDash.Essentials.Core/Devices/DeviceJsonApi.cs b/src/PepperDash.Essentials.Core/Devices/DeviceJsonApi.cs index 691aea55..fcda0730 100644 --- a/src/PepperDash.Essentials.Core/Devices/DeviceJsonApi.cs +++ b/src/PepperDash.Essentials.Core/Devices/DeviceJsonApi.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using Crestron.SimplSharp; using Crestron.SimplSharp.Reflection; using Newtonsoft.Json; @@ -82,7 +83,8 @@ namespace PepperDash.Essentials.Core var convertedParams = mParams .Select((p, i) => ConvertType(action.Params[i], p.ParameterType)) .ToArray(); - method.Invoke(obj, convertedParams); + + Task.Run(() => method.Invoke(obj, convertedParams)); CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name, action.DeviceKey); diff --git a/src/PepperDash.Essentials.Core/Devices/PC/Laptop.cs b/src/PepperDash.Essentials.Core/Devices/PC/Laptop.cs index bfc09292..05cf9e76 100644 --- a/src/PepperDash.Essentials.Core/Devices/PC/Laptop.cs +++ b/src/PepperDash.Essentials.Core/Devices/PC/Laptop.cs @@ -70,7 +70,7 @@ namespace PepperDash.Essentials.Core.Devices { public LaptopFactory() { - TypeNames = new List() { "laptop" }; + TypeNames = new List() { "deprecated" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) diff --git a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs index afe3ef24..b0372b51 100644 --- a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs @@ -161,8 +161,11 @@ namespace PepperDash.Essentials.Core Icon = "Blank"; } - - } + public override string ToString() + { + return $"{SourceKey}:{Name}"; + } + } public class SourceRouteListItem { diff --git a/src/PepperDash.Essentials.Core/Routing/DummyRoutingInputsDevice.cs b/src/PepperDash.Essentials.Core/Routing/DummyRoutingInputsDevice.cs index c6f96c74..d8b50a9b 100644 --- a/src/PepperDash.Essentials.Core/Routing/DummyRoutingInputsDevice.cs +++ b/src/PepperDash.Essentials.Core/Routing/DummyRoutingInputsDevice.cs @@ -8,7 +8,7 @@ using PepperDash.Core; namespace PepperDash.Essentials.Core.Routing { - public class DummyRoutingInputsDevice : Device, IRoutingSource + public class DummyRoutingInputsDevice : Device, IRoutingSource, IRoutingOutputs { /// /// A single output port, backplane, audioVideo diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingSource.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingSource.cs index 6ae51a2b..f4705b8d 100644 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingSource.cs +++ b/src/PepperDash.Essentials.Core/Routing/IRoutingSource.cs @@ -3,7 +3,7 @@ /// /// Defines an IRoutingOutputs devices as being a source - the start of the chain /// - public interface IRoutingSource : IRoutingOutputs - { + public interface IRoutingSource + { } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs b/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs index bf796d5b..ec09e08a 100644 --- a/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs +++ b/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; namespace PepperDash.Essentials.Core.Routing { @@ -48,7 +49,14 @@ namespace PepperDash.Essentials.Core.Routing private void HandleSinkUpdate(IRoutingSinkWithSwitching sender, RoutingInputPort currentInputPort) { - UpdateDestination(sender, currentInputPort); + try + { + UpdateDestination(sender, currentInputPort); + } + catch (Exception ex) + { + Debug.LogMessage(ex, "Error handling Sink update from {senderKey}:{Exception}", this, sender.Key, ex); + } } private void UpdateDestination(IRoutingSinkWithSwitching destination, RoutingInputPort inputPort) @@ -66,7 +74,9 @@ namespace PepperDash.Essentials.Core.Routing return; } - var sourceTieLine = GetRootTieLine(firstTieLine); + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Getting source for first TieLine {tieLine}", this, firstTieLine); + + var sourceTieLine = GetRootTieLine(firstTieLine); if (sourceTieLine == null) { @@ -76,6 +86,7 @@ namespace PepperDash.Essentials.Core.Routing destination.CurrentSourceInfoKey = string.Empty; } + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found root TieLine {tieLine}", this, sourceTieLine); // Does not handle combinable scenarios or other scenarios where a display might be part of multiple rooms yet. var room = DeviceManager.AllDevices.OfType().FirstOrDefault((r) => { @@ -90,7 +101,7 @@ namespace PepperDash.Essentials.Core.Routing } return false; - }) ; + }); if(room == null) { @@ -98,6 +109,8 @@ namespace PepperDash.Essentials.Core.Routing return; } + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found room {room} for destination {destination}", this, room.Key, destination.Key); + var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(room.SourceListKey); if (sourceList == null) @@ -106,7 +119,18 @@ namespace PepperDash.Essentials.Core.Routing return; } - var sourceListItem = sourceList.FirstOrDefault(sli => sli.Value.SourceKey == sourceTieLine.SourcePort.ParentDevice.Key); + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found sourceList for room {room}", this, room.Key); + + var sourceListItem = sourceList.FirstOrDefault(sli => { + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, + "SourceListItem {sourceListItem}:{sourceKey} tieLine sourceport device key {sourcePortDeviceKey}", + this, + sli.Key, + sli.Value.SourceKey, + sourceTieLine.SourcePort.ParentDevice.Key); + + return sli.Value.SourceKey.Equals(sourceTieLine.SourcePort.ParentDevice.Key,StringComparison.InvariantCultureIgnoreCase); + }); var source = sourceListItem.Value; @@ -119,6 +143,8 @@ namespace PepperDash.Essentials.Core.Routing return; } + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Got Source {source}", this, source); + destination.CurrentSourceInfo = source; destination.CurrentSourceInfoKey = source.SourceKey; } @@ -129,6 +155,8 @@ namespace PepperDash.Essentials.Core.Routing if(tieLine.SourcePort.ParentDevice is IRoutingWithFeedback midpoint) { + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "TieLine Source device is midpoint", this); + var currentRoute = midpoint.CurrentRoutes.FirstOrDefault(route => route.OutputPort.Key == tieLine.SourcePort.Key); if(currentRoute == null) @@ -147,8 +175,12 @@ namespace PepperDash.Essentials.Core.Routing return tieLine; } - if(tieLine.SourcePort.ParentDevice is IRoutingSource) //end of the chain + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "TieLIne Source Device {sourceDeviceKey} is IRoutingSource: {isIRoutingSource}", this,tieLine.SourcePort.ParentDevice.Key, tieLine.SourcePort.ParentDevice is IRoutingSource); + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "TieLine Source Device interfaces: {typeFullName}:{interfaces}",this, tieLine.SourcePort.ParentDevice.GetType().FullName, tieLine.SourcePort.ParentDevice.GetType().GetInterfaces().Select(i => i.Name)); + + if(tieLine.SourcePort.ParentDevice is IRoutingSource || tieLine.SourcePort.ParentDevice is IRoutingOutputs) //end of the chain { + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Found root: {tieLine}", this, tieLine); return tieLine; } @@ -159,7 +191,7 @@ namespace PepperDash.Essentials.Core.Routing return GetRootTieLine(nextTieLine); } - return nextTieLine; + return null; } } } diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs index 33d5632a..d5595f5f 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs @@ -28,7 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays return _currentInputPort; } - private set + protected set { _currentInputPort = value; diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs index a1241821..50c2a731 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs @@ -6,6 +6,7 @@ using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.Routing; using Serilog.Events; @@ -139,18 +140,40 @@ namespace PepperDash.Essentials.Devices.Common.Displays public override void ExecuteSwitch(object selector) { - Debug.LogMessage(LogEventLevel.Verbose, this, "ExecuteSwitch: {0}", selector); + try + { + Debug.LogMessage(LogEventLevel.Verbose, "ExecuteSwitch: {0}", this, selector); - if (!_PowerIsOn) - { - PowerOn(); - } + if (!_PowerIsOn) + { + PowerOn(); + } - if (!Inputs.Items.TryGetValue(selector.ToString(), out var input)) - return; + if (!Inputs.Items.TryGetValue(selector.ToString(), out var input)) + return; - input.Select(); - } + Debug.LogMessage(LogEventLevel.Verbose, "Selected input: {input}", this, input.Key); + input.Select(); + + var inputPort = InputPorts.FirstOrDefault(port => + { + Debug.LogMessage(LogEventLevel.Verbose, "Checking input port {inputPort} with selector {portSelector} against {selector}", this, port, port.Selector, selector); + return port.Selector.ToString() == selector.ToString(); + }); + + if (inputPort == null) + { + Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector); + return; + } + + Debug.LogMessage(LogEventLevel.Verbose, "Setting current input port to {inputPort}", this, inputPort); + CurrentInputPort = inputPort; + } catch (Exception ex) + { + Debug.LogMessage(ex, "Error making switch: {Exception}", this); + } + } public void SetInput(string selector) { @@ -251,4 +274,18 @@ namespace PepperDash.Essentials.Devices.Common.Displays } + + public class MockDisplay2Factory : EssentialsDeviceFactory + { + public MockDisplay2Factory() + { + TypeNames = new List() { "mockdisplay2" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device"); + return new MockDisplay(dc.Key, dc.Name); + } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs index c34f7d12..16ddaa25 100644 --- a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs +++ b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs @@ -14,7 +14,7 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { - public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking + public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IRoutingOutputs, IUsageTracking { public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } } diff --git a/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs b/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs index 9e334244..0bc055c8 100644 --- a/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs @@ -20,7 +20,7 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { [Description("Wrapper class for an IR Set Top Box")] - public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingSource, IUsageTracking, IHasPowerControl, ITvPresetsProvider + public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingSource, IRoutingOutputs, IUsageTracking, IHasPowerControl, ITvPresetsProvider { public IrOutputPortController IrPort { get; private set; } diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs index ae7acca1..5a8a3df8 100644 --- a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs @@ -9,7 +9,7 @@ using System.Linq; namespace PepperDash.Essentials.Devices.Common.SoftCodec { - public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWithSwitching + public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingOutputs, IRoutingSinkWithSwitching { private RoutingInputPort _currentInputPort; public RoutingInputPort CurrentInputPort { diff --git a/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs b/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs index b3d8fbee..3de80549 100644 --- a/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs +++ b/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs @@ -8,7 +8,7 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Sources { - public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking + public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking { public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } public string IconName { get; set; } diff --git a/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs b/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs index c2ffb726..bf4a8b45 100644 --- a/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs +++ b/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs @@ -8,7 +8,7 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Sources { - public class Laptop : EssentialsDevice, IHasFeedback, IRoutingSource, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking + public class Laptop : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking { public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } public string IconName { get; set; } @@ -29,11 +29,15 @@ namespace PepperDash.Essentials.Devices.Common.Sources : base(key, name) { IconName = "Laptop"; + HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback", () => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus); - OutputPorts = new RoutingPortCollection(); - OutputPorts.Add(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.None, 0, this)); + + OutputPorts = new RoutingPortCollection + { + (AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.None, 0, this)) + }; } #region IHasFeedback Members diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs index c4a9b5a7..4d744690 100644 --- a/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs @@ -19,8 +19,9 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { [Description("Wrapper class for an IR-Controlled AppleTV")] - public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource - { + public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs + + { public IrOutputPortController IrPort { get; private set; } public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir"; public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } } diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs index 9d08f53a..76284597 100644 --- a/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs @@ -15,7 +15,7 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { [Description("Wrapper class for an IR-Controlled Roku")] - public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource + public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs { [Api] public IrOutputPortController IrPort { get; private set; }