mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-08-31 19:08:29 +00:00
feat: Refactor routing interfaces and feedback mechanisms
- Removed ITxRouting and ITxRoutingWithFeedback interfaces as they were redundant. - Updated RouteDescriptor and RouteSwitchDescriptor to use new feedback interfaces. - Modified RoutingFeedbackManager to utilize IRoutingSinkWithFeedback and IRoutingMidpointWithFeedback. - Adjusted GenericAudioOut, BlueJeansPc, and other device classes to implement new feedback interfaces. - Introduced new messenger classes for IRoutingSinkWithFeedback and IRoutingMidpointWithFeedback. - Cleaned up unused messenger interfaces and consolidated routing logic. - Updated MobileControlEssentialsRoomBridge to remove dependency on IHasCurrentSourceInfoChange.
This commit is contained in:
parent
b9dcec587d
commit
f64b595fd7
46 changed files with 324 additions and 872 deletions
|
|
@ -0,0 +1,72 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using System.Linq;
|
||||
using DisplayBase = PepperDash.Essentials.Devices.Common.Displays.DisplayBase;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a DisplayBaseMessenger
|
||||
/// </summary>
|
||||
public class IRoutingSinkWithFeedbackMessenger : MessengerBase
|
||||
{
|
||||
private readonly IRoutingSinkWithFeedback display;
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of the <see cref="IRoutingSinkWithFeedbackMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
/// <param name="device"></param>
|
||||
public IRoutingSinkWithFeedbackMessenger(string key, string messagePath, IRoutingSinkWithFeedback device) : base(key, messagePath, device)
|
||||
{
|
||||
display = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
/*AddAction("/powerOn", (id, content) => display.PowerOn());
|
||||
AddAction("/powerOff", (id, content) => display.PowerOff());
|
||||
AddAction("/powerToggle", (id, content) => display.PowerToggle());*/
|
||||
|
||||
AddAction("/inputSelect", (id, content) =>
|
||||
{
|
||||
var s = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
var inputPort = display.InputPorts.FirstOrDefault(i => i.Key == s.Value);
|
||||
|
||||
if (inputPort == null)
|
||||
{
|
||||
this.LogWarning("No input named {inputName} found for {deviceKey}", s, display.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
display.ExecuteSwitch(inputPort.Selector);
|
||||
});
|
||||
|
||||
AddAction("/inputs", (id, content) =>
|
||||
{
|
||||
var inputsList = display.InputPorts.Select(p => p.Key).ToList();
|
||||
|
||||
var messageObject = new MobileControlMessage
|
||||
{
|
||||
Type = MessagePath + "/inputs",
|
||||
Content = JToken.FromObject(new
|
||||
{
|
||||
inputKeys = inputsList,
|
||||
})
|
||||
};
|
||||
|
||||
AppServerController.SendMessageObject(messageObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,17 +12,17 @@ namespace PepperDash.Essentials.Room.MobileControl
|
|||
/// <summary>
|
||||
/// Represents a DisplayBaseMessenger
|
||||
/// </summary>
|
||||
public class IRoutingSinkWithSwitchingMessenger : MessengerBase
|
||||
public class IRoutingSinkWithFeedbackMessenger : MessengerBase
|
||||
{
|
||||
private readonly IRoutingSinkWithSwitching display;
|
||||
private readonly IRoutingSinkWithFeedback display;
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of the <see cref="IRoutingSinkWithSwitchingMessenger"/> class.
|
||||
/// Create an instance of the <see cref="IRoutingSinkWithFeedbackMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
/// <param name="device"></param>
|
||||
public IRoutingSinkWithSwitchingMessenger(string key, string messagePath, IRoutingSinkWithSwitching device) : base(key, messagePath, device)
|
||||
public IRoutingSinkWithFeedbackMessenger(string key, string messagePath, IRoutingSinkWithFeedback device) : base(key, messagePath, device)
|
||||
{
|
||||
display = device;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a IHasCurrentSourceInfoMessenger
|
||||
/// </summary>
|
||||
public class IHasCurrentSourceInfoMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHasCurrentSourceInfoChange sourceDevice;
|
||||
|
||||
public IHasCurrentSourceInfoMessenger(string key, string messagePath, IHasCurrentSourceInfoChange device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
sourceDevice = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
|
||||
AddAction("/currentSourceInfoStatus", (id, content) => SendFullStatus(id));
|
||||
|
||||
sourceDevice.CurrentSourceChange += (sender, e) =>
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case ChangeType.DidChange:
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
currentSourceKey = string.IsNullOrEmpty(sourceDevice.CurrentSourceInfoKey) ? string.Empty : sourceDevice.CurrentSourceInfoKey,
|
||||
currentSource = sourceDevice.CurrentSourceInfo
|
||||
}));
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
{
|
||||
var message = new CurrentSourceStateMessage
|
||||
{
|
||||
CurrentSourceKey = sourceDevice.CurrentSourceInfoKey,
|
||||
CurrentSource = sourceDevice.CurrentSourceInfo
|
||||
};
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a CurrentSourceStateMessage
|
||||
/// </summary>
|
||||
public class CurrentSourceStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSourceKey
|
||||
/// </summary>
|
||||
[JsonProperty("currentSourceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentSourceKey { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CurrentSource
|
||||
/// </summary>
|
||||
[JsonProperty("currentSource")]
|
||||
public SourceListItem CurrentSource { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,267 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implment IMatrixRouting
|
||||
/// </summary>
|
||||
public class IMatrixRoutingMessenger : MessengerBase
|
||||
{
|
||||
private readonly IMatrixRouting matrixDevice;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IMatrixRoutingMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
/// <param name="device"></param>
|
||||
public IMatrixRoutingMessenger(string key, string messagePath, IMatrixRouting device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
matrixDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
|
||||
AddAction("/matrixStatus", (id, content) => SendFullStatus(id));
|
||||
|
||||
AddAction("/route", (id, content) =>
|
||||
{
|
||||
var request = content.ToObject<MatrixRouteRequest>();
|
||||
|
||||
matrixDevice.Route(request.InputKey, request.OutputKey, request.RouteType);
|
||||
});
|
||||
|
||||
foreach (var output in matrixDevice.OutputSlots)
|
||||
{
|
||||
var key = output.Key;
|
||||
var outputSlot = output.Value;
|
||||
|
||||
outputSlot.OutputSlotChanged += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value))
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var input in matrixDevice.InputSlots)
|
||||
{
|
||||
var key = input.Key;
|
||||
var inputSlot = input.Value;
|
||||
|
||||
inputSlot.VideoSyncChanged += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value))
|
||||
}));
|
||||
};
|
||||
|
||||
inputSlot.IsOnline.OutputChange += (sender, args) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value))
|
||||
}));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "InputCount: {inputCount}, OutputCount: {outputCount}", this, matrixDevice.InputSlots.Count, matrixDevice.OutputSlots.Count);
|
||||
var message = new MatrixStateMessage
|
||||
{
|
||||
Outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value)),
|
||||
Inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value)),
|
||||
};
|
||||
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(e, "Exception Getting full status: {@exception}", this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a MatrixStateMessage
|
||||
/// </summary>
|
||||
public class MatrixStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Outputs
|
||||
/// </summary>
|
||||
[JsonProperty("outputs")]
|
||||
public Dictionary<string, RoutingOutput> Outputs;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Inputs
|
||||
/// </summary>
|
||||
[JsonProperty("inputs")]
|
||||
public Dictionary<string, RoutingInput> Inputs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a RoutingInput
|
||||
/// </summary>
|
||||
public class RoutingInput : IKeyName
|
||||
{
|
||||
private IRoutingInputSlot _input;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the TxDeviceKey of the input slot
|
||||
/// </summary>
|
||||
[JsonProperty("txDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TxDeviceKey => _input?.TxDeviceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SlotNumber of the input slot
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("slotNumber", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? SlotNumber => _input?.SlotNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SupportedSignalTypes of the input slot
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("supportedSignalTypes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eRoutingSignalType? SupportedSignalTypes => _input?.SupportedSignalTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Name of the input slot
|
||||
/// </summary>
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name => _input?.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the IsOnline of the input slot
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOnline => _input?.IsOnline.BoolValue;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the VideoSyncDetected of the input slot
|
||||
/// </summary>
|
||||
[JsonProperty("videoSyncDetected", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? VideoSyncDetected => _input?.VideoSyncDetected;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Key of the input slot
|
||||
/// </summary>
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key => _input?.Key;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoutingInput"/> class.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
public RoutingInput(IRoutingInputSlot input)
|
||||
{
|
||||
_input = input;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a RoutingOutput
|
||||
/// </summary>
|
||||
public class RoutingOutput : IKeyName
|
||||
{
|
||||
private IRoutingOutputSlot _output;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoutingOutput"/> class.
|
||||
/// </summary>
|
||||
/// <param name="output"></param>
|
||||
public RoutingOutput(IRoutingOutputSlot output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RxDeviceKey of the output slot
|
||||
/// </summary>
|
||||
[JsonProperty("rxDeviceKey")]
|
||||
public string RxDeviceKey => _output.RxDeviceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CurrentRoutes of the output slot
|
||||
/// </summary>
|
||||
[JsonProperty("currentRoutes")]
|
||||
public Dictionary<string, RoutingInput> CurrentRoutes => _output.CurrentRoutes.ToDictionary(kvp => kvp.Key.ToString(), kvp => new RoutingInput(kvp.Value));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SlotNumber of the output slot
|
||||
/// </summary>
|
||||
[JsonProperty("slotNumber")]
|
||||
public int SlotNumber => _output.SlotNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SupportedSignalTypes of the output slot
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("supportedSignalTypes")]
|
||||
public eRoutingSignalType SupportedSignalTypes => _output.SupportedSignalTypes;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Name of the output slot
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name => _output.Name;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Key of the output slot
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key => _output.Key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a MatrixRouteRequest
|
||||
/// </summary>
|
||||
public class MatrixRouteRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the OutputKey
|
||||
/// </summary>
|
||||
[JsonProperty("outputKey")]
|
||||
public string OutputKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InputKey
|
||||
/// </summary>
|
||||
[JsonProperty("inputKey")]
|
||||
public string InputKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the RouteType
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("routeType")]
|
||||
public eRoutingSignalType RouteType { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement IRoutingMidpointWithFeedback
|
||||
/// </summary>
|
||||
public class IRoutingMidpointWithFeedbackMessenger : MessengerBase
|
||||
{
|
||||
private readonly IRoutingMidpointWithFeedback _device;
|
||||
|
||||
public IRoutingMidpointWithFeedbackMessenger(string key, string messagePath, IRoutingMidpointWithFeedback device)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
_device = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
|
||||
AddAction("/route", (id, content) =>
|
||||
{
|
||||
var request = content.ToObject<MidpointRouteRequest>();
|
||||
_device.ExecuteSwitch(request.InputSelector, request.OutputSelector, request.SignalType);
|
||||
});
|
||||
|
||||
AddAction("/clearRoute", (id, content) =>
|
||||
{
|
||||
var request = content.ToObject<MidpointClearRouteRequest>();
|
||||
_device.ClearRoute(request.OutputSelector, request.SignalType);
|
||||
});
|
||||
|
||||
_device.RouteChanged += OnRouteChanged;
|
||||
}
|
||||
|
||||
private void OnRouteChanged(IRoutingMidpointWithFeedback midpoint, RouteSwitchDescriptor newRoute)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
currentRoutes = _device.CurrentRoutes.Select(r => new
|
||||
{
|
||||
inputPort = r.InputPort?.Key,
|
||||
outputPort = r.OutputPort?.Key
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
{
|
||||
var message = JToken.FromObject(new
|
||||
{
|
||||
inputPorts = _device.InputPorts.Select(p => new { key = p.Key }),
|
||||
outputPorts = _device.OutputPorts.Select(p => new { key = p.Key }),
|
||||
currentRoutes = _device.CurrentRoutes.Select(r => new
|
||||
{
|
||||
inputPort = r.InputPort?.Key,
|
||||
outputPort = r.OutputPort?.Key
|
||||
})
|
||||
});
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
}
|
||||
}
|
||||
|
||||
public class MidpointRouteRequest
|
||||
{
|
||||
[JsonProperty("inputSelector")]
|
||||
public object InputSelector { get; set; }
|
||||
|
||||
[JsonProperty("outputSelector")]
|
||||
public object OutputSelector { get; set; }
|
||||
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("signalType")]
|
||||
public eRoutingSignalType SignalType { get; set; }
|
||||
}
|
||||
|
||||
public class MidpointClearRouteRequest
|
||||
{
|
||||
[JsonProperty("outputSelector")]
|
||||
public object OutputSelector { get; set; }
|
||||
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("signalType")]
|
||||
public eRoutingSignalType SignalType { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue