mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-29 20:34:51 +00:00
feat: add RoutingFeedbackManager
RoutingFeedbackManager keeps track of updates from IRoutingSinkWotjFeedbacl devoces & IRoutingWithFeedback devices to allow for walking tieLines and finding a source.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
public LaptopFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "laptop" };
|
||||
TypeNames = new List<string>() { "deprecated" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
|
||||
@@ -161,8 +161,11 @@ namespace PepperDash.Essentials.Core
|
||||
Icon = "Blank";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{SourceKey}:{Name}";
|
||||
}
|
||||
}
|
||||
|
||||
public class SourceRouteListItem
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Routing
|
||||
{
|
||||
public class DummyRoutingInputsDevice : Device, IRoutingSource
|
||||
public class DummyRoutingInputsDevice : Device, IRoutingSource, IRoutingOutputs
|
||||
{
|
||||
/// <summary>
|
||||
/// A single output port, backplane, audioVideo
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// Defines an IRoutingOutputs devices as being a source - the start of the chain
|
||||
/// </summary>
|
||||
public interface IRoutingSource : IRoutingOutputs
|
||||
{
|
||||
public interface IRoutingSource
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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<IEssentialsRoom>().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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
return _currentInputPort;
|
||||
}
|
||||
|
||||
private set
|
||||
protected set
|
||||
{
|
||||
_currentInputPort = value;
|
||||
|
||||
|
||||
@@ -140,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)
|
||||
{
|
||||
|
||||
@@ -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; } }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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<RoutingOutputPort>();
|
||||
OutputPorts.Add(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, 0, this));
|
||||
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>
|
||||
{
|
||||
(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, 0, this))
|
||||
};
|
||||
}
|
||||
|
||||
#region IHasFeedback Members
|
||||
|
||||
@@ -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; } }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user