From 9b1dd099f60ae1b49d226e5298cc61c21c0f23f0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Jun 2025 16:47:09 -0600 Subject: [PATCH 01/15] feat: Add IPresenterTrack and ISpeakerTrack interfaces Introduced two new interfaces, `IPresenterTrack` and `ISpeakerTrack`, in the `PepperDash.Essentials.Devices.Common.Codec.Cisco` namespace. These interfaces provide properties and methods for managing presenter and speaker tracking functionalities in Cisco codecs, including availability, status feedback, and control methods. --- .../Codec/Cisco/IPresenterTrack.cs | 32 +++++++++++++++++++ .../Codec/Cisco/ISpeakerTrack.cs | 25 +++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs new file mode 100644 index 00000000..538a5adf --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs @@ -0,0 +1,32 @@ +using PepperDash.Core; +using PepperDash.Essentials.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PepperDash.Essentials.Devices.Common.Codec.Cisco +{ + /// + /// Describes the Presenter Track controls for a Cisco codec. + /// + public interface IPresenterTrack : IKeyed + { + bool PresenterTrackAvailability { get; } + + BoolFeedback PresenterTrackAvailableFeedback { get; } + + BoolFeedback PresenterTrackStatusOffFeedback { get; } + BoolFeedback PresenterTrackStatusFollowFeedback { get; } + BoolFeedback PresenterTrackStatusBackgroundFeedback { get; } + BoolFeedback PresenterTrackStatusPersistentFeedback { get; } + + bool PresenterTrackStatus { get; } + + void PresenterTrackOff(); + void PresenterTrackFollow(); + void PresenterTrackBackground(); + void PresenterTrackPersistent(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs new file mode 100644 index 00000000..4e72dcf6 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs @@ -0,0 +1,25 @@ +using PepperDash.Core; +using PepperDash.Essentials.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PepperDash.Essentials.Devices.Common.Codec.Cisco +{ + /// + /// Describes the available tracking modes for a Cisco codec + /// + public interface ISpeakerTrack : IKeyed + { + bool SpeakerTrackAvailability { get; } + + BoolFeedback SpeakerTrackAvailableFeedback { get; } + + bool SpeakerTrackStatus { get; } + + void SpeakerTrackOff(); + void SpeakerTrackOn(); + } +} From 0a6896910d3d0971d06606819480819f56a1ff22 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Jun 2025 18:35:36 -0600 Subject: [PATCH 02/15] feat: Add screen/layout management and codec tracking features Introduced new interfaces and classes for screen and layout management, including `IHasScreensWithLayouts`, `ScreenInfo`, and `LayoutInfo`. Enhanced `IPresenterTrack` and `ISpeakerTrack` interfaces with additional properties and methods for managing presenter and speaker tracking. Added `IHasCodecRoomPresets` interface for room preset management and updated `CodecRoomPreset` class with a new constructor. --- .../IHasScreensWithLayouts.cs | 70 +++++++++++++++++++ .../Codec/Cisco/IPresenterTrack.cs | 39 +++++++++++ .../Codec/Cisco/ISpeakerTrack.cs | 15 ++++ .../VideoCodec/CiscoCodec/RoomPresets.cs | 34 ++++++++- 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs new file mode 100644 index 00000000..ccae1e11 --- /dev/null +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs @@ -0,0 +1,70 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces +{ + /// + /// This defines a device that has screens with layouts + /// Simply decorative + /// + public interface IHasScreensWithLayouts + { + /// + /// A dictionary of screens, keyed by screen ID, that contains information about each screen and its layouts. + /// + Dictionary Screens { get; } + } + + /// + /// Represents information about a screen and its layouts. + /// + public class ScreenInfo + { + + /// + /// Indicates whether the screen is enabled or not. + /// + [JsonProperty("enabled")] + public bool Enabled { get; set; } + + /// + /// The name of the screen. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// The index of the screen. + /// + [JsonProperty("screenIndex")] + public int ScreenIndex { get; set; } + + /// + /// A dictionary of layout information for the screen, keyed by layout ID. + /// + [JsonProperty("layouts")] + public Dictionary Layouts { get; set; } + } + + /// + /// Represents information about a layout on a screen. + /// + public class LayoutInfo + { + /// + /// The display name for the layout + /// + [JsonProperty("layoutName")] + public string LayoutName { get; set; } + + /// + /// The index of the layout. + /// + [JsonProperty("layoutIndex")] + public int LayoutIndex { get; set; } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs index 538a5adf..b38225fe 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs @@ -13,20 +13,59 @@ namespace PepperDash.Essentials.Devices.Common.Codec.Cisco /// public interface IPresenterTrack : IKeyed { + /// + /// + /// bool PresenterTrackAvailability { get; } + /// + /// Feedback indicating whether Presenter Track is available. + /// BoolFeedback PresenterTrackAvailableFeedback { get; } + /// + /// Feedback indicateing the current status of Presenter Track is off + /// BoolFeedback PresenterTrackStatusOffFeedback { get; } + + /// + /// Feedback indicating the current status of Presenter Track is follow + /// BoolFeedback PresenterTrackStatusFollowFeedback { get; } + + /// + /// Feedback indicating the current status of Presenter Track is background + /// BoolFeedback PresenterTrackStatusBackgroundFeedback { get; } + + /// + /// Feedback indicating the current status of Presenter Track is persistent + /// BoolFeedback PresenterTrackStatusPersistentFeedback { get; } + /// + /// Indicates the current status of Presenter Track. + /// bool PresenterTrackStatus { get; } + /// + /// Turns off Presenter Track. + /// void PresenterTrackOff(); + + /// + /// Turns on Presenter Track in follow mode. + /// void PresenterTrackFollow(); + + /// + /// Turns on Presenter Track in background mode. + /// void PresenterTrackBackground(); + + /// + /// Turns on Presenter Track in persistent mode. + /// void PresenterTrackPersistent(); } } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs index 4e72dcf6..83735183 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs @@ -13,13 +13,28 @@ namespace PepperDash.Essentials.Devices.Common.Codec.Cisco /// public interface ISpeakerTrack : IKeyed { + /// + /// Indicates whether Speaker Track is available on the codec. + /// bool SpeakerTrackAvailability { get; } + /// + /// + /// BoolFeedback SpeakerTrackAvailableFeedback { get; } + /// + /// Feedback indicating the current status of Speaker Track is off + /// bool SpeakerTrackStatus { get; } + /// + /// Turns Speaker Track off + /// void SpeakerTrackOff(); + /// + /// Turns Speaker Track on + /// void SpeakerTrackOn(); } } diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs index 8fc8a1d0..0adf40a2 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs @@ -12,20 +12,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasCodecRoomPresets { + /// + /// Event that is raised when the list of room presets has changed. + /// event EventHandler CodecRoomPresetsListHasChanged; + /// + /// List of near end presets that can be recalled. + /// List NearEndPresets { get; } + /// + /// List of far end presets that can be recalled. + /// List FarEndRoomPresets { get; } + /// + /// Selects a near end preset by its ID. + /// + /// void CodecRoomPresetSelect(int preset); + /// + /// Stores a near end preset with the given ID and description. + /// + /// + /// void CodecRoomPresetStore(int preset, string description); + /// + /// Selects a far end preset by its ID. This is typically used to recall a preset that has been defined on the far end codec. + /// + /// void SelectFarEndPreset(int preset); } - public static class RoomPresets + /// + /// Static class for converting non-generic RoomPresets to generic CameraPresets. + /// + public static class RoomPresets { /// /// Converts non-generic RoomPresets to generic CameraPresets @@ -47,6 +72,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public class CodecRoomPreset : PresetBase { + /// + /// + /// + /// + /// + /// + /// public CodecRoomPreset(int id, string description, bool def, bool isDef) : base(id, description, def, isDef) { From af98a92f8c53e5bb802eaaed64c2974ce3bdacc2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Jun 2025 19:01:13 -0600 Subject: [PATCH 03/15] (force-patch): generate new build to test updated workflow nuget push issues --- .../VideoCodec/CiscoCodec/RoomPresets.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs index 0adf40a2..a6531a40 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs @@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// /// /// - void CodecRoomPresetStore(int preset, string description); + void CodecRoomPresetStore(int preset, string description); /// /// Selects a far end preset by its ID. This is typically used to recall a preset that has been defined on the far end codec. From 7178d8e284cfd3722f0a6982d78e03438584a518 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Jun 2025 19:17:34 -0600 Subject: [PATCH 04/15] featr: Add PresenterTrackMode enum to IPresenterTrack.cs Introduces a new enumeration `PresenterTrackMode` that defines four tracking modes for the Cisco codec's Presenter Track feature: `Off`, `Follow`, `Background`, and `Persistent`. Each mode includes a summary comment for clarity. --- .../Codec/Cisco/IPresenterTrack.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs index b38225fe..15b378f8 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs @@ -8,6 +8,30 @@ using System.Threading.Tasks; namespace PepperDash.Essentials.Devices.Common.Codec.Cisco { + /// + /// Describes the available tracking modes for a Cisco codec's Presenter Track feature. + /// + public enum PresenterTrackMode + { + /// + /// Presenter Track is turned off. + /// + Off, + /// + /// Presenter Track follows the speaker's movements. + /// + Follow, + /// + /// Presenter Track is set to background mode, where it tracks the speaker but does not actively follow. + /// + Background, + /// + /// Presenter Track is set to persistent mode, where it maintains a fixed position or focus on the speaker. + /// + Persistent + } + + /// /// Describes the Presenter Track controls for a Cisco codec. /// From 2c5cae9f4119e562cff3c1f82dfdfc74e9efedcd Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Jun 2025 19:18:30 -0600 Subject: [PATCH 05/15] fix: Rename PresenterTrackMode to ePresenterTrackMode Updated the enum name to reflect new naming conventions and potentially broader categorization within the codebase. --- .../Codec/Cisco/IPresenterTrack.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs index 15b378f8..a03dfddb 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs @@ -11,7 +11,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec.Cisco /// /// Describes the available tracking modes for a Cisco codec's Presenter Track feature. /// - public enum PresenterTrackMode + public enum ePresenterTrackMode { /// /// Presenter Track is turned off. From f3159738ce4e333c40eecd95d9cf0517ef1916b1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Jun 2025 20:33:25 -0600 Subject: [PATCH 06/15] feat: Enhance layout and window configuration classes Added `LayoutType` and `Windows` properties to the `LayoutInfo` class. Introduced a new `WindowConfig` class with `Label` and `Input` properties to represent window configurations within a layout. --- .../IHasScreensWithLayouts.cs | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs index ccae1e11..dec9c0b3 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs @@ -56,7 +56,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces public class LayoutInfo { /// - /// The display name for the layout + /// The name of the layout. /// [JsonProperty("layoutName")] public string LayoutName { get; set; } @@ -66,5 +66,35 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces /// [JsonProperty("layoutIndex")] public int LayoutIndex { get; set; } + + /// + /// The type of the layout, which can be "single", "double", "triple", or "quad". + /// + [JsonProperty("layoutType")] + public string LayoutType { get; set; } + + /// + /// A dictionary of window configurations for the layout, keyed by window ID. + /// + [JsonProperty("windows")] + public Dictionary Windows { get; set; } + } + + /// + /// Represents the configuration of a window within a layout on a screen. + /// + public class WindowConfig + { + /// + /// The display label for the window + /// + [JsonProperty("label")] + public string Label { get; set; } + + /// + /// The input for the window + /// + [JsonProperty("input")] + public string Input { get; set; } } } From 183879f1c435490eafb0b3eda4fe7f34dafe0aad Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 18 Jun 2025 11:11:12 -0600 Subject: [PATCH 07/15] feat: Add ApplyLayout method to IHasScreensWithLayouts Introduced a new method `ApplyLayout` in the `IHasScreensWithLayouts` interface. This method enables the application of a specific layout to a screen using the provided screen ID and layout index. XML documentation has been added to clarify its purpose and parameters. --- .../DeviceTypeInterfaces/IHasScreensWithLayouts.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs index dec9c0b3..439462c6 100644 --- a/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs +++ b/src/PepperDash.Essentials.Core/DeviceTypeInterfaces/IHasScreensWithLayouts.cs @@ -17,6 +17,13 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces /// A dictionary of screens, keyed by screen ID, that contains information about each screen and its layouts. /// Dictionary Screens { get; } + + /// + /// Applies a specific layout to a screen based on the provided screen ID and layout index. + /// + /// + /// + void ApplyLayout(uint screenId, uint layoutIndex); } /// From 9c94806e4f0e55c71cfd228d09176bd379e7b2f0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 18 Jun 2025 13:21:32 -0600 Subject: [PATCH 08/15] Update src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Codec/Cisco/IPresenterTrack.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs index a03dfddb..f3f164bd 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs @@ -48,7 +48,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec.Cisco BoolFeedback PresenterTrackAvailableFeedback { get; } /// - /// Feedback indicateing the current status of Presenter Track is off + /// Feedback indicating the current status of Presenter Track is off /// BoolFeedback PresenterTrackStatusOffFeedback { get; } From d96edfa8d0e457f1c35a9faf85366606eb8e5964 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 26 Jun 2025 13:50:42 -0400 Subject: [PATCH 09/15] fix: end devcommstatus with cr-lf instead of just -lf --- src/PepperDash.Essentials.Core/Devices/DeviceManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs b/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs index ae8eba03..5cd921b8 100644 --- a/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs +++ b/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs @@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core foreach (var dev in Devices.Values.OfType()) { - CrestronConsole.ConsoleCommandResponse($"{dev}: {dev.CommunicationMonitor.Status}{Environment.NewLine}"); + CrestronConsole.ConsoleCommandResponse($"{dev}: {dev.CommunicationMonitor.Status}\r\n"); } } From 253b2cddaf0b10bbf6522a9d609b015d21a7fa14 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 26 Jun 2025 13:54:24 -0400 Subject: [PATCH 10/15] fix: print device key & name instead of type --- src/PepperDash.Essentials.Core/Devices/DeviceManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs b/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs index 5cd921b8..eaf696ba 100644 --- a/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs +++ b/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs @@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core foreach (var dev in Devices.Values.OfType()) { - CrestronConsole.ConsoleCommandResponse($"{dev}: {dev.CommunicationMonitor.Status}\r\n"); + CrestronConsole.ConsoleCommandResponse($"{dev.Key}|{dev.Name}: {dev.CommunicationMonitor.Status}\r\n"); } } From c9b32057364a011d8896f38e49ec2749765d368e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 26 Jun 2025 14:14:04 -0400 Subject: [PATCH 11/15] fix: return --- if the device was created without a name --- src/PepperDash.Core/Device.cs | 169 ++++++++++-------- .../Devices/DeviceManager.cs | 2 +- .../Devices/EssentialsDevice.cs | 16 +- 3 files changed, 101 insertions(+), 86 deletions(-) diff --git a/src/PepperDash.Core/Device.cs b/src/PepperDash.Core/Device.cs index fda30c4c..ef9f6111 100644 --- a/src/PepperDash.Core/Device.cs +++ b/src/PepperDash.Core/Device.cs @@ -11,35 +11,35 @@ namespace PepperDash.Core public class Device : IKeyName { - /// - /// Unique Key - /// + /// + /// Unique Key + /// public string Key { get; protected set; } /// /// Name of the devie /// - public string Name { get; protected set; } - /// - /// - /// + public string Name { get; protected set; } + /// + /// + /// public bool Enabled { get; protected set; } - ///// - ///// A place to store reference to the original config object, if any. These values should - ///// NOT be used as properties on the device as they are all publicly-settable values. - ///// - //public DeviceConfig Config { get; private set; } - ///// - ///// Helper method to check if Config exists - ///// - //public bool HasConfig { get { return Config != null; } } + ///// + ///// A place to store reference to the original config object, if any. These values should + ///// NOT be used as properties on the device as they are all publicly-settable values. + ///// + //public DeviceConfig Config { get; private set; } + ///// + ///// Helper method to check if Config exists + ///// + //public bool HasConfig { get { return Config != null; } } List _PreActivationActions; List _PostActivationActions; - /// - /// - /// + /// + /// + /// public static Device DefaultDevice { get { return _DefaultDevice; } } static Device _DefaultDevice = new Device("Default", "Default"); @@ -54,27 +54,27 @@ namespace PepperDash.Core Name = ""; } - /// - /// Constructor with key and name - /// - /// - /// + /// + /// Constructor with key and name + /// + /// + /// public Device(string key, string name) : this(key) { Name = name; } - //public Device(DeviceConfig config) - // : this(config.Key, config.Name) - //{ - // Config = config; - //} + //public Device(DeviceConfig config) + // : this(config.Key, config.Name) + //{ + // Config = config; + //} - /// - /// Adds a pre activation action - /// - /// + /// + /// Adds a pre activation action + /// + /// public void AddPreActivationAction(Action act) { if (_PreActivationActions == null) @@ -82,10 +82,10 @@ namespace PepperDash.Core _PreActivationActions.Add(act); } - /// - /// Adds a post activation action - /// - /// + /// + /// Adds a post activation action + /// + /// public void AddPostActivationAction(Action act) { if (_PostActivationActions == null) @@ -93,55 +93,58 @@ namespace PepperDash.Core _PostActivationActions.Add(act); } - /// - /// Executes the preactivation actions - /// - public void PreActivate() - { - if (_PreActivationActions != null) - _PreActivationActions.ForEach(a => { + /// + /// Executes the preactivation actions + /// + public void PreActivate() + { + if (_PreActivationActions != null) + _PreActivationActions.ForEach(a => + { try { a.Invoke(); - } catch (Exception e) - { + } + catch (Exception e) + { Debug.LogMessage(e, "Error in PreActivationAction: " + e.Message, this); } - }); - } + }); + } /// /// Gets this device ready to be used in the system. Runs any added pre-activation items, and /// all post-activation at end. Classes needing additional logic to /// run should override CustomActivate() /// - public bool Activate() + public bool Activate() { - //if (_PreActivationActions != null) - // _PreActivationActions.ForEach(a => a.Invoke()); + //if (_PreActivationActions != null) + // _PreActivationActions.ForEach(a => a.Invoke()); var result = CustomActivate(); - //if(result && _PostActivationActions != null) - // _PostActivationActions.ForEach(a => a.Invoke()); - return result; + //if(result && _PostActivationActions != null) + // _PostActivationActions.ForEach(a => a.Invoke()); + return result; } - /// - /// Executes the postactivation actions - /// - public void PostActivate() - { - if (_PostActivationActions != null) - _PostActivationActions.ForEach(a => { - try - { - a.Invoke(); - } - catch (Exception e) - { - Debug.LogMessage(e, "Error in PostActivationAction: " + e.Message, this); - } - }); - } + /// + /// Executes the postactivation actions + /// + public void PostActivate() + { + if (_PostActivationActions != null) + _PostActivationActions.ForEach(a => + { + try + { + a.Invoke(); + } + catch (Exception e) + { + Debug.LogMessage(e, "Error in PostActivationAction: " + e.Message, this); + } + }); + } /// /// Called in between Pre and PostActivationActions when Activate() is called. @@ -158,14 +161,14 @@ namespace PepperDash.Core /// public virtual bool Deactivate() { return true; } - /// - /// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize() - /// - public virtual void Initialize() - { - } + /// + /// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize() + /// + public virtual void Initialize() + { + } - /// + /// /// Helper method to check object for bool value false and fire an Action method /// /// Should be of type bool, others will be ignored @@ -175,5 +178,15 @@ namespace PepperDash.Core if (o is bool && !(bool)o) a(); } + /// + /// Returns a string representation of the object, including its key and name. + /// + /// The returned string is formatted as "{Key} - {Name}". If the Name property is + /// null or empty, "---" is used in place of the name. + /// A string that represents the object, containing the key and name in the format "{Key} - {Name}". + public override string ToString() + { + return string.Format("{0} - {1}", Key, string.IsNullOrEmpty(Name) ? "---" : Name); + } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs b/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs index eaf696ba..5cd921b8 100644 --- a/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs +++ b/src/PepperDash.Essentials.Core/Devices/DeviceManager.cs @@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core foreach (var dev in Devices.Values.OfType()) { - CrestronConsole.ConsoleCommandResponse($"{dev.Key}|{dev.Name}: {dev.CommunicationMonitor.Status}\r\n"); + CrestronConsole.ConsoleCommandResponse($"{dev}: {dev.CommunicationMonitor.Status}\r\n"); } } diff --git a/src/PepperDash.Essentials.Core/Devices/EssentialsDevice.cs b/src/PepperDash.Essentials.Core/Devices/EssentialsDevice.cs index bdb8b45a..778f9226 100644 --- a/src/PepperDash.Essentials.Core/Devices/EssentialsDevice.cs +++ b/src/PepperDash.Essentials.Core/Devices/EssentialsDevice.cs @@ -20,19 +20,20 @@ namespace PepperDash.Essentials.Core public event EventHandler Initialized; private bool _isInitialized; - public bool IsInitialized { + public bool IsInitialized + { get { return _isInitialized; } - private set - { + private set + { if (_isInitialized == value) return; - + _isInitialized = value; if (_isInitialized) { Initialized?.Invoke(this, new EventArgs()); } - } + } } protected EssentialsDevice(string key) @@ -80,8 +81,9 @@ namespace PepperDash.Essentials.Core /// /// Override this method to build and create custom Mobile Control Messengers during the Activation phase /// - protected virtual void CreateMobileControlMessengers() { - + protected virtual void CreateMobileControlMessengers() + { + } } From 19e799f11d2d104b74f05e5d83b76f58d262afc6 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 26 Jun 2025 17:12:36 -0400 Subject: [PATCH 12/15] fix: debounce device info events In some cases, multiple device info update events are triggering, causing the queue to be flooded with multiple unneccessary messages containing the same info. This clogs the queue and makes it harder for UIs to come online when Essentials restarts, especially in systems with a lot of NVX devices. The events are now debounced. If there are no new messages for 1 second, then the MC message is sent out. --- .../Messengers/DeviceInfoMessenger.cs | 58 +++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceInfoMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceInfoMessenger.cs index ffd58948..c588195e 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceInfoMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceInfoMessenger.cs @@ -2,27 +2,69 @@ using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core.DeviceInfo; +using System.Timers; namespace PepperDash.Essentials.AppServer.Messengers { + /// + /// Facilitates communication of device information by providing mechanisms for status updates and device + /// information reporting. + /// + /// The class integrates with an to manage device-specific information. It uses a debounce timer to limit the + /// frequency of updates, ensuring efficient communication. The timer is initialized with a 1-second interval and + /// is disabled by default. This class also subscribes to device information change events and provides actions for + /// reporting full device status and triggering updates. public class DeviceInfoMessenger : MessengerBase { private readonly IDeviceInfoProvider _deviceInfoProvider; + + private readonly Timer debounceTimer; + + /// + /// Initializes a new instance of the class, which facilitates communication + /// of device information. + /// + /// The messenger uses a debounce timer to limit the frequency of certain operations. The + /// timer is initialized with a 1-second interval and is disabled by default. + /// A unique identifier for the messenger instance. + /// The path used for sending and receiving messages. + /// An implementation of that provides device-specific information. public DeviceInfoMessenger(string key, string messagePath, IDeviceInfoProvider device) : base(key, messagePath, device as Device) { _deviceInfoProvider = device; - } + debounceTimer = new Timer(1000) + { + Enabled = false, + AutoReset = false + }; + + debounceTimer.Elapsed += DebounceTimer_Elapsed; + } + + private void DebounceTimer_Elapsed(object sender, ElapsedEventArgs e) + { + PostStatusMessage(JToken.FromObject(new + { + deviceInfo = _deviceInfoProvider.DeviceInfo + })); + } + + /// + /// Registers actions and event handlers for device information updates and status reporting. + /// + /// This method sets up actions for handling device status updates and reporting full + /// device status. It also subscribes to the event to + /// trigger debounced updates when the device information changes. protected override void RegisterActions() { base.RegisterActions(); _deviceInfoProvider.DeviceInfoChanged += (o, a) => { - PostStatusMessage(JToken.FromObject(new - { - deviceInfo = a.DeviceInfo - })); + debounceTimer.Stop(); + debounceTimer.Start(); }; AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage @@ -34,6 +76,12 @@ namespace PepperDash.Essentials.AppServer.Messengers } } + /// + /// Represents a message containing the state information of a device, including detailed device information. + /// + /// This class is used to encapsulate the state of a device along with its associated + /// information. It extends to provide additional details about the + /// device. public class DeviceInfoStateMessage : DeviceStateMessageBase { [JsonProperty("deviceInfo")] From 1a9e1087de4a58a3ac59cd833c534faa9ad45e13 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 27 Jun 2025 10:32:21 -0400 Subject: [PATCH 13/15] fix: add property to disable auto mode --- .../Room/Combining/EssentialsRoomCombiner.cs | 105 ++++++++++++++++++ .../EssentialsRoomCombinerPropertiesConfig.cs | 45 ++++++-- 2 files changed, 143 insertions(+), 7 deletions(-) diff --git a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs index f0fb5e98..681f8810 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs @@ -10,6 +10,13 @@ using System.Threading.Tasks; namespace PepperDash.Essentials.Core { + /// + /// Represents a device that manages room combinations by controlling partitions and scenarios. + /// + /// The allows for dynamic configuration of room + /// combinations based on partition states and predefined scenarios. It supports both automatic and manual modes + /// for managing room combinations. In automatic mode, the device determines the current room combination scenario + /// based on partition sensor states. In manual mode, scenarios can be set explicitly by the user. public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner { private EssentialsRoomCombinerPropertiesConfig _propertiesConfig; @@ -18,6 +25,9 @@ namespace PepperDash.Essentials.Core private List _rooms; + /// + /// Gets a list of rooms represented as key-name pairs. + /// public List Rooms { get @@ -28,6 +38,12 @@ namespace PepperDash.Essentials.Core private bool _isInAutoMode; + /// + /// Gets or sets a value indicating whether the system is operating in automatic mode. + /// + /// Changing this property triggers an update event via + /// IsInAutoModeFeedback.FireUpdate(). Ensure that any event listeners are properly configured to handle + /// this update. public bool IsInAutoMode { get @@ -52,6 +68,19 @@ namespace PepperDash.Essentials.Core private Mutex _scenarioChange = new Mutex(); + /// + /// Initializes a new instance of the class, which manages room combination + /// scenarios and partition states. + /// + /// The class is designed to handle dynamic room + /// combination scenarios based on partition states. It supports both automatic and manual modes for managing + /// room combinations. By default, the instance starts in automatic mode unless the + /// specifies otherwise. After activation, the room combiner initializes partition state providers and sets up + /// the initial room configuration. Additionally, it subscribes to the event to ensure proper initialization of dependent devices + /// before determining or setting the room combination scenario. + /// The unique identifier for the room combiner instance. + /// The configuration properties for the room combiner, including default settings and debounce times. public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props) : base(key) { @@ -246,8 +275,16 @@ namespace PepperDash.Essentials.Core #region IEssentialsRoomCombiner Members + /// + /// Occurs when the room combination scenario changes. + /// + /// This event is triggered whenever the configuration or state of the room combination + /// changes. Subscribers can use this event to update their logic or UI based on the new scenario. public event EventHandler RoomCombinationScenarioChanged; + /// + /// Gets the current room combination scenario. + /// public IRoomCombinationScenario CurrentScenario { get @@ -256,10 +293,25 @@ namespace PepperDash.Essentials.Core } } + /// + /// Gets the feedback indicating whether the system is currently in auto mode. + /// public BoolFeedback IsInAutoModeFeedback { get; private set; } + /// + /// Enables auto mode for the room combiner and its partitions, allowing automatic room combination scenarios to + /// be determined. + /// + /// Auto mode allows the room combiner to automatically adjust its configuration based on + /// the state of its partitions. If auto mode is disabled in the configuration, this method logs a warning and + /// does not enable auto mode. public void SetAutoMode() { + if(_propertiesConfig.DisableAutoMode) + { + this.LogWarning("Auto mode is disabled for this room combiner. Cannot set to auto mode."); + return; + } IsInAutoMode = true; foreach (var partition in Partitions) @@ -270,6 +322,12 @@ namespace PepperDash.Essentials.Core DetermineRoomCombinationScenario(); } + /// + /// Switches the system to manual mode, disabling automatic operations. + /// + /// This method sets the system to manual mode by updating the mode state and propagates + /// the change to all partitions. Once in manual mode, automatic operations are disabled for the system and its + /// partitions. public void SetManualMode() { IsInAutoMode = false; @@ -280,6 +338,11 @@ namespace PepperDash.Essentials.Core } } + /// + /// Toggles the current mode between automatic and manual. + /// + /// If the current mode is automatic, this method switches to manual mode. If the + /// current mode is manual, it switches to automatic mode. public void ToggleMode() { if (IsInAutoMode) @@ -292,10 +355,22 @@ namespace PepperDash.Essentials.Core } } + /// + /// Gets the collection of room combination scenarios. + /// public List RoomCombinationScenarios { get; private set; } + /// + /// Gets the collection of partition controllers managed by this instance. + /// public List Partitions { get; private set; } + /// + /// Toggles the state of the partition identified by the specified partition key. + /// + /// If no partition with the specified key exists, the method performs no + /// action. + /// The key of the partition whose state is to be toggled. This value cannot be null or empty. public void TogglePartitionState(string partitionKey) { var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey)); @@ -306,6 +381,17 @@ namespace PepperDash.Essentials.Core } } + /// + /// Sets the room combination scenario based on the specified scenario key. + /// + /// This method manually adjusts the partition states according to the specified + /// scenario. If the application is in auto mode, the operation will not proceed, and a log message will be + /// generated indicating that the mode must be set to manual first. If the specified scenario key does not + /// match any existing scenario, a debug log message will be generated. For each partition state in the + /// scenario, the corresponding partition will be updated to either "Present" or "Not Present" based on the + /// scenario's configuration. If a partition key in the scenario cannot be found, a debug log message will be + /// generated. + /// The key identifying the room combination scenario to apply. This must match the key of an existing scenario. public void SetRoomCombinationScenario(string scenarioKey) { if (IsInAutoMode) @@ -354,13 +440,32 @@ namespace PepperDash.Essentials.Core #endregion } + /// + /// Provides a factory for creating instances of devices. + /// + /// This factory is responsible for constructing devices + /// based on the provided configuration. It supports the type name "essentialsroomcombiner" for device + /// creation. public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory { + /// + /// Initializes a new instance of the class. + /// + /// This factory is used to create instances of room combiners with the specified type + /// names. By default, the factory includes the type name "essentialsroomcombiner". public EssentialsRoomCombinerFactory() { TypeNames = new List { "essentialsroomcombiner" }; } + /// + /// Creates and initializes a new instance of the device. + /// + /// This method uses the provided device configuration to extract the properties and + /// create an device. Ensure that the configuration contains valid + /// properties for the device to be created successfully. + /// The device configuration containing the key and properties required to build the device. + /// A new instance of initialized with the specified configuration. public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) { Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new EssentialsRoomCombiner Device"); diff --git a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 745f303f..cd6f3f17 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -1,10 +1,4 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Collections.Generic; using PepperDash.Core; @@ -17,6 +11,13 @@ namespace PepperDash.Essentials.Core /// public class EssentialsRoomCombinerPropertiesConfig { + /// + /// Gets or sets a value indicating whether the system operates in automatic mode. + /// Some systems don't have partitions sensors, and show shouldn't allow auto mode to be turned on. When this is true in the configuration, + /// auto mode won't be allowed to be turned on. + /// + public bool DisableAutoMode { get; set; } + /// /// The list of partitions that device the rooms /// @@ -47,6 +48,9 @@ namespace PepperDash.Essentials.Core [JsonProperty("defaultScenarioKey")] public string defaultScenarioKey { get; set; } + /// + /// Gets or sets the debounce time, in seconds, for scenario changes. + /// [JsonProperty("scenarioChangeDebounceTimeSeconds")] public int ScenarioChangeDebounceTimeSeconds { get; set; } } @@ -56,9 +60,15 @@ namespace PepperDash.Essentials.Core /// public class PartitionConfig : IKeyName { + /// + /// Gets or sets the unique key associated with the object. + /// [JsonProperty("key")] public string Key { get; set; } + /// + /// Gets or sets the name associated with the object. + /// [JsonProperty("name")] public string Name { get; set; } @@ -80,12 +90,21 @@ namespace PepperDash.Essentials.Core /// public class RoomCombinationScenarioConfig : IKeyName { + /// + /// Gets or sets the key associated with the object. + /// [JsonProperty("key")] public string Key { get; set; } + /// + /// Gets or sets the name associated with the object. + /// [JsonProperty("name")] public string Name { get; set; } + /// + /// Gets or sets the collection of partition states. + /// [JsonProperty("partitionStates")] public List PartitionStates { get; set; } @@ -95,9 +114,15 @@ namespace PepperDash.Essentials.Core [JsonProperty("uiMap")] public Dictionary UiMap { get; set; } + /// + /// Gets or sets the list of actions to be performed during device activation. + /// [JsonProperty("activationActions")] public List ActivationActions { get; set; } + /// + /// Gets or sets the list of actions to be performed when a device is deactivated. + /// [JsonProperty("deactivationActions")] public List DeactivationActions { get; set; } } @@ -107,9 +132,15 @@ namespace PepperDash.Essentials.Core /// public class PartitionState { + /// + /// Gets or sets the partition key used to group and organize data within a storage system. + /// [JsonProperty("partitionKey")] public string PartitionKey { get; set; } + /// + /// Gets or sets a value indicating whether a partition is currently present. + /// [JsonProperty("partitionSensedState")] public bool PartitionPresent { get; set; } } From c1809459a62f2ef6a8457d0969ffe89ae5896665 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 27 Jun 2025 10:37:49 -0400 Subject: [PATCH 14/15] chore: format property name correctly for JSON --- .../Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index cd6f3f17..fec7e380 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -16,6 +16,7 @@ namespace PepperDash.Essentials.Core /// Some systems don't have partitions sensors, and show shouldn't allow auto mode to be turned on. When this is true in the configuration, /// auto mode won't be allowed to be turned on. /// + [JsonProperty("disableAutoMode")] public bool DisableAutoMode { get; set; } /// From 96ac266d24e9dd1102408bc2206d4b3f69280b87 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 27 Jun 2025 10:45:42 -0400 Subject: [PATCH 15/15] fix: room combiner messenger sends disableAutoMode property --- .../Room/Combining/EssentialsRoomCombiner.cs | 11 ++++ .../Room/Combining/IEssentialsRoomCombiner.cs | 21 +++++++ .../IEssentialsRoomCombinerMessenger.cs | 55 +++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs index 681f8810..d2a16739 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombiner.cs @@ -62,6 +62,17 @@ namespace PepperDash.Essentials.Core } } + /// + /// Gets a value indicating whether automatic mode is disabled. + /// + public bool DisableAutoMode + { + get + { + return _propertiesConfig.DisableAutoMode; + } + } + private CTimer _scenarioChangeDebounceTimer; private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s diff --git a/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs b/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs index fefdc2da..04dfd16f 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs @@ -28,9 +28,20 @@ namespace PepperDash.Essentials.Core [JsonIgnore] BoolFeedback IsInAutoModeFeedback {get;} + /// + /// Gets a value indicating whether the automatic mode is disabled. + /// + [JsonProperty("disableAutoMode")] + bool DisableAutoMode { get; } + /// + /// Gets a value indicating whether the system is operating in automatic mode. + /// [JsonProperty("isInAutoMode")] bool IsInAutoMode { get; } + /// + /// Gets the collection of rooms associated with the current object. + /// [JsonProperty("rooms")] List Rooms { get; } @@ -74,6 +85,13 @@ namespace PepperDash.Essentials.Core void SetRoomCombinationScenario(string scenarioKey); } + /// + /// Represents a scenario for combining rooms, including activation, deactivation, and associated state. + /// + /// This interface defines the behavior for managing room combination scenarios, including + /// activation and deactivation, tracking the active state, and managing related partition states and UI mappings. + /// Implementations of this interface are expected to handle the logic for room combinations based on the provided + /// partition states and UI mappings. public interface IRoomCombinationScenario : IKeyName { /// @@ -82,6 +100,9 @@ namespace PepperDash.Essentials.Core [JsonIgnore] BoolFeedback IsActiveFeedback { get; } + /// + /// Gets a value indicating whether the entity is active. + /// [JsonProperty("isActive")] bool IsActive { get; } diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IEssentialsRoomCombinerMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IEssentialsRoomCombinerMessenger.cs index a29d7b9e..1752b567 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IEssentialsRoomCombinerMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IEssentialsRoomCombinerMessenger.cs @@ -8,16 +8,42 @@ using System.Collections.Generic; namespace PepperDash.Essentials.AppServer.Messengers { + /// + /// Provides messaging functionality for managing room combination scenarios and partition states in an instance. Enables external systems to interact with the room combiner via + /// predefined actions and status updates. + /// + /// This class facilitates communication with an by + /// exposing actions for toggling modes, managing partitions, and setting room combination scenarios. It also + /// listens for feedback changes and broadcasts status updates to connected systems. Typical usage involves + /// registering actions for external commands and handling feedback events to synchronize state changes. public class IEssentialsRoomCombinerMessenger : MessengerBase { private readonly IEssentialsRoomCombiner _roomCombiner; + /// + /// Initializes a new instance of the class, which facilitates + /// messaging for an instance. + /// + /// This class is designed to enable communication and interaction with an through the specified messaging path. Ensure that the parameter is not null when creating an instance. + /// The unique key identifying this messenger instance. + /// The path used for messaging operations. + /// The instance associated with this messenger. public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner) : base(key, messagePath, roomCombiner as IKeyName) { _roomCombiner = roomCombiner; } + /// + /// Registers actions and event handlers for managing room combination scenarios and partition states. + /// + /// This method sets up various actions that can be triggered via specific endpoints, + /// such as toggling modes, setting room combination scenarios, and managing partition states. It also + /// subscribes to feedback events to update the status when changes occur in room combination scenarios or + /// partition states. protected override void RegisterActions() { AddAction("/fullStatus", (id, content) => SendFullStatus()); @@ -107,6 +133,7 @@ namespace PepperDash.Essentials.AppServer.Messengers var message = new IEssentialsRoomCombinerStateMessage { + DisableAutoMode = _roomCombiner.DisableAutoMode, IsInAutoMode = _roomCombiner.IsInAutoMode, CurrentScenario = _roomCombiner.CurrentScenario, Rooms = rooms, @@ -132,20 +159,48 @@ namespace PepperDash.Essentials.AppServer.Messengers } } + /// + /// Represents the state message for a room combiner system, providing information about the current configuration, + /// operational mode, and associated rooms, partitions, and scenarios. + /// + /// This class is used to encapsulate the state of a room combiner system, including its current + /// mode of operation, active room combination scenario, and the list of rooms and partitions involved. It is + /// typically serialized and transmitted to communicate the state of the system. public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase { + /// + /// Gets or sets a value indicating whether automatic mode is disabled. + /// + [JsonProperty("disableAutoMode", NullValueHandling = NullValueHandling.Ignore)] + public bool DisableAutoMode { get; set; } + + /// + /// Gets or sets a value indicating whether the system is operating in automatic mode. + /// [JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)] public bool IsInAutoMode { get; set; } + /// + /// Gets or sets the current room combination scenario. + /// [JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)] public IRoomCombinationScenario CurrentScenario { get; set; } + /// + /// Gets or sets the collection of rooms associated with the entity. + /// [JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)] public List Rooms { get; set; } + /// + /// Gets or sets the collection of room combination scenarios. + /// [JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)] public List RoomCombinationScenarios { get; set; } + /// + /// Gets or sets the collection of partition controllers. + /// [JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)] public List Partitions { get; set; } }