From 056614cba111396fa79477d650f5863a0d3751c8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 9 Jul 2025 14:32:01 -0500 Subject: [PATCH 01/11] fix: add IMeterFeedback interface --- .vscode/extensions.json | 9 +++++++++ .../DeviceTypeInterfaces/IMeterFeedback.cs | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .vscode/extensions.json create mode 100644 src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMeterFeedback.cs diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..48c5715a --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "ms-dotnettools.vscode-dotnet-runtime", + "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit", + "vivaxy.vscode-conventional-commits", + "mhutchie.git-graph" + ] +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMeterFeedback.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMeterFeedback.cs new file mode 100644 index 00000000..a4b935a5 --- /dev/null +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IMeterFeedback.cs @@ -0,0 +1,18 @@ +using System; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces +{ + + /// + /// Interface for devices that provide audio meter feedback. + /// This interface is used to standardize access to meter feedback across different devices. + /// + public interface IMeterFeedback + { + /// + /// Gets the meter feedback for the device. + /// This property provides an IntFeedback that represents the current audio level or meter value. + /// + IntFeedback MeterFeedback { get; } + } +} From 2a70fc678e0394eca70489abdf33672c5d934344 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 11 Jul 2025 13:13:52 -0500 Subject: [PATCH 02/11] fix: add IStateFeedback interface --- .../DeviceTypeInterfaces/IStateFeedback.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs new file mode 100644 index 00000000..e4070594 --- /dev/null +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs @@ -0,0 +1,18 @@ +using System; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces +{ + + /// + /// Interface for devices that provide audio meter feedback. + /// This interface is used to standardize access to meter feedback across different devices. + /// + public interface IStateFeedback + { + /// + /// Gets the state feedback for the device. + /// This property provides a BoolFeedback that represents the current state (on/off) of the device. + /// + BoolFeedback StateFeedback { get; } + } +} From ddbcc13c50613ad752588df42d8e49d540043a1d Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 16 Jul 2025 10:41:46 -0500 Subject: [PATCH 03/11] fix: add property for sync device association --- .../Devices/SourceListItem.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs index ae223005..0c7f3cf0 100644 --- a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs @@ -1,12 +1,14 @@ -using Newtonsoft.Json; +using System.Collections.Generic; +using Newtonsoft.Json; using Newtonsoft.Json.Converters; using PepperDash.Core; -using System.Collections.Generic; namespace PepperDash.Essentials.Core { /// - /// + /// Defines the type of source list item, which can be a route, off, or other. + /// This is used to categorize the source list items in a room. + /// The type is serialized to JSON and can be used to determine how the item should be displayed or handled in the UI. /// public enum eSourceListItemType { @@ -166,6 +168,12 @@ namespace PepperDash.Essentials.Core [JsonProperty("disableSimpleRouting")] public bool DisableSimpleRouting { get; set; } + /// + /// The key of the device that provides video sync for this source item + /// + [JsonProperty("syncProviderDeviceKey")] + public string SyncProviderDeviceKey { get; set; } + /// /// Default constructor for SourceListItem, initializes the Icon to "Blank" /// @@ -177,7 +185,7 @@ namespace PepperDash.Essentials.Core /// /// Returns a string representation of the SourceListItem, including the SourceKey and Name /// - /// + /// A string representation of the SourceListItem public override string ToString() { return $"{SourceKey}:{Name}"; From 9813673b663d465cf0420b19233f13180fd108af Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 17 Jul 2025 09:15:25 -0500 Subject: [PATCH 04/11] feat: ICurrentSources interface to allow for tracking breakaway routing --- .../DeviceTypeInterfaces/IDisplay.cs | 9 +- .../Devices/SourceListItem.cs | 7 + .../Routing/ICurrentSources.cs | 28 ++ .../Routing/IHasCurrentSourceInfoChange.cs | 16 + .../Routing/IRoutingSink.cs | 22 +- .../Displays/DisplayBase.cs | 341 ++++++++++++------ 6 files changed, 309 insertions(+), 114 deletions(-) create mode 100644 src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs index 9b82cacd..af3428f6 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IDisplay.cs @@ -2,7 +2,14 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { - public interface IDisplay: IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName + /// + /// Interface for display devices that can be controlled and monitored. + /// This interface combines functionality for feedback, routing, power control, + /// warming/cooling, usage tracking, and key name management. + /// 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 { } } diff --git a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs index 0c7f3cf0..bfba4b4c 100644 --- a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs @@ -174,6 +174,13 @@ namespace PepperDash.Essentials.Core [JsonProperty("syncProviderDeviceKey")] public string SyncProviderDeviceKey { get; set; } + /// + /// Indicates if the source supports USB connections + /// + [JsonProperty("supportsUsb")] + public bool SupportsUsb { get; set; } + + /// /// Default constructor for SourceListItem, initializes the Icon to "Blank" /// diff --git a/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs b/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs new file mode 100644 index 00000000..d3f51483 --- /dev/null +++ b/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace PepperDash.Essentials.Core.Routing +{ + /// + /// The current sources for the room, keyed by eRoutingSignalType. + /// This allows for multiple sources to be tracked, such as audio and video. + /// + /// + /// This interface is used to provide access to the current sources in a room, + /// allowing for more complex routing scenarios where multiple signal types are involved. + /// + public interface ICurrentSources + { + /// + /// Gets the current sources for the room, keyed by eRoutingSignalType. + /// This dictionary contains the current source for each signal type, such as audio, video, + /// + Dictionary CurrentSources { get; } + + /// + /// Gets the current source keys for the room, keyed by eRoutingSignalType. + /// This dictionary contains the keys for the current source for each signal type, such as audio, + /// + Dictionary CurrentSourceKeys { get; } + + } +} diff --git a/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs b/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs index 505a8652..a8dbc594 100644 --- a/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs +++ b/src/PepperDash.Essentials.Core/Routing/IHasCurrentSourceInfoChange.cs @@ -9,6 +9,8 @@ using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Core.Routing.Interfaces */ +using System; + namespace PepperDash.Essentials.Core { /// @@ -21,10 +23,24 @@ namespace PepperDash.Essentials.Core /// /// 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/IRoutingSink.cs b/src/PepperDash.Essentials.Core/Routing/IRoutingSink.cs index 59bcd65b..dd1d004e 100644 --- a/src/PepperDash.Essentials.Core/Routing/IRoutingSink.cs +++ b/src/PepperDash.Essentials.Core/Routing/IRoutingSink.cs @@ -1,29 +1,29 @@ -namespace PepperDash.Essentials.Core +using PepperDash.Essentials.Core.Routing; + +namespace PepperDash.Essentials.Core { /// /// For fixed-source endpoint devices /// public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange - { + { } /// /// For fixed-source endpoint devices with an input port /// - public interface IRoutingSinkWithInputPort :IRoutingSink + public interface IRoutingSinkWithInputPort : IRoutingSink { /// /// Gets the current input port for this routing sink. /// RoutingInputPort CurrentInputPort { get; } } - /*/// - /// For fixed-source endpoint devices - /// - public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange - { - void UpdateRouteRequest(RouteRequest request); - RouteRequest GetRouteRequest(); - }*/ + /// + /// Interface for routing sinks that have access to the current source information. + /// + public interface IRoutingSinkWithCurrentSources : IRoutingSink, ICurrentSources + { + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs index 24d55c2e..926fca04 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs @@ -1,110 +1,199 @@ -using Crestron.SimplSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Routing; using Serilog.Events; -using System; -using System.Collections.Generic; -using System.Linq; using Feedback = PepperDash.Essentials.Core.Feedback; namespace PepperDash.Essentials.Devices.Common.Displays { - public abstract class DisplayBase : EssentialsDevice, IDisplay + /// + /// Abstract base class for display devices that provides common display functionality + /// including power control, input switching, and routing capabilities. + /// + public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources { - private RoutingInputPort _currentInputPort; - public RoutingInputPort CurrentInputPort - { - get - { - return _currentInputPort; - } + private RoutingInputPort _currentInputPort; - protected set - { - if (_currentInputPort == value) return; + /// + /// Gets or sets the current input port that is selected on the display. + /// + public RoutingInputPort CurrentInputPort + { + get + { + return _currentInputPort; + } - _currentInputPort = value; + protected set + { + if (_currentInputPort == value) return; - InputChanged?.Invoke(this, _currentInputPort); - } - } + _currentInputPort = value; - public event InputChangedEventHandler InputChanged; + InputChanged?.Invoke(this, _currentInputPort); + } + } - public event SourceInfoChangeHandler CurrentSourceChange; + /// + /// Event that is raised when the input changes on the display. + /// + public event InputChangedEventHandler InputChanged; - public string CurrentSourceInfoKey { get; set; } - public SourceListItem CurrentSourceInfo - { - get - { - return _CurrentSourceInfo; - } - set - { - if (value == _CurrentSourceInfo) return; + /// + /// Event that is raised when the current source information changes. + /// + public event SourceInfoChangeHandler CurrentSourceChange; - var handler = CurrentSourceChange; + /// + /// Gets or sets the key of the current source information. + /// + public string CurrentSourceInfoKey { get; set; } - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.WillChange); + /// + /// Gets or sets the current source information for the display. + /// + public SourceListItem CurrentSourceInfo + { + get + { + return _CurrentSourceInfo; + } + set + { + if (value == _CurrentSourceInfo) return; - _CurrentSourceInfo = value; + var handler = CurrentSourceChange; - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.DidChange); - } - } - SourceListItem _CurrentSourceInfo; + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.WillChange); + _CurrentSourceInfo = value; + + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.DidChange); + } + } + SourceListItem _CurrentSourceInfo; + + /// + public Dictionary CurrentSources { get; private set; } + + /// + public Dictionary CurrentSourceKeys { get; private set; } + + /// + /// Gets feedback indicating whether the display is currently cooling down after being powered off. + /// public BoolFeedback IsCoolingDownFeedback { get; protected set; } + + /// + /// Gets feedback indicating whether the display is currently warming up after being powered on. + /// public BoolFeedback IsWarmingUpFeedback { get; private set; } - public UsageTracking UsageTracker { get; set; } + /// + /// Gets or sets the usage tracking instance for monitoring display usage statistics. + /// + public UsageTracking UsageTracker { get; set; } + /// + /// Gets or sets the warmup time in milliseconds for the display to become ready after power on. + /// public uint WarmupTime { get; set; } + + /// + /// Gets or sets the cooldown time in milliseconds for the display to fully power down. + /// public uint CooldownTime { get; set; } /// - /// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented - /// by concrete sub-classes + /// Abstract function that must be implemented by derived classes to provide the cooling down feedback value. + /// Must be implemented by concrete sub-classes. /// abstract protected Func IsCoolingDownFeedbackFunc { get; } - abstract protected Func IsWarmingUpFeedbackFunc { get; } - + /// + /// Abstract function that must be implemented by derived classes to provide the warming up feedback value. + /// Must be implemented by concrete sub-classes. + /// + abstract protected Func IsWarmingUpFeedbackFunc { get; } + + /// + /// Timer used for managing display warmup timing. + /// protected CTimer WarmupTimer; + + /// + /// Timer used for managing display cooldown timing. + /// protected CTimer CooldownTimer; #region IRoutingInputs Members + /// + /// Gets the collection of input ports available on this display device. + /// public RoutingPortCollection InputPorts { get; private set; } #endregion - protected DisplayBase(string key, string name) - : base(key, name) + /// + /// Initializes a new instance of the DisplayBase class. + /// + /// The unique key identifier for this display device. + /// The friendly name for this display device. + protected DisplayBase(string key, string name) + : base(key, name) { IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc); IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc); InputPorts = new RoutingPortCollection(); + CurrentSources = new Dictionary + { + { eRoutingSignalType.Audio, null }, + { eRoutingSignalType.Video, null }, + }; + + CurrentSourceKeys = new Dictionary + { + { eRoutingSignalType.Audio, string.Empty }, + { eRoutingSignalType.Video, string.Empty }, + }; } + /// + /// Powers on the display device. Must be implemented by derived classes. + /// public abstract void PowerOn(); + + /// + /// Powers off the display device. Must be implemented by derived classes. + /// public abstract void PowerOff(); + + /// + /// Toggles the power state of the display device. Must be implemented by derived classes. + /// public abstract void PowerToggle(); - public virtual FeedbackCollection Feedbacks + /// + /// Gets the collection of feedback objects for this display device. + /// + public virtual FeedbackCollection Feedbacks { get { - return new FeedbackCollection + return new FeedbackCollection { IsCoolingDownFeedback, IsWarmingUpFeedback @@ -112,30 +201,50 @@ namespace PepperDash.Essentials.Devices.Common.Displays } } - public abstract void ExecuteSwitch(object selector); + /// + /// Executes a switch to the specified input on the display device. Must be implemented by derived classes. + /// + /// The selector object that identifies which input to switch to. + public abstract void ExecuteSwitch(object selector); - protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey, - EiscApiAdvanced bridge) - { - var joinMap = new DisplayControllerJoinMap(joinStart); + /// + /// Links the display device to an API using a trilist, join start, join map key, and bridge. + /// This overload uses serialized join map configuration. + /// + /// The display device to link. + /// The BasicTriList for communication. + /// The starting join number for the device. + /// The key for the join map configuration. + /// The EISC API bridge instance. + protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey, + EiscApiAdvanced bridge) + { + var joinMap = new DisplayControllerJoinMap(joinStart); - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.LogMessage(LogEventLevel.Information,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } LinkDisplayToApi(displayDevice, trilist, joinMap); - } + } + /// + /// Links the display device to an API using a trilist and join map. + /// This overload uses a pre-configured join map instance. + /// + /// The display device to link. + /// The BasicTriList for communication. + /// The join map configuration for the device. protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap) { Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); @@ -268,68 +377,96 @@ namespace PepperDash.Essentials.Devices.Common.Displays volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]); } - } + } - public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback + /// + /// 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 StringFeedback CurrentInputFeedback { get; private set; } + /// + /// Gets feedback for the current input selection on the display. + /// + public StringFeedback CurrentInputFeedback { get; private set; } - abstract protected Func CurrentInputFeedbackFunc { get; } + /// + /// Abstract function that must be implemented by derived classes to provide the current input feedback value. + /// Must be implemented by concrete sub-classes. + /// + abstract protected Func CurrentInputFeedbackFunc { get; } - public BoolFeedback PowerIsOnFeedback { get; protected set; } + /// + /// Gets feedback indicating whether the display is currently powered on. + /// + public BoolFeedback PowerIsOnFeedback { get; protected set; } - abstract protected Func PowerIsOnFeedbackFunc { get; } + /// + /// Abstract function that must be implemented by derived classes to provide the power state feedback value. + /// Must be implemented by concrete sub-classes. + /// + abstract protected Func PowerIsOnFeedbackFunc { get; } - - public static MockDisplay DefaultDisplay - { - get + /// + /// Gets the default mock display instance for testing and development purposes. + /// + public static MockDisplay DefaultDisplay + { + get { if (_DefaultDisplay == null) _DefaultDisplay = new MockDisplay("default", "Default Display"); return _DefaultDisplay; - } + } } static MockDisplay _DefaultDisplay; + /// + /// Initializes a new instance of the TwoWayDisplayBase class. + /// + /// The unique key identifier for this display device. + /// The friendly name for this display device. public TwoWayDisplayBase(string key, string name) : base(key, name) { - CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc); + CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc); WarmupTime = 7000; CooldownTime = 15000; - PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc); + PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc); - Feedbacks.Add(CurrentInputFeedback); - Feedbacks.Add(PowerIsOnFeedback); + Feedbacks.Add(CurrentInputFeedback); + Feedbacks.Add(PowerIsOnFeedback); - PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; + PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; } - void PowerIsOnFeedback_OutputChange(object sender, EventArgs e) - { - if (UsageTracker != null) - { - if (PowerIsOnFeedback.BoolValue) - UsageTracker.StartDeviceUsage(); - else - UsageTracker.EndDeviceUsage(); - } - } + void PowerIsOnFeedback_OutputChange(object sender, EventArgs e) + { + if (UsageTracker != null) + { + if (PowerIsOnFeedback.BoolValue) + UsageTracker.StartDeviceUsage(); + else + UsageTracker.EndDeviceUsage(); + } + } - public event EventHandler NumericSwitchChange; + /// + /// Event that is raised when a numeric switch change occurs on the display. + /// + public event EventHandler NumericSwitchChange; - /// - /// Raise an event when the status of a switch object changes. - /// - /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType - protected void OnSwitchChange(RoutingNumericEventArgs e) - { - var newEvent = NumericSwitchChange; - if (newEvent != null) newEvent(this, e); - } + /// + /// Raise an event when the status of a switch object changes. + /// + /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType + protected void OnSwitchChange(RoutingNumericEventArgs e) + { + var newEvent = NumericSwitchChange; + if (newEvent != null) newEvent(this, e); + } } } \ No newline at end of file From e76369726d58e897e47904fdc77460a0d4ef890c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 17 Jul 2025 12:25:52 -0500 Subject: [PATCH 05/11] docs: XML comments for DestinationListItem --- .../Devices/DestinationListItem.cs | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs index 0c21216a..19c40adb 100644 --- a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs @@ -5,19 +5,34 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core { + /// + /// Represents a destination item in a routing system that can receive audio/video signals. + /// Contains information about the destination device, its properties, and location settings. + /// public class DestinationListItem { + /// + /// Gets or sets the key identifier for the sink device that this destination represents. + /// [JsonProperty("sinkKey")] public string SinkKey { get; set; } private EssentialsDevice _sinkDevice; + /// + /// Gets the actual device instance for this destination. + /// Lazily loads the device from the DeviceManager using the SinkKey. + /// [JsonIgnore] public EssentialsDevice SinkDevice { get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); } } + /// + /// Gets the preferred display name for this destination. + /// Returns the custom Name if set, otherwise returns the SinkDevice name, or "---" if no device is found. + /// [JsonProperty("preferredName")] public string PreferredName { @@ -32,30 +47,62 @@ namespace PepperDash.Essentials.Core } } + /// + /// Gets or sets the custom name for this destination. + /// If set, this name will be used as the PreferredName instead of the device name. + /// [JsonProperty("name")] public string Name { get; set; } + /// + /// Gets or sets a value indicating whether this destination should be included in destination lists. + /// [JsonProperty("includeInDestinationList")] public bool IncludeInDestinationList { get; set; } + /// + /// Gets or sets the display order for this destination in lists. + /// Lower values appear first in sorted lists. + /// [JsonProperty("order")] public int Order { get; set; } + /// + /// Gets or sets the surface location identifier for this destination. + /// Used to specify which surface or screen this destination is located on. + /// [JsonProperty("surfaceLocation")] public int SurfaceLocation { get; set; } + /// + /// Gets or sets the vertical location position for this destination. + /// Used for spatial positioning in multi-display configurations. + /// [JsonProperty("verticalLocation")] public int VerticalLocation { get; set; } - + + /// + /// Gets or sets the horizontal location position for this destination. + /// Used for spatial positioning in multi-display configurations. + /// [JsonProperty("horizontalLocation")] public int HorizontalLocation { get; set; } + /// + /// Gets or sets the signal type that this destination can receive (Audio, Video, AudioVideo, etc.). + /// [JsonProperty("sinkType")] public eRoutingSignalType SinkType { get; set; } + /// + /// Gets or sets a value indicating whether this destination is used for codec content sharing. + /// [JsonProperty("isCodecContentDestination")] public bool isCodecContentDestination { get; set; } + /// + /// Gets or sets a value indicating whether this destination is used for program audio output. + /// [JsonProperty("isProgramAudioDestination")] public bool isProgramAudioDestination { get; set; } } From 1dcd4e328c8f84795e85c8ce197496632c701599 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 17 Jul 2025 12:32:26 -0500 Subject: [PATCH 06/11] fix: Destination support for USB --- .../Devices/DestinationListItem.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs index 19c40adb..41043b82 100644 --- a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs @@ -105,5 +105,12 @@ namespace PepperDash.Essentials.Core /// [JsonProperty("isProgramAudioDestination")] public bool isProgramAudioDestination { get; set; } + + /// + /// Gets or sets a value indicating whether this destination supports USB connections. + /// This is used to determine if the destination can handle USB. + /// + [JsonProperty("supportsUsb")] + public bool SupportsUsb { get; set; } } } \ No newline at end of file From 2bbefa062d26db30578a169399f83c7e7648898b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Jul 2025 13:28:10 -0500 Subject: [PATCH 07/11] docs: fix comments Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../DeviceTypeInterfaces/IStateFeedback.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs index e4070594..a4f6c2bb 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IStateFeedback.cs @@ -4,8 +4,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { /// - /// Interface for devices that provide audio meter feedback. - /// This interface is used to standardize access to meter feedback across different devices. + /// Interface for devices that provide state feedback. + /// This interface is used to standardize access to state feedback across different devices. /// public interface IStateFeedback { From 97b2ffed9c07ee3a9e012041a33538ee4b65cb11 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Jul 2025 13:28:37 -0500 Subject: [PATCH 08/11] docs: fix comment Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs b/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs index d3f51483..8c6323d4 100644 --- a/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs +++ b/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs @@ -14,13 +14,13 @@ namespace PepperDash.Essentials.Core.Routing { /// /// Gets the current sources for the room, keyed by eRoutingSignalType. - /// This dictionary contains the current source for each signal type, such as audio, video, + /// This dictionary contains the current source for each signal type, such as audio, video, and control signals. /// Dictionary CurrentSources { get; } /// /// Gets the current source keys for the room, keyed by eRoutingSignalType. - /// This dictionary contains the keys for the current source for each signal type, such as audio, + /// This dictionary contains the keys for the current source for each signal type, such as audio, video, and control signals. /// Dictionary CurrentSourceKeys { get; } From 660836bd5a3c19149b9322188f736c6dc2684aa2 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Jul 2025 13:28:59 -0500 Subject: [PATCH 09/11] docs: remove spaces Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/PepperDash.Essentials.Core/Devices/SourceListItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs index bfba4b4c..3d08a218 100644 --- a/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/SourceListItem.cs @@ -169,7 +169,7 @@ namespace PepperDash.Essentials.Core public bool DisableSimpleRouting { get; set; } /// - /// The key of the device that provides video sync for this source item + /// The key of the device that provides video sync for this source item /// [JsonProperty("syncProviderDeviceKey")] public string SyncProviderDeviceKey { get; set; } From 789113008ea553dab398a2e49b554c9db77e6c50 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Jul 2025 13:29:11 -0500 Subject: [PATCH 10/11] docs: update comments Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs index 41043b82..c0837401 100644 --- a/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs +++ b/src/PepperDash.Essentials.Core/Devices/DestinationListItem.cs @@ -108,7 +108,8 @@ namespace PepperDash.Essentials.Core /// /// Gets or sets a value indicating whether this destination supports USB connections. - /// This is used to determine if the destination can handle USB. + /// Indicates if the destination can handle USB functionality, such as USB signal routing or device connections. + /// This property is used to determine compatibility with USB-based devices or systems. /// [JsonProperty("supportsUsb")] public bool SupportsUsb { get; set; } From 311452beaccc18f6c28a7acdfb9a077148d2cf1a Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Jul 2025 13:30:11 -0500 Subject: [PATCH 11/11] fix: use correct namespaces Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs b/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs index 8c6323d4..bef0fd95 100644 --- a/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs +++ b/src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core.Routing {