diff --git a/src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs b/src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs index c6a10622..82c5ce6c 100644 --- a/src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs +++ b/src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs @@ -155,10 +155,10 @@ namespace PepperDash.Essentials.Core; } - var inputsOutputs = dev as IRoutingInputsOutputs; + var inputsOutputs = dev as IRoutingMidpoint; if (inputsOutputs == null) { - Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'", + Debug.LogMessage(LogEventLevel.Information, "GetCecPort: Device '{0}' does not support IRoutingMidpoint, failed to get CEC port called '{1}'", config.ControlPortDevKey, config.ControlPortName); return null; diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IAudioZones.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IAudioZones.cs index 540b7a03..cf7fa623 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IAudioZones.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IAudioZones.cs @@ -5,7 +5,7 @@ namespace PepperDash.Essentials.Core /// /// Identifies a device that contains audio zones /// - public interface IAudioZones : IRouting + public interface IAudioZones : IRoutingMidpointWithFeedback { /// /// Gets the collection of audio zones diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs index 3f38d4e4..2acceb89 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs @@ -9,6 +9,6 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces; /// It is designed to be implemented by devices that require these capabilities, /// such as projectors, displays, and other visual output devices. /// -public interface IDisplay : IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName +public interface IDisplay : IHasFeedback, IRoutingSinkWithFeedback, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName { } diff --git a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs index 3e61bd80..9ec918a9 100644 --- a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs @@ -18,16 +18,16 @@ public class DestinationListItem [JsonProperty("sinkKey")] public string SinkKey { get; set; } - private IRoutingSink _sinkDevice; + private IRoutingSinkWithFeedback _sinkDevice; /// /// Gets the actual device instance for this destination. /// Lazily loads the device from the DeviceManager using the SinkKey. /// [JsonIgnore] - public IRoutingSink SinkDevice + public IRoutingSinkWithFeedback SinkDevice { - get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as IRoutingSink); } + get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as IRoutingSinkWithFeedback); } } /// diff --git a/src/PepperDash.Essentials.Core/Room/Interfaces.cs b/src/PepperDash.Essentials.Core/Room/Interfaces.cs index fd55755a..5d3c704c 100644 --- a/src/PepperDash.Essentials.Core/Room/Interfaces.cs +++ b/src/PepperDash.Essentials.Core/Room/Interfaces.cs @@ -25,7 +25,7 @@ public interface IHasDefaultDisplay /// /// The default display for the room, used for presentation routing and other default routes /// - IRoutingSink DefaultDisplay { get; } + IRoutingSinkWithFeedback DefaultDisplay { get; } } /// diff --git a/src/PepperDash.Essentials.Core/Routing/Extensions.cs b/src/PepperDash.Essentials.Core/Routing/Extensions.cs index e2b30eee..19982f52 100644 --- a/src/PepperDash.Essentials.Core/Routing/Extensions.cs +++ b/src/PepperDash.Essentials.Core/Routing/Extensions.cs @@ -465,8 +465,8 @@ public static class Extensions IndexTieLines(); } - var sinks = DeviceManager.AllDevices.OfType().Where(d => !(d is IRoutingInputsOutputs)); - var sources = DeviceManager.AllDevices.OfType().Where(d => !(d is IRoutingInputsOutputs)); + var sinks = DeviceManager.AllDevices.OfType().Where(d => !(d is IRoutingMidpoint)); + var sources = DeviceManager.AllDevices.OfType().Where(d => !(d is IRoutingMidpoint)); foreach (var sink in sinks) { @@ -544,7 +544,7 @@ public static class Extensions /// The RouteDescriptor being populated as the route is discovered /// true if source is hit private static bool GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source, - RoutingOutputPort outputPortToUse, List alreadyCheckedDevices, + RoutingOutputPort outputPortToUse, List alreadyCheckedDevices, eRoutingSignalType signalType, int cycle, RouteDescriptor routeTable, RoutingInputPort destinationPort, RoutingOutputPort sourcePort) { cycle++; @@ -608,16 +608,16 @@ public static class Extensions // No direct tie? Run back out on the inputs' attached devices... // Only the ones that are routing devices - var midpointTieLines = destinationTieLines.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs); + var midpointTieLines = destinationTieLines.Where(t => t.SourcePort.ParentDevice is IRoutingMidpoint); //Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration if (alreadyCheckedDevices == null) - alreadyCheckedDevices = new List(); - alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs); + alreadyCheckedDevices = new List(); + alreadyCheckedDevices.Add(destination as IRoutingMidpoint); foreach (var tieLine in midpointTieLines) { - var midpointDevice = tieLine.SourcePort.ParentDevice as IRoutingInputsOutputs; + var midpointDevice = tieLine.SourcePort.ParentDevice as IRoutingMidpoint; // Check if this previous device has already been walked if (alreadyCheckedDevices.Contains(midpointDevice)) @@ -659,12 +659,12 @@ public static class Extensions // we have a route on corresponding inputPort. *** Do the route *** - if (destination is IRoutingSink) + if (destination is IRoutingSinkWithFeedback) { // it's a sink device routeTable.Routes.Add(new RouteSwitchDescriptor(goodInputPort)); } - else if (destination is IRouting) + else if (destination is IRoutingMidpointWithFeedback) { routeTable.Routes.Add(new RouteSwitchDescriptor(outputPortToUse, goodInputPort)); } diff --git a/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs b/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs deleted file mode 100644 index 107501b3..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace PepperDash.Essentials.Core -{ - /// - /// Delegate for SourceInfoChangeHandler - /// - public delegate void SourceInfoChangeHandler(SourceListItem info, ChangeType type); - //******************************************************************************************* - // Interfaces - - /// - /// For rooms with a single presentation source, change event - /// - [Obsolete("Use ICurrentSources instead")] - public interface IHasCurrentSourceInfoChange - { - /// - /// The key for the current source info, used to look up the source in the SourceList - /// - string CurrentSourceInfoKey { get; set; } - - /// - /// The current source info for the room, used to look up the source in the SourceList - /// - SourceListItem CurrentSourceInfo { get; set; } - - /// - /// Event that is raised when the current source info changes. - /// This is used to notify the system of changes to the current source info. - /// The event handler receives the new source info and the type of change that occurred. - /// - event SourceInfoChangeHandler CurrentSourceChange; - } -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/IMatrixRouting.cs b/src/PepperDash.Essentials.Core/Routing/IMatrixRouting.cs deleted file mode 100644 index d12e704e..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IMatrixRouting.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace PepperDash.Essentials.Core.Routing -{ - /// - /// Defines the contract for IMatrixRouting - /// - public interface IMatrixRouting - { - /// - /// Gets the input slots - /// - Dictionary InputSlots { get; } - - /// - /// Gets the output slots - /// - Dictionary OutputSlots { get; } - - /// - /// Routes the specified input slot to the specified output slot for the specified signal type - /// - /// key of the input slot - /// key of the output slot - /// signal type - void Route(string inputSlotKey, string outputSlotKey, eRoutingSignalType type); - } -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRmcRouting.cs b/src/PepperDash.Essentials.Core/Routing/IRmcRouting.cs deleted file mode 100644 index d2752f4a..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRmcRouting.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace PepperDash.Essentials.Core; - - -/// -/// Defines the contract for IRmcRouting -/// -public interface IRmcRouting : IRoutingNumeric -{ - /// - /// Feedback for the current Audio/Video source as a number - /// - IntFeedback AudioVideoSourceNumericFeedback { get; } -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRmcRoutingWithFeedback.cs b/src/PepperDash.Essentials.Core/Routing/IRmcRoutingWithFeedback.cs deleted file mode 100644 index 660183c1..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRmcRoutingWithFeedback.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace PepperDash.Essentials.Core; - -/// -/// Defines an IRmcRouting with a feedback event -/// -public interface IRmcRoutingWithFeedback : IRmcRouting -{ -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/IRouting.cs b/src/PepperDash.Essentials.Core/Routing/IRouting.cs deleted file mode 100644 index e8ab124f..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRouting.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace PepperDash.Essentials.Core; - -/// -/// Defines a midpoint device as have internal routing. Any devices in the middle of the -/// signal chain, that do switching, must implement this for routing to work otherwise -/// the routing algorithm will treat the IRoutingInputsOutputs device as a passthrough -/// device. -/// -public interface IRouting : IRoutingInputsOutputs - { - /// - /// Executes a switch on the device - /// - /// input selector - /// output selector - /// type of signal - void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType); -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingFeedback.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingFeedback.cs deleted file mode 100644 index a4e18e83..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingFeedback.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using PepperDash.Core; -namespace PepperDash.Essentials.Core; - -/// -/// Defines the contract for IRoutingFeedback -/// -public interface IRoutingFeedback : IKeyName -{ - /// - /// Event raised when a numeric switch changes - /// - event EventHandler NumericSwitchChange; - //void OnSwitchChange(RoutingNumericEventArgs e); -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingInputSlot.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingInputSlot.cs deleted file mode 100644 index 0137d6c1..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingInputSlot.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace PepperDash.Essentials.Core.Routing; - - -/// -/// Defines the contract for IRoutingInputSlot -/// -public interface IRoutingInputSlot : IRoutingSlot, IOnline, IVideoSync -{ - /// - /// Gets the Tx device key - /// - string TxDeviceKey { get; } -} - diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingInputsOutputs.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingInputsOutputs.cs deleted file mode 100644 index 9257b3d9..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingInputsOutputs.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace PepperDash.Essentials.Core; - -/// -/// Defines the contract for IRoutingInputsOutputs -/// -public interface IRoutingInputsOutputs : IRoutingInputs, IRoutingOutputs -{ -} - diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingMidpoint.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingMidpoint.cs new file mode 100644 index 00000000..e1a01521 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Routing/IRoutingMidpoint.cs @@ -0,0 +1,10 @@ +namespace PepperDash.Essentials.Core; + +/// +/// Defines a midpoint (passthrough) device that has both input and output routing ports +/// but does not perform active switching. For switching midpoints, see . +/// +public interface IRoutingMidpoint : IRoutingInputs, IRoutingOutputs +{ +} + diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingMidpointWithFeedback.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingMidpointWithFeedback.cs new file mode 100644 index 00000000..6c137c96 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Routing/IRoutingMidpointWithFeedback.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System; + +namespace PepperDash.Essentials.Core; + +/// +/// Delegate for RouteChangedEventHandler. +/// +/// The routing device where the change occurred. +/// A descriptor of the new route that was established. +public delegate void RouteChangedEventHandler(IRoutingMidpointWithFeedback midpoint, RouteSwitchDescriptor newRoute); + +/// +/// Defines a midpoint device that performs active switching and provides feedback about its current routes. +/// Combines the capabilities of the former IRouting, IRoutingWithFeedback, and IRoutingWithClear interfaces. +/// +public interface IRoutingMidpointWithFeedback : IRoutingMidpoint +{ + /// + /// Executes a switch on the device. + /// + /// Input selector. + /// Output selector. + /// Type of signal. + void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType); + + /// + /// Clears a route to an output. + /// + /// Output to clear. + /// Signal type to clear. + void ClearRoute(object outputSelector, eRoutingSignalType signalType); + + /// + /// Gets a list describing the currently active routes on this device. + /// + List CurrentRoutes { get; } + + /// + /// Event triggered when a route changes on this device. + /// + event RouteChangedEventHandler RouteChanged; +} diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingNumeric.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingNumeric.cs deleted file mode 100644 index ba334afa..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingNumeric.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace PepperDash.Essentials.Core; - - -/// -/// Defines the contract for IRoutingNumeric -/// -public interface IRoutingNumeric : IRouting -{ - /// - /// Executes a numeric switch on the device - /// - /// input selector - /// output selector - /// type of signal - void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type); -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingNumericWithFeedback.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingNumericWithFeedback.cs deleted file mode 100644 index a59e9699..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingNumericWithFeedback.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace PepperDash.Essentials.Core; - -/// -/// Defines an IRoutingNumeric with a feedback event -/// -public interface IRoutingNumericWithFeedback : IRoutingNumeric, IRoutingFeedback -{ -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingOutputSlot.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingOutputSlot.cs deleted file mode 100644 index ded827e7..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingOutputSlot.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace PepperDash.Essentials.Core.Routing; - - -/// -/// Defines the contract for IRoutingOutputSlot -/// -public interface IRoutingOutputSlot : IRoutingSlot -{ - /// - /// Event raised when output slot changes - /// - event EventHandler OutputSlotChanged; - - /// - /// Gets the Rx device key - /// - string RxDeviceKey { get; } - - /// - /// Gets the current routes - /// - Dictionary CurrentRoutes { get; } -} - diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingSink.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingSink.cs deleted file mode 100644 index 9426474a..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingSink.cs +++ /dev/null @@ -1,24 +0,0 @@ -using PepperDash.Core; -using PepperDash.Essentials.Core.Routing; - -namespace PepperDash.Essentials.Core; - -/// -/// Defines the contract for IRoutingSink -/// -public interface IRoutingSink : IRoutingInputs, IKeyName, ICurrentSources -{ -} - -/// -/// For fixed-source endpoint devices with an input port -/// -public interface IRoutingSinkWithInputPort : IRoutingSink -{ - /// - /// Gets the current input port for this routing sink. - /// - RoutingInputPort CurrentInputPort { get; } -} - - diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithFeedback.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithFeedback.cs index d4f9c484..b6f578c7 100644 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithFeedback.cs +++ b/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithFeedback.cs @@ -1,12 +1,37 @@ -namespace PepperDash.Essentials.Core; - +using PepperDash.Core; +using PepperDash.Essentials.Core.Routing; +namespace PepperDash.Essentials.Core; /// -/// Defines the contract for IRoutingSinkWithFeedback +/// Delegate for InputChangedEventHandler. /// -public interface IRoutingSinkWithFeedback : IRoutingSink +/// The sink device that changed input. +/// The new input port selected on the sink device. +public delegate void InputChangedEventHandler(IRoutingSinkWithFeedback destination, RoutingInputPort currentPort); + +/// +/// Defines a routing sink (endpoint) device that can switch inputs and provides feedback. +/// Consolidates the former IRoutingSink, IRoutingSinkWithInputPort, IRoutingSinkWithSwitching, +/// IRoutingSinkWithSwitchingWithInputPort, and IRoutingSinkWithFeedback interfaces. +/// +public interface IRoutingSinkWithFeedback : IRoutingInputs, IKeyName, ICurrentSources { + /// + /// Executes a switch on the device. + /// + /// Input selector. + void ExecuteSwitch(object inputSelector); + + /// + /// Gets the current input port for this routing sink. + /// + RoutingInputPort CurrentInputPort { get; } + + /// + /// Event raised when the input changes. + /// + event InputChangedEventHandler InputChanged; } diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithSwitching.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithSwitching.cs deleted file mode 100644 index 88e1f72b..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingSinkWithSwitching.cs +++ /dev/null @@ -1,30 +0,0 @@ - -namespace PepperDash.Essentials.Core; - -/// -/// Delegate for InputChangedEventHandler -/// -public delegate void InputChangedEventHandler(IRoutingSinkWithSwitching destination, RoutingInputPort currentPort); - -/// -/// Defines the contract for IRoutingSinkWithSwitching -/// -public interface IRoutingSinkWithSwitching : IRoutingSink -{ - /// - /// Executes a switch on the device - /// - /// input selector - void ExecuteSwitch(object inputSelector); -} - -/// -/// Defines the contract for IRoutingSinkWithSwitchingWithInputPort -/// -public interface IRoutingSinkWithSwitchingWithInputPort : IRoutingSinkWithSwitching, IRoutingSinkWithInputPort -{ - /// - /// Event raised when the input changes - /// - event InputChangedEventHandler InputChanged; -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingSlot.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingSlot.cs deleted file mode 100644 index deb5cabe..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingSlot.cs +++ /dev/null @@ -1,20 +0,0 @@ -using PepperDash.Core; - -namespace PepperDash.Essentials.Core.Routing -{ - /// - /// Defines the contract for IRoutingSlot - /// - public interface IRoutingSlot:IKeyName - { - /// - /// Gets the slot number - /// - int SlotNumber { get; } - - /// - /// Gets the supported signal types - /// - eRoutingSignalType SupportedSignalTypes { get; } - } -} diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingWithClear.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingWithClear.cs deleted file mode 100644 index dc027db9..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingWithClear.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace PepperDash.Essentials.Core; - -/// -/// Defines a routing device () that supports explicitly clearing a route on an output. -/// -public interface IRoutingWithClear : IRouting -{ - /// - /// Clears a route to an output, however a device needs to do that - /// - /// Output to clear - /// signal type to clear - void ClearRoute(object outputSelector, eRoutingSignalType signalType); -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/IRoutingWithFeedback.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingWithFeedback.cs deleted file mode 100644 index 6578ee4f..00000000 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingWithFeedback.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using System; - -namespace PepperDash.Essentials.Core; - -/// -/// Gets a list describing the currently active routes on this device. -/// -/// The routing device where the change occurred. -/// A descriptor of the new route that was established. -/// -/// Delegate for RouteChangedEventHandler -/// -public delegate void RouteChangedEventHandler(IRoutingWithFeedback midpoint, RouteSwitchDescriptor newRoute); -/// -/// Defines a routing device () that provides feedback about its current routes. -/// -public interface IRoutingWithFeedback : IRouting -{ - /// - /// Gets a list describing the currently active routes on this device. - /// - List CurrentRoutes { get; } - - /// - /// Event triggered when a route changes on this device. - /// - event RouteChangedEventHandler RouteChanged; -} diff --git a/src/PepperDash.Essentials.Core/Routing/ITxRouting.cs b/src/PepperDash.Essentials.Core/Routing/ITxRouting.cs deleted file mode 100644 index 67901117..00000000 --- a/src/PepperDash.Essentials.Core/Routing/ITxRouting.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace PepperDash.Essentials.Core; - -/// -/// Represents a routing device (typically a transmitter or source) that provides numeric feedback for its current route. -/// Extends . -/// -public interface ITxRouting : IRoutingNumeric -{ - /// - /// Feedback indicating the currently routed video source by its numeric identifier. - /// - IntFeedback VideoSourceNumericFeedback { get; } - /// - /// Feedback indicating the currently routed audio source by its numeric identifier. - /// - IntFeedback AudioSourceNumericFeedback { get; } -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/ITxRoutingWithFeedback.cs b/src/PepperDash.Essentials.Core/Routing/ITxRoutingWithFeedback.cs deleted file mode 100644 index 0ba49439..00000000 --- a/src/PepperDash.Essentials.Core/Routing/ITxRoutingWithFeedback.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace PepperDash.Essentials.Core; - -/// -/// Defines an IRmcRouting with a feedback event -/// -public interface ITxRoutingWithFeedback : ITxRouting -{ -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Routing/RouteDescriptor.cs b/src/PepperDash.Essentials.Core/Routing/RouteDescriptor.cs index fa68a42d..631aff62 100644 --- a/src/PepperDash.Essentials.Core/Routing/RouteDescriptor.cs +++ b/src/PepperDash.Essentials.Core/Routing/RouteDescriptor.cs @@ -74,13 +74,13 @@ public class RouteDescriptor { Debug.LogMessage(LogEventLevel.Verbose, "ExecuteRoutes: {0}", null, route.ToString()); - if (route.SwitchingDevice is IRoutingSinkWithSwitching sink) + if (route.SwitchingDevice is IRoutingSinkWithFeedback sink) { sink.ExecuteSwitch(route.InputPort.Selector); continue; } - if (route.SwitchingDevice is IRouting switchingDevice) + if (route.SwitchingDevice is IRoutingMidpointWithFeedback switchingDevice) { switchingDevice.ExecuteSwitch(route.InputPort.Selector, route.OutputPort.Selector, SignalType); @@ -97,9 +97,9 @@ public class RouteDescriptor /// If true, attempts to clear the route on the switching devices (e.g., set input to null/0). public void ReleaseRoutes(bool clearRoute = false) { - foreach (var route in Routes.Where(r => r.SwitchingDevice is IRouting)) + foreach (var route in Routes.Where(r => r.SwitchingDevice is IRoutingMidpointWithFeedback)) { - if (route.SwitchingDevice is IRouting switchingDevice) + if (route.SwitchingDevice is IRoutingMidpointWithFeedback switchingDevice) { if (clearRoute) { diff --git a/src/PepperDash.Essentials.Core/Routing/RouteSwitchDescriptor.cs b/src/PepperDash.Essentials.Core/Routing/RouteSwitchDescriptor.cs index 227e6d5b..38d56b93 100644 --- a/src/PepperDash.Essentials.Core/Routing/RouteSwitchDescriptor.cs +++ b/src/PepperDash.Essentials.Core/Routing/RouteSwitchDescriptor.cs @@ -45,7 +45,7 @@ /// public override string ToString() { - if (SwitchingDevice is IRouting) + if (SwitchingDevice is IRoutingMidpointWithFeedback) return $"{(SwitchingDevice != null ? SwitchingDevice.Key : "No Device")} switches output {(OutputPort != null ? OutputPort.Key : "No output port")} to input {(InputPort != null ? InputPort.Key : "No input port")}"; else return $"{(SwitchingDevice != null ? SwitchingDevice.Key : "No Device")} switches to input {(InputPort != null ? InputPort.Key : "No input port")}"; diff --git a/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs b/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs index 73401600..15855cf4 100644 --- a/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs +++ b/src/PepperDash.Essentials.Core/Routing/RoutingFeedbackManager.cs @@ -49,8 +49,8 @@ namespace PepperDash.Essentials.Core.Routing { midpointToSinksMap = new Dictionary>(); - var sinks = DeviceManager.AllDevices.OfType(); - var midpoints = DeviceManager.AllDevices.OfType(); + var sinks = DeviceManager.AllDevices.OfType(); + var midpoints = DeviceManager.AllDevices.OfType(); foreach (var sink in sinks) { @@ -80,7 +80,7 @@ namespace PepperDash.Essentials.Core.Routing /// /// Gets all upstream midpoint device keys for a given sink /// - private HashSet GetUpstreamMidpoints(IRoutingSinkWithSwitchingWithInputPort sink) + private HashSet GetUpstreamMidpoints(IRoutingSinkWithFeedback sink) { var result = new HashSet(); var visited = new HashSet(); @@ -109,7 +109,7 @@ namespace PepperDash.Essentials.Core.Routing visited.Add(tieLine.SourcePort.ParentDevice.Key); - if (tieLine.SourcePort.ParentDevice is IRoutingWithFeedback midpoint) + if (tieLine.SourcePort.ParentDevice is IRoutingMidpointWithFeedback midpoint) { midpoints.Add(midpoint.Key); @@ -131,11 +131,11 @@ namespace PepperDash.Essentials.Core.Routing } /// - /// Subscribes to the RouteChanged event on all devices implementing . + /// Subscribes to the RouteChanged event on all devices implementing . /// private void SubscribeForMidpointFeedback() { - var midpointDevices = DeviceManager.AllDevices.OfType(); + var midpointDevices = DeviceManager.AllDevices.OfType(); foreach (var device in midpointDevices) { @@ -144,12 +144,12 @@ namespace PepperDash.Essentials.Core.Routing } /// - /// Subscribes to the InputChanged event on all devices implementing . + /// Subscribes to the InputChanged event on all devices implementing . /// private void SubscribeForSinkFeedback() { var sinkDevices = - DeviceManager.AllDevices.OfType(); + DeviceManager.AllDevices.OfType(); foreach (var device in sinkDevices) { @@ -164,7 +164,7 @@ namespace PepperDash.Essentials.Core.Routing /// The midpoint device that reported a route change. /// The descriptor of the new route. private void HandleMidpointUpdate( - IRoutingWithFeedback midpoint, + IRoutingMidpointWithFeedback midpoint, RouteSwitchDescriptor newRoute ) { @@ -183,7 +183,7 @@ namespace PepperDash.Essentials.Core.Routing foreach (var sinkKey in affectedSinkKeys) { - if (DeviceManager.GetDeviceForKey(sinkKey) is IRoutingSinkWithSwitchingWithInputPort sink) + if (DeviceManager.GetDeviceForKey(sinkKey) is IRoutingSinkWithFeedback sink) { UpdateDestination(sink, sink.CurrentInputPort); } @@ -218,7 +218,7 @@ namespace PepperDash.Essentials.Core.Routing /// The sink device that reported an input change. /// The new input port selected on the sink device. private void HandleSinkUpdate( - IRoutingSinkWithSwitching sender, + IRoutingSinkWithFeedback sender, RoutingInputPort currentInputPort ) { @@ -246,7 +246,7 @@ namespace PepperDash.Essentials.Core.Routing /// The destination sink device to update. /// The currently selected input port on the destination device. private void UpdateDestination( - IRoutingSinkWithSwitching destination, + IRoutingSinkWithFeedback destination, RoutingInputPort inputPort ) { @@ -298,7 +298,7 @@ namespace PepperDash.Essentials.Core.Routing /// Called after debounce delay. /// private void UpdateDestinationImmediate( - IRoutingSinkWithSwitching destination, + IRoutingSinkWithFeedback destination, RoutingInputPort inputPort ) { @@ -491,7 +491,7 @@ namespace PepperDash.Essentials.Core.Routing // Get all potential sources (devices that only have outputs, not inputs+outputs) var sources = DeviceManager.AllDevices .OfType() - .Where(s => !(s is IRoutingInputsOutputs)); + .Where(s => !(s is IRoutingMidpoint)); // Try each signal type that this TieLine supports var signalTypes = new[] diff --git a/src/PepperDash.Essentials.Core/Web/RequestHandlers/GetRoutingDevicesAndTieLinesHandler.cs b/src/PepperDash.Essentials.Core/Web/RequestHandlers/GetRoutingDevicesAndTieLinesHandler.cs index f924c951..d532e7a2 100644 --- a/src/PepperDash.Essentials.Core/Web/RequestHandlers/GetRoutingDevicesAndTieLinesHandler.cs +++ b/src/PepperDash.Essentials.Core/Web/RequestHandlers/GetRoutingDevicesAndTieLinesHandler.cs @@ -62,8 +62,8 @@ namespace PepperDash.Essentials.Core.Web.RequestHandlers })]; } - // Check if device implements IRoutingInputsOutputs - if (device is IRoutingInputsOutputs) + // Check if device implements IRoutingMidpoint + if (device is IRoutingMidpoint) { deviceInfo.HasInputsAndOutputs = true; } diff --git a/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs b/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs index 252e4dc4..24df64ae 100644 --- a/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs +++ b/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs @@ -12,11 +12,16 @@ namespace PepperDash.Essentials.Devices.Common; /// /// Represents and audio endpoint /// -public class GenericAudioOut : EssentialsDevice, IRoutingSink +public class GenericAudioOut : EssentialsDevice, IRoutingSinkWithFeedback { /// public RoutingInputPort CurrentInputPort => AnyAudioIn; + /// + public event InputChangedEventHandler InputChanged; + + /// + public void ExecuteSwitch(object inputSelector) { } /// public Dictionary CurrentSources { get; private set; } diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs b/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs index 5a018a84..9c8137d7 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs @@ -229,7 +229,7 @@ public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced t.Start(); } - #region IRoutingSink Members + #region IRoutingSinkWithFeedback Members /// /// Typically called by the discovery routing algorithm. diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs index a9d9a261..f176c24c 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs @@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays; /// /// Represents a mock display device for testing and simulation purposes. /// -public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback +public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs, IHasPowerControlWithFeedback { /// public ISelectableItems Inputs { get; private set; } diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs index 226d4bbe..92dc2007 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs @@ -7,7 +7,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// Abstract base class for two-way display devices that provide feedback capabilities. /// Extends DisplayBase with routing feedback and power control feedback functionality. /// - public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback + public abstract class TwoWayDisplayBase : DisplayBase, IHasPowerControlWithFeedback { /// /// Gets feedback for the current input selection on the display. diff --git a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs index 7e449564..be3590ad 100644 --- a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs +++ b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Devices.Common.Generic; /// /// Represents a GenericSink /// -public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputPort, ICurrentSources +public class GenericSink : EssentialsDevice, IRoutingSinkWithFeedback { /// public Dictionary CurrentSources { get; private set; } @@ -104,43 +104,13 @@ public class GenericSink : EssentialsDevice, IRoutingSinkWithSwitchingWithInputP /// public RoutingPortCollection InputPorts { get; private set; } - /// - /// Gets or sets the CurrentSourceInfoKey - /// - public string CurrentSourceInfoKey { get; set; } - private SourceListItem _currentSource; - /// - /// Gets or sets the CurrentSourceInfo - /// - public SourceListItem CurrentSourceInfo - { - get => _currentSource; - set - { - if (value == _currentSource) - { - return; - } - - CurrentSourceChange?.Invoke(_currentSource, ChangeType.WillChange); - - _currentSource = value; - - CurrentSourceChange?.Invoke(_currentSource, ChangeType.DidChange); - } - } /// /// Gets the current input port /// public RoutingInputPort CurrentInputPort => InputPorts[0]; - /// - /// Event fired when the current source changes - /// - public event SourceInfoChangeHandler CurrentSourceChange; - /// public event InputChangedEventHandler InputChanged; diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs index 54a9d989..f2ab5254 100644 --- a/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs @@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec; /// /// Class representing a BlueJeans soft codec running on an in-room PC. /// -public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink +public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSinkWithFeedback { /// @@ -29,6 +29,12 @@ public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink /// public RoutingInputPort CurrentInputPort => AnyVideoIn; + /// + public event InputChangedEventHandler InputChanged; + + /// + public void ExecuteSwitch(object inputSelector) { } + /// public Dictionary CurrentSources { get; private set; } @@ -170,16 +176,7 @@ public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink } // store the name and UI info for routes - if (item.SourceKey == "none") - { - CurrentSourceInfoKey = routeKey; - CurrentSourceInfo = null; - } - else if (item.SourceKey != null) - { - CurrentSourceInfoKey = routeKey; - CurrentSourceInfo = item; - } + // CurrentSourceInfo tracking removed in v3 interface consolidation // report back when done if (successCallback != null) @@ -196,9 +193,9 @@ public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink /// bool DoRoute(SourceRouteListItem route) { - IRoutingSink dest = null; + IRoutingSinkWithFeedback dest = null; - dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink; + dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkWithFeedback; if (dest == null) { @@ -227,42 +224,5 @@ public class BlueJeansPc : InRoomPc, IRunRouteAction, IRoutingSink - #region IHasCurrentSourceInfoChange Members - /// - public string CurrentSourceInfoKey { get; set; } - - /// - /// The SourceListItem last run - containing names and icons - /// - public SourceListItem CurrentSourceInfo - { - get { return _CurrentSourceInfo; } - set - { - if (value == _CurrentSourceInfo) return; - - var handler = CurrentSourceChange; - // remove from in-use tracker, if so equipped - if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking) - (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control"); - - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.WillChange); - - _CurrentSourceInfo = value; - - // add to in-use tracking - if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking) - (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control"); - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.DidChange); - } - } - SourceListItem _CurrentSourceInfo; - - /// - public event SourceInfoChangeHandler CurrentSourceChange; - - #endregion } diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs index 9cc4c1d8..3e40f6b6 100644 --- a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec; /// /// Represents a GenericSoftCodec /// -public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWithSwitchingWithInputPort +public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWithFeedback { private RoutingInputPort _currentInputPort; @@ -141,46 +141,11 @@ public class GenericSoftCodec : EssentialsDevice, IRoutingSource, IRoutingSinkWi /// public RoutingPortCollection InputPorts { get; private set; } + /// /// /// Gets or sets the OutputPorts /// public RoutingPortCollection OutputPorts { get; private set; } - /// - /// Gets or sets the CurrentSourceInfoKey - /// - public string CurrentSourceInfoKey { get; set; } - - /// - /// Gets or sets the CurrentSourceInfo - /// - public SourceListItem CurrentSourceInfo - { - get - { - return _CurrentSourceInfo; - } - set - { - if (value == _CurrentSourceInfo) return; - - var handler = CurrentSourceChange; - - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.WillChange); - - _CurrentSourceInfo = value; - - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.DidChange); - } - } - - SourceListItem _CurrentSourceInfo; - - /// - /// Event fired when the current source changes - /// - public event SourceInfoChangeHandler CurrentSourceChange; /// /// Event fired when the input changes diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs index 59f6097b..de6900af 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs @@ -27,7 +27,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec; /// Base class for video codecs. Contains common properties, methods, and feedback for video codecs. /// Also contains the logic to link commonly implemented interfaces to the API bridge. /// -public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, +public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingMidpoint, IUsageTracking, ICodecCallControls, IHasContentSharing, ICodecAudio, IVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode, IHasReady { private const int XSigEncoding = 28591; @@ -302,7 +302,7 @@ public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutpu #endregion - #region IRoutingInputsOutputs Members + #region IRoutingMidpoint Members /// /// Gets or sets the InputPorts diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithFeedbackMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithFeedbackMessenger.cs new file mode 100644 index 00000000..d2883903 --- /dev/null +++ b/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithFeedbackMessenger.cs @@ -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 +{ + /// + /// Represents a DisplayBaseMessenger + /// + public class IRoutingSinkWithFeedbackMessenger : MessengerBase + { + private readonly IRoutingSinkWithFeedback display; + + /// + /// Create an instance of the class. + /// + /// + /// + /// + public IRoutingSinkWithFeedbackMessenger(string key, string messagePath, IRoutingSinkWithFeedback device) : base(key, messagePath, device) + { + display = device; + } + + /// + 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>(); + + 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); + }); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithSwitchingMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithSwitchingMessenger.cs index 1426dc25..1298608b 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithSwitchingMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/DeviceTypeExtensions/IRoutingSinkWithSwitchingMessenger.cs @@ -12,17 +12,17 @@ namespace PepperDash.Essentials.Room.MobileControl /// /// Represents a DisplayBaseMessenger /// - public class IRoutingSinkWithSwitchingMessenger : MessengerBase + public class IRoutingSinkWithFeedbackMessenger : MessengerBase { - private readonly IRoutingSinkWithSwitching display; + private readonly IRoutingSinkWithFeedback display; /// - /// Create an instance of the class. + /// Create an instance of the class. /// /// /// /// - 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; } diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCurrentSourceInfoMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCurrentSourceInfoMessenger.cs deleted file mode 100644 index 2a8dd5bc..00000000 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCurrentSourceInfoMessenger.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.AppServer.Messengers -{ - /// - /// Represents a IHasCurrentSourceInfoMessenger - /// - 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); - } - } - - /// - /// Represents a CurrentSourceStateMessage - /// - public class CurrentSourceStateMessage : DeviceStateMessageBase - { - - /// - /// Gets or sets the CurrentSourceKey - /// - [JsonProperty("currentSourceKey", NullValueHandling = NullValueHandling.Ignore)] - public string CurrentSourceKey { get; set; } - - - /// - /// Gets or sets the CurrentSource - /// - [JsonProperty("currentSource")] - public SourceListItem CurrentSource { get; set; } - } -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IMatrixRoutingMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IMatrixRoutingMessenger.cs deleted file mode 100644 index 3ea457d2..00000000 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IMatrixRoutingMessenger.cs +++ /dev/null @@ -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 -{ - /// - /// Messenger for devices that implment IMatrixRouting - /// - public class IMatrixRoutingMessenger : MessengerBase - { - private readonly IMatrixRouting matrixDevice; - - - /// - /// Initializes a new instance of the class. - /// - /// - /// - /// - public IMatrixRoutingMessenger(string key, string messagePath, IMatrixRouting device) : base(key, messagePath, device as IKeyName) - { - matrixDevice = device; - } - - /// - 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(); - - 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); - } - } - } - - /// - /// Represents a MatrixStateMessage - /// - public class MatrixStateMessage : DeviceStateMessageBase - { - /// - /// Gets or sets the Outputs - /// - [JsonProperty("outputs")] - public Dictionary Outputs; - - /// - /// Gets or sets the Inputs - /// - [JsonProperty("inputs")] - public Dictionary Inputs; - } - - /// - /// Represents a RoutingInput - /// - public class RoutingInput : IKeyName - { - private IRoutingInputSlot _input; - - /// - /// Gets the TxDeviceKey of the input slot - /// - [JsonProperty("txDeviceKey", NullValueHandling = NullValueHandling.Ignore)] - public string TxDeviceKey => _input?.TxDeviceKey; - - /// - /// Gets the SlotNumber of the input slot - /// - /// - [JsonProperty("slotNumber", NullValueHandling = NullValueHandling.Ignore)] - public int? SlotNumber => _input?.SlotNumber; - - /// - /// Gets the SupportedSignalTypes of the input slot - /// - [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - [JsonProperty("supportedSignalTypes", NullValueHandling = NullValueHandling.Ignore)] - public eRoutingSignalType? SupportedSignalTypes => _input?.SupportedSignalTypes; - - /// - /// Gets the Name of the input slot - /// - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] - public string Name => _input?.Name; - - /// - /// Gets the IsOnline of the input slot - /// - /// - [JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)] - public bool? IsOnline => _input?.IsOnline.BoolValue; - - - /// - /// Gets the VideoSyncDetected of the input slot - /// - [JsonProperty("videoSyncDetected", NullValueHandling = NullValueHandling.Ignore)] - public bool? VideoSyncDetected => _input?.VideoSyncDetected; - - /// - /// Gets the Key of the input slot - /// - [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)] - public string Key => _input?.Key; - - /// - /// Initializes a new instance of the class. - /// - /// - public RoutingInput(IRoutingInputSlot input) - { - _input = input; - } - } - - /// - /// Represents a RoutingOutput - /// - public class RoutingOutput : IKeyName - { - private IRoutingOutputSlot _output; - - /// - /// Initializes a new instance of the class. - /// - /// - public RoutingOutput(IRoutingOutputSlot output) - { - _output = output; - } - - /// - /// Gets the RxDeviceKey of the output slot - /// - [JsonProperty("rxDeviceKey")] - public string RxDeviceKey => _output.RxDeviceKey; - - /// - /// Gets the CurrentRoutes of the output slot - /// - [JsonProperty("currentRoutes")] - public Dictionary CurrentRoutes => _output.CurrentRoutes.ToDictionary(kvp => kvp.Key.ToString(), kvp => new RoutingInput(kvp.Value)); - - /// - /// Gets the SlotNumber of the output slot - /// - [JsonProperty("slotNumber")] - public int SlotNumber => _output.SlotNumber; - - /// - /// Gets the SupportedSignalTypes of the output slot - /// - [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - [JsonProperty("supportedSignalTypes")] - public eRoutingSignalType SupportedSignalTypes => _output.SupportedSignalTypes; - - - /// - /// Gets the Name of the output slot - /// - [JsonProperty("name")] - public string Name => _output.Name; - - - /// - /// Gets the Key of the output slot - /// - [JsonProperty("key")] - public string Key => _output.Key; - } - - /// - /// Represents a MatrixRouteRequest - /// - public class MatrixRouteRequest - { - /// - /// Gets or sets the OutputKey - /// - [JsonProperty("outputKey")] - public string OutputKey { get; set; } - - /// - /// Gets or sets the InputKey - /// - [JsonProperty("inputKey")] - public string InputKey { get; set; } - - /// - /// Gets or sets the RouteType - /// - [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - [JsonProperty("routeType")] - public eRoutingSignalType RouteType { get; set; } - } -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IRoutingMidpointWithFeedbackMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IRoutingMidpointWithFeedbackMessenger.cs new file mode 100644 index 00000000..1f5c7789 --- /dev/null +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IRoutingMidpointWithFeedbackMessenger.cs @@ -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 +{ + /// + /// Messenger for devices that implement IRoutingMidpointWithFeedback + /// + 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(); + _device.ExecuteSwitch(request.InputSelector, request.OutputSelector, request.SignalType); + }); + + AddAction("/clearRoute", (id, content) => + { + var request = content.ToObject(); + _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; } + } +} diff --git a/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs b/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs index 6caae7b2..e3454031 100644 --- a/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs +++ b/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs @@ -116,9 +116,9 @@ namespace PepperDash.Essentials // ── Displays ───────────────────────────────────────────────────────────── new MessengerFactoryEntry( - typeof(IRoutingSinkWithSwitching), - (d, mp, ck) => new IRoutingSinkWithSwitchingMessenger( - $"{d.Key}-displayBase-{ck}", mp, (IRoutingSinkWithSwitching)d) + typeof(IRoutingSinkWithFeedback), + (d, mp, ck) => new IRoutingSinkWithFeedbackMessenger( + $"{d.Key}-displayBase-{ck}", mp, (IRoutingSinkWithFeedback)d) ), new MessengerFactoryEntry( typeof(IDisplayCurrentInput), @@ -337,9 +337,9 @@ namespace PepperDash.Essentials // ── Matrix routing ──────────────────────────────────────────────────────── // Preserving original key format (no controller key suffix) new MessengerFactoryEntry( - typeof(IMatrixRouting), - (d, mp, _) => new IMatrixRoutingMessenger( - $"{d.Key}-matrixRouting", mp, (IMatrixRouting)d) + typeof(IRoutingMidpointWithFeedback), + (d, mp, _) => new IRoutingMidpointWithFeedbackMessenger( + $"{d.Key}-matrixRouting", mp, (IRoutingMidpointWithFeedback)d) ), // ── Environmental sensors ───────────────────────────────────────────────── diff --git a/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs b/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs index b6aca416..22143a51 100644 --- a/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs +++ b/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs @@ -140,9 +140,6 @@ namespace PepperDash.Essentials.RoomBridges if (Room is IRunDefaultPresentRoute defaultRoom) AddAction("/defaultsource", (id, content) => defaultRoom.RunDefaultPresentRoute()); - if (Room is IHasCurrentSourceInfoChange sscRoom) - sscRoom.CurrentSourceChange += Room_CurrentSingleSourceChange; - if (Room is IPrivacy privacyRoom) { @@ -353,9 +350,9 @@ namespace PepperDash.Essentials.RoomBridges string shareText; bool isSharing; - if (Room is IHasCurrentSourceInfoChange srcInfoRoom && Room is IHasVideoCodec vcRoom && vcRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && srcInfoRoom.CurrentSourceInfo != null) + if (Room is IHasVideoCodec vcRoom && vcRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue) { - shareText = srcInfoRoom.CurrentSourceInfo.PreferredName; + shareText = "Sharing"; isSharing = true; } else @@ -470,18 +467,7 @@ namespace PepperDash.Essentials.RoomBridges } - private void Room_CurrentSingleSourceChange(SourceListItem info, ChangeType type) - { - /* Example message - * { -   "type":"/room/status", -   "content": { -     "selectedSourceKey": "off", -   } - } - */ - } /// /// Sends the full status of the room to the server @@ -512,7 +498,7 @@ namespace PepperDash.Essentials.RoomBridges { this.LogVerbose("GetFullStatus"); - var sourceKey = room is IHasCurrentSourceInfoChange ? (room as IHasCurrentSourceInfoChange).CurrentSourceInfoKey : null; + var sourceKey = (string)null; var volumes = new Dictionary(); if (room is IHasCurrentVolumeControls rmVc)