mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-16 13:15:03 +00:00
feat: implement feedback manager
This commit is contained in:
@@ -169,9 +169,15 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonProperty("sourceKey")]
|
[JsonProperty("sourceKey")]
|
||||||
public string SourceKey { get; set; }
|
public string SourceKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("sourcePortKey")]
|
||||||
|
public string SourcePortKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("destinationKey")]
|
[JsonProperty("destinationKey")]
|
||||||
public string DestinationKey { get; set; }
|
public string DestinationKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("destinationPortKey")]
|
||||||
|
public string DestinationPortKey { get; set; }
|
||||||
|
|
||||||
[JsonProperty("type")]
|
[JsonProperty("type")]
|
||||||
public eRoutingSignalType Type { get; set; }
|
public eRoutingSignalType Type { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Routing\GenericExtensions.cs" />
|
<Compile Remove="Routing\GenericExtensions.cs" />
|
||||||
|
<Compile Remove="Routing\IRoutingSinkWithFeedback.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.20.42" />
|
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.20.42" />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Text;
|
|||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
@@ -41,6 +42,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
void RunRouteAction(string routeKey, string sourceListKey);
|
void RunRouteAction(string routeKey, string sourceListKey);
|
||||||
|
|
||||||
void RunRouteAction(string routeKey, string sourceListKey, Action successCallback);
|
void RunRouteAction(string routeKey, string sourceListKey, Action successCallback);
|
||||||
|
|
||||||
|
RoutingFeedbackManager RoutingFeedbackManager { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -49,6 +52,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
public interface IRunDirectRouteAction
|
public interface IRunDirectRouteAction
|
||||||
{
|
{
|
||||||
void RunDirectRoute(string sourceKey, string destinationKey, eRoutingSignalType type = eRoutingSignalType.AudioVideo);
|
void RunDirectRoute(string sourceKey, string destinationKey, eRoutingSignalType type = eRoutingSignalType.AudioVideo);
|
||||||
|
|
||||||
|
RoutingFeedbackManager RoutingFeedbackManager { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -169,18 +169,17 @@ namespace PepperDash.Essentials.Core
|
|||||||
RoutingOutputPort outputPortToUse, List<IRoutingInputsOutputs> alreadyCheckedDevices,
|
RoutingOutputPort outputPortToUse, List<IRoutingInputsOutputs> alreadyCheckedDevices,
|
||||||
eRoutingSignalType signalType, int cycle, RouteDescriptor routeTable)
|
eRoutingSignalType signalType, int cycle, RouteDescriptor routeTable)
|
||||||
{
|
{
|
||||||
|
|
||||||
cycle++;
|
cycle++;
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "GetRouteToSource: {0} {1}--> {2}", null, cycle, source.Key, destination.Key);
|
Debug.LogMessage(LogEventLevel.Verbose, "GetRouteToSource: {0} {1}--> {2}", null, cycle, source.Key, destination.Key);
|
||||||
|
|
||||||
RoutingInputPort goodInputPort = null;
|
RoutingInputPort goodInputPort = null;
|
||||||
|
|
||||||
var destDevInputTies = TieLineCollection.Default.Where(t =>
|
var destinationTieLines = TieLineCollection.Default.Where(t =>
|
||||||
t.DestinationPort.ParentDevice == destination && (t.Type == signalType || t.Type.HasFlag(eRoutingSignalType.AudioVideo)));
|
t.DestinationPort.ParentDevice == destination && (t.Type == signalType || t.Type.HasFlag(eRoutingSignalType.AudioVideo)));
|
||||||
|
|
||||||
// find a direct tie
|
// find a direct tie
|
||||||
var directTie = destDevInputTies.FirstOrDefault(
|
var directTie = destinationTieLines.FirstOrDefault(
|
||||||
t => t.DestinationPort.ParentDevice == destination
|
t => t.DestinationPort.ParentDevice == destination
|
||||||
&& t.SourcePort.ParentDevice == source);
|
&& t.SourcePort.ParentDevice == source);
|
||||||
if (directTie != null) // Found a tie directly to the source
|
if (directTie != null) // Found a tie directly to the source
|
||||||
@@ -193,7 +192,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
// No direct tie? Run back out on the inputs' attached devices...
|
// No direct tie? Run back out on the inputs' attached devices...
|
||||||
// Only the ones that are routing devices
|
// Only the ones that are routing devices
|
||||||
var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
|
var attachedMidpoints = destinationTieLines.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
|
||||||
|
|
||||||
//Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
|
//Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
|
||||||
if (alreadyCheckedDevices == null)
|
if (alreadyCheckedDevices == null)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
||||||
{
|
{
|
||||||
|
RoutingInputPort CurrentInputPort { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*/// <summary>
|
/*/// <summary>
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For fixed-source endpoint devices
|
/// For fixed-source endpoint devices
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoutingSinkWithFeedback : IRoutingSinkWithSwitching
|
public interface IRoutingSinkWithFeedback : IRoutingSinkWithSwitching
|
||||||
{
|
{
|
||||||
RouteSwitchDescriptor CurrentRoute { get; }
|
|
||||||
|
|
||||||
event EventHandler InputChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// <summary>
|
/* /// <summary>
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
|
public delegate void InputChangedEventHandler(IRoutingSinkWithSwitching destination, RoutingInputPort currentPort);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Endpoint device like a display, that selects inputs
|
/// Endpoint device like a display, that selects inputs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoutingSinkWithSwitching : IRoutingSink
|
public interface IRoutingSinkWithSwitching : IRoutingSink
|
||||||
{
|
{
|
||||||
void ExecuteSwitch(object inputSelector);
|
void ExecuteSwitch(object inputSelector);
|
||||||
}
|
|
||||||
|
event InputChangedEventHandler InputChanged;
|
||||||
|
}
|
||||||
|
|
||||||
/* /// <summary>
|
/* /// <summary>
|
||||||
/// Endpoint device like a display, that selects inputs
|
/// Endpoint device like a display, that selects inputs
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
|
public delegate void RouteChangedEventHandler(IRoutingWithFeedback midpoint, RouteSwitchDescriptor newRoute);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines an IRouting with a feedback event
|
/// Defines an IRouting with a feedback event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -10,6 +11,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
List<RouteSwitchDescriptor> CurrentRoutes { get; }
|
List<RouteSwitchDescriptor> CurrentRoutes { get; }
|
||||||
|
|
||||||
event EventHandler RoutingChanged;
|
event RouteChangedEventHandler RouteChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
165
src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs
Normal file
165
src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
using Org.BouncyCastle.Crypto.Prng;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Routing
|
||||||
|
{
|
||||||
|
public class RoutingFeedbackManager:EssentialsDevice
|
||||||
|
{
|
||||||
|
public RoutingFeedbackManager(string key, string name): base(key, name)
|
||||||
|
{
|
||||||
|
AddPostActivationAction(SubscribeForMidpointFeedback);
|
||||||
|
AddPostActivationAction(SubscribeForSinkFeedback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeForMidpointFeedback()
|
||||||
|
{
|
||||||
|
var midpointDevices = DeviceManager.AllDevices.OfType<IRoutingWithFeedback>();
|
||||||
|
|
||||||
|
foreach (var device in midpointDevices)
|
||||||
|
{
|
||||||
|
device.RouteChanged += HandleMidpointUpdate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeForSinkFeedback()
|
||||||
|
{
|
||||||
|
var sinkDevices = DeviceManager.AllDevices.OfType<IRoutingSinkWithSwitching>();
|
||||||
|
|
||||||
|
foreach (var device in sinkDevices)
|
||||||
|
{
|
||||||
|
device.InputChanged += HandleSinkUpdate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleMidpointUpdate(IRoutingWithFeedback midpoint, RouteSwitchDescriptor newRoute)
|
||||||
|
{
|
||||||
|
var devices = DeviceManager.AllDevices.OfType<IRoutingSinkWithSwitching>();
|
||||||
|
|
||||||
|
foreach(var device in devices)
|
||||||
|
{
|
||||||
|
UpdateDestination(device, device.CurrentInputPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSinkUpdate(IRoutingSinkWithSwitching sender, RoutingInputPort currentInputPort)
|
||||||
|
{
|
||||||
|
UpdateDestination(sender, currentInputPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDestination(IRoutingSinkWithSwitching destination, RoutingInputPort inputPort)
|
||||||
|
{
|
||||||
|
var tieLines = TieLineCollection.Default;
|
||||||
|
|
||||||
|
var firstTieLine = tieLines.FirstOrDefault(tl => tl.DestinationPort.Key == inputPort.Key);
|
||||||
|
|
||||||
|
if (firstTieLine == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No tieline found for inputPort {inputPort}. Clearing current source", this, inputPort);
|
||||||
|
|
||||||
|
destination.CurrentSourceInfo = null;
|
||||||
|
destination.CurrentSourceInfoKey = string.Empty;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceTieLine = GetRootTieLine(firstTieLine);
|
||||||
|
|
||||||
|
if (sourceTieLine == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No route found to source for inputPort {inputPort}. Clearing current source", this, inputPort);
|
||||||
|
|
||||||
|
destination.CurrentSourceInfo = null;
|
||||||
|
destination.CurrentSourceInfoKey = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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) => {
|
||||||
|
if(r is IHasMultipleDisplays roomMultipleDisplays)
|
||||||
|
{
|
||||||
|
return roomMultipleDisplays.Displays.Any(d => d.Value.Key == destination.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(r is IHasDefaultDisplay roomDefaultDisplay)
|
||||||
|
{
|
||||||
|
return roomDefaultDisplay.DefaultDisplay.Key == destination.Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}) ;
|
||||||
|
|
||||||
|
if(room == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "No room found for display {destination}", this, destination.Key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(room.SourceListKey);
|
||||||
|
|
||||||
|
if (sourceList == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "No source list found for source list key {key}. Unable to find source for tieLine {sourceTieLine}", this, room.SourceListKey, sourceTieLine);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceListItem = sourceList.FirstOrDefault(sli => sli.Value.SourceKey == sourceTieLine.SourcePort.ParentDevice.Key);
|
||||||
|
|
||||||
|
var source = sourceListItem.Value;
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No source found for device {key}. Clearing current source on {destination}", this, sourceTieLine.SourcePort.ParentDevice.Key, destination);
|
||||||
|
|
||||||
|
destination.CurrentSourceInfo = null;
|
||||||
|
destination.CurrentSourceInfoKey = string.Empty;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.CurrentSourceInfo = source;
|
||||||
|
destination.CurrentSourceInfoKey = source.SourceKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TieLine GetRootTieLine(TieLine tieLine)
|
||||||
|
{
|
||||||
|
TieLine nextTieLine = null;
|
||||||
|
|
||||||
|
if(tieLine.SourcePort.ParentDevice is IRoutingWithFeedback midpoint)
|
||||||
|
{
|
||||||
|
var currentRoute = midpoint.CurrentRoutes.FirstOrDefault(route => route.OutputPort.Key == tieLine.SourcePort.Key);
|
||||||
|
|
||||||
|
if(currentRoute == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "No route through midpoint {midpoint} for outputPort {outputPort}", this, midpoint.Key, tieLine.SourcePort);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTieLine = TieLineCollection.Default.FirstOrDefault(tl => tl.DestinationPort.Key == currentRoute.InputPort.Key);
|
||||||
|
|
||||||
|
if(tieLine != null)
|
||||||
|
{
|
||||||
|
return GetRootTieLine(nextTieLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tieLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tieLine.SourcePort.ParentDevice is IRoutingSource) //end of the chain
|
||||||
|
{
|
||||||
|
return tieLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTieLine = TieLineCollection.Default.FirstOrDefault(tl => tl.SourcePort.Key == tieLine.SourcePort.Key);
|
||||||
|
|
||||||
|
if(nextTieLine != null)
|
||||||
|
{
|
||||||
|
return GetRootTieLine(nextTieLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextTieLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -88,7 +88,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("Tie line: [{0}]{1} --> [{2}]{3}", SourcePort.ParentDevice.Key, SourcePort.Key,
|
return string.Format("Tie line: {0}:{1} --> {2}:{3}", SourcePort.ParentDevice.Key, SourcePort.Key,
|
||||||
DestinationPort.ParentDevice.Key, DestinationPort.Key);
|
DestinationPort.ParentDevice.Key, DestinationPort.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
/// <returns>null if config data does not match ports, cards or devices</returns>
|
/// <returns>null if config data does not match ports, cards or devices</returns>
|
||||||
public TieLine GetTieLine()
|
public TieLine GetTieLine()
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Build TieLine: {0}", this);
|
Debug.LogMessage(LogEventLevel.Information, "Build TieLine: {0}",null, this);
|
||||||
// Get the source device
|
// Get the source device
|
||||||
var sourceDev = DeviceManager.GetDeviceForKey(SourceKey) as IRoutingOutputs;
|
var sourceDev = DeviceManager.GetDeviceForKey(SourceKey) as IRoutingOutputs;
|
||||||
if (sourceDev == null)
|
if (sourceDev == null)
|
||||||
@@ -48,68 +48,29 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Get the source port
|
//Get the source port
|
||||||
RoutingOutputPort sourceOutputPort = null;
|
var sourceOutputPort = sourceDev.OutputPorts[SourcePort];
|
||||||
//// If it's a card-based device, get the card and then the source port
|
|
||||||
//if (sourceDev is ICardPortsDevice)
|
|
||||||
//{
|
|
||||||
// if (SourceCard == null)
|
|
||||||
// {
|
|
||||||
// LogError("Card missing from source device config");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// sourceOutputPort = (sourceDev as ICardPortsDevice).GetChildOutputPort(SourceCard, SourcePort);
|
|
||||||
// if (sourceOutputPort == null)
|
|
||||||
// {
|
|
||||||
// LogError("Source card does not contain port");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//// otherwise it's a normal port device, get the source port
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
sourceOutputPort = sourceDev.OutputPorts[SourcePort];
|
|
||||||
if (sourceOutputPort == null)
|
|
||||||
{
|
|
||||||
LogError("Source does not contain port");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
if (sourceOutputPort == null)
|
||||||
|
{
|
||||||
|
LogError("Source does not contain port");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//Get the Destination port
|
//Get the Destination port
|
||||||
RoutingInputPort destinationInputPort = null;
|
var destinationInputPort = destDev.InputPorts[DestinationPort];
|
||||||
//// If it's a card-based device, get the card and then the Destination port
|
|
||||||
//if (destDev is ICardPortsDevice)
|
if (destinationInputPort == null)
|
||||||
//{
|
|
||||||
// if (DestinationCard == null)
|
|
||||||
// {
|
|
||||||
// LogError("Card missing from destination device config");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// destinationInputPort = (destDev as ICardPortsDevice).GetChildInputPort(DestinationCard, DestinationPort);
|
|
||||||
// if (destinationInputPort == null)
|
|
||||||
// {
|
|
||||||
// LogError("Destination card does not contain port");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//// otherwise it's a normal port device, get the Destination port
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
destinationInputPort = destDev.InputPorts[DestinationPort];
|
|
||||||
if (destinationInputPort == null)
|
|
||||||
{
|
{
|
||||||
LogError("Destination does not contain port");
|
LogError("Destination does not contain port");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
return new TieLine(sourceOutputPort, destinationInputPort);
|
return new TieLine(sourceOutputPort, destinationInputPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogError(string msg)
|
void LogError(string msg)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "WARNING: Cannot create tie line: {0}:\r {1}", msg, this);
|
Debug.LogMessage(LogEventLevel.Error, "WARNING: Cannot create tie line: {message}:\r {tieLineConfig}",null, msg, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|||||||
@@ -20,6 +20,24 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
, IWarmingCooling
|
, IWarmingCooling
|
||||||
, IUsageTracking
|
, IUsageTracking
|
||||||
{
|
{
|
||||||
|
private RoutingInputPort _currentInputPort;
|
||||||
|
public RoutingInputPort CurrentInputPort
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _currentInputPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_currentInputPort = value;
|
||||||
|
|
||||||
|
InputChanged?.Invoke(this, _currentInputPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event InputChangedEventHandler InputChanged;
|
||||||
|
|
||||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|
||||||
public string CurrentSourceInfoKey { get; set; }
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
{
|
{
|
||||||
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingOutputs, IUsageTracking
|
public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking
|
||||||
{
|
{
|
||||||
|
|
||||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
|
public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } }
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ using Serilog.Events;
|
|||||||
namespace PepperDash.Essentials.Devices.Common
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
{
|
{
|
||||||
[Description("Wrapper class for an IR Set Top Box")]
|
[Description("Wrapper class for an IR Set Top Box")]
|
||||||
public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IHasPowerControl, ITvPresetsProvider
|
public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingSource, IUsageTracking, IHasPowerControl, ITvPresetsProvider
|
||||||
{
|
{
|
||||||
public IrOutputPortController IrPort { get; private set; }
|
public IrOutputPortController IrPort { get; private set; }
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Sources
|
namespace PepperDash.Essentials.Devices.Common.Sources
|
||||||
{
|
{
|
||||||
public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
||||||
{
|
{
|
||||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||||
public string IconName { get; set; }
|
public string IconName { get; set; }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Sources
|
namespace PepperDash.Essentials.Devices.Common.Sources
|
||||||
{
|
{
|
||||||
public class Laptop : EssentialsDevice, IHasFeedback, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
public class Laptop : EssentialsDevice, IHasFeedback, IRoutingSource, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking
|
||||||
{
|
{
|
||||||
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } }
|
||||||
public string IconName { get; set; }
|
public string IconName { get; set; }
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ using Serilog.Events;
|
|||||||
namespace PepperDash.Essentials.Devices.Common
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
{
|
{
|
||||||
[Description("Wrapper class for an IR-Controlled AppleTV")]
|
[Description("Wrapper class for an IR-Controlled AppleTV")]
|
||||||
public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs
|
public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource
|
||||||
{
|
{
|
||||||
public IrOutputPortController IrPort { get; private set; }
|
public IrOutputPortController IrPort { get; private set; }
|
||||||
public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir";
|
public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir";
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using Serilog.Events;
|
|||||||
namespace PepperDash.Essentials.Devices.Common
|
namespace PepperDash.Essentials.Devices.Common
|
||||||
{
|
{
|
||||||
[Description("Wrapper class for an IR-Controlled Roku")]
|
[Description("Wrapper class for an IR-Controlled Roku")]
|
||||||
public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs
|
public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource
|
||||||
{
|
{
|
||||||
[Api]
|
[Api]
|
||||||
public IrOutputPortController IrPort { get; private set; }
|
public IrOutputPortController IrPort { get; private set; }
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using PepperDash.Essentials.Core.Web;
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
|
||||||
namespace PepperDash.Essentials
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
@@ -386,6 +387,8 @@ namespace PepperDash.Essentials
|
|||||||
// Build the processor wrapper class
|
// Build the processor wrapper class
|
||||||
DeviceManager.AddDevice(new Core.Devices.CrestronProcessor("processor"));
|
DeviceManager.AddDevice(new Core.Devices.CrestronProcessor("processor"));
|
||||||
|
|
||||||
|
DeviceManager.AddDevice(new RoutingFeedbackManager($"routingFeedbackManager", "Routing Feedback Manager"));
|
||||||
|
|
||||||
// Add global System Monitor device
|
// Add global System Monitor device
|
||||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user