mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-04-20 07:56:50 +00:00
fix: pre-built routes now respect source ports for finding routes
This commit is contained in:
parent
db14a614bc
commit
2197dc489d
5 changed files with 94 additions and 66 deletions
|
|
@ -3,10 +3,8 @@ using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Crestron.SimplSharpPro.Keypads;
|
|
||||||
using PepperDash.Essentials.Core.Queues;
|
using PepperDash.Essentials.Core.Queues;
|
||||||
using PepperDash.Essentials.Core.Routing;
|
using PepperDash.Essentials.Core.Routing;
|
||||||
using Serilog.Events;
|
|
||||||
using Debug = PepperDash.Core.Debug;
|
using Debug = PepperDash.Core.Debug;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -69,7 +67,7 @@ namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Indexing TieLines for faster route discovery");
|
Debug.LogInformation("Indexing TieLines for faster route discovery");
|
||||||
|
|
||||||
_tieLinesByDestination = TieLineCollection.Default
|
_tieLinesByDestination = TieLineCollection.Default
|
||||||
.GroupBy(t => t.DestinationPort.ParentDevice.Key)
|
.GroupBy(t => t.DestinationPort.ParentDevice.Key)
|
||||||
|
|
@ -79,8 +77,8 @@ namespace PepperDash.Essentials.Core
|
||||||
.GroupBy(t => t.SourcePort.ParentDevice.Key)
|
.GroupBy(t => t.SourcePort.ParentDevice.Key)
|
||||||
.ToDictionary(g => g.Key, g => g.ToList());
|
.ToDictionary(g => g.Key, g => g.ToList());
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "TieLine indexing complete. {0} destination keys, {1} source keys",
|
Debug.LogInformation("TieLine indexing complete. {0} destination keys, {1} source keys",
|
||||||
null, _tieLinesByDestination.Count, _tieLinesBySource.Count);
|
_tieLinesByDestination.Count, _tieLinesBySource.Count);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -128,11 +126,13 @@ namespace PepperDash.Essentials.Core
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceKey">Source device key</param>
|
/// <param name="sourceKey">Source device key</param>
|
||||||
/// <param name="destKey">Destination device key</param>
|
/// <param name="destKey">Destination device key</param>
|
||||||
|
/// <param name="sourcePortKey">Source port key</param>
|
||||||
|
/// <param name="destinationPortKey">Destination port key</param>
|
||||||
/// <param name="type">Signal type</param>
|
/// <param name="type">Signal type</param>
|
||||||
/// <returns>Cache key string</returns>
|
/// <returns>Cache key string</returns>
|
||||||
private static string GetRouteKey(string sourceKey, string destKey, eRoutingSignalType type)
|
private static string GetRouteKey(string sourceKey, string destKey, string sourcePortKey, string destinationPortKey, eRoutingSignalType type)
|
||||||
{
|
{
|
||||||
return string.Format("{0}|{1}|{2}", sourceKey, destKey, type);
|
return $"{sourceKey}|{destKey}|{sourcePortKey}|{destinationPortKey}|{type}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -141,7 +141,7 @@ namespace PepperDash.Essentials.Core
|
||||||
public static void ClearImpossibleRoutesCache()
|
public static void ClearImpossibleRoutesCache()
|
||||||
{
|
{
|
||||||
_impossibleRoutes.Clear();
|
_impossibleRoutes.Clear();
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Impossible routes cache cleared");
|
Debug.LogInformation("Impossible routes cache cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -153,7 +153,7 @@ namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
// Remove this line before committing!!!!!
|
// Remove this line before committing!!!!!
|
||||||
var frame = new StackFrame(1, true);
|
var frame = new StackFrame(1, true);
|
||||||
Debug.LogMessage(LogEventLevel.Information, "ReleaseAndMakeRoute Called from {method} with params {destinationKey}:{sourceKey}:{signalType}:{destinationPortKey}:{sourcePortKey}", frame.GetMethod().Name, destination.Key, source.Key, signalType.ToString(), destinationPortKey, sourcePortKey);
|
Debug.LogInformation("ReleaseAndMakeRoute Called from {method} with params {destinationKey}:{sourceKey}:{signalType}:{destinationPortKey}:{sourcePortKey}", frame.GetMethod().Name, destination.Key, source.Key, signalType.ToString(), destinationPortKey, sourcePortKey);
|
||||||
|
|
||||||
var inputPort = string.IsNullOrEmpty(destinationPortKey) ? null : destination.InputPorts.FirstOrDefault(p => p.Key == destinationPortKey);
|
var inputPort = string.IsNullOrEmpty(destinationPortKey) ? null : destination.InputPorts.FirstOrDefault(p => p.Key == destinationPortKey);
|
||||||
var outputPort = string.IsNullOrEmpty(sourcePortKey) ? null : source.OutputPorts.FirstOrDefault(p => p.Key == sourcePortKey);
|
var outputPort = string.IsNullOrEmpty(sourcePortKey) ? null : source.OutputPorts.FirstOrDefault(p => p.Key == sourcePortKey);
|
||||||
|
|
@ -211,13 +211,13 @@ namespace PepperDash.Essentials.Core
|
||||||
/// <param name="destinationKey">destination device key</param>
|
/// <param name="destinationKey">destination device key</param>
|
||||||
public static void RemoveRouteRequestForDestination(string destinationKey)
|
public static void RemoveRouteRequestForDestination(string destinationKey)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Removing route request for {destination}", null, destinationKey);
|
Debug.LogInformation("Removing route request for {destination}", destinationKey);
|
||||||
|
|
||||||
var result = RouteRequests.Remove(destinationKey);
|
var result = RouteRequests.Remove(destinationKey);
|
||||||
|
|
||||||
var messageTemplate = result ? "Route Request for {destination} removed" : "Route Request for {destination} not found";
|
var messageTemplate = result ? "Route Request for {destination} removed" : "Route Request for {destination} not found";
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, messageTemplate, null, destinationKey);
|
Debug.LogInformation(messageTemplate, destinationKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -233,8 +233,8 @@ namespace PepperDash.Essentials.Core
|
||||||
if (!signalType.HasFlag(eRoutingSignalType.AudioVideo) &&
|
if (!signalType.HasFlag(eRoutingSignalType.AudioVideo) &&
|
||||||
!(signalType.HasFlag(eRoutingSignalType.Video) && signalType.HasFlag(eRoutingSignalType.SecondaryAudio)))
|
!(signalType.HasFlag(eRoutingSignalType.Video) && signalType.HasFlag(eRoutingSignalType.SecondaryAudio)))
|
||||||
{
|
{
|
||||||
var singleTypeRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, signalType);
|
var singleTypeRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, sourcePort, signalType);
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Attempting to build source route from {sourceKey} of type {type}", destination, source.Key, signalType);
|
Debug.LogDebug(destination, "Attempting to build source route from {sourceKey} of type {type}", source.Key, signalType);
|
||||||
|
|
||||||
if (!destination.GetRouteToSource(source, null, null, signalType, 0, singleTypeRouteDescriptor, destinationPort, sourcePort))
|
if (!destination.GetRouteToSource(source, null, null, signalType, 0, singleTypeRouteDescriptor, destinationPort, sourcePort))
|
||||||
singleTypeRouteDescriptor = null;
|
singleTypeRouteDescriptor = null;
|
||||||
|
|
@ -242,46 +242,46 @@ namespace PepperDash.Essentials.Core
|
||||||
var routes = singleTypeRouteDescriptor?.Routes ?? new List<RouteSwitchDescriptor>();
|
var routes = singleTypeRouteDescriptor?.Routes ?? new List<RouteSwitchDescriptor>();
|
||||||
foreach (var route in routes)
|
foreach (var route in routes)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Route for device: {route}", destination, route.ToString());
|
Debug.LogVerbose(destination, "Route for device: {route}", route.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (singleTypeRouteDescriptor, null);
|
return (singleTypeRouteDescriptor, null);
|
||||||
}
|
}
|
||||||
// otherwise, audioVideo needs to be handled as two steps.
|
// otherwise, audioVideo needs to be handled as two steps.
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Attempting to build source route from {destinationKey} to {sourceKey} of type {type}", destination, source.Key, signalType);
|
Debug.LogDebug(destination, "Attempting to build source route from {destinationKey} to {sourceKey} of type {type}", source.Key, signalType);
|
||||||
|
|
||||||
RouteDescriptor audioRouteDescriptor;
|
RouteDescriptor audioRouteDescriptor;
|
||||||
|
|
||||||
if (signalType.HasFlag(eRoutingSignalType.SecondaryAudio))
|
if (signalType.HasFlag(eRoutingSignalType.SecondaryAudio))
|
||||||
{
|
{
|
||||||
audioRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, eRoutingSignalType.SecondaryAudio);
|
audioRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, sourcePort, eRoutingSignalType.SecondaryAudio);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
audioRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, eRoutingSignalType.Audio);
|
audioRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, sourcePort, eRoutingSignalType.Audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
var audioSuccess = destination.GetRouteToSource(source, null, null, signalType.HasFlag(eRoutingSignalType.SecondaryAudio) ? eRoutingSignalType.SecondaryAudio : eRoutingSignalType.Audio, 0, audioRouteDescriptor, destinationPort, sourcePort);
|
var audioSuccess = destination.GetRouteToSource(source, null, null, signalType.HasFlag(eRoutingSignalType.SecondaryAudio) ? eRoutingSignalType.SecondaryAudio : eRoutingSignalType.Audio, 0, audioRouteDescriptor, destinationPort, sourcePort);
|
||||||
|
|
||||||
if (!audioSuccess)
|
if (!audioSuccess)
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Cannot find audio route to {0}", destination, source.Key);
|
Debug.LogDebug(destination, "Cannot find audio route to {0}", source.Key);
|
||||||
|
|
||||||
var videoRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, eRoutingSignalType.Video);
|
var videoRouteDescriptor = new RouteDescriptor(source, destination, destinationPort, sourcePort, eRoutingSignalType.Video);
|
||||||
|
|
||||||
var videoSuccess = destination.GetRouteToSource(source, null, null, eRoutingSignalType.Video, 0, videoRouteDescriptor, destinationPort, sourcePort);
|
var videoSuccess = destination.GetRouteToSource(source, null, null, eRoutingSignalType.Video, 0, videoRouteDescriptor, destinationPort, sourcePort);
|
||||||
|
|
||||||
if (!videoSuccess)
|
if (!videoSuccess)
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Cannot find video route to {0}", destination, source.Key);
|
Debug.LogDebug(destination, "Cannot find video route to {0}", source.Key);
|
||||||
|
|
||||||
foreach (var route in audioRouteDescriptor.Routes)
|
foreach (var route in audioRouteDescriptor.Routes)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Audio route for device: {route}", destination, route.ToString());
|
Debug.LogVerbose(destination, "Audio route for device: {route}", route.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var route in videoRouteDescriptor.Routes)
|
foreach (var route in videoRouteDescriptor.Routes)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Video route for device: {route}", destination, route.ToString());
|
Debug.LogVerbose(destination, "Video route for device: {route}", route.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -306,8 +306,8 @@ namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
if (destination == null) throw new ArgumentNullException(nameof(destination));
|
if (destination == null) throw new ArgumentNullException(nameof(destination));
|
||||||
if (source == null) throw new ArgumentNullException(nameof(source));
|
if (source == null) throw new ArgumentNullException(nameof(source));
|
||||||
if (destinationPort == null) Debug.LogMessage(LogEventLevel.Information, "Destination port is null");
|
if (destinationPort == null) Debug.LogDebug("Destination port is null");
|
||||||
if (sourcePort == null) Debug.LogMessage(LogEventLevel.Information, "Source port is null");
|
if (sourcePort == null) Debug.LogDebug("Source port is null");
|
||||||
|
|
||||||
var routeRequest = new RouteRequest
|
var routeRequest = new RouteRequest
|
||||||
{
|
{
|
||||||
|
|
@ -329,7 +329,7 @@ namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
RouteRequests[destination.Key] = routeRequest;
|
RouteRequests[destination.Key] = routeRequest;
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Device: {destination} is cooling down and already has a routing request stored. Storing new route request to route to source key: {sourceKey}", null, destination.Key, routeRequest.Source.Key);
|
Debug.LogInformation("Device: {destination} is cooling down and already has a routing request stored. Storing new route request to route to source key: {sourceKey}", destination.Key, routeRequest.Source.Key);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +341,7 @@ namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
RouteRequests.Add(destination.Key, routeRequest);
|
RouteRequests.Add(destination.Key, routeRequest);
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Device: {destination} is cooling down. Storing route request to route to source key: {sourceKey}", null, destination.Key, routeRequest.Source.Key);
|
Debug.LogInformation("Device: {destination} is cooling down. Storing route request to route to source key: {sourceKey}", destination.Key, routeRequest.Source.Key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -353,7 +353,7 @@ namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
RouteRequests.Remove(destination.Key);
|
RouteRequests.Remove(destination.Key);
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Device: {destination} is NOT cooling down. Removing stored route request and routing to source key: {sourceKey}", null, destination.Key, routeRequest.Source.Key);
|
Debug.LogInformation("Device: {destination} is NOT cooling down. Removing stored route request and routing to source key: {sourceKey}", destination.Key, routeRequest.Source.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
routeRequestQueue.Enqueue(new ReleaseRouteQueueItem(ReleaseRouteInternal, destination, destinationPort?.Key ?? string.Empty, false));
|
routeRequestQueue.Enqueue(new ReleaseRouteQueueItem(ReleaseRouteInternal, destination, destinationPort?.Key ?? string.Empty, false));
|
||||||
|
|
@ -469,7 +469,8 @@ namespace PepperDash.Essentials.Core
|
||||||
audioOrSingleRoute = audioCollection.Descriptors.FirstOrDefault(d =>
|
audioOrSingleRoute = audioCollection.Descriptors.FirstOrDefault(d =>
|
||||||
d.Source.Key == request.Source.Key &&
|
d.Source.Key == request.Source.Key &&
|
||||||
d.Destination.Key == request.Destination.Key &&
|
d.Destination.Key == request.Destination.Key &&
|
||||||
(request.DestinationPort == null || d.InputPort?.Key == request.DestinationPort.Key));
|
(request.DestinationPort == null || d.InputPort?.Key == request.DestinationPort.Key) &&
|
||||||
|
(request.SourcePort == null || d.OutputPort?.Key == request.SourcePort.Key));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RouteDescriptors.TryGetValue(eRoutingSignalType.Video, out RouteDescriptorCollection videoCollection))
|
if (RouteDescriptors.TryGetValue(eRoutingSignalType.Video, out RouteDescriptorCollection videoCollection))
|
||||||
|
|
@ -477,7 +478,8 @@ namespace PepperDash.Essentials.Core
|
||||||
videoRoute = videoCollection.Descriptors.FirstOrDefault(d =>
|
videoRoute = videoCollection.Descriptors.FirstOrDefault(d =>
|
||||||
d.Source.Key == request.Source.Key &&
|
d.Source.Key == request.Source.Key &&
|
||||||
d.Destination.Key == request.Destination.Key &&
|
d.Destination.Key == request.Destination.Key &&
|
||||||
(request.DestinationPort == null || d.InputPort?.Key == request.DestinationPort.Key));
|
(request.DestinationPort == null || d.InputPort?.Key == request.DestinationPort.Key) &&
|
||||||
|
(request.SourcePort == null || d.OutputPort?.Key == request.SourcePort.Key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -492,14 +494,15 @@ namespace PepperDash.Essentials.Core
|
||||||
audioOrSingleRoute = collection.Descriptors.FirstOrDefault(d =>
|
audioOrSingleRoute = collection.Descriptors.FirstOrDefault(d =>
|
||||||
d.Source.Key == request.Source.Key &&
|
d.Source.Key == request.Source.Key &&
|
||||||
d.Destination.Key == request.Destination.Key &&
|
d.Destination.Key == request.Destination.Key &&
|
||||||
(request.DestinationPort == null || d.InputPort?.Key == request.DestinationPort.Key));
|
(request.DestinationPort == null || d.InputPort?.Key == request.DestinationPort.Key) &&
|
||||||
|
(request.SourcePort == null || d.OutputPort?.Key == request.SourcePort.Key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no pre-loaded route found, build it dynamically
|
// If no pre-loaded route found, build it dynamically
|
||||||
if (audioOrSingleRoute == null && videoRoute == null)
|
if (audioOrSingleRoute == null && videoRoute == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "No pre-loaded route found, building dynamically", request.Destination);
|
Debug.LogDebug(request.Destination, "No pre-loaded route found, building dynamically");
|
||||||
(audioOrSingleRoute, videoRoute) = request.Destination.GetRouteToSource(request.Source, request.SignalType, request.DestinationPort, request.SourcePort);
|
(audioOrSingleRoute, videoRoute) = request.Destination.GetRouteToSource(request.Source, request.SignalType, request.DestinationPort, request.SourcePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -513,14 +516,15 @@ namespace PepperDash.Essentials.Core
|
||||||
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(videoRoute);
|
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(videoRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Executing full route", request.Destination);
|
Debug.LogVerbose(request.Destination, "Executing full route");
|
||||||
|
|
||||||
audioOrSingleRoute.ExecuteRoutes();
|
audioOrSingleRoute.ExecuteRoutes();
|
||||||
videoRoute?.ExecuteRoutes();
|
videoRoute?.ExecuteRoutes();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(ex, "Exception Running Route Request {request}", null, request);
|
Debug.LogError("Exception Running Route Request {request}: {exception}", request, ex.Message);
|
||||||
|
Debug.LogDebug(ex, "Stack Trace: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -534,7 +538,7 @@ namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Release route for '{destination}':'{inputPortKey}'", destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
|
Debug.LogInformation(destination, "Release route for '{destination}':'{inputPortKey}'", destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
|
||||||
|
|
||||||
if (RouteRequests.TryGetValue(destination.Key, out RouteRequest existingRequest) && destination is IWarmingCooling)
|
if (RouteRequests.TryGetValue(destination.Key, out RouteRequest existingRequest) && destination is IWarmingCooling)
|
||||||
{
|
{
|
||||||
|
|
@ -548,13 +552,14 @@ namespace PepperDash.Essentials.Core
|
||||||
var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination, inputPortKey);
|
var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination, inputPortKey);
|
||||||
if (current != null)
|
if (current != null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Releasing current route: {0}", destination, current.Source.Key);
|
Debug.LogInformation(destination, "Releasing current route: {0}", current.Source.Key);
|
||||||
current.ReleaseRoutes(clearRoute);
|
current.ReleaseRoutes(clearRoute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(ex, "Exception releasing route for '{destination}':'{inputPortKey}'", null, destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey);
|
Debug.LogError("Exception releasing route for '{destination}':'{inputPortKey}': {exception}", destination?.Key ?? null, string.IsNullOrEmpty(inputPortKey) ? "auto" : inputPortKey, ex.Message);
|
||||||
|
Debug.LogDebug(ex, "Stack Trace: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -580,14 +585,14 @@ namespace PepperDash.Essentials.Core
|
||||||
cycle++;
|
cycle++;
|
||||||
|
|
||||||
// Check if this route has already been determined to be impossible
|
// Check if this route has already been determined to be impossible
|
||||||
var routeKey = GetRouteKey(source.Key, destination.Key, signalType);
|
var routeKey = GetRouteKey(source.Key, destination.Key, sourcePort?.Key ?? "auto", destinationPort?.Key ?? "auto", signalType);
|
||||||
if (_impossibleRoutes.ContainsKey(routeKey))
|
if (_impossibleRoutes.ContainsKey(routeKey))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Route {0} is cached as impossible, skipping", null, routeKey);
|
Debug.LogVerbose("Route {0} is cached as impossible, skipping", routeKey);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "GetRouteToSource: {cycle} {sourceKey}:{sourcePortKey}--> {destinationKey}:{destinationPortKey} {type}", null, cycle, source.Key, sourcePort?.Key ?? "auto", destination.Key, destinationPort?.Key ?? "auto", signalType.ToString());
|
Debug.LogVerbose("GetRouteToSource: {cycle} {sourceKey}:{sourcePortKey}--> {destinationKey}:{destinationPortKey} {type}", null, cycle, source.Key, sourcePort?.Key ?? "auto", destination.Key, destinationPort?.Key ?? "auto", signalType.ToString());
|
||||||
|
|
||||||
RoutingInputPort goodInputPort = null;
|
RoutingInputPort goodInputPort = null;
|
||||||
|
|
||||||
|
|
@ -635,7 +640,7 @@ namespace PepperDash.Essentials.Core
|
||||||
}
|
}
|
||||||
else // no direct-connect. Walk back devices.
|
else // no direct-connect. Walk back devices.
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "is not directly connected to {sourceKey}. Walking down tie lines", destination, source.Key);
|
Debug.LogVerbose(destination, "is not directly connected to {sourceKey}. Walking down tie lines", source.Key);
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -653,13 +658,13 @@ namespace PepperDash.Essentials.Core
|
||||||
// Check if this previous device has already been walked
|
// Check if this previous device has already been walked
|
||||||
if (alreadyCheckedDevices.Contains(midpointDevice))
|
if (alreadyCheckedDevices.Contains(midpointDevice))
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Skipping input {midpointDeviceKey} on {destinationKey}, this was already checked", destination, midpointDevice.Key, destination.Key);
|
Debug.LogVerbose(destination, "Skipping input {midpointDeviceKey} on {destinationKey}, this was already checked", midpointDevice.Key, destination.Key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var midpointOutputPort = tieLine.SourcePort;
|
var midpointOutputPort = tieLine.SourcePort;
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Trying to find route on {midpointDeviceKey}", destination, midpointDevice.Key);
|
Debug.LogVerbose(destination, "Trying to find route on {midpointDeviceKey}", midpointDevice.Key);
|
||||||
|
|
||||||
// haven't seen this device yet. Do it. Pass the output port to the next
|
// haven't seen this device yet. Do it. Pass the output port to the next
|
||||||
// level to enable switching on success
|
// level to enable switching on success
|
||||||
|
|
@ -668,9 +673,9 @@ namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
if (upstreamRoutingSuccess)
|
if (upstreamRoutingSuccess)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Upstream device route found", destination);
|
Debug.LogVerbose(destination, "Upstream device route found");
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Route found on {midpointDeviceKey}", destination, midpointDevice.Key);
|
Debug.LogVerbose(destination, "Route found on {midpointDeviceKey}", midpointDevice.Key);
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "TieLine: SourcePort: {SourcePort} DestinationPort: {DestinationPort}", destination, tieLine.SourcePort, tieLine.DestinationPort);
|
Debug.LogVerbose(destination, "TieLine: SourcePort: {SourcePort} DestinationPort: {DestinationPort}", tieLine.SourcePort, tieLine.DestinationPort);
|
||||||
goodInputPort = tieLine.DestinationPort;
|
goodInputPort = tieLine.DestinationPort;
|
||||||
break; // Stop looping the inputs in this cycle
|
break; // Stop looping the inputs in this cycle
|
||||||
}
|
}
|
||||||
|
|
@ -680,7 +685,7 @@ namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
if (goodInputPort == null)
|
if (goodInputPort == null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "No route found to {0}", destination, source.Key);
|
Debug.LogVerbose(destination, "No route found to {0}", source.Key);
|
||||||
|
|
||||||
// Cache this as an impossible route
|
// Cache this as an impossible route
|
||||||
_impossibleRoutes.TryAdd(routeKey, 0);
|
_impossibleRoutes.TryAdd(routeKey, 0);
|
||||||
|
|
@ -700,7 +705,7 @@ namespace PepperDash.Essentials.Core
|
||||||
routeTable.Routes.Add(new RouteSwitchDescriptor(outputPortToUse, goodInputPort));
|
routeTable.Routes.Add(new RouteSwitchDescriptor(outputPortToUse, goodInputPort));
|
||||||
}
|
}
|
||||||
else // device is merely IRoutingInputOutputs
|
else // device is merely IRoutingInputOutputs
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "No routing. Passthrough device", destination);
|
Debug.LogVerbose(destination, "No routing. Passthrough device");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,27 @@ namespace PepperDash.Essentials.Core
|
||||||
public IRoutingInputs Destination { get; private set; }
|
public IRoutingInputs Destination { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the InputPort
|
/// The InputPort on the destination device for this route, if applicable. May be null if the route is not for a specific input port.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RoutingInputPort InputPort { get; private set; }
|
public RoutingInputPort InputPort { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Source
|
/// Gets the source device (sink or midpoint) for the route.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IRoutingOutputs Source { get; private set; }
|
public IRoutingOutputs Source { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the SignalType
|
/// Gets the OutputPort on the source device for this route, if applicable. May be null if the route is not for a specific output port.
|
||||||
|
/// </summary>
|
||||||
|
public RoutingOutputPort OutputPort { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the signal type for this route.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public eRoutingSignalType SignalType { get; private set; }
|
public eRoutingSignalType SignalType { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Routes
|
/// Gets the collection of route switch descriptors for this route.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<RouteSwitchDescriptor> Routes { get; private set; }
|
public List<RouteSwitchDescriptor> Routes { get; private set; }
|
||||||
|
|
||||||
|
|
@ -56,11 +61,24 @@ namespace PepperDash.Essentials.Core
|
||||||
/// <param name="destination">The destination device.</param>
|
/// <param name="destination">The destination device.</param>
|
||||||
/// <param name="inputPort">The destination input port (optional).</param>
|
/// <param name="inputPort">The destination input port (optional).</param>
|
||||||
/// <param name="signalType">The signal type for this route.</param>
|
/// <param name="signalType">The signal type for this route.</param>
|
||||||
public RouteDescriptor(IRoutingOutputs source, IRoutingInputs destination, RoutingInputPort inputPort, eRoutingSignalType signalType)
|
public RouteDescriptor(IRoutingOutputs source, IRoutingInputs destination, RoutingInputPort inputPort, eRoutingSignalType signalType) : this(source, destination, inputPort, null, signalType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RouteDescriptor"/> class for a route with specific destination input and source output ports.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <param name="destination"></param>
|
||||||
|
/// <param name="inputPort"></param>
|
||||||
|
/// <param name="outputPort"></param>
|
||||||
|
/// <param name="signalType"></param>
|
||||||
|
public RouteDescriptor(IRoutingOutputs source, IRoutingInputs destination, RoutingInputPort inputPort, RoutingOutputPort outputPort, eRoutingSignalType signalType)
|
||||||
{
|
{
|
||||||
Destination = destination;
|
Destination = destination;
|
||||||
InputPort = inputPort;
|
InputPort = inputPort;
|
||||||
Source = source;
|
Source = source;
|
||||||
|
OutputPort = outputPort;
|
||||||
SignalType = signalType;
|
SignalType = signalType;
|
||||||
Routes = new List<RouteSwitchDescriptor>();
|
Routes = new List<RouteSwitchDescriptor>();
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +90,7 @@ namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
foreach (var route in Routes)
|
foreach (var route in Routes)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "ExecuteRoutes: {0}", null, route.ToString());
|
Debug.LogVerbose("ExecuteRoutes: {0}", route.ToString());
|
||||||
|
|
||||||
if (route.SwitchingDevice is IRoutingSinkWithSwitching sink)
|
if (route.SwitchingDevice is IRoutingSinkWithSwitching sink)
|
||||||
{
|
{
|
||||||
|
|
@ -86,7 +104,7 @@ namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
route.OutputPort.InUseTracker.AddUser(Destination, "destination-" + SignalType);
|
route.OutputPort.InUseTracker.AddUser(Destination, "destination-" + SignalType);
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Output port {0} routing. Count={1}", null, route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
|
Debug.LogVerbose("Output port {0} routing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -112,6 +130,7 @@ namespace PepperDash.Essentials.Core
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogError("Error executing switch: {exception}", e.Message);
|
Debug.LogError("Error executing switch: {exception}", e.Message);
|
||||||
|
Debug.LogDebug(e, "Stack Trace: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,11 +142,11 @@ namespace PepperDash.Essentials.Core
|
||||||
if (route.OutputPort.InUseTracker != null)
|
if (route.OutputPort.InUseTracker != null)
|
||||||
{
|
{
|
||||||
route.OutputPort.InUseTracker.RemoveUser(Destination, "destination-" + SignalType);
|
route.OutputPort.InUseTracker.RemoveUser(Destination, "destination-" + SignalType);
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Port {0} releasing. Count={1}", null, route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
|
Debug.LogVerbose("Port {0} releasing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Error, "InUseTracker is null for OutputPort {0}", null, route.OutputPort.Key);
|
Debug.LogVerbose("InUseTracker is null for OutputPort {0}", route.OutputPort.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,20 +51,25 @@ namespace PepperDash.Essentials.Core
|
||||||
t.Destination == descriptor.Destination &&
|
t.Destination == descriptor.Destination &&
|
||||||
t.SignalType == descriptor.SignalType &&
|
t.SignalType == descriptor.SignalType &&
|
||||||
((t.InputPort == null && descriptor.InputPort == null) ||
|
((t.InputPort == null && descriptor.InputPort == null) ||
|
||||||
(t.InputPort != null && descriptor.InputPort != null && t.InputPort.Key == descriptor.InputPort.Key)));
|
(t.InputPort != null && descriptor.InputPort != null && t.InputPort.Key == descriptor.InputPort.Key)) &&
|
||||||
|
((t.OutputPort == null && descriptor.OutputPort == null) ||
|
||||||
|
(t.OutputPort != null && descriptor.OutputPort != null && t.OutputPort.Key == descriptor.OutputPort.Key)));
|
||||||
|
|
||||||
if (existingRoute != null)
|
if (existingRoute != null)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, descriptor.Destination,
|
Debug.LogInformation(descriptor.Destination,
|
||||||
"Route from {0} to {1}:{2} ({3}) already exists in this collection",
|
"Route from {source}:{outputPort} to {destination}:{inputPort} ({signalType}) already exists in this collection",
|
||||||
descriptor?.Source?.Key,
|
descriptor?.Source?.Key,
|
||||||
|
descriptor?.OutputPort?.Key ?? "auto",
|
||||||
descriptor?.Destination?.Key,
|
descriptor?.Destination?.Key,
|
||||||
descriptor?.InputPort?.Key ?? "auto",
|
descriptor?.InputPort?.Key ?? "auto",
|
||||||
descriptor?.SignalType);
|
descriptor?.SignalType
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Adding route descriptor: {0} -> {1}:{2} ({3})",
|
Debug.LogVerbose("Adding route descriptor: {source}:{outputPort} -> {destination}:{inputPort} ({signalType})",
|
||||||
descriptor?.Source?.Key,
|
descriptor?.Source?.Key,
|
||||||
|
descriptor?.OutputPort?.Key ?? "auto",
|
||||||
descriptor?.Destination?.Key,
|
descriptor?.Destination?.Key,
|
||||||
descriptor?.InputPort?.Key ?? "auto",
|
descriptor?.InputPort?.Key ?? "auto",
|
||||||
descriptor?.SignalType);
|
descriptor?.SignalType);
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ namespace PepperDash.Essentials.Core.Web
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Print the available pahts
|
/// Print the available paths
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// http(s)://{ipaddress}/cws/{basePath}
|
/// http(s)://{ipaddress}/cws/{basePath}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
@ -462,7 +461,7 @@ namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (args.Contains("?"))
|
if (!string.IsNullOrEmpty(args) && args.Contains("?"))
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Usage: listtielines [signaltype]\r\n");
|
CrestronConsole.ConsoleCommandResponse("Usage: listtielines [signaltype]\r\n");
|
||||||
CrestronConsole.ConsoleCommandResponse("Signal types: Audio, Video, SecondaryAudio, AudioVideo, UsbInput, UsbOutput\r\n");
|
CrestronConsole.ConsoleCommandResponse("Signal types: Audio, Video, SecondaryAudio, AudioVideo, UsbInput, UsbOutput\r\n");
|
||||||
|
|
@ -508,7 +507,7 @@ namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (args.Contains("?"))
|
if (!string.IsNullOrEmpty(args) && args.Contains("?"))
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Usage: visualizeroutes [signaltype] [-s source] [-d destination]\r\n");
|
CrestronConsole.ConsoleCommandResponse("Usage: visualizeroutes [signaltype] [-s source] [-d destination]\r\n");
|
||||||
CrestronConsole.ConsoleCommandResponse(" signaltype: Audio, Video, AudioVideo, etc.\r\n");
|
CrestronConsole.ConsoleCommandResponse(" signaltype: Audio, Video, AudioVideo, etc.\r\n");
|
||||||
|
|
@ -557,7 +556,7 @@ namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (args.Contains("?"))
|
if (!string.IsNullOrEmpty(args) && args.Contains("?"))
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Usage: visualizecurrentroutes [signaltype] [-s source] [-d destination]\r\n");
|
CrestronConsole.ConsoleCommandResponse("Usage: visualizecurrentroutes [signaltype] [-s source] [-d destination]\r\n");
|
||||||
CrestronConsole.ConsoleCommandResponse(" signaltype: Audio, Video, AudioVideo, etc.\r\n");
|
CrestronConsole.ConsoleCommandResponse(" signaltype: Audio, Video, AudioVideo, etc.\r\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue