From 37cea8a11c7e3e18eb2fba09f08d1d7b14643a04 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 7 Oct 2025 11:52:07 -0600 Subject: [PATCH 01/11] fix: Refactor camera control interfaces and event arguments Significantly restructure camera control interfaces and event arguments. Removed obsolete interfaces like `IHasCameras` and `CameraSelectedEventArgs`, and introduced generic event argument classes for improved type safety. Added `IHasCamerasWithControls` for better management of camera controls. Corrected the `IHasCameraMuteWithUnmuteReqeust` interface name. Reintroduced the `eCameraControlMode` enum to define camera control modes. These changes enhance the organization, clarity, and functionality of the camera control system. --- .../Cameras/CameraControl.cs | 326 ------------------ .../Interfaces/CameraSelectedEventArgs.cs | 49 +++ .../Cameras/Interfaces/IAmFarEndCamera.cs | 12 + .../Cameras/Interfaces/IHasAutoFocusMode.cs | 24 ++ .../Cameras/Interfaces/IHasCameraAutoMode.cs | 31 ++ .../Cameras/Interfaces/IHasCameraControls.cs | 13 + .../Interfaces/IHasCameraFocusControl.cs | 29 ++ .../Cameras/Interfaces/IHasCameraMute.cs | 31 ++ .../IHasCameraMuteWithUnmuteRequest.cs | 16 + .../Cameras/Interfaces/IHasCameraOff.cs | 27 ++ .../Interfaces/IHasCameraPanControl.cs | 24 ++ .../Interfaces/IHasCameraPtzControl.cs | 14 + .../Interfaces/IHasCameraTiltControl.cs | 24 ++ .../Interfaces/IHasCameraZoomControl.cs | 24 ++ .../Cameras/Interfaces/IHasCameras.cs | 40 +++ .../Interfaces/IHasCamerasWithControls.cs | 39 +++ .../Cameras/Interfaces/IHasCodecCameras.cs | 13 + .../Interfaces/IHasFarEndCameraControl.cs | 23 ++ .../Cameras/Interfaces/eCameraControlMode.cs | 24 ++ 19 files changed, 457 insertions(+), 326 deletions(-) delete mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/CameraSelectedEventArgs.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IAmFarEndCamera.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasAutoFocusMode.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraAutoMode.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraControls.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraFocusControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMute.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMuteWithUnmuteRequest.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraOff.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPanControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPtzControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraTiltControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraZoomControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCodecCameras.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasFarEndCameraControl.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/eCameraControlMode.cs diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs deleted file mode 100644 index cec2f58b..00000000 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs +++ /dev/null @@ -1,326 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Core; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Devices.Common.Cameras -{ - /// - /// Enum for camera control modes - /// - public enum eCameraControlMode - { - /// - /// Manual control mode, where the camera is controlled directly by the user or system - /// - Manual = 0, - /// - /// Off control mode, where the camera is turned off or disabled - /// - Off, - /// - /// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions - /// - Auto - } - - - /// - /// Interface for devices that have cameras - /// - public interface IHasCameras : IKeyName - { - /// - /// Event that is raised when a camera is selected - /// - event EventHandler CameraSelected; - - /// - /// List of cameras on the device. This should be a list of CameraBase objects - /// - List Cameras { get; } - - /// - /// The currently selected camera. This should be a CameraBase object - /// - CameraBase SelectedCamera { get; } - - /// - /// Feedback that indicates the currently selected camera - /// - StringFeedback SelectedCameraFeedback { get; } - - /// - /// Selects a camera from the list of available cameras based on the provided key. - /// - /// The unique identifier or name of the camera to select. - void SelectCamera(string key); - } - - /// - /// Defines the contract for IHasCodecCameras - /// - public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl - { - - } - - /// - /// To be implmented on codecs that can disable their camera(s) to blank the near end video - /// - public interface IHasCameraOff - { - /// - /// Feedback that indicates whether the camera is off - /// - BoolFeedback CameraIsOffFeedback { get; } - - /// - /// Turns the camera off, blanking the near end video - /// - void CameraOff(); - } - - /// - /// Describes the ability to mute and unmute camera video - /// - public interface IHasCameraMute - { - /// - /// Feedback that indicates whether the camera is muted - /// - BoolFeedback CameraIsMutedFeedback { get; } - - /// - /// Mutes the camera video, preventing it from being sent to the far end - /// - void CameraMuteOn(); - - /// - /// Unmutes the camera video, allowing it to be sent to the far end - /// - void CameraMuteOff(); - - /// - /// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa. - /// - void CameraMuteToggle(); - } - - /// - /// Interface for devices that can mute and unmute their camera video, with an event for unmute requests - /// - public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute - { - /// - /// Event that is raised when a video unmute is requested, typically by the far end - /// - event EventHandler VideoUnmuteRequested; - } - - /// - /// Event arguments for the CameraSelected event - /// - public class CameraSelectedEventArgs : EventArgs - { - /// - /// Gets or sets the SelectedCamera - /// - public CameraBase SelectedCamera { get; private set; } - - /// - /// Constructor for CameraSelectedEventArgs - /// - /// - public CameraSelectedEventArgs(CameraBase camera) - { - SelectedCamera = camera; - } - } - - /// - /// Interface for devices that have a far end camera control - /// - public interface IHasFarEndCameraControl - { - /// - /// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call - /// - CameraBase FarEndCamera { get; } - - /// - /// Feedback that indicates whether the far end camera is being controlled - /// - BoolFeedback ControllingFarEndCameraFeedback { get; } - - } - - /// - /// Defines the contract for IAmFarEndCamera - /// - public interface IAmFarEndCamera - { - - } - - /// - /// Interface for devices that have camera controls - /// - public interface IHasCameraControls - { - } - - /// - /// Defines the contract for IHasCameraPtzControl - /// - public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl - { - /// - /// Resets the camera position - /// - void PositionHome(); - } - - /// - /// Interface for camera pan control - /// - public interface IHasCameraPanControl : IHasCameraControls - { - /// - /// Pans the camera left - /// - void PanLeft(); - - /// - /// Pans the camera right - /// - void PanRight(); - - /// - /// Stops the camera pan movement - /// - void PanStop(); - } - - /// - /// Defines the contract for IHasCameraTiltControl - /// - public interface IHasCameraTiltControl : IHasCameraControls - { - /// - /// Tilts the camera down - /// - void TiltDown(); - - /// - /// Tilts the camera up - /// - void TiltUp(); - - /// - /// Stops the camera tilt movement - /// - void TiltStop(); - } - - /// - /// Defines the contract for IHasCameraZoomControl - /// - public interface IHasCameraZoomControl : IHasCameraControls - { - /// - /// Zooms the camera in - /// - void ZoomIn(); - - /// - /// Zooms the camera out - /// - void ZoomOut(); - - /// - /// Stops the camera zoom movement - /// - void ZoomStop(); - } - - /// - /// Defines the contract for IHasCameraFocusControl - /// - public interface IHasCameraFocusControl : IHasCameraControls - { - /// - /// Focuses the camera near - /// - void FocusNear(); - - /// - /// Focuses the camera far - /// - void FocusFar(); - - /// - /// Stops the camera focus movement - /// - void FocusStop(); - - /// - /// Triggers the camera's auto focus functionality, if available. - /// - void TriggerAutoFocus(); - } - - /// - /// Interface for devices that have auto focus mode control - /// - public interface IHasAutoFocusMode - { - /// - /// Sets the focus mode to auto or manual, or toggles between them. - /// - void SetFocusModeAuto(); - - /// - /// Sets the focus mode to manual, allowing for manual focus adjustments. - /// - void SetFocusModeManual(); - - /// - /// Toggles the focus mode between auto and manual. - /// - void ToggleFocusMode(); - } - - /// - /// Interface for devices that have camera auto mode control - /// - public interface IHasCameraAutoMode : IHasCameraControls - { - /// - /// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings. - /// - void CameraAutoModeOn(); - - /// - /// Disables the camera's auto mode, allowing for manual control of camera settings. - /// - void CameraAutoModeOff(); - - /// - /// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa. - /// - void CameraAutoModeToggle(); - - /// - /// Feedback that indicates whether the camera's auto mode is currently enabled. - /// - BoolFeedback CameraAutoModeIsOnFeedback { get; } - } - - - - -} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/CameraSelectedEventArgs.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/CameraSelectedEventArgs.cs new file mode 100644 index 00000000..bb2a85a2 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/CameraSelectedEventArgs.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Event arguments for the CameraSelected event + /// + [Obsolete("Use CameraSelectedEventArgs instead. This class will be removed in a future version")] + public class CameraSelectedEventArgs : EventArgs + { + /// Gets or sets the SelectedCamera + /// + public CameraBase SelectedCamera { get; private set; } + + /// + /// Constructor for CameraSelectedEventArgs + /// + /// + public CameraSelectedEventArgs(CameraBase camera) + { + SelectedCamera = camera; + } + } + + /// + /// Event arguments for the CameraSelected event + /// + /// + public class CameraSelectedEventArgs : EventArgs + { + /// + /// Gets or sets the SelectedCamera + /// + public T SelectedCamera { get; private set; } + + /// + /// Constructor for CameraSelectedEventArgs + /// + /// + public CameraSelectedEventArgs(T camera) + { + SelectedCamera = camera; + } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IAmFarEndCamera.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IAmFarEndCamera.cs new file mode 100644 index 00000000..a8e96664 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IAmFarEndCamera.cs @@ -0,0 +1,12 @@ +using PepperDash.Core; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Defines the contract for IAmFarEndCamera + /// + public interface IAmFarEndCamera : IKeyName + { + + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasAutoFocusMode.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasAutoFocusMode.cs new file mode 100644 index 00000000..0dbd5f52 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasAutoFocusMode.cs @@ -0,0 +1,24 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for devices that have auto focus mode control + /// + public interface IHasAutoFocusMode : IHasCameraControls + { + /// + /// Sets the focus mode to auto or manual, or toggles between them. + /// + void SetFocusModeAuto(); + + /// + /// Sets the focus mode to manual, allowing for manual focus adjustments. + /// + void SetFocusModeManual(); + + /// + /// Toggles the focus mode between auto and manual. + /// + void ToggleFocusMode(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraAutoMode.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraAutoMode.cs new file mode 100644 index 00000000..9eeb1f40 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraAutoMode.cs @@ -0,0 +1,31 @@ +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + + /// + /// Interface for devices that have camera auto mode control + /// + public interface IHasCameraAutoMode : IHasCameraControls + { + /// + /// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings. + /// + void CameraAutoModeOn(); + + /// + /// Disables the camera's auto mode, allowing for manual control of camera settings. + /// + void CameraAutoModeOff(); + + /// + /// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa. + /// + void CameraAutoModeToggle(); + + /// + /// Feedback that indicates whether the camera's auto mode is currently enabled. + /// + BoolFeedback CameraAutoModeIsOnFeedback { get; } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraControls.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraControls.cs new file mode 100644 index 00000000..a4ed5937 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraControls.cs @@ -0,0 +1,13 @@ +using PepperDash.Core; + + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + + /// + /// Interface for devices that have camera controls + /// + public interface IHasCameraControls : IKeyName + { + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraFocusControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraFocusControl.cs new file mode 100644 index 00000000..bf266d56 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraFocusControl.cs @@ -0,0 +1,29 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Defines the contract for IHasCameraFocusControl + /// + public interface IHasCameraFocusControl : IHasCameraControls + { + /// + /// Focuses the camera near + /// + void FocusNear(); + + /// + /// Focuses the camera far + /// + void FocusFar(); + + /// + /// Stops the camera focus movement + /// + void FocusStop(); + + /// + /// Triggers the camera's auto focus functionality, if available. + /// + void TriggerAutoFocus(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMute.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMute.cs new file mode 100644 index 00000000..cae6f5ef --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMute.cs @@ -0,0 +1,31 @@ +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Describes the ability to mute and unmute camera video + /// + public interface IHasCameraMute : IKeyName + { + /// + /// Feedback that indicates whether the camera is muted + /// + BoolFeedback CameraIsMutedFeedback { get; } + + /// + /// Mutes the camera video, preventing it from being sent to the far end + /// + void CameraMuteOn(); + + /// + /// Unmutes the camera video, allowing it to be sent to the far end + /// + void CameraMuteOff(); + + /// + /// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa. + /// + void CameraMuteToggle(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMuteWithUnmuteRequest.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMuteWithUnmuteRequest.cs new file mode 100644 index 00000000..5426ea2b --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraMuteWithUnmuteRequest.cs @@ -0,0 +1,16 @@ +using System; + + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for devices that can mute and unmute their camera video, with an event for unmute requests + /// + public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute + { + /// + /// Event that is raised when a video unmute is requested, typically by the far end + /// + event EventHandler VideoUnmuteRequested; + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraOff.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraOff.cs new file mode 100644 index 00000000..6dc451c1 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraOff.cs @@ -0,0 +1,27 @@ +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.Cameras +{ + + + /// + /// To be implmented on codecs that can disable their camera(s) to blank the near end video + /// + public interface IHasCameraOff : IHasCameraControls + { + /// + /// Feedback that indicates whether the camera is off + /// + BoolFeedback CameraIsOffFeedback { get; } + + /// + /// Turns the camera off, blanking the near end video + /// + void CameraOff(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPanControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPanControl.cs new file mode 100644 index 00000000..507dc555 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPanControl.cs @@ -0,0 +1,24 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for camera pan control + /// + public interface IHasCameraPanControl : IHasCameraControls + { + /// + /// Pans the camera left + /// + void PanLeft(); + + /// + /// Pans the camera right + /// + void PanRight(); + + /// + /// Stops the camera pan movement + /// + void PanStop(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPtzControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPtzControl.cs new file mode 100644 index 00000000..de2b52dd --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraPtzControl.cs @@ -0,0 +1,14 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Defines the contract for IHasCameraPtzControl + /// + public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl + { + /// + /// Resets the camera position + /// + void PositionHome(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraTiltControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraTiltControl.cs new file mode 100644 index 00000000..87dc1751 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraTiltControl.cs @@ -0,0 +1,24 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Defines the contract for IHasCameraTiltControl + /// + public interface IHasCameraTiltControl : IHasCameraControls + { + /// + /// Tilts the camera down + /// + void TiltDown(); + + /// + /// Tilts the camera up + /// + void TiltUp(); + + /// + /// Stops the camera tilt movement + /// + void TiltStop(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraZoomControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraZoomControl.cs new file mode 100644 index 00000000..72bf16c4 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameraZoomControl.cs @@ -0,0 +1,24 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Defines the contract for IHasCameraZoomControl + /// + public interface IHasCameraZoomControl : IHasCameraControls + { + /// + /// Zooms the camera in + /// + void ZoomIn(); + + /// + /// Zooms the camera out + /// + void ZoomOut(); + + /// + /// Stops the camera zoom movement + /// + void ZoomStop(); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs new file mode 100644 index 00000000..f242f4f4 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs @@ -0,0 +1,40 @@ +using PepperDash.Core; +using PepperDash.Essentials.Core; +using System; +using System.Collections.Generic; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for devices that have cameras + /// + [Obsolete("Use IHasCamerasWithControls instead. This interface will be removed in a future version")] + public interface IHasCameras : IKeyName + { + /// + /// Event that is raised when a camera is selected + /// + event EventHandler CameraSelected; + + /// + /// List of cameras on the device. This should be a list of CameraBase objects + /// + List Cameras { get; } + + /// + /// The currently selected camera. This should be a CameraBase object + /// + CameraBase SelectedCamera { get; } + + /// + /// Feedback that indicates the currently selected camera + /// + StringFeedback SelectedCameraFeedback { get; } + + /// + /// Selects a camera from the list of available cameras based on the provided key. + /// + /// The unique identifier or name of the camera to select. + void SelectCamera(string key); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs new file mode 100644 index 00000000..a842364d --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs @@ -0,0 +1,39 @@ +using PepperDash.Core; +using PepperDash.Essentials.Core; +using System; +using System.Collections.Generic; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for devices that have cameras with controls + /// + public interface IHasCamerasWithControls : IKeyName, IKeyed + { + /// + /// List of cameras on the device. This should be a list of IHasCameraControls objects + /// + List Cameras { get; } + + /// + /// The currently selected camera. This should be an IHasCameraControls object + /// + IHasCameraControls SelectedCamera { get; } + + /// + /// Feedback that indicates the currently selected camera + /// + StringFeedback SelectedCameraFeedback { get; } + + /// + /// Event that is raised when a camera is selected + /// + event EventHandler> CameraSelected; + + /// + /// Selects a camera from the list of available cameras based on the provided key. + /// + /// + void SelectCamera(string key); + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCodecCameras.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCodecCameras.cs new file mode 100644 index 00000000..01cdf24e --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCodecCameras.cs @@ -0,0 +1,13 @@ + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + + /// + /// Defines the contract for IHasCodecCameras + /// + public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl + { + + } + +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasFarEndCameraControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasFarEndCameraControl.cs new file mode 100644 index 00000000..10a4ba69 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasFarEndCameraControl.cs @@ -0,0 +1,23 @@ +using PepperDash.Core; +using PepperDash.Essentials.Core; + + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for devices that have a far end camera control + /// + public interface IHasFarEndCameraControl : IKeyName + { + /// + /// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call + /// + CameraBase FarEndCamera { get; } + + /// + /// Feedback that indicates whether the far end camera is being controlled + /// + BoolFeedback ControllingFarEndCameraFeedback { get; } + + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/eCameraControlMode.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/eCameraControlMode.cs new file mode 100644 index 00000000..c966ac41 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/eCameraControlMode.cs @@ -0,0 +1,24 @@ + + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Enum for camera control modes + /// + public enum eCameraControlMode + { + /// + /// Manual control mode, where the camera is controlled directly by the user or system + /// + Manual = 0, + /// + /// Off control mode, where the camera is turned off or disabled + /// + Off, + /// + /// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions + /// + Auto + } + +} From 82b5dc96c13e1ab89659b4cd161ca5bd4b8ed46b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 7 Oct 2025 12:00:01 -0600 Subject: [PATCH 02/11] feat: Deprecate IHasCamerasMessenger; introduce new controls Mark IHasCamerasMessenger as obsolete and replace it with IHasCamerasWithControlMessenger, which adds functionality for devices with camera controls. A new state message class, IHasCamerasWithControlsStateMessage, has been added to encapsulate camera state. Update MobileControlSystemController to use the new messenger implementation. --- .../Messengers/IHasCamerasMessenger.cs | 11 +-- .../IHasCamerasWithControlMessenger.cs | 99 +++++++++++++++++++ .../MobileControlSystemController.cs | 13 +++ 3 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs index 7099e52c..00c2c2fe 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs @@ -1,17 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using Newtonsoft.Json; using PepperDash.Essentials.Devices.Common.Cameras; +using System; +using System.Collections.Generic; namespace PepperDash.Essentials.AppServer.Messengers { /// /// Messenger for devices that implement the IHasCameras interface. /// + [Obsolete("Use IHasCamerasWithControlsMessenger instead. This class will be removed in a future version")] public class IHasCamerasMessenger : MessengerBase { /// diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs new file mode 100644 index 00000000..d94cc4c4 --- /dev/null +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs @@ -0,0 +1,99 @@ +using Newtonsoft.Json; +using PepperDash.Essentials.Devices.Common.Cameras; +using System; +using System.Collections.Generic; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + /// + /// Messenger for devices that implement the IHasCameras interface. + /// + public class IHasCamerasWithControlMessenger : MessengerBase + { + /// + /// Device being bridged that implements IHasCameras interface. + /// + public IHasCamerasWithControls CameraController { get; private set; } + + /// + /// Messenger for devices that implement IHasCameras interface. + /// + /// + /// + /// + /// + public IHasCamerasWithControlMessenger(string key, string messagePath, IHasCamerasWithControls cameraController) + : base(key, messagePath, cameraController) + { + CameraController = cameraController ?? throw new ArgumentNullException("cameraController"); + CameraController.CameraSelected += CameraController_CameraSelected; + } + + private void CameraController_CameraSelected(object sender, CameraSelectedEventArgs e) + { + PostStatusMessage(new IHasCamerasWithControlsStateMessage + { + SelectedCamera = e.SelectedCamera + }); + } + + /// + /// Registers the actions for this messenger. + /// + /// + protected override void RegisterActions() + { + base.RegisterActions(); + + AddAction("/fullStatus", (id, context) => SendFullStatus(id)); + + AddAction("/cameraListStatus", (id, content) => SendFullStatus(id)); + + AddAction("/selectCamera", (id, content) => + { + var cameraKey = content?.ToObject(); + + if (!string.IsNullOrEmpty(cameraKey)) + { + CameraController.SelectCamera(cameraKey); + } + else + { + throw new ArgumentException("Content must be a string representing the camera key"); + } + }); + } + + private void SendFullStatus(string clientId) + { + var state = new IHasCamerasWithControlsStateMessage + { + CameraList = CameraController.Cameras, + SelectedCamera = CameraController.SelectedCamera + }; + + PostStatusMessage(state, clientId); + } + + + } + + /// + /// State message for devices that implement the IHasCameras interface. + /// + public class IHasCamerasWithControlsStateMessage : DeviceStateMessageBase + { + /// + /// List of cameras available in the device. + /// + [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)] + public List CameraList { get; set; } + + /// + /// The currently selected camera on the device. + /// + [JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)] + public IHasCameraControls SelectedCamera { get; set; } + + } +} diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs index 0579c1f6..a4914c10 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs @@ -975,6 +975,19 @@ namespace PepperDash.Essentials messengerAdded = true; } + if (device is IHasCamerasWithControls cameras2) + { + this.LogVerbose("Adding IHasCamerasMessenger for {deviceKey}", device.Key + ); + var messenger = new IHasCamerasWithControlMessenger( + $"{device.Key}-cameras-{Key}", + $"/device/{device.Key}", + cameras2 + ); + AddDefaultDeviceMessenger(messenger); + messengerAdded = true; + } + this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key); if (device is EssentialsDevice) From 2928c5cf94b25284352d81f83bdcd6b3c314ab07 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 7 Oct 2025 15:37:31 -0600 Subject: [PATCH 03/11] feat: Enhance camera capabilities and messaging structure - Introduced `ICameraCapabilities` interface and `CameraCapabilities` class for defining camera features like pan, tilt, zoom, and focus. - Modified `IHasCameras` interface to include a list of `IHasCameraControls` objects for improved camera management. - Refactored `CameraBaseMessenger` to be generic, enhancing flexibility and type safety. - Updated `SendCameraFullMessageObject` to include detailed camera capabilities in status messages. - Added `CameraStateMessage` class to encapsulate camera state, including control support and capabilities. - Updated `IHasCamerasWithControlMessenger` to use `IKeyName` for camera list and selected camera properties, improving type consistency. - Enhanced `MobileControlSystemController` to manage devices implementing `IHasCameraControls`, creating appropriate messengers for different device types. --- .../Cameras/Interfaces/ICameraCapabilities.cs | 86 ++++++++++++++ .../Cameras/Interfaces/IHasCameras.cs | 3 +- .../Interfaces/IHasCamerasWithControls.cs | 1 + .../Messengers/CameraBaseMessenger.cs | 111 ++++++++++++++++-- .../IHasCamerasWithControlMessenger.cs | 15 +-- .../MobileControlSystemController.cs | 22 +++- 6 files changed, 214 insertions(+), 24 deletions(-) create mode 100644 src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs new file mode 100644 index 00000000..cf39a95c --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs @@ -0,0 +1,86 @@ +using Newtonsoft.Json; +using PepperDash.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for camera capabilities + /// + public interface ICameraCapabilities: IKeyName + { + /// + /// Indicates whether the camera can pan + /// + [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)] + bool CanPan { get; } + + /// + /// Indicates whether the camera can tilt + /// + [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)] + bool CanTilt { get; } + + /// + /// Indicates whether the camera can zoom + /// + [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)] + bool CanZoom { get; } + + + /// + /// Indicates whether the camera can focus + /// + [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)] + bool CanFocus { get; } + } + + /// + /// Indicates the capabilities of a camera + /// + public class CameraCapabilities : ICameraCapabilities + { + + /// + /// Unique Key + /// + [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)] + public string Key { get; set; } + + /// + /// Isn't it obvious :) + /// + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name { get; set; } + + + /// + /// Indicates whether the camera can pan + /// + [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)] + public bool CanPan { get; set; } + + /// + /// Indicates whether the camera can tilt + /// + [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)] + public bool CanTilt { get; set; } + + /// + /// Indicates whether the camera can zoom + /// + [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)] + public bool CanZoom { get; set; } + + + /// + /// Indicates whether the camera can focus + /// + [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)] + public bool CanFocus { get; set; } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs index f242f4f4..5a5962f8 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs @@ -1,4 +1,5 @@ -using PepperDash.Core; +using Newtonsoft.Json; +using PepperDash.Core; using PepperDash.Essentials.Core; using System; using System.Collections.Generic; diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs index a842364d..f7aff6d2 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs @@ -13,6 +13,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// /// List of cameras on the device. This should be a list of IHasCameraControls objects /// + List Cameras { get; } /// diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs index 7650b430..8c9f0451 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.Cameras; @@ -9,12 +11,12 @@ namespace PepperDash.Essentials.AppServer.Messengers /// /// Messenger for a CameraBase device /// - public class CameraBaseMessenger : MessengerBase + public class CameraBaseMessenger : MessengerBase where T : IKeyed { /// /// Gets or sets the Camera /// - public CameraBase Camera { get; set; } + public T Camera { get; set; } /// /// Constructor @@ -22,10 +24,13 @@ namespace PepperDash.Essentials.AppServer.Messengers /// /// /// - public CameraBaseMessenger(string key, CameraBase camera, string messagePath) - : base(key, messagePath, camera) + public CameraBaseMessenger(string key, T camera, string messagePath) + : base(key, messagePath, camera as IKeyName) { - Camera = camera ?? throw new ArgumentNullException("camera"); + if (camera == null) + throw new ArgumentNullException(nameof(camera)); + + Camera = camera; if (Camera is IHasCameraPresets presetsCamera) @@ -178,19 +183,44 @@ namespace PepperDash.Essentials.AppServer.Messengers private void SendCameraFullMessageObject(string id = null) { var presetList = new List(); + CameraCapabilities capabilities = null; if (Camera is IHasCameraPresets presetsCamera) presetList = presetsCamera.Presets; - PostStatusMessage(JToken.FromObject(new + if (Camera is ICameraCapabilities cameraCapabilities) + capabilities = new CameraCapabilities + { + CanPan = cameraCapabilities.CanPan, + CanTilt = cameraCapabilities.CanTilt, + CanZoom = cameraCapabilities.CanZoom, + CanFocus = cameraCapabilities.CanFocus + + }; + + if (Camera is CameraBase cameraBase) + capabilities = new CameraCapabilities + { + CanPan = cameraBase.CanPan, + CanTilt = cameraBase.CanTilt, + CanZoom = cameraBase.CanZoom, + CanFocus = cameraBase.CanFocus + + }; + + var message = new CameraStateMessage { - cameraManualSupported = Camera is IHasCameraControls, - cameraAutoSupported = Camera is IHasCameraAutoMode, - cameraOffSupported = Camera is IHasCameraOff, - cameraMode = GetCameraMode(), - hasPresets = Camera is IHasCameraPresets, - presets = presetList - }), id + CameraManualSupported = Camera is IHasCameraControls, + CameraAutoSupported = Camera is IHasCameraAutoMode, + CameraOffSupported = Camera is IHasCameraOff, + CameraMode = (eCameraControlMode)Enum.Parse(typeof(eCameraControlMode), GetCameraMode(), true), + HasPresets = Camera is IHasCameraPresets, + Presets = presetList, + Capabilities = capabilities, + IsFarEnd = Camera is IAmFarEndCamera + }; + + PostStatusMessage(message, id ); } @@ -210,4 +240,59 @@ namespace PepperDash.Essentials.AppServer.Messengers return m; } } + + /// + /// State message for a camera device + /// + public class CameraStateMessage : DeviceStateMessageBase + { + /// + /// Indicates whether the camera supports manual control + /// + [JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)] + public bool CameraManualSupported { get; set; } + + /// + /// Indicates whether the camera supports auto control + /// + [JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)] + public bool CameraAutoSupported { get; set; } + + /// + /// Indicates whether the camera supports off control + /// + [JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)] + public bool CameraOffSupported { get; set; } + + /// + /// Indicates the current camera control mode + /// + [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public eCameraControlMode CameraMode { get; set; } + + /// + /// Indicates whether the camera has presets + /// + [JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)] + public bool HasPresets { get; set; } + + /// + /// List of presets if the camera supports them + /// + [JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)] + public List Presets { get; set; } + + /// + /// Indicates the capabilities of the camera + /// + [JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)] + public CameraCapabilities Capabilities { get; set; } + + /// + /// Indicates whether the camera is a far end camera + /// + [JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)] + public bool IsFarEnd { get; set; } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs index d94cc4c4..e8c4a6a0 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs @@ -1,7 +1,9 @@ using Newtonsoft.Json; +using PepperDash.Core; using PepperDash.Essentials.Devices.Common.Cameras; using System; using System.Collections.Generic; +using System.Linq; namespace PepperDash.Essentials.AppServer.Messengers { @@ -68,14 +70,12 @@ namespace PepperDash.Essentials.AppServer.Messengers { var state = new IHasCamerasWithControlsStateMessage { - CameraList = CameraController.Cameras, - SelectedCamera = CameraController.SelectedCamera + CameraList = CameraController.Cameras.Cast().ToList(), + SelectedCamera = CameraController.SelectedCamera as IKeyName }; PostStatusMessage(state, clientId); } - - } /// @@ -87,13 +87,14 @@ namespace PepperDash.Essentials.AppServer.Messengers /// List of cameras available in the device. /// [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)] - public List CameraList { get; set; } + public List CameraList { get; set; } /// /// The currently selected camera on the device. /// [JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)] - public IHasCameraControls SelectedCamera { get; set; } - + public IKeyName SelectedCamera { get; set; } } + + } diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs index a4914c10..d6a40ede 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs @@ -405,14 +405,15 @@ namespace PepperDash.Essentials messengerAdded = true; } - if (device is CameraBase cameraDevice) + // Default to IHasCameraControls if CameraBase and IHasCameraControls + if (device is CameraBase cameraDevice && !(device is IHasCameraControls)) { this.LogVerbose( "Adding CameraBaseMessenger for {deviceKey}", device.Key ); - var cameraMessenger = new CameraBaseMessenger( + var cameraMessenger = new CameraBaseMessenger( $"{device.Key}-cameraBase-{Key}", cameraDevice, $"/device/{device.Key}" @@ -423,6 +424,21 @@ namespace PepperDash.Essentials messengerAdded = true; } + if (device is IHasCameraControls cameraControlDev) + { + this.LogVerbose( + "Adding IHasCamerasWithControlMessenger for {deviceKey}", + device.Key + ); + var cameraControlMessenger = new CameraBaseMessenger( + $"{device.Key}-hasCamerasWithControls-{Key}", + cameraControlDev, + $"/device/{device.Key}" + ); + AddDefaultDeviceMessenger(cameraControlMessenger); + messengerAdded = true; + } + if (device is BlueJeansPc) { this.LogVerbose( @@ -977,7 +993,7 @@ namespace PepperDash.Essentials if (device is IHasCamerasWithControls cameras2) { - this.LogVerbose("Adding IHasCamerasMessenger for {deviceKey}", device.Key + this.LogVerbose("Adding IHasCamerasWithControlsMessenger for {deviceKey}", device.Key ); var messenger = new IHasCamerasWithControlMessenger( $"{device.Key}-cameras-{Key}", From bd01e2bacce4df7af3165ebaa85da113bca11a4b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 7 Oct 2025 17:10:11 -0600 Subject: [PATCH 04/11] fix: Add KeyName class and update camera messaging This commit introduces a new `KeyName` class implementing the `IKeyName` interface, enhancing the representation of camera data. The `CameraController_CameraSelected` and `SendFullStatus` methods are updated to utilize `KeyName` instances for selected and listed cameras, improving data encapsulation and consistency in the `IHasCamerasWithControlsStateMessage`. Additionally, new using directives for logging and core functionalities are added. --- .../IHasCamerasWithControlMessenger.cs | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs index e8c4a6a0..cce07dcd 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs @@ -1,5 +1,7 @@ using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Core.Logging; +using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.Cameras; using System; using System.Collections.Generic; @@ -33,9 +35,15 @@ namespace PepperDash.Essentials.AppServer.Messengers private void CameraController_CameraSelected(object sender, CameraSelectedEventArgs e) { + var selectedCamera = new KeyName + { + Key = e.SelectedCamera.Key, + Name = e.SelectedCamera.Name + }; + PostStatusMessage(new IHasCamerasWithControlsStateMessage { - SelectedCamera = e.SelectedCamera + SelectedCamera = selectedCamera }); } @@ -68,10 +76,30 @@ namespace PepperDash.Essentials.AppServer.Messengers private void SendFullStatus(string clientId) { + var cameraList = new List(); + KeyName selectedCamera = null; + + foreach (var cam in CameraController.Cameras) + { + cameraList.Add(new KeyName{ + Key = cam.Key, + Name = cam.Name + }); + } + + if (CameraController.SelectedCamera != null) + { + selectedCamera = new KeyName + { + Key = CameraController.SelectedCamera.Key, + Name = CameraController.SelectedCamera.Name + }; + } + var state = new IHasCamerasWithControlsStateMessage { - CameraList = CameraController.Cameras.Cast().ToList(), - SelectedCamera = CameraController.SelectedCamera as IKeyName + CameraList = cameraList, + SelectedCamera = selectedCamera }; PostStatusMessage(state, clientId); @@ -96,5 +124,14 @@ namespace PepperDash.Essentials.AppServer.Messengers public IKeyName SelectedCamera { get; set; } } - + class KeyName : IKeyName + { + public string Key { get; set; } + public string Name { get; set; } + public KeyName() + { + Key = ""; + Name = ""; + } + } } From 419177ccd54f2b88cdeb0a74f105fac58d250ddd Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 8 Oct 2025 12:24:17 -0600 Subject: [PATCH 05/11] fix: Add item management and update handling in messenger Introduces a new private field `_itemKeys` to store item keys. Adds the `SetItems` method to manage item actions and update events, ensuring proper registration and cleanup. The `SendFullStatus` method is now invoked from a dedicated event handler `LocalItem_ItemUpdated`, improving the handling of item updates. --- .../Messengers/ISelectableItemsMessenger.cs | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs index 36d73a3e..c3b3715f 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs @@ -16,6 +16,8 @@ namespace PepperDash.Essentials.AppServer.Messengers private readonly string _propName; + private List _itemKeys = new List(); + /// /// Constructs a messenger for a device that implements ISelectableItems /// @@ -41,7 +43,7 @@ namespace PepperDash.Essentials.AppServer.Messengers itemDevice.ItemsUpdated += (sender, args) => { - SendFullStatus(); + SetItems(); }; itemDevice.CurrentItemChanged += (sender, args) => @@ -49,6 +51,22 @@ namespace PepperDash.Essentials.AppServer.Messengers SendFullStatus(); }; + SetItems(); + } + + /// + /// Sets the items and registers their update events + /// + private void SetItems() + { + /// Clear out any existing item actions + foreach (var item in _itemKeys) + { + RemoveAction($"/{item}"); + } + + _itemKeys.Clear(); + foreach (var input in itemDevice.Items) { var key = input.Key; @@ -59,13 +77,18 @@ namespace PepperDash.Essentials.AppServer.Messengers localItem.Select(); }); - localItem.ItemUpdated += (sender, args) => - { - SendFullStatus(); - }; + _itemKeys.Add(key.ToString()); + + localItem.ItemUpdated -= LocalItem_ItemUpdated; + localItem.ItemUpdated += LocalItem_ItemUpdated; } } + private void LocalItem_ItemUpdated(object sender, EventArgs e) + { + SendFullStatus(); + } + private void SendFullStatus(string id = null) { try From 59944c0e2f530d11fa8f4b01957ca97432a609b8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 9 Oct 2025 08:33:22 -0500 Subject: [PATCH 06/11] refactor: split up classes to separate files --- .../Displays/DisplayBase.cs | 91 ------------------ .../Displays/TwoWayDisplayBase.cs | 95 +++++++++++++++++++ 2 files changed, 95 insertions(+), 91 deletions(-) create mode 100644 src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs index c94591a3..ae070387 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs @@ -430,95 +430,4 @@ 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 - { - /// - /// Gets feedback for the current input selection on the display. - /// - public StringFeedback CurrentInputFeedback { get; private set; } - - /// - /// 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; } - - /// - /// Gets feedback indicating whether the display is currently powered on. - /// - public BoolFeedback PowerIsOnFeedback { get; protected set; } - - /// - /// 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; } - - /// - /// 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); - - WarmupTime = 7000; - CooldownTime = 15000; - - PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc); - - Feedbacks.Add(CurrentInputFeedback); - Feedbacks.Add(PowerIsOnFeedback); - - PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; - - } - - void PowerIsOnFeedback_OutputChange(object sender, EventArgs e) - { - if (UsageTracker != null) - { - if (PowerIsOnFeedback.BoolValue) - UsageTracker.StartDeviceUsage(); - else - UsageTracker.EndDeviceUsage(); - } - } - - /// - /// 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); - } - } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs new file mode 100644 index 00000000..226d4bbe --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Displays/TwoWayDisplayBase.cs @@ -0,0 +1,95 @@ +using System; +using PepperDash.Essentials.Core; + +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 + { + /// + /// Gets feedback for the current input selection on the display. + /// + public StringFeedback CurrentInputFeedback { get; private set; } + + /// + /// 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; } + + /// + /// Gets feedback indicating whether the display is currently powered on. + /// + public BoolFeedback PowerIsOnFeedback { get; protected set; } + + /// + /// 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; } + + /// + /// 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("currentInput", CurrentInputFeedbackFunc); + + WarmupTime = 7000; + CooldownTime = 15000; + + PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc); + + Feedbacks.Add(CurrentInputFeedback); + Feedbacks.Add(PowerIsOnFeedback); + + PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; + + } + + void PowerIsOnFeedback_OutputChange(object sender, EventArgs e) + { + if (UsageTracker != null) + { + if (PowerIsOnFeedback.BoolValue) + UsageTracker.StartDeviceUsage(); + else + UsageTracker.EndDeviceUsage(); + } + } + + /// + /// 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) + { + NumericSwitchChange?.Invoke(this, e); + } + } +} \ No newline at end of file From a5d409e93a2581509ca806e03cbf2f812b6ac10c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 9 Oct 2025 08:36:26 -0500 Subject: [PATCH 07/11] fix: analog input check uese correct comparison input selection coming from SIMPL is 1-based, not 0-based. Comparison to input port array length needs to be <= instead of < --- .../Displays/DisplayBase.cs | 129 +++++++++--------- 1 file changed, 67 insertions(+), 62 deletions(-) diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs index ae070387..5db03a30 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/DisplayBase.cs @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// 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 + public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources, IHasFeedback { private RoutingInputPort _currentInputPort; @@ -73,13 +73,11 @@ namespace PepperDash.Essentials.Devices.Common.Displays var handler = CurrentSourceChange; - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.WillChange); + handler?.Invoke(_CurrentSourceInfo, ChangeType.WillChange); _CurrentSourceInfo = value; - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.DidChange); + handler?.Invoke(_CurrentSourceInfo, ChangeType.DidChange); } } SourceListItem _CurrentSourceInfo; @@ -160,6 +158,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc); IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc); + Feedbacks.Add(IsCoolingDownFeedback); + Feedbacks.Add(IsWarmingUpFeedback); + InputPorts = new RoutingPortCollection(); CurrentSources = new Dictionary @@ -194,17 +195,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// Gets the collection of feedback objects for this display device. /// /// - public virtual FeedbackCollection Feedbacks - { - get - { - return new FeedbackCollection - { - IsCoolingDownFeedback, - IsWarmingUpFeedback - }; - } - } + public virtual FeedbackCollection Feedbacks { get; private set; } = new FeedbackCollection(); + /// /// Executes a switch to the specified input on the display device. Must be implemented by derived classes. @@ -252,47 +244,35 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// 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")); - Debug.LogMessage(LogEventLevel.Information, "Linking to Display: {0}", displayDevice.Name); + this.LogDebug("Linking to Trilist {ipId}", trilist.ID.ToString("X")); + this.LogDebug("Linking to Display: {displayName}", displayDevice.Name); trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name; - var commMonitor = displayDevice as ICommunicationMonitor; - if (commMonitor != null) + if (displayDevice is ICommunicationMonitor commMonitor) { commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); } + // TODO: revisit this as there could be issues with this approach var inputNumber = 0; var inputKeys = new List(); - var inputNumberFeedback = new IntFeedback(() => inputNumber); + var inputNumberFeedback = new IntFeedback("inputNumber", () => inputNumber); - // Two way feedbacks - var twoWayDisplay = displayDevice as TwoWayDisplayBase; + // Add input number feedback to the device feedback collection to keep it around... + Feedbacks.Add(inputNumberFeedback); - if (twoWayDisplay != null) + // Two way feedbacks + if (displayDevice is TwoWayDisplayBase twoWayDisplay) { trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true); - twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Information, "CurrentInputFeedback_OutputChange {0}", a.StringValue); - + twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => this.LogDebug("CurrentInputFeedback_OutputChange {input}", a.StringValue); inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]); - } - // Power Off - trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () => - { - inputNumber = 102; - inputNumberFeedback.FireUpdate(); - displayDevice.PowerOff(); - }); - - var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase; - if (twoWayDisplayDevice != null) - { - twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) => + twoWayDisplay.PowerIsOnFeedback.OutputChange += (o, a) => { if (!a.BoolValue) { @@ -307,10 +287,18 @@ namespace PepperDash.Essentials.Devices.Common.Displays } }; - twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]); - twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]); + twoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]); + twoWayDisplay.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]); } + // Power Off + trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () => + { + inputNumber = 102; + inputNumberFeedback.FireUpdate(); + displayDevice.PowerOff(); + }); + // PowerOn trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () => { @@ -320,44 +308,61 @@ namespace PepperDash.Essentials.Devices.Common.Displays }); - for (int i = 0; i < displayDevice.InputPorts.Count; i++) { - if (i < joinMap.InputNamesOffset.JoinSpan) + var localindex = i; + if (localindex >= joinMap.InputNamesOffset.JoinSpan) { - inputKeys.Add(displayDevice.InputPorts[i].Key); - var tempKey = inputKeys.ElementAt(i); - trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i), - () => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector)); - Debug.LogMessage(LogEventLevel.Verbose, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}", - joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString()); - trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString(); + this.LogWarning("Device has {inputCount} inputs. The Join Map allows up to {joinSpan} inputs. Discarding inputs {discardStart} - {discardEnd} from bridge.", + displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, localindex + 1, displayDevice.InputPorts.Count); + + continue; } else - Debug.LogMessage(LogEventLevel.Information, displayDevice, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.", - displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count); + { + inputKeys.Add(displayDevice.InputPorts[localindex].Key); + + var tempKey = inputKeys.ElementAt(localindex); + + trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + localindex), () => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector)); + + this.LogDebug("Setting Input Select Action on Digital Join {joinNumber} to Input: {input}", joinMap.InputSelectOffset.JoinNumber + localindex, displayDevice.InputPorts[tempKey].Key); + + trilist.SetString((uint)(joinMap.InputNamesOffset.JoinNumber + localindex), displayDevice.InputPorts[localindex].Key); + } } - Debug.LogMessage(LogEventLevel.Verbose, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect); - trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) => + this.LogDebug("Setting Input Select Action on Analog Join {inputSelectJoin}", joinMap.InputSelect); + + trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (requestedInput) => { - if (a == 0) + if (requestedInput == 0) { displayDevice.PowerOff(); inputNumber = 0; + return; } - else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber) + + // using 1-based indexing for inputs coming from SIMPL, so need to check if the input is <= the count, not < + if (requestedInput > 0 && requestedInput <= displayDevice.InputPorts.Count && requestedInput != inputNumber) { - displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector); - inputNumber = a; + displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(requestedInput - 1).Selector); + + inputNumber = requestedInput; + + return; } - else if (a == 102) + + if (requestedInput == 102) { displayDevice.PowerToggle(); - + return; + } + + if (displayDevice is TwoWayDisplayBase) + { + inputNumberFeedback?.FireUpdate(); } - if (twoWayDisplay != null) - inputNumberFeedback.FireUpdate(); }); From 0418f8a7ccc4498be8329a98745fd538493669c2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 9 Oct 2025 09:40:46 -0600 Subject: [PATCH 08/11] fix: Fix typos and enhance item selection handling Corrected parameter name in GenericUdpServer constructor. Added new action for item selection in ISelectableItemsMessenger with error handling for missing or invalid keys. Updated SetItems method to improve clarity and ensure proper clearing and re-adding of item actions. --- src/PepperDash.Core/Comm/GenericUdpServer.cs | 6 +-- .../Messengers/ISelectableItemsMessenger.cs | 45 +++++++++++++++---- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/PepperDash.Core/Comm/GenericUdpServer.cs b/src/PepperDash.Core/Comm/GenericUdpServer.cs index 61bebf8d..1c747998 100644 --- a/src/PepperDash.Core/Comm/GenericUdpServer.cs +++ b/src/PepperDash.Core/Comm/GenericUdpServer.cs @@ -131,14 +131,14 @@ namespace PepperDash.Core /// /// /// - /// - public GenericUdpServer(string key, string address, int port, int buffefSize) + /// + public GenericUdpServer(string key, string address, int port, int bufferSize) : base(key) { StreamDebugging = new CommunicationStreamDebugging(key); Hostname = address; Port = port; - BufferSize = buffefSize; + BufferSize = bufferSize; CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler); diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs index c3b3715f..8e2f8f3e 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/ISelectableItemsMessenger.cs @@ -41,6 +41,32 @@ namespace PepperDash.Essentials.AppServer.Messengers AddAction("/itemsStatus", (id, content) => SendFullStatus(id)); + AddAction("/selectItem", (id, content) => + { + try + { + var key = content.ToObject(); + + if (key == null) + { + this.LogError("No key specified to select"); + return; + } + if (itemDevice.Items.ContainsKey((TKey)Convert.ChangeType(key, typeof(TKey)))) + { + itemDevice.Items[(TKey)Convert.ChangeType(key, typeof(TKey))].Select(); + } + else + { + this.LogError("Key {0} not found in items", key); + } + } + catch (Exception e) + { + this.LogError("Error selecting item: {0}", e.Message); + } + }); + itemDevice.ItemsUpdated += (sender, args) => { SetItems(); @@ -59,18 +85,21 @@ namespace PepperDash.Essentials.AppServer.Messengers /// private void SetItems() { - /// Clear out any existing item actions - foreach (var item in _itemKeys) + if (_itemKeys != null && _itemKeys.Count > 0) { - RemoveAction($"/{item}"); + /// Clear out any existing item actions + foreach (var item in _itemKeys) + { + RemoveAction($"/{item}"); + } + + _itemKeys.Clear(); } - _itemKeys.Clear(); - - foreach (var input in itemDevice.Items) + foreach (var item in itemDevice.Items) { - var key = input.Key; - var localItem = input.Value; + var key = item.Key; + var localItem = item.Value; AddAction($"/{key}", (id, content) => { From c284c4275f070d49ea0c779fee420863305ab3b8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 9 Oct 2025 11:31:38 -0600 Subject: [PATCH 09/11] feat: Enhance UDPServer initialization in Connect method Updated the `Connect` method in `GenericUdpServer.cs` to include error handling for hostname parsing. The method now attempts to create a `UDPServer` instance with specified parameters and falls back to default initialization if an error occurs. This improves flexibility and robustness in server setup. --- src/PepperDash.Core/Comm/GenericUdpServer.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Core/Comm/GenericUdpServer.cs b/src/PepperDash.Core/Comm/GenericUdpServer.cs index 1c747998..52ac627a 100644 --- a/src/PepperDash.Core/Comm/GenericUdpServer.cs +++ b/src/PepperDash.Core/Comm/GenericUdpServer.cs @@ -194,7 +194,21 @@ namespace PepperDash.Core { if (Server == null) { - Server = new UDPServer(); + try + { + var address = IPAddress.Parse(Hostname); + + Server = new UDPServer(address, Port, BufferSize); + + } + catch (Exception ex) + { + this.LogError("Error parsing IP Address '{ipAddress}': message: {message}", Hostname, ex.Message); + this.LogInformation("Creating UDPServer with default buffersize"); + + Server = new UDPServer(); + } + } if (string.IsNullOrEmpty(Hostname)) From f9d9df9d5cdbbdc4d93095eaa126df9dcf5766f8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 9 Oct 2025 13:18:36 -0500 Subject: [PATCH 10/11] docs: XML comments for Devices.Common --- .../Audio/GenericAudioOut.cs | 137 +- .../AudioCodec/AudioCodecBase.cs | 27 +- .../AudioCodec/Interfaces/IAudioCodecInfo.cs | 14 +- .../AudioCodec/Interfaces/IHasAudioCodec.cs | 16 +- .../AudioCodec/MockAC/MockAC.cs | 21 +- .../MockAC/MockAcPropertiesConfig.cs | 12 +- .../Cameras/CameraBase.cs | 145 +- .../Cameras/CameraControl.cs | 3 - .../Cameras/CameraVisca.cs | 410 ++-- .../Cameras/IHasCameraPresets.cs | 18 +- .../Codec/Call.cs | 26 + .../Codec/Cisco/IPresenterTrack.cs | 5 - .../Codec/Cisco/ISpeakerTrack.cs | 5 - .../Codec/CodecActiveCallItem.cs | 32 +- .../Codec/CodecDirectory.cs | 121 + .../Codec/CodecScheduleAwareness.cs | 146 ++ .../Codec/ContactMethod.cs | 37 + .../Codec/DirectoryContact.cs | 39 + .../Codec/DirectoryEventArgs.cs | 21 + .../Codec/DirectoryFolder.cs | 27 + .../Codec/DirectoryItem.cs | 41 + .../Codec/ICiscoCodecCameraConfig.cs | 52 +- .../Codec/IHasCallHold.cs | 8 +- .../Codec/IHasDirectoryHistoryStack.cs | 14 + .../Codec/IHasDoNotDisturb.cs | 11 +- .../Codec/IHasExternalSourceSwitching.cs | 51 +- .../Codec/IInvitableContact.cs | 13 + .../Codec/InvitableDirectoryContact.cs | 22 + .../Codec/Meeting.cs | 182 ++ .../Codec/MeetingEventArgs.cs | 22 + .../Codec/eCodecCallDirection.cs | 23 +- .../Codec/eCodecCallStatus.cs | 71 +- .../Codec/eCodecCallType.cs | 35 +- .../Codec/eContactMethodCallType.cs | 21 + .../Codec/eContactMethodDevice.cs | 29 + .../Codec/eMeetingEventChangeType.cs | 35 + .../Codec/eMeetingPrivacy.cs | 19 +- .../Codec/iCodecAudio.cs | 8 +- .../Codec/iHasCallFavorites.cs | 12 +- .../Codec/iHasCallHistory.cs | 44 +- .../Codec/iHasContentSharing.cs | 26 +- .../Codec/iHasDialer.cs | 40 +- .../Codec/iHasDirectory.cs | 320 +-- .../Codec/iHasScheduleAwareness.cs | 333 +-- .../DSP/DspBase.cs | 138 +- .../DeviceFactory.cs | 4 +- .../Displays/BasicIrDisplay.cs | 228 +- .../Displays/InputInterfaces.cs | 73 +- .../Displays/MockDisplay.cs | 412 ++-- .../Displays/MockDisplayInputs.cs | 38 +- .../Displays/ScreenLiftController.cs | 80 +- .../ScreenLiftControllerConfigProperties.cs | 41 + .../Displays/ScreenLiftRelaysConfig.cs | 22 + .../Displays/eScreenLiftControlMode.cs | 17 + .../Generic/GenericSink.cs | 29 +- .../Generic/GenericSource.cs | 68 +- .../Lighting/LightingBase.cs | 238 +- .../Room/IEssentialsHuddleSpaceRoom.cs | 10 + .../Room/IEssentialsHuddleVtc1Room.cs | 22 + .../Room/IEssentialsRoomPropertiesConfig.cs | 8 +- .../Room/IEssentialsTechRoom.cs | 24 +- .../SetTopBox/IRSetTopBoxBase.cs | 941 ++++---- .../SetTopBox/IRSetTopBoxBaseFactory.cs | 41 + .../SetTopBox/SetTopBoxPropertiesConfig.cs | 8 +- .../Shades/RelayControlledShade.cs | 9 + .../Shades/ShadeBase.cs | 21 +- .../Shades/ShadeController.cs | 12 + .../SoftCodec/BlueJeansPc.cs | 33 +- .../SoftCodec/BlueJeansPcFactory.cs | 35 + .../SoftCodec/GenericSoftCodec.cs | 89 +- .../SoftCodec/GenericSoftCodecFactory.cs | 35 + .../SoftCodec/GenericSoftCodecProperties.cs | 34 + .../Sources/InRoomPc.cs | 126 +- .../Sources/InRoomPcFactory.cs | 33 + .../Sources/Laptop.cs | 105 +- .../Sources/LaptopFactory.cs | 32 + .../Streaming/AppleTV.cs | 356 ++- .../Streaming/AppleTVFactory.cs | 33 + .../Streaming/AppleTvIrCommands.cs | 56 + .../Streaming/Roku.cs | 146 +- .../Streaming/Roku2Factory.cs | 36 + .../CiscoCodec/CallHistoryDataClasses.cs | 3 - .../VideoCodec/CiscoCodec/RoomPresets.cs | 8 +- .../CiscoCodec/eExternalSourceMode.cs | 20 +- .../CiscoCodec/eExternalSourceType.cs | 32 +- .../VideoCodec/CodecCommandWithLabel.cs | 31 + .../VideoCodec/CodecPhonebookSyncState.cs | 150 ++ .../VideoCodec/ConvertiblePreset.cs | 7 + .../Interfaces/CodecParticipants.cs | 63 + .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 30 +- .../Interfaces/IHasCodecSelfview.cs | 23 +- .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 98 +- .../VideoCodec/Interfaces/IHasMeetingLock.cs | 21 +- .../Interfaces/IHasMeetingRecording.cs | 33 +- .../IHasMeetingRecordingWithPrompt.cs | 21 + .../Interfaces/IHasParticipantAudioMute.cs | 31 + .../Interfaces/IHasParticipantPinUnpin.cs | 40 + .../Interfaces/IHasParticipantVideoMute.cs | 26 + .../VideoCodec/Interfaces/IHasParticipants.cs | 163 +- .../Interfaces/IHasPresentationOnlyMeeting.cs | 34 + .../Interfaces/IHasSelfviewPosition.cs | 12 +- .../VideoCodec/Interfaces/IHasSelfviewSize.cs | 16 +- .../VideoCodec/Interfaces/IHasStandbyMode.cs | 26 +- .../VideoCodec/Interfaces/IHasStartMeeting.cs | 8 +- .../VideoCodec/Interfaces/IHasVideoCodec.cs | 18 +- .../VideoCodec/Interfaces/IJoinCalls.cs | 16 +- .../VideoCodec/Interfaces/MeetingInfo.cs | 106 + .../Interfaces/MeetingInfoEventArgs.cs | 27 + .../VideoCodec/Interfaces/Participant.cs | 72 + .../VideoCodec/Interfaces/iVideoCodecInfo.cs | 34 +- .../VideoCodec/MockVC/MockCodecDirectory.cs | 227 +- .../VideoCodec/MockVC/MockVC.cs | 296 +-- .../VideoCodec/MockVC/MockVCCamera.cs | 27 +- .../MockVC/MockVcPropertiesConfig.cs | 18 +- .../VideoCodec/VideoCodecBase.cs | 2000 ++++++++--------- 115 files changed, 5772 insertions(+), 4292 deletions(-) create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/Call.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/CodecDirectory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/CodecScheduleAwareness.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/ContactMethod.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/DirectoryContact.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/DirectoryEventArgs.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/DirectoryFolder.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/DirectoryItem.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/IHasDirectoryHistoryStack.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/IInvitableContact.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/InvitableDirectoryContact.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/Meeting.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/MeetingEventArgs.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodCallType.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodDevice.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Codec/eMeetingEventChangeType.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftControllerConfigProperties.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftRelaysConfig.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Displays/eScreenLiftControlMode.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBaseFactory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPcFactory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecFactory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecProperties.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Sources/InRoomPcFactory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Sources/LaptopFactory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Streaming/AppleTVFactory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Streaming/AppleTvIrCommands.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/Streaming/Roku2Factory.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecCommandWithLabel.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecPhonebookSyncState.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/CodecParticipants.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecordingWithPrompt.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantAudioMute.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantPinUnpin.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantVideoMute.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfo.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfoEventArgs.cs create mode 100644 src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs diff --git a/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs b/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs index 23f46007..c0f8ac1e 100644 --- a/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs +++ b/src/PepperDash.Essentials.Devices.Common/Audio/GenericAudioOut.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Collections.Generic; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -17,48 +13,68 @@ namespace PepperDash.Essentials.Devices.Common /// public class GenericAudioOut : EssentialsDevice, IRoutingSink { - public RoutingInputPort CurrentInputPort => AnyAudioIn; + /// + /// Gets the current input port + /// + public RoutingInputPort CurrentInputPort => AnyAudioIn; - public event SourceInfoChangeHandler CurrentSourceChange; + /// + /// Event fired when the current source changes + /// + public event SourceInfoChangeHandler CurrentSourceChange; - public string CurrentSourceInfoKey { get; set; } - public SourceListItem CurrentSourceInfo - { - get - { - return _CurrentSourceInfo; - } - set - { - if (value == _CurrentSourceInfo) return; + /// + /// Gets or sets the current source info key + /// + public string CurrentSourceInfoKey { get; set; } + /// + /// Gets or sets the current source info + /// + public SourceListItem CurrentSourceInfo + { + get + { + return _CurrentSourceInfo; + } + set + { + if (value == _CurrentSourceInfo) return; - var handler = CurrentSourceChange; + var handler = CurrentSourceChange; - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.WillChange); + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.WillChange); - _CurrentSourceInfo = value; + _CurrentSourceInfo = value; - if (handler != null) - handler(_CurrentSourceInfo, ChangeType.DidChange); - } - } - SourceListItem _CurrentSourceInfo; + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.DidChange); + } + } + SourceListItem _CurrentSourceInfo; - /// - /// Gets or sets the AnyAudioIn - /// + /// + /// Gets or sets the AnyAudioIn + /// public RoutingInputPort AnyAudioIn { get; private set; } + /// + /// Constructor for GenericAudioOut + /// + /// Device key + /// Device name public GenericAudioOut(string key, string name) : base(key, name) { - AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio, + AnyAudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, null, this); } #region IRoutingInputs Members + /// + /// Gets the collection of input ports + /// public RoutingPortCollection InputPorts { get { return new RoutingPortCollection { AnyAudioIn }; } @@ -68,23 +84,32 @@ namespace PepperDash.Essentials.Devices.Common } - /// - /// Represents a GenericAudioOutWithVolume - /// + /// + /// Represents a GenericAudioOutWithVolume + /// public class GenericAudioOutWithVolume : GenericAudioOut, IHasVolumeDevice { + /// + /// Gets the volume device key + /// public string VolumeDeviceKey { get; private set; } + /// + /// Gets the volume zone + /// public uint VolumeZone { get; private set; } + /// + /// Gets the volume device + /// public IBasicVolumeControls VolumeDevice - { + { get { var dev = DeviceManager.GetDeviceForKey(VolumeDeviceKey); if (dev is IAudioZones) return (dev as IAudioZones).Zone[VolumeZone]; else return dev as IBasicVolumeControls; - } + } } /// @@ -103,24 +128,30 @@ namespace PepperDash.Essentials.Devices.Common } - public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory - { - public GenericAudioOutWithVolumeFactory() - { - TypeNames = new List() { "genericaudiooutwithvolume" }; - } + /// + /// Factory for creating GenericAudioOutWithVolume devices + /// + public class GenericAudioOutWithVolumeFactory : EssentialsDeviceFactory + { + /// + /// Constructor for GenericAudioOutWithVolumeFactory + /// + public GenericAudioOutWithVolumeFactory() + { + TypeNames = new List() { "genericaudiooutwithvolume" }; + } - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device"); - var zone = dc.Properties.Value("zone"); - return new GenericAudioOutWithVolume(dc.Key, dc.Name, - dc.Properties.Value("volumeDeviceKey"), zone); - } - } + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new GenericAudioOutWithVolumeFactory Device"); + var zone = dc.Properties.Value("zone"); + return new GenericAudioOutWithVolume(dc.Key, dc.Name, + dc.Properties.Value("volumeDeviceKey"), zone); + } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/AudioCodec/AudioCodecBase.cs b/src/PepperDash.Essentials.Devices.Common/AudioCodec/AudioCodecBase.cs index c0eff735..7f760bc3 100644 --- a/src/PepperDash.Essentials.Devices.Common/AudioCodec/AudioCodecBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/AudioCodec/AudioCodecBase.cs @@ -1,18 +1,20 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.Codec; namespace PepperDash.Essentials.Devices.Common.AudioCodec { + /// + /// Abstract base class for audio codec devices + /// public abstract class AudioCodecBase : EssentialsDevice, IHasDialer, IUsageTracking, IAudioCodecInfo { + /// + /// Event fired when call status changes + /// public event EventHandler CallStatusChange; /// @@ -52,6 +54,11 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec /// public List ActiveCalls { get; set; } + /// + /// Constructor for AudioCodecBase + /// + /// Device key + /// Device name public AudioCodecBase(string key, string name) : base(key, name) { @@ -70,11 +77,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec } /// - /// + /// Handles call status change events /// - /// - /// - /// + /// The call item that changed status protected void OnCallStatusChange(CodecActiveCallItem item) { var handler = CallStatusChange; @@ -92,16 +97,22 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec #region IHasDialer Members + /// public abstract void Dial(string number); + /// public abstract void EndCall(CodecActiveCallItem activeCall); + /// public abstract void EndAllCalls(); + /// public abstract void AcceptCall(CodecActiveCallItem item); + /// public abstract void RejectCall(CodecActiveCallItem item); + /// public abstract void SendDtmf(string digit); #endregion diff --git a/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IAudioCodecInfo.cs b/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IAudioCodecInfo.cs index e853c898..3e6b0418 100644 --- a/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IAudioCodecInfo.cs +++ b/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IAudioCodecInfo.cs @@ -1,16 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.AudioCodec +namespace PepperDash.Essentials.Devices.Common.AudioCodec { /// /// Implements a common set of data about a codec /// public interface IAudioCodecInfo { + /// + /// Gets the codec information + /// AudioCodecInfo CodecInfo { get; } } @@ -19,6 +16,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec /// public abstract class AudioCodecInfo { + /// + /// Gets or sets the phone number + /// public abstract string PhoneNumber { get; set; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IHasAudioCodec.cs b/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IHasAudioCodec.cs index a1a2d64d..946c2053 100644 --- a/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IHasAudioCodec.cs +++ b/src/PepperDash.Essentials.Devices.Common/AudioCodec/Interfaces/IHasAudioCodec.cs @@ -1,23 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.AudioCodec { /// /// For rooms that have audio codec /// - public interface IHasAudioCodec:IHasInCallFeedback + public interface IHasAudioCodec : IHasInCallFeedback { + /// + /// Gets the audio codec device + /// AudioCodecBase AudioCodec { get; } - /// - /// Make this more specific - /// //List ActiveCalls { get; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAC.cs b/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAC.cs index 85c21474..48235a45 100644 --- a/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAC.cs +++ b/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAC.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Collections.Generic; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -17,6 +13,12 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec /// public class MockAC : AudioCodecBase { + /// + /// Constructor for MockAC + /// + /// Device key + /// Device name + /// MockAC properties configuration public MockAC(string key, string name, MockAcPropertiesConfig props) : base(key, name) { @@ -109,13 +111,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s); } - /// - /// - /// - /// /// /// TestIncomingAudioCall method /// + /// Phone number to call from public void TestIncomingAudioCall(string number) { Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingAudioCall from {0}", number); @@ -133,6 +132,7 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec { string _phoneNumber; + /// public override string PhoneNumber { get @@ -151,6 +151,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec /// public class MockACFactory : EssentialsDeviceFactory { + /// + /// Constructor for MockACFactory + /// public MockACFactory() { TypeNames = new List() { "mockac" }; diff --git a/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAcPropertiesConfig.cs b/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAcPropertiesConfig.cs index 5ac31dcc..0deaca97 100644 --- a/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAcPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Devices.Common/AudioCodec/MockAC/MockAcPropertiesConfig.cs @@ -1,12 +1,4 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using Newtonsoft.Json; +using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.AudioCodec { @@ -15,10 +7,10 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec /// public class MockAcPropertiesConfig { - [JsonProperty("phoneNumber")] /// /// Gets or sets the PhoneNumber /// + [JsonProperty("phoneNumber")] public string PhoneNumber { get; set; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraBase.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraBase.cs index 0fb6f6ca..e2e15668 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraBase.cs @@ -3,20 +3,14 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Crestron.SimplSharp; -using System.Reflection; using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Devices; using PepperDash.Essentials.Core.Presets; -using PepperDash.Essentials.Devices.Common.Codec; - -using Newtonsoft.Json; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Cameras @@ -26,31 +20,52 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public enum eCameraCapabilities { + /// + /// No camera capabilities + /// None = 0, + /// + /// Camera supports pan movement + /// Pan = 1, - Tilt = 2, + /// + /// Camera supports tilt movement + /// + Tilt = 2, + /// + /// Camera supports zoom functionality + /// Zoom = 4, + /// + /// Camera supports focus adjustment + /// Focus = 8 } + /// + /// Abstract base class for camera devices that provides common camera functionality and capabilities + /// public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs - { - [JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)] + { /// /// Gets or sets the ControlMode /// + [JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)] public eCameraControlMode ControlMode { get; protected set; } #region IRoutingOutputs Members - [JsonIgnore] /// /// Gets or sets the OutputPorts /// + [JsonIgnore] public RoutingPortCollection OutputPorts { get; protected set; } #endregion + /// + /// Gets a value indicating whether this camera supports pan movement + /// [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)] public bool CanPan { @@ -59,6 +74,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras return (Capabilities & eCameraCapabilities.Pan) == eCameraCapabilities.Pan; } } + + /// + /// Gets a value indicating whether this camera supports tilt movement + /// [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)] public bool CanTilt { @@ -67,6 +86,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras return (Capabilities & eCameraCapabilities.Tilt) == eCameraCapabilities.Tilt; } } + + /// + /// Gets a value indicating whether this camera supports zoom functionality + /// [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)] public bool CanZoom { @@ -75,6 +98,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras return (Capabilities & eCameraCapabilities.Zoom) == eCameraCapabilities.Zoom; } } + + /// + /// Gets a value indicating whether this camera supports focus adjustment + /// [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)] public bool CanFocus { @@ -84,23 +111,42 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } } - // A bitmasked value to indicate the movement capabilites of this camera + /// + /// Gets or sets a bitmasked value to indicate the movement capabilities of this camera + /// protected eCameraCapabilities Capabilities { get; set; } - protected CameraBase(DeviceConfig config) : base(config) - { - OutputPorts = new RoutingPortCollection(); - - ControlMode = eCameraControlMode.Manual; - - } - - protected CameraBase(string key, string name) : - this (new DeviceConfig{Name = name, Key = key}) + /// + /// Initializes a new instance of the CameraBase class with the specified device configuration + /// + /// The device configuration + protected CameraBase(DeviceConfig config) : base(config) { - + OutputPorts = new RoutingPortCollection(); + + ControlMode = eCameraControlMode.Manual; + } + /// + /// Initializes a new instance of the CameraBase class with the specified key and name + /// + /// The unique key for this camera device + /// The friendly name for this camera device + protected CameraBase(string key, string name) : + this(new DeviceConfig { Name = name, Key = key }) + { + + } + + /// + /// Links the camera device to the API bridge for control and feedback + /// + /// The camera device to link + /// The trilist for communication + /// The starting join number for the camera controls + /// The join map key for custom join mappings + /// The EiscApiAdvanced bridge for advanced join mapping protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { @@ -240,13 +286,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras { int tempNum = i; - trilist.SetSigTrueAction((ushort) (joinMap.PresetRecallStart.JoinNumber + tempNum), () => + trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallStart.JoinNumber + tempNum), () => { presetsCamera.PresetSelect(tempNum); }); - trilist.SetSigTrueAction((ushort) (joinMap.PresetSaveStart.JoinNumber + tempNum), () => + trilist.SetSigTrueAction((ushort)(joinMap.PresetSaveStart.JoinNumber + tempNum), () => { - var label = trilist.GetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum)); + var label = trilist.GetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum)); presetsCamera.PresetStore(tempNum, label); }); @@ -277,7 +323,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label); } } - } + } /// @@ -285,6 +331,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public class CameraPreset : PresetBase { + /// + /// Initializes a new instance of the CameraPreset class + /// + /// The preset ID + /// The preset description + /// Whether the preset is defined + /// Whether the preset can be defined public CameraPreset(int id, string description, bool isDefined, bool isDefinable) : base(id, description, isDefined, isDefinable) { @@ -293,37 +346,37 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } - /// - /// Represents a CameraPropertiesConfig - /// - public class CameraPropertiesConfig - { - /// - /// Gets or sets the CommunicationMonitorProperties - /// - public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } + /// + /// Represents a CameraPropertiesConfig + /// + public class CameraPropertiesConfig + { + /// + /// Gets or sets the CommunicationMonitorProperties + /// + public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } - /// - /// Gets or sets the Control - /// - public ControlPropertiesConfig Control { get; set; } + /// + /// Gets or sets the Control + /// + public ControlPropertiesConfig Control { get; set; } - [JsonProperty("supportsAutoMode")] /// /// Gets or sets the SupportsAutoMode /// + [JsonProperty("supportsAutoMode")] public bool SupportsAutoMode { get; set; } - [JsonProperty("supportsOffMode")] /// /// Gets or sets the SupportsOffMode /// + [JsonProperty("supportsOffMode")] public bool SupportsOffMode { get; set; } - [JsonProperty("presets")] /// /// Gets or sets the Presets /// + [JsonProperty("presets")] public List Presets { get; set; } - } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs index cec2f58b..e2120638 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraVisca.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraVisca.cs index 9a8bce8b..126bcd27 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraVisca.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraVisca.cs @@ -3,38 +3,33 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; 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.Config; -using PepperDash.Essentials.Devices.Common.Codec; -using System.Text.RegularExpressions; -using System.Reflection; - -using Newtonsoft.Json; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Cameras { - /// - /// Represents a CameraVisca - /// - public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode - { + /// + /// Represents a CameraVisca + /// + public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode + { private readonly CameraViscaPropertiesConfig PropertiesConfig; - /// - /// Gets or sets the Communication - /// - public IBasicCommunication Communication { get; private set; } + /// + /// Gets or sets the Communication + /// + public IBasicCommunication Communication { get; private set; } - /// - /// Gets or sets the CommunicationMonitor - /// - public StatusMonitorBase CommunicationMonitor { get; private set; } + /// + /// Gets or sets the CommunicationMonitor + /// + public StatusMonitorBase CommunicationMonitor { get; private set; } /// /// Used to store the actions to parse inquiry responses as the inquiries are sent @@ -45,20 +40,41 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// Camera ID (Default 1) /// public byte ID = 0x01; + + /// + /// Response ID used for VISCA communication + /// public byte ResponseID; + /// + /// Slow speed value for pan movement + /// + public byte PanSpeedSlow = 0x10; - public byte PanSpeedSlow = 0x10; - public byte TiltSpeedSlow = 0x10; + /// + /// Slow speed value for tilt movement + /// + public byte TiltSpeedSlow = 0x10; + /// + /// Fast speed value for pan movement + /// public byte PanSpeedFast = 0x13; + + /// + /// Fast speed value for tilt movement + /// public byte TiltSpeedFast = 0x13; // private bool IsMoving; - private bool IsZooming; + private bool IsZooming; bool _powerIsOn; - public bool PowerIsOn + + /// + /// Gets or sets a value indicating whether the camera power is on + /// + public bool PowerIsOn { get { @@ -87,12 +103,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras long FastSpeedHoldTimeMs = 2000; - byte[] IncomingBuffer = new byte[] { }; - public BoolFeedback PowerIsOnFeedback { get; private set; } + byte[] IncomingBuffer = new byte[] { }; + /// + /// Feedback indicating whether the camera power is on + /// + public BoolFeedback PowerIsOnFeedback { get; private set; } + + /// + /// Initializes a new instance of the CameraVisca class + /// + /// The unique key for this camera device + /// The friendly name for this camera device + /// The communication interface for VISCA protocol + /// The camera properties configuration public CameraVisca(string key, string name, IBasicCommunication comm, CameraViscaPropertiesConfig props) : - base(key, name) - { + base(key, name) + { InquiryResponseQueue = new CrestronQueue>(15); Presets = props.Presets; @@ -107,8 +134,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras OutputPorts.Add(new RoutingOutputPort("videoOut", eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, this, true)); // Default to all capabilties - Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus; - + Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus; + Communication = comm; if (comm is ISocketStatus socket) { @@ -121,19 +148,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } Communication.BytesReceived += new EventHandler(Communication_BytesReceived); - PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; }); - CameraIsOffFeedback = new BoolFeedback(() => { return !PowerIsOn; }); + PowerIsOnFeedback = new BoolFeedback("powerIsOn", () => { return PowerIsOn; }); + CameraIsOffFeedback = new BoolFeedback("cameraIsOff", () => { return !PowerIsOn; }); - if (props.CommunicationMonitorProperties != null) - { - CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties); - } - else - { - CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF"); - } - DeviceManager.AddDevice(CommunicationMonitor); - } + if (props.CommunicationMonitorProperties != null) + { + CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties); + } + else + { + CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF"); + } + DeviceManager.AddDevice(CommunicationMonitor); + } /// @@ -165,57 +192,57 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } } - /// - /// CustomActivate method - /// - /// - public override bool CustomActivate() - { - Communication.Connect(); - - - CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); }; - CommunicationMonitor.Start(); + /// + /// CustomActivate method + /// + /// + public override bool CustomActivate() + { + Communication.Connect(); - CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator); - return true; - } + CommunicationMonitor.StatusChange += (o, a) => { Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor state: {0}", CommunicationMonitor.Status); }; + CommunicationMonitor.Start(); - /// - /// LinkToApi method - /// - public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); - } - void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) - { - Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString()); + CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator); + return true; + } - if (e.Client.IsConnected) - { - - } - else - { + /// + /// LinkToApi method + /// + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + } - } - } - + void Socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) + { + Debug.LogMessage(LogEventLevel.Verbose, this, "Socket Status Change: {0}", e.Client.ClientStatus.ToString()); - void SendBytes(byte[] b) - { - - if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1 - Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b)); + if (e.Client.IsConnected) + { - Communication.SendBytes(b); - } + } + else + { - void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e) - { + } + } + + + void SendBytes(byte[] b) + { + + if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1 + Debug.LogMessage(LogEventLevel.Verbose, this, "Sending:{0}", ComTextHelper.GetEscapedText(b)); + + Communication.SendBytes(b); + } + + void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e) + { var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length]; try @@ -355,10 +382,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// /// Sends a pan/tilt command. If the command is not for fastSpeed then it starts a timer to initiate fast speed. /// - /// - /// - private void SendPanTiltCommand (byte[] cmd, bool fastSpeedEnabled) - { + /// The VISCA command to send + /// Whether fast speed is enabled for this command + private void SendPanTiltCommand(byte[] cmd, bool fastSpeedEnabled) + { SendBytes(GetPanTiltCommand(cmd, fastSpeedEnabled)); if (!fastSpeedEnabled) @@ -372,7 +399,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras SpeedTimer = new CTimer((o) => SendPanTiltCommand(GetPanTiltCommand(cmd, true), true), FastSpeedHoldTimeMs); } - } + } private void StopSpeedTimer() { @@ -381,7 +408,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras SpeedTimer.Stop(); SpeedTimer.Dispose(); SpeedTimer = null; - } + } } /// @@ -424,14 +451,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras InquiryResponseQueue.Enqueue(HandlePowerResponse); } - /// - /// PowerOn method - /// - public void PowerOn() - { - SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF }); + /// + /// PowerOn method + /// + public void PowerOn() + { + SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF }); SendPowerQuery(); - } + } void HandlePowerResponse(byte[] response) { @@ -450,12 +477,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } } - /// - /// PowerOff method - /// - public void PowerOff() - { - SendBytes(new byte[] {ID, 0x01, 0x04, 0x00, 0x03, 0xFF}); + /// + /// PowerOff method + /// + public void PowerOff() + { + SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x03, 0xFF }); SendPowerQuery(); } @@ -470,22 +497,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras PowerOn(); } - /// - /// PanLeft method - /// - public void PanLeft() - { - SendPanTiltCommand(new byte[] {0x01, 0x03}, false); - // IsMoving = true; - } - /// - /// PanRight method - /// - public void PanRight() - { + /// + /// PanLeft method + /// + public void PanLeft() + { + SendPanTiltCommand(new byte[] { 0x01, 0x03 }, false); + // IsMoving = true; + } + /// + /// PanRight method + /// + public void PanRight() + { SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false); - // IsMoving = true; - } + // IsMoving = true; + } /// /// PanStop method /// @@ -493,22 +520,22 @@ namespace PepperDash.Essentials.Devices.Common.Cameras { Stop(); } - /// - /// TiltDown method - /// - public void TiltDown() - { + /// + /// TiltDown method + /// + public void TiltDown() + { SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false); - // IsMoving = true; - } - /// - /// TiltUp method - /// - public void TiltUp() - { + // IsMoving = true; + } + /// + /// TiltUp method + /// + public void TiltUp() + { SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false); - // IsMoving = true; - } + // IsMoving = true; + } /// /// TiltStop method /// @@ -517,28 +544,28 @@ namespace PepperDash.Essentials.Devices.Common.Cameras Stop(); } - private void SendZoomCommand (byte cmd) - { - SendBytes(new byte[] {ID, 0x01, 0x04, 0x07, cmd, 0xFF} ); - } + private void SendZoomCommand(byte cmd) + { + SendBytes(new byte[] { ID, 0x01, 0x04, 0x07, cmd, 0xFF }); + } - /// - /// ZoomIn method - /// - public void ZoomIn() - { + /// + /// ZoomIn method + /// + public void ZoomIn() + { SendZoomCommand(ZoomInCmd); - IsZooming = true; - } - /// - /// ZoomOut method - /// - public void ZoomOut() - { + IsZooming = true; + } + /// + /// ZoomOut method + /// + public void ZoomOut() + { SendZoomCommand(ZoomOutCmd); - IsZooming = true; - } + IsZooming = true; + } /// /// ZoomStop method /// @@ -547,23 +574,23 @@ namespace PepperDash.Essentials.Devices.Common.Cameras Stop(); } - /// - /// Stop method - /// - public void Stop() - { - if (IsZooming) - { + /// + /// Stop method + /// + public void Stop() + { + if (IsZooming) + { SendZoomCommand(ZoomStopCmd); - IsZooming = false; - } - else - { + IsZooming = false; + } + else + { StopSpeedTimer(); SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false); - // IsMoving = false; - } - } + // IsMoving = false; + } + } /// /// PositionHome method /// @@ -572,33 +599,39 @@ namespace PepperDash.Essentials.Devices.Common.Cameras SendBytes(new byte[] { ID, 0x01, 0x06, 0x02, PanSpeedFast, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }); SendBytes(new byte[] { ID, 0x01, 0x04, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFF }); } - /// - /// RecallPreset method - /// - public void RecallPreset(int presetNumber) - { - SendBytes(new byte[] {ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF} ); - } - /// - /// SavePreset method - /// - public void SavePreset(int presetNumber) - { - SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF }); - } + /// + /// RecallPreset method + /// + public void RecallPreset(int presetNumber) + { + SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF }); + } + /// + /// SavePreset method + /// + public void SavePreset(int presetNumber) + { + SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF }); + } #region IHasCameraPresets Members + /// + /// Event that is raised when the presets list has changed + /// public event EventHandler PresetsListHasChanged; - protected void OnPresetsListHasChanged() - { - var handler = PresetsListHasChanged; - if (handler == null) - return; + /// + /// Raises the PresetsListHasChanged event + /// + protected void OnPresetsListHasChanged() + { + var handler = PresetsListHasChanged; + if (handler == null) + return; - handler.Invoke(this, EventArgs.Empty); - } + handler.Invoke(this, EventArgs.Empty); + } /// /// Gets or sets the Presets @@ -741,6 +774,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public class CameraViscaFactory : EssentialsDeviceFactory { + /// + /// Initializes a new instance of the CameraViscaFactory class + /// public CameraViscaFactory() { TypeNames = new List() { "cameravisca" }; @@ -768,11 +804,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras { /// /// Control ID of the camera (1-7) - /// - [JsonProperty("id")] - /// /// Gets or sets the Id /// + [JsonProperty("id")] public uint Id { get; set; } /// @@ -790,7 +824,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// /// Slow tilt speed (0-18) /// - [JsonProperty("tiltSpeedSlow")] + [JsonProperty("tiltSpeedSlow")] public uint TiltSpeedSlow { get; set; } /// diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/IHasCameraPresets.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/IHasCameraPresets.cs index a8e8983d..0234a405 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/IHasCameraPresets.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/IHasCameraPresets.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; namespace PepperDash.Essentials.Devices.Common.Cameras { @@ -11,12 +8,27 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public interface IHasCameraPresets { + /// + /// Event that is raised when the presets list has changed + /// event EventHandler PresetsListHasChanged; + /// + /// Gets the list of camera presets + /// List Presets { get; } + /// + /// Selects the specified preset + /// + /// The preset number to select void PresetSelect(int preset); + /// + /// Stores a preset at the specified location with the given description + /// + /// The preset number to store + /// The description for the preset void PresetStore(int preset, string description); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Call.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Call.cs new file mode 100644 index 00000000..807a29d0 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Call.cs @@ -0,0 +1,26 @@ +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a Call + /// + public class Call + { + /// + /// Gets or sets the Number + /// + public string Number { get; set; } + /// + /// Gets or sets the Protocol + /// + public string Protocol { get; set; } + /// + /// Gets or sets the CallRate + /// + public string CallRate { get; set; } + /// + /// Gets or sets the CallType + /// + public string CallType { 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 f3f164bd..134dc7b5 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/IPresenterTrack.cs @@ -1,10 +1,5 @@ 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 { diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs index 83735183..522e6ad2 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Cisco/ISpeakerTrack.cs @@ -1,10 +1,5 @@ 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 { diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/CodecActiveCallItem.cs b/src/PepperDash.Essentials.Devices.Common/Codec/CodecActiveCallItem.cs index b0c91e4e..23a39f29 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/CodecActiveCallItem.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/CodecActiveCallItem.cs @@ -1,10 +1,6 @@  using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -17,55 +13,55 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public class CodecActiveCallItem { - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] /// /// Gets or sets the Name /// + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; set; } - [JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)] /// /// Gets or sets the Number /// + [JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)] public string Number { get; set; } - [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] - [JsonConverter(typeof(StringEnumConverter))] /// /// Gets or sets the Type /// + [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(StringEnumConverter))] public eCodecCallType Type { get; set; } - [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] - [JsonConverter(typeof(StringEnumConverter))] /// /// Gets or sets the Status /// + [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(StringEnumConverter))] public eCodecCallStatus Status { get; set; } - [JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)] - [JsonConverter(typeof(StringEnumConverter))] /// /// Gets or sets the Direction /// + [JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(StringEnumConverter))] public eCodecCallDirection Direction { get; set; } - [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] /// /// Gets or sets the Id /// + [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] public string Id { get; set; } - [JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)] /// /// Gets or sets the IsOnHold /// + [JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)] public bool IsOnHold { get; set; } - [JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)] /// /// Gets or sets the Duration /// + [JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)] public TimeSpan Duration { get; set; } //public object CallMetaData { get; set; } @@ -81,7 +77,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec { return !(Status == eCodecCallStatus.Disconnected || Status == eCodecCallStatus.Disconnecting - || Status == eCodecCallStatus.Idle + || Status == eCodecCallStatus.Idle || Status == eCodecCallStatus.Unknown); } } @@ -97,6 +93,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public CodecActiveCallItem CallItem { get; private set; } + /// + /// Initializes a new instance of the CodecCallStatusItemChangeEventArgs class + /// + /// The call item that changed public CodecCallStatusItemChangeEventArgs(CodecActiveCallItem item) { CallItem = item; diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/CodecDirectory.cs b/src/PepperDash.Essentials.Devices.Common/Codec/CodecDirectory.cs new file mode 100644 index 00000000..df613941 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/CodecDirectory.cs @@ -0,0 +1,121 @@ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a codec directory + /// + public class CodecDirectory + { + /// + /// Represents the contents of the directory + /// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data + /// + [JsonIgnore] + public List CurrentDirectoryResults { get; private set; } + + /// + /// Gets the Contacts in the CurrentDirectoryResults + /// + [JsonProperty("contacts")] + public List Contacts + { + get + { + return CurrentDirectoryResults.OfType().Cast().ToList(); + } + } + + /// + /// Gets the Folders in the CurrentDirectoryResults + /// + [JsonProperty("folders")] + public List Folders + { + get + { + return CurrentDirectoryResults.OfType().Cast().ToList(); + } + } + + /// + /// Used to store the ID of the current folder for CurrentDirectoryResults + /// Gets or sets the ResultsFolderId + /// + [JsonProperty("resultsFolderId")] + public string ResultsFolderId { get; set; } + + /// + /// Constructor for + /// + public CodecDirectory() + { + CurrentDirectoryResults = new List(); + } + + /// + /// Adds folders to the directory + /// + /// + public void AddFoldersToDirectory(List folders) + { + if (folders != null) + CurrentDirectoryResults.AddRange(folders); + + SortDirectory(); + } + + /// + /// Adds contacts to the directory + /// + /// + public void AddContactsToDirectory(List contacts) + { + if (contacts != null) + CurrentDirectoryResults.AddRange(contacts); + + SortDirectory(); + } + + /// + /// Filters the CurrentDirectoryResults by the predicate + /// + /// + + public void FilterContacts(Func predicate) + { + CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList(); + } + + /// + /// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically + /// + private void SortDirectory() + { + var sortedFolders = new List(); + + sortedFolders.AddRange(CurrentDirectoryResults.Where(f => f is DirectoryFolder)); + + sortedFolders.OrderBy(f => f.Name); + + var sortedContacts = new List(); + + sortedContacts.AddRange(CurrentDirectoryResults.Where(c => c is DirectoryContact)); + + sortedFolders.OrderBy(c => c.Name); + + CurrentDirectoryResults.Clear(); + + CurrentDirectoryResults.AddRange(sortedFolders); + + CurrentDirectoryResults.AddRange(sortedContacts); + } + + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/CodecScheduleAwareness.cs b/src/PepperDash.Essentials.Devices.Common/Codec/CodecScheduleAwareness.cs new file mode 100644 index 00000000..4eea3d2a --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/CodecScheduleAwareness.cs @@ -0,0 +1,146 @@ + + +using System; +using System.Collections.Generic; +using Crestron.SimplSharp; +using PepperDash.Core; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a CodecScheduleAwareness + /// + public class CodecScheduleAwareness + { + List _meetings; + + /// + /// Event that is raised when a meeting event changes + /// + public event EventHandler MeetingEventChange; + + /// + /// Event that is raised when the meetings list has changed + /// + public event EventHandler MeetingsListHasChanged; + + private int _meetingWarningMinutes = 5; + + //private Meeting _previousChangedMeeting; + + //private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown; + + /// + /// Gets or sets the number of minutes before a meeting to issue a warning + /// + public int MeetingWarningMinutes + { + get { return _meetingWarningMinutes; } + set { _meetingWarningMinutes = value; } + } + + /// + /// Setter triggers MeetingsListHasChanged event + /// + public List Meetings + { + get + { + return _meetings; + } + set + { + _meetings = value; + MeetingsListHasChanged?.Invoke(this, new EventArgs()); + } + } + + private readonly CTimer _scheduleChecker; + + /// + /// Initializes a new instance of the CodecScheduleAwareness class with default poll time + /// + public CodecScheduleAwareness() + { + Meetings = new List(); + + _scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000); + } + + /// + /// Initializes a new instance of the CodecScheduleAwareness class with specified poll time + /// + /// The poll time in milliseconds for checking schedule changes + public CodecScheduleAwareness(long pollTime) + { + Meetings = new List(); + + _scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime); + } + + /// + /// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting + /// + /// + /// + private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting) + { + Debug.LogMessage(LogEventLevel.Verbose, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType); + if (changeType != (changeType & meeting.NotifiedChangeTypes)) + { + // Add this change type to the NotifiedChangeTypes + meeting.NotifiedChangeTypes |= changeType; + MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting }); + } + else + { + Debug.LogMessage(LogEventLevel.Verbose, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType); + } + } + + + /// + /// Checks the schedule to see if any MeetingEventChange updates should be fired + /// + /// + private void CheckSchedule(object o) + { + // Iterate the meeting list and check if any meeting need to do anything + + const double meetingTimeEpsilon = 0.05; + foreach (var m in Meetings) + { + var changeType = eMeetingEventChangeType.Unknown; + + if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start + { + Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds); + changeType = eMeetingEventChangeType.MeetingStartWarning; + } + else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start + { + Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStart"); + changeType = eMeetingEventChangeType.MeetingStart; + } + else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end + { + Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds); + changeType = eMeetingEventChangeType.MeetingEndWarning; + } + else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended + { + Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEnd"); + changeType = eMeetingEventChangeType.MeetingEnd; + } + + if (changeType != eMeetingEventChangeType.Unknown) + { + OnMeetingChange(changeType, m); + } + } + + } + } + +} diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/ContactMethod.cs b/src/PepperDash.Essentials.Devices.Common/Codec/ContactMethod.cs new file mode 100644 index 00000000..9cbd43cb --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/ContactMethod.cs @@ -0,0 +1,37 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a ContactMethod + /// + public class ContactMethod + { + /// + /// Gets or sets the ContactMethodId + /// + [JsonProperty("contactMethodId")] + public string ContactMethodId { get; set; } + + /// + /// Gets or sets the Number + /// + [JsonProperty("number")] + public string Number { get; set; } + + /// + /// Gets or sets the Device + /// + [JsonProperty("device")] + [JsonConverter(typeof(StringEnumConverter))] + public eContactMethodDevice Device { get; set; } + + /// + /// Gets or sets the CallType + /// + [JsonProperty("callType")] + [JsonConverter(typeof(StringEnumConverter))] + public eContactMethodCallType CallType { get; set; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryContact.cs b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryContact.cs new file mode 100644 index 00000000..8fd8bf82 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryContact.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a DirectoryContact + /// + public class DirectoryContact : DirectoryItem + { + + /// + /// Gets or sets the ContactId + /// + [JsonProperty("contactId")] + public string ContactId { get; set; } + + /// + /// Gets or sets the Title + /// + [JsonProperty("title")] + public string Title { get; set; } + + /// + /// Gets or sets the ContactMethods + /// + [JsonProperty("contactMethods")] + public List ContactMethods { get; set; } + + /// + /// Constructor for + /// + public DirectoryContact() + { + ContactMethods = new List(); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryEventArgs.cs b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryEventArgs.cs new file mode 100644 index 00000000..f7ba8a5f --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryEventArgs.cs @@ -0,0 +1,21 @@ + + +using System; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a DirectoryEventArgs + /// + public class DirectoryEventArgs : EventArgs + { + /// + /// Gets or sets the Directory + /// + public CodecDirectory Directory { get; set; } + /// + /// Gets or sets the DirectoryIsOnRoot + /// + public bool DirectoryIsOnRoot { get; set; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryFolder.cs b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryFolder.cs new file mode 100644 index 00000000..6da08fba --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryFolder.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a DirectoryFolder + /// + public class DirectoryFolder : DirectoryItem + { + + /// + /// Gets or sets the Contacts + /// + [JsonProperty("contacts")] + public List Contacts { get; set; } + + /// + /// Constructor for + /// + public DirectoryFolder() + { + Contacts = new List(); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryItem.cs b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryItem.cs new file mode 100644 index 00000000..92996868 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/DirectoryItem.cs @@ -0,0 +1,41 @@ + + +using System; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a DirectoryItem + /// + public class DirectoryItem : ICloneable + { + /// + /// Clone method + /// + public object Clone() + { + return MemberwiseClone(); + } + + /// + /// Gets or sets the FolderId + /// + [JsonProperty("folderId")] + public string FolderId { get; set; } + + + /// + /// Gets or sets the Name + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Gets or sets the ParentFolderId + /// + [JsonProperty("parentFolderId")] + public string ParentFolderId { get; set; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/ICiscoCodecCameraConfig.cs b/src/PepperDash.Essentials.Devices.Common/Codec/ICiscoCodecCameraConfig.cs index fefb4b09..a93337aa 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/ICiscoCodecCameraConfig.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/ICiscoCodecCameraConfig.cs @@ -1,31 +1,65 @@ -using Crestron.SimplSharpPro; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace PepperDash.Essentials.Devices.Common.Codec -{ +namespace PepperDash.Essentials.Devices.Common.Codec +{ /// /// Describes a cisco codec device that can allow configuration of cameras /// public interface ICiscoCodecCameraConfig { + /// + /// Sets the assigned serial number for the specified camera + /// + /// The camera identifier + /// The serial number to assign void SetCameraAssignedSerialNumber(uint cameraId, string serialNumber); + /// + /// Sets the name for the camera on the specified video connector + /// + /// The video connector identifier + /// The name to assign void SetCameraName(uint videoConnectorId, string name); + /// + /// Sets the input source type for the specified video connector + /// + /// The video connector identifier + /// The source type to set void SetInputSourceType(uint videoConnectorId, eCiscoCodecInputSourceType sourceType); } + /// + /// Enumeration of Cisco codec input source types + /// public enum eCiscoCodecInputSourceType { + /// + /// PC source type + /// PC, + + /// + /// Camera source type + /// camera, + + /// + /// Document camera source type + /// document_camera, + + /// + /// Media player source type + /// mediaplayer, + + /// + /// Other source type + /// other, + + /// + /// Whiteboard source type + /// whiteboard } } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/IHasCallHold.cs b/src/PepperDash.Essentials.Devices.Common/Codec/IHasCallHold.cs index 8fbe2b9b..1445bd61 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/IHasCallHold.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/IHasCallHold.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec +namespace PepperDash.Essentials.Devices.Common.Codec { /// /// Defines the contract for IHasCallHold diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/IHasDirectoryHistoryStack.cs b/src/PepperDash.Essentials.Devices.Common/Codec/IHasDirectoryHistoryStack.cs new file mode 100644 index 00000000..e46d8762 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/IHasDirectoryHistoryStack.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using PepperDash.Essentials.Devices.Common.Codec; + + +/// +/// Defines the contract for IHasDirectoryHistoryStack +/// +public interface IHasDirectoryHistoryStack : IHasDirectory +{ + /// + /// Gets the DirectoryBrowseHistoryStack + /// + Stack DirectoryBrowseHistoryStack { get; } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/IHasDoNotDisturb.cs b/src/PepperDash.Essentials.Devices.Common/Codec/IHasDoNotDisturb.cs index 7bb9b924..c989e671 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/IHasDoNotDisturb.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/IHasDoNotDisturb.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Codec { @@ -34,6 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec void ToggleDoNotDisturbMode(); } + /// + /// Defines the contract for devices that support Do Not Disturb mode with timeout functionality + /// public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode { /// diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/IHasExternalSourceSwitching.cs b/src/PepperDash.Essentials.Devices.Common/Codec/IHasExternalSourceSwitching.cs index d22acbba..73884a2a 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/IHasExternalSourceSwitching.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/IHasExternalSourceSwitching.cs @@ -1,25 +1,54 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; namespace PepperDash.Essentials.Devices.Common.Codec { - /// - /// Defines the contract for IHasExternalSourceSwitching - /// + /// + /// Defines the contract for IHasExternalSourceSwitching + /// public interface IHasExternalSourceSwitching { + /// + /// Gets a value indicating whether the external source list is enabled + /// bool ExternalSourceListEnabled { get; } - string ExternalSourceInputPort { get; } + + /// + /// Gets the external source input port identifier + /// + string ExternalSourceInputPort { get; } + + /// + /// Adds an external source to the available sources + /// + /// The connector identifier + /// The unique key for the source + /// The display name for the source + /// The type of external source void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type); + + /// + /// Sets the state of the specified external source + /// + /// The unique key of the external source + /// The mode to set for the source void SetExternalSourceState(string key, eExternalSourceMode mode); + + /// + /// Clears all external sources from the list + /// void ClearExternalSources(); - void SetSelectedSource(string key); - Action RunRouteAction { set;} + + /// + /// Sets the selected source by its key + /// + /// The unique key of the source to select + void SetSelectedSource(string key); + + /// + /// Sets the action to run when routing between sources + /// + Action RunRouteAction { set; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/IInvitableContact.cs b/src/PepperDash.Essentials.Devices.Common/Codec/IInvitableContact.cs new file mode 100644 index 00000000..598a9b22 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/IInvitableContact.cs @@ -0,0 +1,13 @@ +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Defines the contract for IInvitableContact + /// + public interface IInvitableContact + { + /// + /// Gets a value indicating whether this contact is invitable + /// + bool IsInvitableContact { get; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/InvitableDirectoryContact.cs b/src/PepperDash.Essentials.Devices.Common/Codec/InvitableDirectoryContact.cs new file mode 100644 index 00000000..68707c35 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/InvitableDirectoryContact.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents an InvitableDirectoryContact + /// + public class InvitableDirectoryContact : DirectoryContact, IInvitableContact + { + /// + /// Gets a value indicating whether this contact is invitable + /// + [JsonProperty("isInvitableContact")] + public bool IsInvitableContact + { + get + { + return this is IInvitableContact; + } + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Meeting.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Meeting.cs new file mode 100644 index 00000000..22bc697a --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/Meeting.cs @@ -0,0 +1,182 @@ + + +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a Meeting + /// + public class Meeting + { + /// + /// Minutes before the meeting to show warning + /// + [JsonProperty("minutesBeforeMeeting")] + public int MinutesBeforeMeeting; + + /// + /// Gets or sets the meeting ID + /// + [JsonProperty("id")] + public string Id { get; set; } + /// + /// Gets or sets the meeting organizer + /// + [JsonProperty("organizer")] + public string Organizer { get; set; } + /// + /// Gets or sets the Title + /// + [JsonProperty("title")] + public string Title { get; set; } + /// + /// Gets or sets the Agenda + /// + [JsonProperty("agenda")] + public string Agenda { get; set; } + + /// + /// Gets the meeting warning time span in minutes before the meeting starts + /// + [JsonProperty("meetingWarningMinutes")] + public TimeSpan MeetingWarningMinutes + { + get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); } + } + /// + /// Gets the time remaining until the meeting starts + /// + [JsonProperty("timeToMeetingStart")] + public TimeSpan TimeToMeetingStart + { + get + { + return StartTime - DateTime.Now; + } + } + /// + /// Gets the time remaining until the meeting ends + /// + [JsonProperty("timeToMeetingEnd")] + public TimeSpan TimeToMeetingEnd + { + get + { + return EndTime - DateTime.Now; + } + } + /// + /// Gets or sets the StartTime + /// + [JsonProperty("startTime")] + public DateTime StartTime { get; set; } + /// + /// Gets or sets the EndTime + /// + [JsonProperty("endTime")] + public DateTime EndTime { get; set; } + /// + /// Gets the duration of the meeting + /// + [JsonProperty("duration")] + public TimeSpan Duration + { + get + { + return EndTime - StartTime; + } + } + /// + /// Gets or sets the Privacy + /// + [JsonProperty("privacy")] + public eMeetingPrivacy Privacy { get; set; } + /// + /// Gets a value indicating whether the meeting can be joined + /// + [JsonProperty("joinable")] + public bool Joinable + { + get + { + var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now + && DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds); + //Debug.LogMessage(LogEventLevel.Verbose, "Meeting Id: {0} joinable: {1}", Id, joinable); + return joinable; + } + } + + /// + /// Gets or sets the Dialable + /// + [JsonProperty("dialable")] + public bool Dialable { get; set; } + + //public string ConferenceNumberToDial { get; set; } + + /// + /// Gets or sets the ConferencePassword + /// + [JsonProperty("conferencePassword")] + public string ConferencePassword { get; set; } + + /// + /// Gets or sets the IsOneButtonToPushMeeting + /// + [JsonProperty("isOneButtonToPushMeeting")] + public bool IsOneButtonToPushMeeting { get; set; } + + /// + /// Gets or sets the Calls + /// + [JsonProperty("calls")] + public List Calls { get; private set; } + + /// + /// Tracks the change types that have already been notified for + /// Gets or sets the NotifiedChangeTypes + /// + [JsonIgnore] + public eMeetingEventChangeType NotifiedChangeTypes { get; set; } + + [JsonIgnore] private readonly int _joinableCooldownSeconds; + + /// + /// Constructor for Meeting + /// + public Meeting() + { + Calls = new List(); + _joinableCooldownSeconds = 300; + } + + /// + /// Constructor for Meeting + /// + /// Number of seconds after meeting start when it is no longer joinable + public Meeting(int joinableCooldownSeconds) + { + Calls = new List(); + _joinableCooldownSeconds = joinableCooldownSeconds; + } + + + + #region Overrides of Object + + /// + /// ToString method + /// + /// + public override string ToString() + { + return string.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime); + } + + #endregion + } + +} diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/MeetingEventArgs.cs b/src/PepperDash.Essentials.Devices.Common/Codec/MeetingEventArgs.cs new file mode 100644 index 00000000..ed706a1c --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/MeetingEventArgs.cs @@ -0,0 +1,22 @@ + + +using System; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Represents a MeetingEventArgs + /// + public class MeetingEventArgs : EventArgs + { + /// + /// Gets or sets the ChangeType + /// + public eMeetingEventChangeType ChangeType { get; set; } + /// + /// Gets or sets the Meeting + /// + public Meeting Meeting { get; set; } + } + +} diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallDirection.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallDirection.cs index 01eca3d1..e10f61a3 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallDirection.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallDirection.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec +namespace PepperDash.Essentials.Devices.Common.Codec { /// @@ -12,7 +6,20 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public enum eCodecCallDirection { - Unknown = 0, Incoming, Outgoing + /// + /// Unknown call direction + /// + Unknown = 0, + + /// + /// Incoming call direction + /// + Incoming, + + /// + /// Outgoing call direction + /// + Outgoing } /// diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallStatus.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallStatus.cs index b2ab5d99..6116ab16 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallStatus.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallStatus.cs @@ -1,27 +1,68 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec +namespace PepperDash.Essentials.Devices.Common.Codec { /// /// Enumeration of eCodecCallStatus values /// public enum eCodecCallStatus { + /// + /// Unknown call status + /// Unknown = 0, - Connected, - Connecting, - Dialing, + + /// + /// Call is connected + /// + Connected, + + /// + /// Call is connecting + /// + Connecting, + + /// + /// Call is dialing + /// + Dialing, + + /// + /// Call is disconnected + /// Disconnected, - Disconnecting, - EarlyMedia, + + /// + /// Call is disconnecting + /// + Disconnecting, + + /// + /// Early media is being sent/received + /// + EarlyMedia, + + /// + /// Call is idle + /// Idle, - OnHold, - Ringing, - Preserved, + + /// + /// Call is on hold + /// + OnHold, + + /// + /// Call is ringing + /// + Ringing, + + /// + /// Call is preserved + /// + Preserved, + + /// + /// Call is remote preserved + /// RemotePreserved, } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallType.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallType.cs index cf15140e..2b9609fb 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallType.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eCodecCallType.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec +namespace PepperDash.Essentials.Devices.Common.Codec { /// @@ -12,10 +6,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public enum eCodecCallType { - Unknown = 0, - Audio, - Video, - AudioCanEscalate, + /// + /// Unknown call type + /// + Unknown = 0, + + /// + /// Audio-only call type + /// + Audio, + + /// + /// Video call type + /// + Video, + + /// + /// Audio call that can be escalated to video + /// + AudioCanEscalate, + + /// + /// Forward all call type + /// ForwardAllCall } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodCallType.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodCallType.cs new file mode 100644 index 00000000..8e46a721 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodCallType.cs @@ -0,0 +1,21 @@ +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Enumeration of eContactMethodCallType values + /// + public enum eContactMethodCallType + { + /// + /// Unknown call type + /// + Unknown = 0, + /// + /// Audio call type + /// + Audio, + /// + /// Video call type + /// + Video + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodDevice.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodDevice.cs new file mode 100644 index 00000000..83bfc995 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eContactMethodDevice.cs @@ -0,0 +1,29 @@ +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Enumeration of eContactMethodDevice values + /// + public enum eContactMethodDevice + { + /// + /// Unknown contact method + /// + Unknown = 0, + /// + /// Mobile contact method + /// + Mobile, + /// + /// Other contact method + /// + Other, + /// + /// Telephone contact method + /// + Telephone, + /// + /// Video contact method + /// + Video + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingEventChangeType.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingEventChangeType.cs new file mode 100644 index 00000000..2861703f --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingEventChangeType.cs @@ -0,0 +1,35 @@ + + +using System; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Enumeration of eMeetingEventChangeType values + /// + [Flags] + public enum eMeetingEventChangeType + { + /// + /// Unknown change type + /// + Unknown = 0, + /// + /// Meeting start warning + /// + MeetingStartWarning = 1, + /// + /// Meeting start + /// + MeetingStart = 2, + /// + /// Meeting end warning + /// + MeetingEndWarning = 4, + /// + /// Meeting end + /// + MeetingEnd = 8 + } + +} diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingPrivacy.cs b/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingPrivacy.cs index 29ac5247..19a6d31b 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingPrivacy.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/eMeetingPrivacy.cs @@ -1,18 +1,23 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec +namespace PepperDash.Essentials.Devices.Common.Codec { /// /// Enumeration of eMeetingPrivacy values /// public enum eMeetingPrivacy { + /// + /// Unknown meeting privacy level + /// Unknown = 0, + + /// + /// Public meeting + /// Public, + + /// + /// Private meeting + /// Private } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iCodecAudio.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iCodecAudio.cs index d61f7d26..eeab2801 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iCodecAudio.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iCodecAudio.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Codec { diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallFavorites.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallFavorites.cs index ae5351c1..eeb6610f 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallFavorites.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallFavorites.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Collections.Generic; namespace PepperDash.Essentials.Devices.Common.Codec { @@ -11,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public interface IHasCallFavorites { + /// + /// Gets the call favorites for this device + /// CodecCallFavorites CallFavorites { get; } } @@ -24,6 +23,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public List Favorites { get; set; } + /// + /// Initializes a new instance of the CodecCallFavorites class + /// public CodecCallFavorites() { Favorites = new List(); diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallHistory.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallHistory.cs index cd7d7b96..7f495daa 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallHistory.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasCallHistory.cs @@ -2,10 +2,9 @@ using System; using System.Collections.Generic; -using PepperDash.Essentials.Devices.Common.VideoCodec; - using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using PepperDash.Essentials.Devices.Common.VideoCodec; namespace PepperDash.Essentials.Devices.Common.Codec { @@ -15,8 +14,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public interface IHasCallHistory { + /// + /// Gets the call history for this device + /// CodecCallHistory CallHistory { get; } + /// + /// Removes the specified call history entry + /// + /// The call history entry to remove void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry); } @@ -25,9 +31,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public enum eCodecOccurrenceType { + /// + /// Unknown occurrence type + /// Unknown = 0, + + /// + /// Call was placed (outgoing) + /// Placed = 1, + + /// + /// Call was received (incoming) + /// Received = 2, + + /// + /// Call received no answer + /// NoAnswer = 3, } @@ -36,6 +57,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public class CodecCallHistory { + /// + /// Event that is raised when the recent calls list has changed + /// public event EventHandler RecentCallsListHasChanged; /// @@ -48,6 +72,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// CallHistoryEntry ListEmptyEntry; + /// + /// Initializes a new instance of the CodecCallHistory class + /// public CodecCallHistory() { ListEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" }; @@ -80,15 +107,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public class CallHistoryEntry : CodecActiveCallItem { - [JsonConverter(typeof(IsoDateTimeConverter))] - [JsonProperty("startTime")] /// /// Gets or sets the StartTime /// + [JsonConverter(typeof(IsoDateTimeConverter))] + [JsonProperty("startTime")] public DateTime StartTime { get; set; } + /// + /// Gets or sets the occurrence type for this call history entry + /// [JsonConverter(typeof(StringEnumConverter))] [JsonProperty("occurrenceType")] public eCodecOccurrenceType OccurrenceType { get; set; } + + /// + /// Gets or sets the occurrence history identifier + /// [JsonProperty("occurrenceHistoryId")] public string OccurrenceHistoryId { get; set; } } @@ -119,7 +153,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec } // Check if list is empty and if so, add an item to display No Recent Calls - if(genericEntries.Count == 0) + if (genericEntries.Count == 0) genericEntries.Add(ListEmptyEntry); RecentCalls = genericEntries; diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasContentSharing.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasContentSharing.cs index e944b432..2dea5b4a 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasContentSharing.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasContentSharing.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Codec @@ -15,12 +8,29 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public interface IHasContentSharing { + /// + /// Gets feedback indicating whether content sharing is currently active + /// BoolFeedback SharingContentIsOnFeedback { get; } + + /// + /// Gets feedback about the current sharing source + /// StringFeedback SharingSourceFeedback { get; } + /// + /// Gets a value indicating whether content should be automatically shared while in a call + /// bool AutoShareContentWhileInCall { get; } + /// + /// Starts content sharing + /// void StartSharing(); + + /// + /// Stops content sharing + /// void StopSharing(); } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs index bce2dee3..a5373004 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs @@ -1,10 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Codec { @@ -15,15 +9,49 @@ namespace PepperDash.Essentials.Devices.Common.Codec { // Add requirements for Dialer functionality + /// + /// Event that is raised when call status changes + /// event EventHandler CallStatusChange; + /// + /// Dials the specified number + /// + /// The number to dial void Dial(string number); + + /// + /// Ends the specified active call + /// + /// The active call to end void EndCall(CodecActiveCallItem activeCall); + + /// + /// Ends all active calls + /// void EndAllCalls(); + + /// + /// Accepts the specified incoming call + /// + /// The call item to accept void AcceptCall(CodecActiveCallItem item); + + /// + /// Rejects the specified incoming call + /// + /// The call item to reject void RejectCall(CodecActiveCallItem item); + + /// + /// Sends DTMF digits during a call + /// + /// The DTMF digit(s) to send void SendDtmf(string digit); + /// + /// Gets a value indicating whether the device is currently in a call + /// bool IsInCall { get; } } diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasDirectory.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasDirectory.cs index de82bcfb..83cc6c8d 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasDirectory.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasDirectory.cs @@ -1,319 +1,59 @@  using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - - -using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.VideoCodec; namespace PepperDash.Essentials.Devices.Common.Codec { - /// - /// Defines the API for codecs with a directory - /// + /// + /// Defines the API for codecs with a directory + /// public interface IHasDirectory { + /// + /// Event that fires when a directory result is returned from the codec + /// event EventHandler DirectoryResultReturned; + /// + /// Gets the DirectoryRoot + /// CodecDirectory DirectoryRoot { get; } + /// + /// Gets the CurrentDirectoryResult + /// CodecDirectory CurrentDirectoryResult { get; } + /// + /// Gets the PhonebookSyncState + /// CodecPhonebookSyncState PhonebookSyncState { get; } + /// + /// Method to initiate a search of the directory on the server + /// void SearchDirectory(string searchString); + /// + /// Method to get the contents of a specific folder in the directory on the server + /// void GetDirectoryFolderContents(string folderId); + /// + /// Method to set the current directory to the root folder + /// void SetCurrentDirectoryToRoot(); + /// + /// Method to get the contents of the parent folder in the directory on the server + /// void GetDirectoryParentFolderContents(); + /// + /// Gets the CurrentDirectoryResultIsNotDirectoryRoot + /// BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; } } - - /// - /// Defines the contract for IHasDirectoryHistoryStack - /// - public interface IHasDirectoryHistoryStack : IHasDirectory - { - Stack DirectoryBrowseHistoryStack { get; } - } - - - /// - /// Represents a DirectoryEventArgs - /// - public class DirectoryEventArgs : EventArgs - { - /// - /// Gets or sets the Directory - /// - public CodecDirectory Directory { get; set; } - /// - /// Gets or sets the DirectoryIsOnRoot - /// - public bool DirectoryIsOnRoot { get; set; } - } - - /// - /// Represents a codec directory - /// - public class CodecDirectory - { - /// - /// Represents the contents of the directory - /// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data - /// - [JsonIgnore] - public List CurrentDirectoryResults { get; private set; } - - [JsonProperty("contacts")] - public List Contacts - { - get - { - return CurrentDirectoryResults.OfType().Cast().ToList(); - } - } - - [JsonProperty("folders")] - public List Folders - { - get - { - return CurrentDirectoryResults.OfType().Cast().ToList(); - } - } - - /// - /// Used to store the ID of the current folder for CurrentDirectoryResults - /// - [JsonProperty("resultsFolderId")] - /// - /// Gets or sets the ResultsFolderId - /// - public string ResultsFolderId { get; set; } - - public CodecDirectory() - { - CurrentDirectoryResults = new List(); - } - - /// - /// Adds folders to the directory - /// - /// - /// - /// AddFoldersToDirectory method - /// - public void AddFoldersToDirectory(List folders) - { - if(folders != null) - CurrentDirectoryResults.AddRange(folders); - - SortDirectory(); - } - - /// - /// Adds contacts to the directory - /// - /// - /// - /// AddContactsToDirectory method - /// - public void AddContactsToDirectory(List contacts) - { - if(contacts != null) - CurrentDirectoryResults.AddRange(contacts); - - SortDirectory(); - } - - /// - /// Filters the CurrentDirectoryResults by the predicate - /// - /// - /// - /// FilterContacts method - /// - public void FilterContacts(Func predicate) - { - CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList(); - } - - /// - /// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically - /// - private void SortDirectory() - { - var sortedFolders = new List(); - - sortedFolders.AddRange(CurrentDirectoryResults.Where(f => f is DirectoryFolder)); - - sortedFolders.OrderBy(f => f.Name); - - var sortedContacts = new List(); - - sortedContacts.AddRange(CurrentDirectoryResults.Where(c => c is DirectoryContact)); - - sortedFolders.OrderBy(c => c.Name); - - CurrentDirectoryResults.Clear(); - - CurrentDirectoryResults.AddRange(sortedFolders); - - CurrentDirectoryResults.AddRange(sortedContacts); - } - - } - - /// - /// Defines the contract for IInvitableContact - /// - public interface IInvitableContact - { - bool IsInvitableContact { get; } - } - - public class InvitableDirectoryContact : DirectoryContact, IInvitableContact - { - [JsonProperty("isInvitableContact")] - public bool IsInvitableContact - { - get - { - return this is IInvitableContact; - } - } - } - - /// - /// Represents a DirectoryItem - /// - public class DirectoryItem : ICloneable - { - /// - /// Clone method - /// - public object Clone() - { - return this.MemberwiseClone(); - } - - [JsonProperty("folderId")] - public string FolderId { get; set; } - - [JsonProperty("name")] - /// - /// Gets or sets the Name - /// - public string Name { get; set; } - - [JsonProperty("parentFolderId")] - /// - /// Gets or sets the ParentFolderId - /// - public string ParentFolderId { get; set; } - } - - /// - /// Represents a DirectoryFolder - /// - public class DirectoryFolder : DirectoryItem - { - [JsonProperty("contacts")] - /// - /// Gets or sets the Contacts - /// - public List Contacts { get; set; } - - - public DirectoryFolder() - { - Contacts = new List(); - } - } - - /// - /// Represents a DirectoryContact - /// - public class DirectoryContact : DirectoryItem - { - [JsonProperty("contactId")] - /// - /// Gets or sets the ContactId - /// - public string ContactId { get; set; } - - [JsonProperty("title")] - public string Title { get; set; } - - [JsonProperty("contactMethods")] - public List ContactMethods { get; set; } - - public DirectoryContact() - { - ContactMethods = new List(); - } - } - - /// - /// Represents a ContactMethod - /// - public class ContactMethod - { - [JsonProperty("contactMethodId")] - /// - /// Gets or sets the ContactMethodId - /// - public string ContactMethodId { get; set; } - - [JsonProperty("number")] - public string Number { get; set; } - - [JsonProperty("device")] - [JsonConverter(typeof(StringEnumConverter))] - /// - /// Gets or sets the Device - /// - public eContactMethodDevice Device { get; set; } - - [JsonProperty("callType")] - [JsonConverter(typeof(StringEnumConverter))] - /// - /// Gets or sets the CallType - /// - public eContactMethodCallType CallType { get; set; } - } - - /// - /// Enumeration of eContactMethodDevice values - /// - public enum eContactMethodDevice - { - Unknown = 0, - Mobile, - Other, - Telephone, - Video - } - - /// - /// Enumeration of eContactMethodCallType values - /// - public enum eContactMethodCallType - { - Unknown = 0, - Audio, - Video - } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasScheduleAwareness.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasScheduleAwareness.cs index 240ac15f..ed17762a 100644 --- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasScheduleAwareness.cs +++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasScheduleAwareness.cs @@ -1,339 +1,20 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; - -using Newtonsoft.Json; -using Serilog.Events; - -namespace PepperDash.Essentials.Devices.Common.Codec +namespace PepperDash.Essentials.Devices.Common.Codec { - [Flags] - /// - /// Enumeration of eMeetingEventChangeType values - /// - public enum eMeetingEventChangeType - { - Unknown = 0, - MeetingStartWarning = 1, - MeetingStart = 2, - MeetingEndWarning = 4, - MeetingEnd = 8 - } /// /// Defines the contract for IHasScheduleAwareness /// public interface IHasScheduleAwareness { + /// + /// Gets the CodecScheduleAwareness instance + /// CodecScheduleAwareness CodecSchedule { get; } + /// + /// Method to initiate getting the schedule from the server + /// void GetSchedule(); } - /// - /// Represents a CodecScheduleAwareness - /// - public class CodecScheduleAwareness - { - List _meetings; - - public event EventHandler MeetingEventChange; - - public event EventHandler MeetingsListHasChanged; - - private int _meetingWarningMinutes = 5; - - //private Meeting _previousChangedMeeting; - - //private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown; - - public int MeetingWarningMinutes - { - get { return _meetingWarningMinutes; } - set { _meetingWarningMinutes = value; } - } - - /// - /// Setter triggers MeetingsListHasChanged event - /// - public List Meetings - { - get - { - return _meetings; - } - set - { - _meetings = value; - MeetingsListHasChanged?.Invoke(this, new EventArgs()); - } - } - - private readonly CTimer _scheduleChecker; - - public CodecScheduleAwareness() - { - Meetings = new List(); - - _scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000); - } - - public CodecScheduleAwareness(long pollTime) - { - Meetings = new List(); - - _scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime); - } - - /// - /// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting - /// - /// - /// - private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting) - { - Debug.LogMessage(LogEventLevel.Verbose, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType); - if (changeType != (changeType & meeting.NotifiedChangeTypes)) - { - // Add this change type to the NotifiedChangeTypes - meeting.NotifiedChangeTypes |= changeType; - MeetingEventChange?.Invoke(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting }); - } - else - { - Debug.LogMessage(LogEventLevel.Verbose, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType); - } - } - - - /// - /// Checks the schedule to see if any MeetingEventChange updates should be fired - /// - /// - private void CheckSchedule(object o) - { - // Iterate the meeting list and check if any meeting need to do anything - - const double meetingTimeEpsilon = 0.05; - foreach (var m in Meetings) - { - var changeType = eMeetingEventChangeType.Unknown; - - if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start - { - Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds); - changeType = eMeetingEventChangeType.MeetingStartWarning; - } - else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start - { - Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingStart"); - changeType = eMeetingEventChangeType.MeetingStart; - } - else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end - { - Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds); - changeType = eMeetingEventChangeType.MeetingEndWarning; - } - else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended - { - Debug.LogMessage(LogEventLevel.Verbose, "********************* MeetingEnd"); - changeType = eMeetingEventChangeType.MeetingEnd; - } - - if (changeType != eMeetingEventChangeType.Unknown) - { - OnMeetingChange(changeType, m); - } - } - - } - } - - /// - /// Represents a Meeting - /// - public class Meeting - { - [JsonProperty("minutesBeforeMeeting")] - public int MinutesBeforeMeeting; - - [JsonProperty("id")] - public string Id { get; set; } - [JsonProperty("organizer")] - public string Organizer { get; set; } - [JsonProperty("title")] - /// - /// Gets or sets the Title - /// - public string Title { get; set; } - [JsonProperty("agenda")] - /// - /// Gets or sets the Agenda - /// - public string Agenda { get; set; } - - [JsonProperty("meetingWarningMinutes")] - public TimeSpan MeetingWarningMinutes - { - get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); } - } - [JsonProperty("timeToMeetingStart")] - public TimeSpan TimeToMeetingStart - { - get - { - return StartTime - DateTime.Now; - } - } - [JsonProperty("timeToMeetingEnd")] - public TimeSpan TimeToMeetingEnd - { - get - { - return EndTime - DateTime.Now; - } - } - [JsonProperty("startTime")] - /// - /// Gets or sets the StartTime - /// - public DateTime StartTime { get; set; } - [JsonProperty("endTime")] - /// - /// Gets or sets the EndTime - /// - public DateTime EndTime { get; set; } - [JsonProperty("duration")] - public TimeSpan Duration - { - get - { - return EndTime - StartTime; - } - } - [JsonProperty("privacy")] - /// - /// Gets or sets the Privacy - /// - public eMeetingPrivacy Privacy { get; set; } - [JsonProperty("joinable")] - public bool Joinable - { - get - { - var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now - && DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds); - //Debug.LogMessage(LogEventLevel.Verbose, "Meeting Id: {0} joinable: {1}", Id, joinable); - return joinable; - } - } - - [JsonProperty("dialable")] - /// - /// Gets or sets the Dialable - /// - public bool Dialable { get; set; } - - //public string ConferenceNumberToDial { get; set; } - [JsonProperty("conferencePassword")] - /// - /// Gets or sets the ConferencePassword - /// - public string ConferencePassword { get; set; } - [JsonProperty("isOneButtonToPushMeeting")] - /// - /// Gets or sets the IsOneButtonToPushMeeting - /// - public bool IsOneButtonToPushMeeting { get; set; } - - [JsonProperty("calls")] - /// - /// Gets or sets the Calls - /// - public List Calls { get; private set; } - - /// - /// Tracks the change types that have already been notified for - /// - [JsonIgnore] - /// - /// Gets or sets the NotifiedChangeTypes - /// - public eMeetingEventChangeType NotifiedChangeTypes { get; set; } - - [JsonIgnore] private readonly int _joinableCooldownSeconds; - - - public Meeting() - { - Calls = new List(); - _joinableCooldownSeconds = 300; - } - - public Meeting(int joinableCooldownSeconds) - { - Calls = new List(); - _joinableCooldownSeconds = joinableCooldownSeconds; - } - - - - #region Overrides of Object - - /// - /// ToString method - /// - /// - public override string ToString() - { - return String.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime); - } - - #endregion - } - - /// - /// Represents a Call - /// - public class Call - { - /// - /// Gets or sets the Number - /// - public string Number { get; set; } - /// - /// Gets or sets the Protocol - /// - public string Protocol { get; set; } - /// - /// Gets or sets the CallRate - /// - public string CallRate { get; set; } - /// - /// Gets or sets the CallType - /// - public string CallType { get; set; } - } - - /// - /// Represents a MeetingEventArgs - /// - public class MeetingEventArgs : EventArgs - { - /// - /// Gets or sets the ChangeType - /// - public eMeetingEventChangeType ChangeType { get; set; } - /// - /// Gets or sets the Meeting - /// - public Meeting Meeting { get; set; } - } - } diff --git a/src/PepperDash.Essentials.Devices.Common/DSP/DspBase.cs b/src/PepperDash.Essentials.Devices.Common/DSP/DspBase.cs index 296eb91a..e20abc9c 100644 --- a/src/PepperDash.Essentials.Devices.Common/DSP/DspBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/DSP/DspBase.cs @@ -1,61 +1,84 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.DeviceTypeInterfaces; namespace PepperDash.Essentials.Devices.Common.DSP { - public abstract class DspBase : EssentialsDevice, ILevelControls - { - public Dictionary LevelControlPoints { get; private set; } + /// + /// Base class for DSP devices + /// + public abstract class DspBase : EssentialsDevice, ILevelControls + { + /// + /// Gets the collection of level control points + /// + public Dictionary LevelControlPoints { get; private set; } + /// + /// Gets the collection of dialer control points + /// public Dictionary DialerControlPoints { get; private set; } + /// + /// Gets the collection of switcher control points + /// public Dictionary SwitcherControlPoints { get; private set; } - public DspBase(string key, string name) : - base(key, name) - { + /// + /// Initializes a new instance of the DspBase class + /// + /// The device key + /// The device name + public DspBase(string key, string name) : + base(key, name) + { - LevelControlPoints = new Dictionary(); - DialerControlPoints = new Dictionary(); - SwitcherControlPoints = new Dictionary(); - } + LevelControlPoints = new Dictionary(); + DialerControlPoints = new Dictionary(); + SwitcherControlPoints = new Dictionary(); + } - // in audio call feedback + // in audio call feedback - // VOIP - // Phone dialer + // VOIP + // Phone dialer - } + } - // Fusion - // Privacy state - // Online state - // level/mutes ? - - // AC Log call stats - - // Typical presets: - // call default preset to restore levels and mutes + // Fusion + // Privacy state + // Online state + // level/mutes ? - public abstract class DspControlPoint :IKeyed - { + // AC Log call stats + + // Typical presets: + // call default preset to restore levels and mutes + + /// + /// Base class for DSP control points + /// + public abstract class DspControlPoint : IKeyed + { /// /// Gets or sets the Key /// public string Key { get; } + /// + /// Initializes a new instance of the DspControlPoint class + /// + /// The control point key protected DspControlPoint(string key) => Key = key; - } + } - public abstract class DspLevelControlPoint :DspControlPoint, IBasicVolumeWithFeedback + /// + /// Base class for DSP level control points with volume and mute functionality + /// + public abstract class DspLevelControlPoint : DspControlPoint, IBasicVolumeWithFeedback { /// /// Gets or sets the MuteFeedback @@ -66,30 +89,63 @@ namespace PepperDash.Essentials.Devices.Common.DSP /// public IntFeedback VolumeLevelFeedback { get; } + /// + /// Initializes a new instance of the DspLevelControlPoint class + /// + /// The control point key + /// Function to get mute status + /// Function to get volume level protected DspLevelControlPoint(string key, Func muteFeedbackFunc, Func volumeLevelFeedbackFunc) : base(key) { - MuteFeedback = new BoolFeedback(muteFeedbackFunc); - VolumeLevelFeedback = new IntFeedback(volumeLevelFeedbackFunc); + MuteFeedback = new BoolFeedback("mute", muteFeedbackFunc); + VolumeLevelFeedback = new IntFeedback("volume", volumeLevelFeedbackFunc); } + /// + /// Turns mute off + /// public abstract void MuteOff(); + /// + /// Turns mute on + /// public abstract void MuteOn(); + /// + /// Toggles mute state + /// public abstract void MuteToggle(); + /// + /// Sets the volume level + /// + /// The volume level to set public abstract void SetVolume(ushort level); + /// + /// Decreases volume + /// + /// True when pressed, false when released public abstract void VolumeDown(bool pressRelease); + /// + /// Increases volume + /// + /// True when pressed, false when released public abstract void VolumeUp(bool pressRelease); } - - public abstract class DspDialerBase:DspControlPoint - { + /// + /// Base class for DSP dialer control points + /// + public abstract class DspDialerBase : DspControlPoint + { + /// + /// Initializes a new instance of the DspDialerBase class + /// + /// The dialer control point key protected DspDialerBase(string key) : base(key) { } - } + } - // Main program - // VTC - // ATC - // Mics, unusual + // Main program + // VTC + // ATC + // Mics, unusual } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs b/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs index 178c53a7..2c7507ba 100644 --- a/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs +++ b/src/PepperDash.Essentials.Devices.Common/DeviceFactory.cs @@ -14,7 +14,9 @@ namespace PepperDash.Essentials.Devices.Common /// public class DeviceFactory { - + /// + /// Initializes a new instance of the DeviceFactory class + /// public DeviceFactory() { var assy = Assembly.GetExecutingAssembly(); diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs b/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs index 52fc5233..858cdf42 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/BasicIrDisplay.cs @@ -11,37 +11,53 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Displays { - /// - /// Represents a BasicIrDisplay - /// - public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced + /// + /// Represents a BasicIrDisplay + /// + public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced { - /// - /// Gets or sets the IrPort - /// + /// + /// Gets or sets the IrPort + /// public IrOutputPortController IrPort { get; private set; } - /// - /// Gets or sets the IrPulseTime - /// + /// + /// Gets or sets the IrPulseTime + /// public ushort IrPulseTime { get; set; } - protected Func PowerIsOnFeedbackFunc - { - get { return () => _PowerIsOn; } - } + /// + /// Gets the power is on feedback function + /// + protected Func PowerIsOnFeedbackFunc + { + get { return () => _PowerIsOn; } + } + /// + /// Gets the is cooling down feedback function + /// protected override Func IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } } + /// + /// Gets the is warming up feedback function + /// protected override Func IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } } - bool _PowerIsOn; + bool _PowerIsOn; bool _IsWarmingUp; bool _IsCoolingDown; + /// + /// Initializes a new instance of the BasicIrDisplay class + /// + /// The device key + /// The device name + /// The IR output port + /// The path to the IR driver file public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath) : base(key, name) { @@ -53,74 +69,74 @@ namespace PepperDash.Essentials.Devices.Common.Displays InputPorts.AddRange(new RoutingPortCollection { - new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false), - new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false), - new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false), - new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false), - new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false), - new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false), - new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false), }); } - /// - /// Hdmi1 method - /// + /// + /// Hdmi1 method + /// public void Hdmi1() { IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime); } - /// - /// Hdmi2 method - /// + /// + /// Hdmi2 method + /// public void Hdmi2() { IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime); } - /// - /// Hdmi3 method - /// + /// + /// Hdmi3 method + /// public void Hdmi3() { IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime); } - /// - /// Hdmi4 method - /// + /// + /// Hdmi4 method + /// public void Hdmi4() { IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime); } - /// - /// Component1 method - /// + /// + /// Component1 method + /// public void Component1() { IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime); } - /// - /// Video1 method - /// + /// + /// Video1 method + /// public void Video1() { IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime); } - /// - /// Antenna method - /// + /// + /// Antenna method + /// public void Antenna() { IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime); @@ -128,31 +144,31 @@ namespace PepperDash.Essentials.Devices.Common.Displays #region IPower Members - /// - /// PowerOn method - /// - /// + /// + /// PowerOn method + /// + /// public override void PowerOn() { IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime); - _PowerIsOn = true; + _PowerIsOn = true; } - /// - /// PowerOff method - /// + /// + /// PowerOff method + /// public override void PowerOff() { - _PowerIsOn = false; + _PowerIsOn = false; IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime); } - /// - /// PowerToggle method - /// + /// + /// PowerToggle method + /// public override void PowerToggle() { - _PowerIsOn = false; + _PowerIsOn = false; IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime); } @@ -160,25 +176,25 @@ namespace PepperDash.Essentials.Devices.Common.Displays #region IBasicVolumeControls Members - /// - /// VolumeUp method - /// + /// + /// VolumeUp method + /// public void VolumeUp(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease); } - /// - /// VolumeDown method - /// + /// + /// VolumeDown method + /// public void VolumeDown(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease); } - /// - /// MuteToggle method - /// + /// + /// MuteToggle method + /// public void MuteToggle() { IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200); @@ -190,7 +206,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays { _IsWarmingUp = true; IsWarmingUpFeedback.FireUpdate(); - new CTimer(o => { + new CTimer(o => + { _IsWarmingUp = false; IsWarmingUpFeedback.FireUpdate(); }, 10000); @@ -213,13 +230,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// Typically called by the discovery routing algorithm. /// /// A delegate containing the input selector method to call - /// - /// ExecuteSwitch method - /// - /// + /// + /// ExecuteSwitch method + /// + /// public override void ExecuteSwitch(object inputSelector) { - Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString()); + Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString()); Action finishSwitch = () => { @@ -246,42 +263,45 @@ namespace PepperDash.Essentials.Devices.Common.Displays #endregion - /// - /// LinkToApi method - /// - public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); - } + /// + /// LinkToApi method + /// + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } } - /// - /// Represents a BasicIrDisplayFactory - /// - public class BasicIrDisplayFactory : EssentialsDeviceFactory - { - public BasicIrDisplayFactory() - { - TypeNames = new List() { "basicirdisplay" }; - } + /// + /// Represents a BasicIrDisplayFactory + /// + public class BasicIrDisplayFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the BasicIrDisplayFactory class + /// + public BasicIrDisplayFactory() + { + TypeNames = new List() { "basicirdisplay" }; + } - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device"); - var ir = IRPortHelper.GetIrPort(dc.Properties); - if (ir != null) - { - var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName); - display.IrPulseTime = 200; // Set default pulse time for IR commands. - return display; - } + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device"); + var ir = IRPortHelper.GetIrPort(dc.Properties); + if (ir != null) + { + var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName); + display.IrPulseTime = 200; // Set default pulse time for IR commands. + return display; + } - return null; - } - } + return null; + } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/InputInterfaces.cs b/src/PepperDash.Essentials.Devices.Common/Displays/InputInterfaces.cs index abc2e7f1..b4314c6b 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/InputInterfaces.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/InputInterfaces.cs @@ -1,38 +1,89 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; namespace PepperDash.Essentials.Devices.Displays { /// /// Defines the contract for IInputHdmi1 /// - public interface IInputHdmi1 { void InputHdmi1(); } + [Obsolete()] + public interface IInputHdmi1 + { + /// + /// Switches to HDMI 1 input + /// + void InputHdmi1(); + } + /// /// Defines the contract for IInputHdmi2 /// - public interface IInputHdmi2 { void InputHdmi2(); } + [Obsolete()] + public interface IInputHdmi2 + { + /// + /// Switches to HDMI 2 input + /// + void InputHdmi2(); + } + /// /// Defines the contract for IInputHdmi3 /// - public interface IInputHdmi3 { void InputHdmi3(); } + [Obsolete()] + public interface IInputHdmi3 + { + /// + /// Switches to HDMI 3 input + /// + void InputHdmi3(); + } + /// /// Defines the contract for IInputHdmi4 /// - public interface IInputHdmi4 { void InputHdmi4(); } + [Obsolete()] + public interface IInputHdmi4 + { + /// + /// Switches to HDMI 4 input + /// + void InputHdmi4(); + } + /// /// Defines the contract for IInputDisplayPort1 /// - public interface IInputDisplayPort1 { void InputDisplayPort1(); } + [Obsolete()] + public interface IInputDisplayPort1 + { + /// + /// Switches to DisplayPort 1 input + /// + void InputDisplayPort1(); + } + /// /// Defines the contract for IInputDisplayPort2 /// - public interface IInputDisplayPort2 { void InputDisplayPort2(); } + [Obsolete()] + public interface IInputDisplayPort2 + { + /// + /// Switches to DisplayPort 2 input + /// + void InputDisplayPort2(); + } + /// /// Defines the contract for IInputVga1 /// - public interface IInputVga1 { void InputVga1(); } + [Obsolete()] + public interface IInputVga1 + { + /// + /// Switches to VGA 1 input + /// + void InputVga1(); + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs index 976dfdc3..6f46b1a4 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplay.cs @@ -16,16 +16,19 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// Represents a MockDisplay /// public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback, IBridgeAdvanced, IHasInputs, IRoutingSinkWithSwitchingWithInputPort, IHasPowerControlWithFeedback - { + { /// /// Gets or sets the Inputs /// public ISelectableItems Inputs { get; private set; } - bool _PowerIsOn; - bool _IsWarmingUp; - bool _IsCoolingDown; + bool _PowerIsOn; + bool _IsWarmingUp; + bool _IsCoolingDown; + /// + /// Gets the power is on feedback function + /// protected override Func PowerIsOnFeedbackFunc { get @@ -34,8 +37,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays { return _PowerIsOn; }; - } } - protected override Func IsCoolingDownFeedbackFunc + } + } + /// + /// Gets the is cooling down feedback function + /// + protected override Func IsCoolingDownFeedbackFunc { get { @@ -45,7 +52,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays }; } } - protected override Func IsWarmingUpFeedbackFunc + /// + /// Gets the is warming up feedback function + /// + protected override Func IsWarmingUpFeedbackFunc { get { @@ -55,120 +65,128 @@ namespace PepperDash.Essentials.Devices.Common.Displays }; } } + /// + /// Gets the current input feedback function + /// protected override Func CurrentInputFeedbackFunc { get { return () => Inputs.CurrentItem; } } int VolumeHeldRepeatInterval = 200; ushort VolumeInterval = 655; - ushort _FakeVolumeLevel = 31768; - bool _IsMuted; + ushort _FakeVolumeLevel = 31768; + bool _IsMuted; - public MockDisplay(string key, string name) - : base(key, name) - { + /// + /// Initializes a new instance of the MockDisplay class + /// + /// The device key + /// The device name + public MockDisplay(string key, string name) + : base(key, name) + { Inputs = new MockDisplayInputs { Items = new Dictionary - { - { "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) }, - { "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) }, - { "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) }, - { "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )}, - { "DP", new MockDisplayInput ("DP", "DisplayPort", this ) } - } + { + { "HDMI1", new MockDisplayInput ( "HDMI1", "HDMI 1",this ) }, + { "HDMI2", new MockDisplayInput ("HDMI2", "HDMI 2",this ) }, + { "HDMI3", new MockDisplayInput ("HDMI3", "HDMI 3",this ) }, + { "HDMI4", new MockDisplayInput ("HDMI4", "HDMI 4",this )}, + { "DP", new MockDisplayInput ("DP", "DisplayPort", this ) } + } }; - Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate(); - - var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, "HDMI1", this); - var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, "HDMI2", this); - var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, "HDMI3", this); - var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, "HDMI4", this); - var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.DisplayPort, "DP", this); - InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn }); + Inputs.CurrentItemChanged += (o, a) => CurrentInputFeedback.FireUpdate(); - VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; }); - MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted); + var hdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, "HDMI1", this); + var hdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, "HDMI2", this); + var hdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, "HDMI3", this); + var hdmiIn4 = new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, "HDMI4", this); + var dpIn = new RoutingInputPort(RoutingPortNames.DisplayPortIn, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.DisplayPort, "DP", this); + InputPorts.AddRange(new[] { hdmiIn1, hdmiIn2, hdmiIn3, hdmiIn4, dpIn }); + + VolumeLevelFeedback = new IntFeedback("volume", () => { return _FakeVolumeLevel; }); + MuteFeedback = new BoolFeedback("muteOn", () => _IsMuted); WarmupTime = 10000; CooldownTime = 10000; - } + } - /// - /// PowerOn method - /// - /// - public override void PowerOn() - { - if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown) - { - _IsWarmingUp = true; - IsWarmingUpFeedback.InvokeFireUpdate(); - // Fake power-up cycle - WarmupTimer = new CTimer(o => - { - _IsWarmingUp = false; - _PowerIsOn = true; - IsWarmingUpFeedback.InvokeFireUpdate(); - PowerIsOnFeedback.InvokeFireUpdate(); - }, WarmupTime); - } - } + /// + /// PowerOn method + /// + /// + public override void PowerOn() + { + if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown) + { + _IsWarmingUp = true; + IsWarmingUpFeedback.InvokeFireUpdate(); + // Fake power-up cycle + WarmupTimer = new CTimer(o => + { + _IsWarmingUp = false; + _PowerIsOn = true; + IsWarmingUpFeedback.InvokeFireUpdate(); + PowerIsOnFeedback.InvokeFireUpdate(); + }, WarmupTime); + } + } - /// - /// PowerOff method - /// - /// - public override void PowerOff() - { - // If a display has unreliable-power off feedback, just override this and - // remove this check. - if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown) - { - _IsCoolingDown = true; - IsCoolingDownFeedback.InvokeFireUpdate(); - // Fake cool-down cycle - CooldownTimer = new CTimer(o => - { - Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this); - _IsCoolingDown = false; - IsCoolingDownFeedback.InvokeFireUpdate(); + /// + /// PowerOff method + /// + /// + public override void PowerOff() + { + // If a display has unreliable-power off feedback, just override this and + // remove this check. + if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown) + { + _IsCoolingDown = true; + IsCoolingDownFeedback.InvokeFireUpdate(); + // Fake cool-down cycle + CooldownTimer = new CTimer(o => + { + Debug.LogMessage(LogEventLevel.Verbose, "Cooldown timer ending", this); + _IsCoolingDown = false; + IsCoolingDownFeedback.InvokeFireUpdate(); _PowerIsOn = false; PowerIsOnFeedback.InvokeFireUpdate(); - }, CooldownTime); - } - } - - /// - /// PowerToggle method - /// - /// - public override void PowerToggle() - { - if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue) - PowerOff(); - else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue) - PowerOn(); - } + }, CooldownTime); + } + } - /// - /// ExecuteSwitch method - /// - /// - public override void ExecuteSwitch(object selector) - { + /// + /// PowerToggle method + /// + /// + public override void PowerToggle() + { + if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue) + PowerOff(); + else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue) + PowerOn(); + } + + /// + /// ExecuteSwitch method + /// + /// + public override void ExecuteSwitch(object selector) + { try { Debug.LogMessage(LogEventLevel.Verbose, "ExecuteSwitch: {0}", this, selector); - if (!_PowerIsOn) - { - PowerOn(); - } + if (!_PowerIsOn) + { + PowerOn(); + } if (!Inputs.Items.TryGetValue(selector.ToString(), out var input)) return; @@ -184,13 +202,14 @@ namespace PepperDash.Essentials.Devices.Common.Displays if (inputPort == null) { - Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector); + Debug.LogMessage(LogEventLevel.Verbose, "Unable to find input port for selector {selector}", this, selector); return; } Debug.LogMessage(LogEventLevel.Verbose, "Setting current input port to {inputPort}", this, inputPort); CurrentInputPort = inputPort; - } catch (Exception ex) + } + catch (Exception ex) { Debug.LogMessage(ex, "Error making switch: {Exception}", this, ex); } @@ -201,14 +220,14 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// public void SetInput(string selector) { - ISelectableItem currentInput = null; + ISelectableItem currentInput = null; + + try + { + currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value; + } + catch { } - try - { - currentInput = Inputs.Items.SingleOrDefault(Inputs => Inputs.Value.IsSelected).Value; - } - catch { } - if (currentInput != null) { @@ -216,12 +235,12 @@ namespace PepperDash.Essentials.Devices.Common.Displays currentInput.IsSelected = false; } - if (!Inputs.Items.TryGetValue(selector, out var input)) + if (!Inputs.Items.TryGetValue(selector, out var input)) return; - input.IsSelected = true; + input.IsSelected = true; - Inputs.CurrentItem = selector; + Inputs.CurrentItem = selector; } @@ -232,37 +251,37 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// public IntFeedback VolumeLevelFeedback { get; private set; } - /// - /// SetVolume method - /// - public void SetVolume(ushort level) - { - _FakeVolumeLevel = level; - VolumeLevelFeedback.InvokeFireUpdate(); - } + /// + /// SetVolume method + /// + public void SetVolume(ushort level) + { + _FakeVolumeLevel = level; + VolumeLevelFeedback.InvokeFireUpdate(); + } - /// - /// MuteOn method - /// - public void MuteOn() - { - _IsMuted = true; - MuteFeedback.InvokeFireUpdate(); - } + /// + /// MuteOn method + /// + public void MuteOn() + { + _IsMuted = true; + MuteFeedback.InvokeFireUpdate(); + } - /// - /// MuteOff method - /// - public void MuteOff() - { - _IsMuted = false; - MuteFeedback.InvokeFireUpdate(); - } + /// + /// MuteOff method + /// + public void MuteOff() + { + _IsMuted = false; + MuteFeedback.InvokeFireUpdate(); + } - /// - /// Gets or sets the MuteFeedback - /// - public BoolFeedback MuteFeedback { get; private set; } + /// + /// Gets or sets the MuteFeedback + /// + public BoolFeedback MuteFeedback { get; private set; } #endregion @@ -273,74 +292,77 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// VolumeUp method /// public void VolumeUp(bool pressRelease) - { + { //while (pressRelease) //{ - Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease); - if (pressRelease) - { - var newLevel = _FakeVolumeLevel + VolumeInterval; - SetVolume((ushort)newLevel); - CrestronEnvironment.Sleep(VolumeHeldRepeatInterval); - } + Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Down {0}", pressRelease); + if (pressRelease) + { + var newLevel = _FakeVolumeLevel + VolumeInterval; + SetVolume((ushort)newLevel); + CrestronEnvironment.Sleep(VolumeHeldRepeatInterval); + } //} - } + } - /// - /// VolumeDown method - /// - public void VolumeDown(bool pressRelease) - { + /// + /// VolumeDown method + /// + public void VolumeDown(bool pressRelease) + { //while (pressRelease) //{ - Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease); - if (pressRelease) - { - var newLevel = _FakeVolumeLevel - VolumeInterval; - SetVolume((ushort)newLevel); - CrestronEnvironment.Sleep(VolumeHeldRepeatInterval); - } + Debug.LogMessage(LogEventLevel.Verbose, this, "Volume Up {0}", pressRelease); + if (pressRelease) + { + var newLevel = _FakeVolumeLevel - VolumeInterval; + SetVolume((ushort)newLevel); + CrestronEnvironment.Sleep(VolumeHeldRepeatInterval); + } //} - } + } - /// - /// MuteToggle method - /// - public void MuteToggle() - { - _IsMuted = !_IsMuted; - MuteFeedback.InvokeFireUpdate(); - } + /// + /// MuteToggle method + /// + public void MuteToggle() + { + _IsMuted = !_IsMuted; + MuteFeedback.InvokeFireUpdate(); + } - #endregion + #endregion - /// - /// LinkToApi method - /// - public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); - } + /// + /// LinkToApi method + /// + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); + } } - /// - /// Represents a MockDisplayFactory - /// - public class MockDisplayFactory : EssentialsDeviceFactory - { - public MockDisplayFactory() - { - TypeNames = new List() { "mockdisplay" , "mockdisplay2" }; - } + /// + /// Represents a MockDisplayFactory + /// + public class MockDisplayFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the MockDisplayFactory class + /// + public MockDisplayFactory() + { + TypeNames = new List() { "mockdisplay", "mockdisplay2" }; + } - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device"); - return new MockDisplay(dc.Key, dc.Name); - } - } + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Mock Display Device"); + return new MockDisplay(dc.Key, dc.Name); + } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplayInputs.cs b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplayInputs.cs index 5b2ee2e2..b30963ac 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplayInputs.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/MockDisplayInputs.cs @@ -1,10 +1,6 @@ -using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using System; +using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; namespace PepperDash.Essentials.Devices.Common.Displays { @@ -15,6 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.Displays { private Dictionary _items; + /// + /// Gets or sets the collection of selectable items + /// public Dictionary Items { get @@ -34,8 +33,11 @@ namespace PepperDash.Essentials.Devices.Common.Displays private string _currentItem; + /// + /// Gets or sets the currently selected item + /// public string CurrentItem - { + { get { return _currentItem; @@ -51,7 +53,13 @@ namespace PepperDash.Essentials.Devices.Common.Displays } } + /// + /// Occurs when the items collection is updated + /// public event EventHandler ItemsUpdated; + /// + /// Occurs when the current item changes + /// public event EventHandler CurrentItemChanged; } @@ -63,7 +71,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays private MockDisplay _parent; private bool _isSelected; - + + /// + /// Gets or sets a value indicating whether this input is selected + /// public bool IsSelected { get @@ -91,8 +102,17 @@ namespace PepperDash.Essentials.Devices.Common.Displays /// public string Key { get; set; } + /// + /// Occurs when this item is updated + /// public event EventHandler ItemUpdated; + /// + /// Initializes a new instance of the MockDisplayInput class + /// + /// The input key + /// The input name + /// The parent mock display public MockDisplayInput(string key, string name, MockDisplay parent) { Key = key; @@ -107,7 +127,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays { if (!_parent.PowerIsOnFeedback.BoolValue) _parent.PowerOn(); - foreach(var input in _parent.Inputs.Items) + foreach (var input in _parent.Inputs.Items) { input.Value.IsSelected = input.Key == this.Key; } diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftController.cs b/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftController.cs index 204fee42..9163c2a3 100644 --- a/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftController.cs +++ b/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftController.cs @@ -1,14 +1,11 @@ using System; using System.Collections.Generic; using Crestron.SimplSharp; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.CrestronIO; using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using PepperDash.Essentials.Devices.Common; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Shades @@ -28,6 +25,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades ISwitchedOutput LowerRelay; ISwitchedOutput LatchedRelay; + /// + /// Gets or sets the InUpPosition + /// public bool InUpPosition { get { return _isInUpPosition; } @@ -41,10 +41,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades } private bool _isInUpPosition { get; set; } + /// /// Gets or sets the Type /// public eScreenLiftControlType Type { get; private set; } + /// /// Gets or sets the Mode /// @@ -54,13 +56,20 @@ namespace PepperDash.Essentials.Devices.Common.Shades /// Gets or sets the DisplayDeviceKey /// public string DisplayDeviceKey { get; private set; } + /// /// Gets or sets the IsInUpPosition /// public BoolFeedback IsInUpPosition { get; private set; } + /// + /// Event that fires when the position changes + /// public event EventHandler PositionChanged; + /// + /// Constructor for ScreenLiftController + /// public ScreenLiftController(string key, string name, ScreenLiftControllerConfigProperties config) : base(key, name) { @@ -69,7 +78,7 @@ namespace PepperDash.Essentials.Devices.Common.Shades Mode = Config.Mode; Type = Config.Type; - IsInUpPosition = new BoolFeedback(() => _isInUpPosition); + IsInUpPosition = new BoolFeedback("isInUpPosition", () => _isInUpPosition); switch (Mode) { @@ -206,14 +215,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades /// /// Attempts to get the port on teh specified device from config /// - /// + /// /// ISwitchedOutput GetSwitchedOutputFromDevice(string relayKey) { var portDevice = DeviceManager.GetDeviceForKey(relayKey); if (portDevice != null) { - return (portDevice as ISwitchedOutput); + return portDevice as ISwitchedOutput; } else { @@ -238,58 +247,14 @@ namespace PepperDash.Essentials.Devices.Common.Shades } - /// - /// Represents a ScreenLiftControllerConfigProperties - /// - public class ScreenLiftControllerConfigProperties - { - [JsonProperty("displayDeviceKey")] - /// - /// Gets or sets the DisplayDeviceKey - /// - public string DisplayDeviceKey { get; set; } - - [JsonProperty("type")] - [JsonConverter(typeof(StringEnumConverter))] - /// - /// Gets or sets the Type - /// - public eScreenLiftControlType Type { get; set; } - - [JsonProperty("mode")] - [JsonConverter(typeof(StringEnumConverter))] - /// - /// Gets or sets the Mode - /// - public eScreenLiftControlMode Mode { get; set; } - - [JsonProperty("relays")] - public Dictionary Relays { get; set; } - - } - /// - /// Represents a ScreenLiftRelaysConfig - /// - public class ScreenLiftRelaysConfig - { - [JsonProperty("deviceKey")] - /// - /// Gets or sets the DeviceKey - /// - public string DeviceKey { get; set; } - - [JsonProperty("pulseTimeInMs")] - /// - /// Gets or sets the PulseTimeInMs - /// - public int PulseTimeInMs { get; set; } - } - /// /// Represents a ScreenLiftControllerFactory /// public class ScreenLiftControllerFactory : EssentialsDeviceFactory { + /// + /// Constructor for ScreenLiftControllerFactory + /// public ScreenLiftControllerFactory() { TypeNames = new List() { "screenliftcontroller" }; @@ -307,13 +272,4 @@ namespace PepperDash.Essentials.Devices.Common.Shades return new ScreenLiftController(dc.Key, dc.Name, props); } } - - /// - /// Enumeration of eScreenLiftControlMode values - /// - public enum eScreenLiftControlMode - { - momentary, - latched - } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftControllerConfigProperties.cs b/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftControllerConfigProperties.cs new file mode 100644 index 00000000..9de1faa0 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftControllerConfigProperties.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; + +namespace PepperDash.Essentials.Devices.Common.Shades +{ + /// + /// Represents a ScreenLiftControllerConfigProperties + /// + public class ScreenLiftControllerConfigProperties + { + + /// + /// Gets or sets the DisplayDeviceKey + /// + [JsonProperty("displayDeviceKey")] + public string DisplayDeviceKey { get; set; } + + /// + /// Gets or sets the Type + /// + [JsonProperty("type")] + [JsonConverter(typeof(StringEnumConverter))] + public eScreenLiftControlType Type { get; set; } + + /// + /// Gets or sets the Mode + /// + [JsonProperty("mode")] + [JsonConverter(typeof(StringEnumConverter))] + public eScreenLiftControlMode Mode { get; set; } + + /// + /// Gets or sets the Relays + /// + [JsonProperty("relays")] + public Dictionary Relays { get; set; } + + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftRelaysConfig.cs b/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftRelaysConfig.cs new file mode 100644 index 00000000..4de9eb25 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Displays/ScreenLiftRelaysConfig.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.Shades +{ + /// + /// Represents a ScreenLiftRelaysConfig + /// + public class ScreenLiftRelaysConfig + { + /// + /// Gets or sets the DeviceKey + /// + [JsonProperty("deviceKey")] + public string DeviceKey { get; set; } + + /// + /// Gets or sets the PulseTimeInMs + /// + [JsonProperty("pulseTimeInMs")] + public int PulseTimeInMs { get; set; } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Displays/eScreenLiftControlMode.cs b/src/PepperDash.Essentials.Devices.Common/Displays/eScreenLiftControlMode.cs new file mode 100644 index 00000000..8114ac26 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Displays/eScreenLiftControlMode.cs @@ -0,0 +1,17 @@ +namespace PepperDash.Essentials.Devices.Common.Shades +{ + /// + /// Enumeration of eScreenLiftControlMode values + /// + public enum eScreenLiftControlMode + { + /// + /// Momentary control mode for screen lift + /// + momentary, + /// + /// Latched control mode for screen lift + /// + latched + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs index 748b48bb..a44eb012 100644 --- a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs +++ b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSink.cs @@ -1,9 +1,8 @@ -using PepperDash.Core; +using System.Collections.Generic; +using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using Serilog.Events; -using System; -using System.Collections.Generic; namespace PepperDash.Essentials.Devices.Common.Generic { @@ -12,11 +11,16 @@ namespace PepperDash.Essentials.Devices.Common.Generic /// public class GenericSink : EssentialsDevice, IRoutingSinkWithInputPort { + /// + /// Initializes a new instance of the GenericSink class + /// + /// The device key + /// The device name public GenericSink(string key, string name) : base(key, name) { InputPorts = new RoutingPortCollection(); - var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this); + var inputPort = new RoutingInputPort(RoutingPortNames.AnyVideoIn, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this); InputPorts.Add(inputPort); } @@ -35,10 +39,12 @@ namespace PepperDash.Essentials.Devices.Common.Generic /// /// Gets or sets the CurrentSourceInfo /// - public SourceListItem CurrentSourceInfo { + public SourceListItem CurrentSourceInfo + { get => _currentSource; - set { - if(value == _currentSource) + set + { + if (value == _currentSource) { return; } @@ -51,8 +57,14 @@ namespace PepperDash.Essentials.Devices.Common.Generic } } + /// + /// Gets the current input port + /// public RoutingInputPort CurrentInputPort => InputPorts[0]; + /// + /// Event fired when the current source changes + /// public event SourceInfoChangeHandler CurrentSourceChange; } @@ -61,6 +73,9 @@ namespace PepperDash.Essentials.Devices.Common.Generic /// public class GenericSinkFactory : EssentialsDeviceFactory { + /// + /// Initializes a new instance of the GenericSinkFactory class + /// public GenericSinkFactory() { TypeNames = new List() { "genericsink", "genericdestination" }; diff --git a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs index 6cf359e8..3d0f1304 100644 --- a/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs +++ b/src/PepperDash.Essentials.Devices.Common/Generic/GenericSource.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; +using System.Collections.Generic; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -13,38 +7,43 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { - /// - /// Represents a GenericSource - /// - public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking - { + /// + /// Represents a GenericSource + /// + public class GenericSource : EssentialsDevice, IUiDisplayInfo, IRoutingSource, IUsageTracking + { - /// - /// Gets or sets the DisplayUiType - /// - public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } } + /// + /// Gets or sets the DisplayUiType + /// + public uint DisplayUiType { get { return DisplayUiConstants.TypeNoControls; } } + /// + /// Initializes a new instance of the GenericSource class + /// + /// The device key + /// The device name public GenericSource(string key, string name) - : base(key, name) - { + : base(key, name) + { - AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - OutputPorts = new RoutingPortCollection { AnyOut }; - } + AnyOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + OutputPorts = new RoutingPortCollection { AnyOut }; + } - #region IRoutingOutputs Members + #region IRoutingOutputs Members - /// - /// Gets or sets the AnyOut - /// - public RoutingOutputPort AnyOut { get; private set; } - /// - /// Gets or sets the OutputPorts - /// - public RoutingPortCollection OutputPorts { get; private set; } + /// + /// Gets or sets the AnyOut + /// + public RoutingOutputPort AnyOut { get; private set; } + /// + /// Gets or sets the OutputPorts + /// + public RoutingPortCollection OutputPorts { get; private set; } - #endregion + #endregion #region IUsageTracking Members @@ -54,13 +53,16 @@ namespace PepperDash.Essentials.Devices.Common public UsageTracking UsageTracker { get; set; } #endregion - } + } /// /// Represents a GenericSourceFactory /// public class GenericSourceFactory : EssentialsDeviceFactory { + /// + /// Initializes a new instance of the GenericSourceFactory class + /// public GenericSourceFactory() { TypeNames = new List() { "genericsource" }; diff --git a/src/PepperDash.Essentials.Devices.Common/Lighting/LightingBase.cs b/src/PepperDash.Essentials.Devices.Common/Lighting/LightingBase.cs index d98d8804..9dd3b816 100644 --- a/src/PepperDash.Essentials.Devices.Common/Lighting/LightingBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Lighting/LightingBase.cs @@ -3,9 +3,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using PepperDash.Core; @@ -16,134 +13,165 @@ using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.Lighting { - public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes - { - #region ILightingScenes Members - - public event EventHandler LightingSceneChange; - - /// - /// Gets or sets the LightingScenes - /// - public List LightingScenes { get; protected set; } - - /// - /// Gets or sets the CurrentLightingScene - /// - public LightingScene CurrentLightingScene { get; protected set; } - /// - /// Gets or sets the CurrentLightingSceneFeedback + /// Base class for lighting devices that support scenes /// - public IntFeedback CurrentLightingSceneFeedback { get; protected set; } + public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes + { + #region ILightingScenes Members - #endregion + /// + /// Event fired when lighting scene changes + /// + public event EventHandler LightingSceneChange; - protected LightingBase(string key, string name) - : base(key, name) - { - LightingScenes = new List(); + /// + /// Gets or sets the LightingScenes + /// + public List LightingScenes { get; protected set; } - CurrentLightingScene = new LightingScene(); - //CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); }); - } + /// + /// Gets or sets the CurrentLightingScene + /// + public LightingScene CurrentLightingScene { get; protected set; } - public abstract void SelectScene(LightingScene scene); + /// + /// Gets or sets the CurrentLightingSceneFeedback + /// + public IntFeedback CurrentLightingSceneFeedback { get; protected set; } - /// - /// SimulateSceneSelect method - /// - public void SimulateSceneSelect(string sceneName) - { - Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName); + #endregion - var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName)); + /// + /// Initializes a new instance of the LightingBase class + /// + /// The device key + /// The device name + protected LightingBase(string key, string name) + : base(key, name) + { + LightingScenes = new List(); - if (scene != null) - { - CurrentLightingScene = scene; - OnLightingSceneChange(); - } - } + CurrentLightingScene = new LightingScene(); + //CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); }); + } - /// - /// Sets the IsActive property on each scene and fires the LightingSceneChange event - /// - protected void OnLightingSceneChange() - { - foreach (var scene in LightingScenes) - { - if (scene == CurrentLightingScene) - scene.IsActive = true; - - else - scene.IsActive = false; - } - LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene)); - } + /// + /// Selects the specified lighting scene + /// + /// The lighting scene to select + public abstract void SelectScene(LightingScene scene); - protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart, - string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new GenericLightingJoinMap(joinStart); + /// + /// SimulateSceneSelect method + /// + public void SimulateSceneSelect(string sceneName) + { + Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName); - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName)); - 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."); - } - - return LinkLightingToApi(lightingDevice, trilist, joinMap); - } - - protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap) + if (scene != null) { - Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + CurrentLightingScene = scene; + OnLightingSceneChange(); + } + } - Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); + /// + /// Sets the IsActive property on each scene and fires the LightingSceneChange event + /// + protected void OnLightingSceneChange() + { + foreach (var scene in LightingScenes) + { + if (scene == CurrentLightingScene) + scene.IsActive = true; - // GenericLighitng Actions & FeedBack - trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u])); + else + scene.IsActive = false; + } + LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene)); + } - var sceneIndex = 0; + /// + /// Links the lighting device to API with join map configuration + /// + /// The lighting device to link + /// The trilist to link to + /// The starting join number + /// The join map key + /// The EISC API bridge + /// The configured join map + protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart, + string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new GenericLightingJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + 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."); + } + + return LinkLightingToApi(lightingDevice, trilist, joinMap); + } + + /// + /// Links the lighting device to API using an existing join map + /// + /// The lighting device to link + /// The trilist to link to + /// The join map to use + /// The join map used for linking + protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap) + { + Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); + + // GenericLighitng Actions & FeedBack + trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u])); + + var sceneIndex = 0; + foreach (var scene in lightingDevice.LightingScenes) + { + var index = sceneIndex; + + trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index])); + scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]); + trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name; + trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true; + + sceneIndex++; + } + + trilist.OnlineStatusChange += (sender, args) => + { + if (!args.DeviceOnLine) return; + + sceneIndex = 0; foreach (var scene in lightingDevice.LightingScenes) { var index = sceneIndex; - trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index])); - scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]); trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name; trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true; + scene.IsActiveFeedback.FireUpdate(); sceneIndex++; } + }; - trilist.OnlineStatusChange += (sender, args) => - { - if (!args.DeviceOnLine) return; - - sceneIndex = 0; - foreach (var scene in lightingDevice.LightingScenes) - { - var index = sceneIndex; - - trilist.StringInput[(uint) (joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name; - trilist.BooleanInput[(uint) (joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true; - scene.IsActiveFeedback.FireUpdate(); - - sceneIndex++; - } - }; - - return joinMap; - } + return joinMap; } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleSpaceRoom.cs b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleSpaceRoom.cs index 6e5e3797..ecce473e 100644 --- a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleSpaceRoom.cs +++ b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleSpaceRoom.cs @@ -9,10 +9,20 @@ namespace PepperDash.Essentials.Devices.Common.Room public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay, IHasCurrentVolumeControls, IRoomOccupancy, IEmergency, IMicrophonePrivacy { + /// + /// Gets whether to exclude this room from global functions + /// bool ExcludeFromGlobalFunctions { get; } + /// + /// Runs the route action for the given routeKey and sourceListKey + /// + /// The route key void RunRouteAction(string routeKey); + /// + /// Gets the PropertiesConfig + /// EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleVtc1Room.cs b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleVtc1Room.cs index 98d01956..5547f595 100644 --- a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleVtc1Room.cs +++ b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsHuddleVtc1Room.cs @@ -12,18 +12,40 @@ namespace PepperDash.Essentials.Devices.Common.Room public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback, IRoomOccupancy, IEmergency, IMicrophonePrivacy { + /// + /// Gets the PropertiesConfig + /// EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; } + /// + /// Gets whether to exclude this room from global functions + /// bool ExcludeFromGlobalFunctions { get; } + /// + /// Runs the route action for the given routeKey and sourceListKey + /// + /// The route key void RunRouteAction(string routeKey); + /// + /// Gets the ScheduleSource + /// IHasScheduleAwareness ScheduleSource { get; } + /// + /// Gets the InCallFeedback + /// new BoolFeedback InCallFeedback { get; } + /// + /// Gets the PrivacyModeIsOnFeedback + /// new BoolFeedback PrivacyModeIsOnFeedback { get; } + /// + /// Gets the DefaultCodecRouteString + /// string DefaultCodecRouteString { get; } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsRoomPropertiesConfig.cs b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsRoomPropertiesConfig.cs index d536242e..e45be6e0 100644 --- a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsRoomPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsRoomPropertiesConfig.cs @@ -1,9 +1,4 @@ using PepperDash.Essentials.Room.Config; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace PepperDash.Essentials.Devices.Common.Room { @@ -12,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Room /// public interface IEssentialsRoomPropertiesConfig { + /// + /// Gets the PropertiesConfig + /// EssentialsRoomPropertiesConfig PropertiesConfig { get; } } } diff --git a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsTechRoom.cs b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsTechRoom.cs index e651011a..9301f37d 100644 --- a/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsTechRoom.cs +++ b/src/PepperDash.Essentials.Devices.Common/Room/IEssentialsTechRoom.cs @@ -1,9 +1,9 @@ -using PepperDash.Essentials.Core; +using System.Collections.Generic; +using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Devices.Common.Displays; using PepperDash.Essentials.Room.Config; -using System.Collections.Generic; -using TwoWayDisplayBase = PepperDash.Essentials.Devices.Common.Displays.TwoWayDisplayBase; namespace PepperDash.Essentials.Devices.Common.Room @@ -11,15 +11,31 @@ namespace PepperDash.Essentials.Devices.Common.Room /// /// Defines the contract for IEssentialsTechRoom /// - public interface IEssentialsTechRoom:IEssentialsRoom, ITvPresetsProvider,IBridgeAdvanced,IRunDirectRouteAction + public interface IEssentialsTechRoom : IEssentialsRoom, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction { + /// + /// Gets the PropertiesConfig + /// EssentialsTechRoomConfig PropertiesConfig { get; } + + /// + /// Gets the Tuners + /// Dictionary Tuners { get; } + /// + /// Gets the Displays + /// Dictionary Displays { get; } + /// + /// Powers on the room + /// void RoomPowerOn(); + /// + /// Powers off the room + /// void RoomPowerOff(); } } diff --git a/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs b/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs index db21a03a..7d49b9b7 100644 --- a/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBase.cs @@ -1,38 +1,31 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Presets; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { - [Description("Wrapper class for an IR Set Top Box")] /// /// Represents a IRSetTopBoxBase + /// Wrapper class for an IR Set Top Box /// + [Description("Wrapper class for an IR Set Top Box")] public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingSource, IRoutingOutputs, IUsageTracking, IHasPowerControl, ITvPresetsProvider - { - /// - /// Gets or sets the IrPort - /// + { + /// + /// Gets or sets the IrPort + /// public IrOutputPortController IrPort { get; private set; } - /// - /// Gets or sets the DisplayUiType - /// - public uint DisplayUiType { get { return DisplayUiConstants.TypeDirecTv; } } + /// + /// Gets or sets the DisplayUiType + /// + public uint DisplayUiType { get { return DisplayUiConstants.TypeDirecTv; } } /// /// Gets or sets the IrPulseTime /// @@ -60,11 +53,18 @@ namespace PepperDash.Essentials.Devices.Common /// public DevicePresetsModel TvPresets { get; private set; } - public IRSetTopBoxBase(string key, string name, IrOutputPortController portCont, + /// + /// Initializes a new instance of the class + /// + /// The unique identifier for the device + /// The name of the device + /// The IR output port controller + /// The properties configuration + public IRSetTopBoxBase(string key, string name, IrOutputPortController portCont, SetTopBoxPropertiesConfig props) - : base(key, name) - { - IrPort = portCont; + : base(key, name) + { + IrPort = portCont; IrPulseTime = 200; if (props.IrPulseTime > 0) @@ -72,424 +72,433 @@ namespace PepperDash.Essentials.Devices.Common IrPulseTime = (ushort)props.IrPulseTime; } - DeviceManager.AddDevice(portCont); + DeviceManager.AddDevice(portCont); HasPresets = props.HasPresets; HasDvr = props.HasDvr; HasDpad = props.HasDpad; HasNumeric = props.HasNumeric; - HasKeypadAccessoryButton1 = true; - KeypadAccessoryButton1Command = "Dash"; - KeypadAccessoryButton1Label = "-"; - - HasKeypadAccessoryButton2 = true; - KeypadAccessoryButton2Command = "KEYPAD_ENTER"; - KeypadAccessoryButton2Label = "Enter"; - - AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, - eRoutingPortConnectionType.DigitalAudio, null, this); - OutputPorts = new RoutingPortCollection { AnyVideoOut, AnyAudioOut }; - } - - /// - /// LoadPresets method - /// - public void LoadPresets(string filePath) - { - TvPresets = new DevicePresetsModel(Key + "-presets", this, filePath); - DeviceManager.AddDevice(TvPresets); - } - - - #region ISetTopBoxControls Members - - /// - /// DvrList method - /// - public void DvrList(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_DVR, pressRelease); - } - - /// - /// Replay method - /// - public void Replay(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); - } - - #endregion - - #region IDPad Members - - /// - /// Up method - /// - public void Up(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease); - } - - /// - /// Down method - /// - public void Down(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease); - } - - /// - /// Left method - /// - public void Left(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease); - } - - /// - /// Right method - /// - public void Right(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease); - } - - /// - /// Select method - /// - public void Select(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease); - } - - /// - /// Menu method - /// - public void Menu(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease); - } - - /// - /// Exit method - /// - public void Exit(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease); - } - - #endregion - - #region INumericKeypad Members - - /// - /// Digit0 method - /// - public void Digit0(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_0, pressRelease); - } - - /// - /// Digit1 method - /// - public void Digit1(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_1, pressRelease); - } - - /// - /// Digit2 method - /// - public void Digit2(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_2, pressRelease); - } - - /// - /// Digit3 method - /// - public void Digit3(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_3, pressRelease); - } - - /// - /// Digit4 method - /// - public void Digit4(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_4, pressRelease); - } - - /// - /// Digit5 method - /// - public void Digit5(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_5, pressRelease); - } - - /// - /// Digit6 method - /// - public void Digit6(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_6, pressRelease); - } - - /// - /// Digit7 method - /// - public void Digit7(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_7, pressRelease); - } - - /// - /// Digit8 method - /// - public void Digit8(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_8, pressRelease); - } - - /// - /// Digit9 method - /// - public void Digit9(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_9, pressRelease); - } - - /// - /// Gets or sets the HasKeypadAccessoryButton1 - /// - public bool HasKeypadAccessoryButton1 { get; set; } - - /// - /// Defaults to "-" - /// - public string KeypadAccessoryButton1Label { get; set; } - - - /// - /// Defaults to "Dash" - /// - public string KeypadAccessoryButton1Command { get; set; } - - public void KeypadAccessoryButton1(bool pressRelease) - { - IrPort.PressRelease(KeypadAccessoryButton1Command, pressRelease); - } - - /// - /// Gets or sets the HasKeypadAccessoryButton2 - /// - public bool HasKeypadAccessoryButton2 { get; set; } - - /// - /// Defaults to "Enter" - /// - public string KeypadAccessoryButton2Label { get; set; } - - - /// - /// Defaults to "Enter" - /// - public string KeypadAccessoryButton2Command { get; set; } - - public void KeypadAccessoryButton2(bool pressRelease) - { - IrPort.PressRelease(KeypadAccessoryButton2Command, pressRelease); - } - - #endregion - - #region ISetTopBoxNumericKeypad Members - - /// - /// Dash method - /// - public void Dash(bool pressRelease) - { - IrPort.PressRelease("dash", pressRelease); - } - - /// - /// Corresponds to "numericEnter" IR command - /// - public void KeypadEnter(bool pressRelease) - { - IrPort.PressRelease("numericEnter", pressRelease); - } - - #endregion - - #region IChannelFunctions Members - - public void ChannelUp(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_CH_PLUS, pressRelease); - } - - /// - /// ChannelDown method - /// - public void ChannelDown(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_CH_MINUS, pressRelease); - } - - /// - /// LastChannel method - /// - public void LastChannel(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_LAST, pressRelease); - } - - /// - /// Guide method - /// - public void Guide(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_GUIDE, pressRelease); - } - - /// - /// Info method - /// - public void Info(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_INFO, pressRelease); - } - - #endregion - - #region IColorFunctions Members - - /// - /// Red method - /// - public void Red(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RED, pressRelease); - } - - /// - /// Green method - /// - public void Green(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_GREEN, pressRelease); - } - - /// - /// Yellow method - /// - public void Yellow(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_YELLOW, pressRelease); - } - - /// - /// Blue method - /// - public void Blue(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_BLUE, pressRelease); - } - - #endregion - - #region IRoutingOutputs Members - - /// - /// Gets or sets the AnyVideoOut - /// - public RoutingOutputPort AnyVideoOut { get; private set; } - /// - /// Gets or sets the AnyAudioOut - /// - public RoutingOutputPort AnyAudioOut { get; private set; } - /// - /// Gets or sets the OutputPorts - /// - public RoutingPortCollection OutputPorts { get; private set; } - - #endregion - - #region ITransport Members - - /// - /// ChapMinus method - /// - public void ChapMinus(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); - } - - /// - /// ChapPlus method - /// - public void ChapPlus(bool pressRelease) - { - } - - /// - /// FFwd method - /// - public void FFwd(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease); - } - - /// - /// Pause method - /// - public void Pause(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); - } - - /// - /// Play method - /// - public void Play(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease); - } - - /// - /// Record method - /// - public void Record(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RECORD, pressRelease); - } - - /// - /// Rewind method - /// - public void Rewind(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); - } - - /// - /// Stop method - /// - public void Stop(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_STOP, pressRelease); - } - - #endregion + HasKeypadAccessoryButton1 = true; + KeypadAccessoryButton1Command = "Dash"; + KeypadAccessoryButton1Label = "-"; + + HasKeypadAccessoryButton2 = true; + KeypadAccessoryButton2Command = "KEYPAD_ENTER"; + KeypadAccessoryButton2Label = "Enter"; + + AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, + eRoutingPortConnectionType.DigitalAudio, null, this); + OutputPorts = new RoutingPortCollection { AnyVideoOut, AnyAudioOut }; + } + + /// + /// LoadPresets method + /// + public void LoadPresets(string filePath) + { + TvPresets = new DevicePresetsModel(Key + "-presets", this, filePath); + DeviceManager.AddDevice(TvPresets); + } + + + #region ISetTopBoxControls Members + + /// + /// DvrList method + /// + public void DvrList(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_DVR, pressRelease); + } + + /// + /// Replay method + /// + public void Replay(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); + } + + #endregion + + #region IDPad Members + + /// + /// Up method + /// + public void Up(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease); + } + + /// + /// Down method + /// + public void Down(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease); + } + + /// + /// Left method + /// + public void Left(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease); + } + + /// + /// Right method + /// + public void Right(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease); + } + + /// + /// Select method + /// + public void Select(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease); + } + + /// + /// Menu method + /// + public void Menu(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease); + } + + /// + /// Exit method + /// + public void Exit(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease); + } + + #endregion + + #region INumericKeypad Members + + /// + /// Digit0 method + /// + public void Digit0(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_0, pressRelease); + } + + /// + /// Digit1 method + /// + public void Digit1(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_1, pressRelease); + } + + /// + /// Digit2 method + /// + public void Digit2(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_2, pressRelease); + } + + /// + /// Digit3 method + /// + public void Digit3(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_3, pressRelease); + } + + /// + /// Digit4 method + /// + public void Digit4(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_4, pressRelease); + } + + /// + /// Digit5 method + /// + public void Digit5(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_5, pressRelease); + } + + /// + /// Digit6 method + /// + public void Digit6(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_6, pressRelease); + } + + /// + /// Digit7 method + /// + public void Digit7(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_7, pressRelease); + } + + /// + /// Digit8 method + /// + public void Digit8(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_8, pressRelease); + } + + /// + /// Digit9 method + /// + public void Digit9(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_9, pressRelease); + } + + /// + /// Gets or sets the HasKeypadAccessoryButton1 + /// + public bool HasKeypadAccessoryButton1 { get; set; } + + /// + /// Defaults to "-" + /// + public string KeypadAccessoryButton1Label { get; set; } + + + /// + /// Defaults to "Dash" + /// + public string KeypadAccessoryButton1Command { get; set; } + + /// + /// Presses the KeypadAccessoryButton1 + /// + public void KeypadAccessoryButton1(bool pressRelease) + { + IrPort.PressRelease(KeypadAccessoryButton1Command, pressRelease); + } + + /// + /// Gets or sets the HasKeypadAccessoryButton2 + /// + public bool HasKeypadAccessoryButton2 { get; set; } + + /// + /// Defaults to "Enter" + /// + public string KeypadAccessoryButton2Label { get; set; } + + + /// + /// Defaults to "Enter" + /// + public string KeypadAccessoryButton2Command { get; set; } + + /// + /// Presses the KeypadAccessoryButton2 + /// + public void KeypadAccessoryButton2(bool pressRelease) + { + IrPort.PressRelease(KeypadAccessoryButton2Command, pressRelease); + } + + #endregion + + #region ISetTopBoxNumericKeypad Members + + /// + /// Dash method + /// + public void Dash(bool pressRelease) + { + IrPort.PressRelease("dash", pressRelease); + } + + /// + /// Corresponds to "numericEnter" IR command + /// + public void KeypadEnter(bool pressRelease) + { + IrPort.PressRelease("numericEnter", pressRelease); + } + + #endregion + + #region IChannelFunctions Members + + /// + /// ChannelUp method + /// + public void ChannelUp(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_CH_PLUS, pressRelease); + } + + /// + /// ChannelDown method + /// + public void ChannelDown(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_CH_MINUS, pressRelease); + } + + /// + /// LastChannel method + /// + public void LastChannel(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_LAST, pressRelease); + } + + /// + /// Guide method + /// + public void Guide(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_GUIDE, pressRelease); + } + + /// + /// Info method + /// + public void Info(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_INFO, pressRelease); + } + + #endregion + + #region IColorFunctions Members + + /// + /// Red method + /// + public void Red(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RED, pressRelease); + } + + /// + /// Green method + /// + public void Green(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_GREEN, pressRelease); + } + + /// + /// Yellow method + /// + public void Yellow(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_YELLOW, pressRelease); + } + + /// + /// Blue method + /// + public void Blue(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_BLUE, pressRelease); + } + + #endregion + + #region IRoutingOutputs Members + + /// + /// Gets or sets the AnyVideoOut + /// + public RoutingOutputPort AnyVideoOut { get; private set; } + /// + /// Gets or sets the AnyAudioOut + /// + public RoutingOutputPort AnyAudioOut { get; private set; } + /// + /// Gets or sets the OutputPorts + /// + public RoutingPortCollection OutputPorts { get; private set; } + + #endregion + + #region ITransport Members + + /// + /// ChapMinus method + /// + public void ChapMinus(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); + } + + /// + /// ChapPlus method + /// + public void ChapPlus(bool pressRelease) + { + } + + /// + /// FFwd method + /// + public void FFwd(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease); + } + + /// + /// Pause method + /// + public void Pause(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); + } + + /// + /// Play method + /// + public void Play(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease); + } + + /// + /// Record method + /// + public void Record(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RECORD, pressRelease); + } + + /// + /// Rewind method + /// + public void Rewind(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); + } + + /// + /// Stop method + /// + public void Stop(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_STOP, pressRelease); + } + + #endregion #region IUsageTracking Members @@ -528,12 +537,12 @@ namespace PepperDash.Essentials.Devices.Common #endregion - /// - /// LinkToApi method - /// - /// - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { + /// + /// LinkToApi method + /// + /// + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { var joinMap = new SetTopBoxControllerJoinMap(joinStart); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); @@ -561,8 +570,7 @@ namespace PepperDash.Essentials.Devices.Common }); - var stbBase = this as ISetTopBoxControls; - if (stbBase != null) + if (this is ISetTopBoxControls stbBase) { trilist.BooleanInput[joinMap.HasDpad.JoinNumber].BoolValue = stbBase.HasDpad; trilist.BooleanInput[joinMap.HasNumeric.JoinNumber].BoolValue = stbBase.HasNumeric; @@ -575,16 +583,14 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetStringSigAction(joinMap.LoadPresets.JoinNumber, stbBase.LoadPresets); } - var stbPower = this as IHasPowerControl; - if (stbPower != null) + if (this is IHasPowerControl stbPower) { trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, stbPower.PowerOn); trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, stbPower.PowerOff); trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, stbPower.PowerToggle); } - var stbDPad = this as IDPad; - if (stbDPad != null) + if (this is IDPad stbDPad) { trilist.SetBoolSigAction(joinMap.Up.JoinNumber, stbDPad.Up); trilist.SetBoolSigAction(joinMap.Down.JoinNumber, stbDPad.Down); @@ -595,8 +601,7 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbDPad.Exit); } - var stbChannel = this as IChannel; - if (stbChannel != null) + if (this is IChannel stbChannel) { trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, stbChannel.ChannelUp); trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, stbChannel.ChannelDown); @@ -606,8 +611,7 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbChannel.Exit); } - var stbColor = this as IColor; - if (stbColor != null) + if (this is IColor stbColor) { trilist.SetBoolSigAction(joinMap.Red.JoinNumber, stbColor.Red); trilist.SetBoolSigAction(joinMap.Green.JoinNumber, stbColor.Green); @@ -615,8 +619,7 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, stbColor.Blue); } - var stbKeypad = this as ISetTopBoxNumericKeypad; - if (stbKeypad != null) + if (this is ISetTopBoxNumericKeypad stbKeypad) { trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton1Label; trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton2Label; @@ -640,8 +643,7 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, stbKeypad.KeypadEnter); } - var stbTransport = this as ITransport; - if (stbTransport != null) + if (this is ITransport stbTransport) { trilist.SetBoolSigAction(joinMap.Play.JoinNumber, stbTransport.Play); trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, stbTransport.Pause); @@ -652,35 +654,6 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, stbTransport.Stop); trilist.SetBoolSigAction(joinMap.Record.JoinNumber, stbTransport.Record); } - } - } - - /// - /// Represents a IRSetTopBoxBaseFactory - /// - public class IRSetTopBoxBaseFactory : EssentialsDeviceFactory - { - public IRSetTopBoxBaseFactory() - { - TypeNames = new List() { "settopbox" }; - } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new SetTopBox Device"); - var irCont = IRPortHelper.GetIrOutputPortController(dc); - var config = dc.Properties.ToObject(); - var stb = new IRSetTopBoxBase(dc.Key, dc.Name, irCont, config); - - var listName = dc.Properties.Value("presetsList"); - if (listName != null) - stb.LoadPresets(listName); - return stb; - } } diff --git a/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBaseFactory.cs b/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBaseFactory.cs new file mode 100644 index 00000000..5b122a6a --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/SetTopBox/IRSetTopBoxBaseFactory.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common +{ + /// + /// Represents a IRSetTopBoxBaseFactory + /// + public class IRSetTopBoxBaseFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the class + /// + public IRSetTopBoxBaseFactory() + { + TypeNames = new List() { "settopbox" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new SetTopBox Device"); + var irCont = IRPortHelper.GetIrOutputPortController(dc); + var config = dc.Properties.ToObject(); + var stb = new IRSetTopBoxBase(dc.Key, dc.Name, irCont, config); + + var listName = dc.Properties.Value("presetsList"); + if (listName != null) + stb.LoadPresets(listName); + return stb; + + } + } + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/SetTopBox/SetTopBoxPropertiesConfig.cs b/src/PepperDash.Essentials.Devices.Common/SetTopBox/SetTopBoxPropertiesConfig.cs index a2ec7e54..193b41e7 100644 --- a/src/PepperDash.Essentials.Devices.Common/SetTopBox/SetTopBoxPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Devices.Common/SetTopBox/SetTopBoxPropertiesConfig.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; +using PepperDash.Core; namespace PepperDash.Essentials.Devices.Common { diff --git a/src/PepperDash.Essentials.Devices.Common/Shades/RelayControlledShade.cs b/src/PepperDash.Essentials.Devices.Common/Shades/RelayControlledShade.cs index ad094703..e0080627 100644 --- a/src/PepperDash.Essentials.Devices.Common/Shades/RelayControlledShade.cs +++ b/src/PepperDash.Essentials.Devices.Common/Shades/RelayControlledShade.cs @@ -27,6 +27,12 @@ namespace PepperDash.Essentials.Devices.Common.Shades /// public string StopOrPresetButtonLabel { get; set; } + /// + /// Initializes a new instance of the RelayControlledShade class + /// + /// The device key + /// The device name + /// The relay controlled shade configuration public RelayControlledShade(string key, string name, RelayControlledShadeConfigProperties config) : base(key, name) { @@ -157,6 +163,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades /// public class RelayControlledShadeFactory : EssentialsDeviceFactory { + /// + /// Initializes a new instance of the RelayControlledShadeFactory class + /// public RelayControlledShadeFactory() { TypeNames = new List() { "relaycontrolledshade" }; diff --git a/src/PepperDash.Essentials.Devices.Common/Shades/ShadeBase.cs b/src/PepperDash.Essentials.Devices.Common/Shades/ShadeBase.cs index 2c506750..ba3d67dd 100644 --- a/src/PepperDash.Essentials.Devices.Common/Shades/ShadeBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/Shades/ShadeBase.cs @@ -1,10 +1,18 @@ -using PepperDash.Essentials.Core.Shades; -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Shades; namespace PepperDash.Essentials.Devices.Common.Shades { + /// + /// Base class for shade devices + /// public abstract class ShadeBase : EssentialsDevice, IShadesOpenCloseStop { + /// + /// Initializes a new instance of the ShadeBase class + /// + /// The device key + /// The device name public ShadeBase(string key, string name) : base(key, name) { @@ -13,8 +21,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades #region iShadesOpenClose Members + /// + /// Opens the shade + /// public abstract void Open(); + /// + /// Stops the shade + /// public abstract void Stop(); + /// + /// Closes the shade + /// public abstract void Close(); #endregion diff --git a/src/PepperDash.Essentials.Devices.Common/Shades/ShadeController.cs b/src/PepperDash.Essentials.Devices.Common/Shades/ShadeController.cs index 9d28fe98..dc8cb125 100644 --- a/src/PepperDash.Essentials.Devices.Common/Shades/ShadeController.cs +++ b/src/PepperDash.Essentials.Devices.Common/Shades/ShadeController.cs @@ -14,8 +14,17 @@ namespace PepperDash.Essentials.Devices.Common.Shades { ShadeControllerConfigProperties Config; + /// + /// Gets the collection of shades controlled by this controller + /// public List Shades { get; private set; } + /// + /// Initializes a new instance of the ShadeController class + /// + /// The device key + /// The device name + /// The shade controller configuration public ShadeController(string key, string name, ShadeControllerConfigProperties config) : base(key, name) { @@ -76,6 +85,9 @@ namespace PepperDash.Essentials.Devices.Common.Shades /// public class ShadeControllerFactory : EssentialsDeviceFactory { + /// + /// Initializes a new instance of the ShadeControllerFactory class + /// public ShadeControllerFactory() { TypeNames = new List() { "shadecontroller" }; diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs index c96e6f01..afe47814 100644 --- a/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPc.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using Crestron.SimplSharp; using PepperDash.Core; @@ -22,6 +21,9 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec /// public RoutingInputPort AnyVideoIn { get; private set; } + /// + /// Gets the CurrentInputPort + /// public RoutingInputPort CurrentInputPort => AnyVideoIn; #region IRoutingInputs Members @@ -33,6 +35,11 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec #endregion + /// + /// Initializes a new instance of the class + /// + /// The device key + /// The device name public BlueJeansPc(string key, string name) : base(key, name) { @@ -177,30 +184,12 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec } SourceListItem _CurrentSourceInfo; + /// + /// Event fired when the current source changes + /// public event SourceInfoChangeHandler CurrentSourceChange; #endregion } - /// - /// Represents a BlueJeansPcFactory - /// - public class BlueJeansPcFactory : EssentialsDeviceFactory - { - public BlueJeansPcFactory() - { - TypeNames = new List() { "bluejeanspc" }; - } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BlueJeansPc Device"); - return new SoftCodec.BlueJeansPc(dc.Key, dc.Name); - } - } - } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPcFactory.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPcFactory.cs new file mode 100644 index 00000000..75f39bbd --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/BlueJeansPcFactory.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + + +namespace PepperDash.Essentials.Devices.Common.SoftCodec +{ + /// + /// Represents a BlueJeansPcFactory + /// + public class BlueJeansPcFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the class + /// + public BlueJeansPcFactory() + { + TypeNames = new List() { "bluejeanspc" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BlueJeansPc Device"); + return new BlueJeansPc(dc.Key, dc.Name); + } + } + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs index f00fb9ce..f8a8f640 100644 --- a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodec.cs @@ -1,10 +1,7 @@ -using Newtonsoft.Json; +using System.Linq; using PepperDash.Core; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; using Serilog.Events; -using System.Collections.Generic; -using System.Linq; namespace PepperDash.Essentials.Devices.Common.SoftCodec { @@ -18,7 +15,8 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec /// /// Gets or sets the CurrentInputPort /// - public RoutingInputPort CurrentInputPort { + public RoutingInputPort CurrentInputPort + { get => _currentInputPort; set { @@ -28,19 +26,25 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec } } + /// + /// Initializes a new instance of the class + /// + /// The device key + /// The device name + /// The device properties public GenericSoftCodec(string key, string name, GenericSoftCodecProperties props) : base(key, name) { InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); - for(var i = 1; i <= props.OutputCount; i++) + for (var i = 1; i <= props.OutputCount; i++) { var outputPort = new RoutingOutputPort($"output{i}", eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this); OutputPorts.Add(outputPort); } - for(var i = 1; i<= props.ContentInputCount; i++) + for (var i = 1; i <= props.ContentInputCount; i++) { var inputPort = new RoutingInputPort($"contentInput{i}", eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, $"contentInput{i}", this); @@ -52,7 +56,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec return; } - for(var i = 1; i <=props.CameraInputCount; i++) + for (var i = 1; i <= props.CameraInputCount; i++) { var cameraPort = new RoutingInputPort($"cameraInput{i}", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, $"cameraInput{i}", this); @@ -72,7 +76,11 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec /// /// Gets or sets the CurrentSourceInfoKey /// - public string CurrentSourceInfoKey { get ; set; } + public string CurrentSourceInfoKey { get; set; } + + /// + /// Gets or sets the CurrentSourceInfo + /// public SourceListItem CurrentSourceInfo { get @@ -97,7 +105,14 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec SourceListItem _CurrentSourceInfo; + /// + /// Event fired when the current source changes + /// public event SourceInfoChangeHandler CurrentSourceChange; + + /// + /// Event fired when the input changes + /// public event InputChangedEventHandler InputChanged; /// @@ -107,7 +122,7 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec { var inputPort = InputPorts.FirstOrDefault(p => p.Selector == inputSelector); - if(inputPort == null) + if (inputPort == null) { Debug.LogMessage(LogEventLevel.Warning, "No input port found for selector {inputSelector}", inputSelector); return; @@ -116,58 +131,4 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec CurrentInputPort = inputPort; } } - - /// - /// Represents a GenericSoftCodecProperties - /// - public class GenericSoftCodecProperties - { - [JsonProperty("hasCameraInputs")] - /// - /// Gets or sets the HasCameraInputs - /// - public bool HasCameraInputs { get; set; } - - [JsonProperty("cameraInputCount")] - /// - /// Gets or sets the CameraInputCount - /// - public int CameraInputCount { get; set; } - - [JsonProperty("contentInputCount")] - /// - /// Gets or sets the ContentInputCount - /// - public int ContentInputCount { get; set; } - - [JsonProperty("contentOutputCount")] - /// - /// Gets or sets the OutputCount - /// - public int OutputCount { get; set; } - } - - /// - /// Represents a GenericSoftCodecFactory - /// - public class GenericSoftCodecFactory: EssentialsDeviceFactory - { - public GenericSoftCodecFactory() - { - TypeNames = new List { "genericsoftcodec" }; - } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Attempting to create new Generic SoftCodec Device"); - - var props = dc.Properties.ToObject(); - - return new GenericSoftCodec(dc.Key, dc.Name, props); - } - } } diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecFactory.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecFactory.cs new file mode 100644 index 00000000..51fa5240 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecFactory.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common.SoftCodec +{ + /// + /// Represents a GenericSoftCodecFactory + /// + public class GenericSoftCodecFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the class + /// + public GenericSoftCodecFactory() + { + TypeNames = new List { "genericsoftcodec" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Attempting to create new Generic SoftCodec Device"); + + var props = dc.Properties.ToObject(); + + return new GenericSoftCodec(dc.Key, dc.Name, props); + } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecProperties.cs b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecProperties.cs new file mode 100644 index 00000000..70ee19e9 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/SoftCodec/GenericSoftCodecProperties.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.SoftCodec +{ + /// + /// Represents a GenericSoftCodecProperties + /// + public class GenericSoftCodecProperties + { + /// + /// Gets or sets the HasCameraInputs + /// + [JsonProperty("hasCameraInputs")] + public bool HasCameraInputs { get; set; } + + /// + /// Gets or sets the CameraInputCount + /// + [JsonProperty("cameraInputCount")] + public int CameraInputCount { get; set; } + + /// + /// Gets or sets the ContentInputCount + /// + [JsonProperty("contentInputCount")] + public int ContentInputCount { get; set; } + + /// + /// Gets or sets the OutputCount + /// + [JsonProperty("contentOutputCount")] + public int OutputCount { get; set; } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs b/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs index 48586bd2..e2ef1c09 100644 --- a/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs +++ b/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPc.cs @@ -1,71 +1,74 @@ -using System; -using System.Collections.Generic; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using Serilog.Events; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Sources { - /// - /// Represents a InRoomPc - /// - public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking - { - /// - /// Gets or sets the DisplayUiType - /// - public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } - /// - /// Gets or sets the IconName - /// - public string IconName { get; set; } - /// - /// Gets or sets the HasPowerOnFeedback - /// - public BoolFeedback HasPowerOnFeedback { get; private set; } + /// + /// Represents a InRoomPc + /// + public class InRoomPc : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking + { + /// + /// Gets or sets the DisplayUiType + /// + public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } + /// + /// Gets or sets the IconName + /// + public string IconName { get; set; } + /// + /// Gets or sets the HasPowerOnFeedback + /// + public BoolFeedback HasPowerOnFeedback { get; private set; } - /// - /// Gets or sets the AnyVideoOut - /// - public RoutingOutputPort AnyVideoOut { get; private set; } + /// + /// Gets or sets the AnyVideoOut + /// + public RoutingOutputPort AnyVideoOut { get; private set; } - #region IRoutingOutputs Members + #region IRoutingOutputs Members - /// - /// Gets or sets the OutputPorts - /// - public RoutingPortCollection OutputPorts { get; private set; } + /// + /// Gets or sets the OutputPorts + /// + public RoutingPortCollection OutputPorts { get; private set; } - #endregion + #endregion - public InRoomPc(string key, string name) - : base(key, name) - { - IconName = "PC"; - HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback", - () => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus); - OutputPorts = new RoutingPortCollection(); - OutputPorts.Add(AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.None, 0, this)); - } + /// + /// Initializes a new instance of the class + /// + /// + /// + public InRoomPc(string key, string name) + : base(key, name) + { + IconName = "PC"; + HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback", + () => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus); - #region IHasFeedback Members + OutputPorts = new RoutingPortCollection + { + (AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.None, 0, this)) + }; + } - /// - /// Passes through the VideoStatuses list - /// + #region IHasFeedback Members + + /// + /// Passes through the VideoStatuses list + /// public FeedbackCollection Feedbacks - { - get + { + get { var newList = new FeedbackCollection(); newList.AddRange(this.GetVideoStatuses().ToList()); return newList; } - } + } - #endregion + #endregion #region IUsageTracking Members @@ -75,27 +78,6 @@ namespace PepperDash.Essentials.Devices.Common.Sources public UsageTracking UsageTracker { get; set; } #endregion - } - - /// - /// Represents a InRoomPcFactory - /// - public class InRoomPcFactory : EssentialsDeviceFactory - { - public InRoomPcFactory() - { - TypeNames = new List() { "inroompc" }; - } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new InRoomPc Device"); - return new InRoomPc(dc.Key, dc.Name); - } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPcFactory.cs b/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPcFactory.cs new file mode 100644 index 00000000..3136fd45 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Sources/InRoomPcFactory.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common.Sources +{ + /// + /// Represents a InRoomPcFactory + /// + public class InRoomPcFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the class + /// + public InRoomPcFactory() + { + TypeNames = new List() { "inroompc" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new InRoomPc Device"); + return new InRoomPc(dc.Key, dc.Name); + } + } + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs b/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs index d2da9475..83ccfc4c 100644 --- a/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs +++ b/src/PepperDash.Essentials.Devices.Common/Sources/Laptop.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using Serilog.Events; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.Sources { @@ -11,54 +6,59 @@ namespace PepperDash.Essentials.Devices.Common.Sources /// Represents a Laptop /// public class Laptop : EssentialsDevice, IHasFeedback, IRoutingSource, IRoutingOutputs, IAttachVideoStatus, IUiDisplayInfo, IUsageTracking - { - /// - /// Gets or sets the DisplayUiType - /// - public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } - /// - /// Gets or sets the IconName - /// - public string IconName { get; set; } - /// - /// Gets or sets the HasPowerOnFeedback - /// - public BoolFeedback HasPowerOnFeedback { get; private set; } + { + /// + /// Gets or sets the DisplayUiType + /// + public uint DisplayUiType { get { return DisplayUiConstants.TypeLaptop; } } + /// + /// Gets or sets the IconName + /// + public string IconName { get; set; } + /// + /// Gets or sets the HasPowerOnFeedback + /// + public BoolFeedback HasPowerOnFeedback { get; private set; } - /// - /// Gets or sets the AnyVideoOut - /// - public RoutingOutputPort AnyVideoOut { get; private set; } + /// + /// Gets or sets the AnyVideoOut + /// + public RoutingOutputPort AnyVideoOut { get; private set; } - #region IRoutingOutputs Members + #region IRoutingOutputs Members - /// - /// Gets or sets the OutputPorts - /// - public RoutingPortCollection OutputPorts { get; private set; } + /// + /// Gets or sets the OutputPorts + /// + public RoutingPortCollection OutputPorts { get; private set; } - #endregion + #endregion - public Laptop(string key, string name) - : base(key, name) - { - IconName = "Laptop"; + /// + /// Initializes a new instance of the Laptop class + /// + /// The device key + /// The device name + public Laptop(string key, string name) + : base(key, name) + { + IconName = "Laptop"; - HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback", - () => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus); + HasPowerOnFeedback = new BoolFeedback("HasPowerFeedback", + () => this.GetVideoStatuses() != VideoStatusOutputs.NoStatus); - OutputPorts = new RoutingPortCollection + OutputPorts = new RoutingPortCollection { (AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this)) }; - } + } - #region IHasFeedback Members + #region IHasFeedback Members - /// - /// Passes through the VideoStatuses list - /// + /// + /// Passes through the VideoStatuses list + /// public FeedbackCollection Feedbacks { get @@ -69,7 +69,7 @@ namespace PepperDash.Essentials.Devices.Common.Sources } } - #endregion + #endregion #region IUsageTracking Members @@ -79,26 +79,5 @@ namespace PepperDash.Essentials.Devices.Common.Sources public UsageTracking UsageTracker { get; set; } #endregion - } - - /// - /// Represents a LaptopFactory - /// - public class LaptopFactory : EssentialsDeviceFactory - { - public LaptopFactory() - { - TypeNames = new List() { "laptop" }; - } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device"); - return new Laptop(dc.Key, dc.Name); - } } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Sources/LaptopFactory.cs b/src/PepperDash.Essentials.Devices.Common/Sources/LaptopFactory.cs new file mode 100644 index 00000000..ebb072ba --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Sources/LaptopFactory.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common.Sources +{ + /// + /// Represents a LaptopFactory + /// + public class LaptopFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the class + /// + public LaptopFactory() + { + TypeNames = new List() { "laptop" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Laptop Device"); + return new Laptop(dc.Key, dc.Name); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs index 365a8271..6cf11c54 100644 --- a/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTV.cs @@ -1,60 +1,63 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Linq; using System.Reflection; -using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Bridges; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { + /// + /// Represents a AppleTV + /// Wrapper class for an IR-Controlled AppleTV + /// [Description("Wrapper class for an IR-Controlled AppleTV")] - /// - /// Represents a AppleTV - /// - public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs + public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs { - /// - /// Gets or sets the IrPort - /// + /// + /// Gets or sets the IrPort + /// public IrOutputPortController IrPort { get; private set; } + + /// + /// Standard Driver Name + /// public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir"; - /// - /// Gets or sets the DisplayUiType - /// - public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } } + /// + /// Gets or sets the DisplayUiType + /// + public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } } - public AppleTV(string key, string name, IrOutputPortController portCont) - : base(key, name) - { - IrPort = portCont; - DeviceManager.AddDevice(portCont); + /// + /// Initializes a new instance of the class + /// + /// The device key + /// The device name + /// The IR output port controller + public AppleTV(string key, string name, IrOutputPortController portCont) + : base(key, name) + { + IrPort = portCont; + DeviceManager.AddDevice(portCont); - HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, - eRoutingPortConnectionType.DigitalAudio, null, this); - OutputPorts = new RoutingPortCollection { HdmiOut, AnyAudioOut }; + HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, + eRoutingPortConnectionType.DigitalAudio, null, this); + OutputPorts = new RoutingPortCollection { HdmiOut, AnyAudioOut }; PrintExpectedIrCommands(); - } + } /// /// PrintExpectedIrCommands method /// public void PrintExpectedIrCommands() { - var cmds = typeof (AppleTvIrCommands).GetFields(BindingFlags.Public | BindingFlags.Static); + var cmds = typeof(AppleTvIrCommands).GetFields(BindingFlags.Public | BindingFlags.Static); foreach (var value in cmds.Select(cmd => cmd.GetValue(null)).OfType()) { @@ -64,151 +67,158 @@ namespace PepperDash.Essentials.Devices.Common #region IDPad Members - /// - /// Up method - /// - public void Up(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.Up, pressRelease); - } + /// + /// Up method + /// + public void Up(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.Up, pressRelease); + } - /// - /// Down method - /// - public void Down(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.Down, pressRelease); - } + /// + /// Down method + /// + public void Down(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.Down, pressRelease); + } - /// - /// Left method - /// - public void Left(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.Left, pressRelease); - } + /// + /// Left method + /// + public void Left(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.Left, pressRelease); + } - /// - /// Right method - /// - public void Right(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.Right, pressRelease); - } + /// + /// Right method + /// + public void Right(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.Right, pressRelease); + } - /// - /// Select method - /// - public void Select(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.Enter, pressRelease); - } + /// + /// Select method + /// + public void Select(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.Enter, pressRelease); + } - /// - /// Menu method - /// - public void Menu(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.Menu, pressRelease); - } + /// + /// Menu method + /// + public void Menu(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.Menu, pressRelease); + } - /// - /// Exit method - /// - public void Exit(bool pressRelease) - { + /// + /// Exit method + /// + public void Exit(bool pressRelease) + { - } + } - #endregion + #endregion - #region ITransport Members + #region ITransport Members - /// - /// Play method - /// - public void Play(bool pressRelease) - { - IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease); - } - - /// - /// Pause method - /// - public void Pause(bool pressRelease) - { + /// + /// Play method + /// + public void Play(bool pressRelease) + { IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease); - } + } - /// - /// Not implemented - /// - /// - /// - /// Rewind method - /// - public void Rewind(bool pressRelease) - { - } + /// + /// Pause method + /// + public void Pause(bool pressRelease) + { + IrPort.PressRelease(AppleTvIrCommands.PlayPause, pressRelease); + } - /// - /// Not implemented - /// - /// - public void FFwd(bool pressRelease) - { - } + /// + /// Not implemented + /// + /// + /// + /// Rewind method + /// + public void Rewind(bool pressRelease) + { + } - /// - /// Not implemented - /// - /// - public void ChapMinus(bool pressRelease) - { - } + /// + /// Not implemented + /// + /// + public void FFwd(bool pressRelease) + { + } - /// - /// Not implemented - /// - /// - public void ChapPlus(bool pressRelease) - { - } + /// + /// Not implemented + /// + /// + public void ChapMinus(bool pressRelease) + { + } - /// - /// Not implemented - /// - /// - public void Stop(bool pressRelease) - { - } + /// + /// Not implemented + /// + /// + public void ChapPlus(bool pressRelease) + { + } - /// - /// Not implemented - /// - /// - public void Record(bool pressRelease) - { - } + /// + /// Not implemented + /// + /// + public void Stop(bool pressRelease) + { + } - #endregion + /// + /// Not implemented + /// + /// + public void Record(bool pressRelease) + { + } - #region IRoutingOutputs Members + #endregion - public RoutingOutputPort HdmiOut { get; private set; } - public RoutingOutputPort AnyAudioOut { get; private set; } - /// - /// Gets or sets the OutputPorts - /// - public RoutingPortCollection OutputPorts { get; private set; } + #region IRoutingOutputs Members - #endregion + /// + /// Gets the HdmiOut + /// + public RoutingOutputPort HdmiOut { get; private set; } - /// - /// LinkToApi method - /// - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { + /// + /// Gets the AnyAudioOut + /// + public RoutingOutputPort AnyAudioOut { get; private set; } + /// + /// Gets or sets the OutputPorts + /// + public RoutingPortCollection OutputPorts { get; private set; } + + #endregion + + /// + /// LinkToApi method + /// + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { var joinMap = new AppleTvJoinMap(joinStart); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); @@ -235,42 +245,6 @@ namespace PepperDash.Essentials.Devices.Common trilist.SetBoolSigAction(joinMap.Select.JoinNumber, Select); trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, Menu); trilist.SetBoolSigAction(joinMap.PlayPause.JoinNumber, Play); - } - } - - /// - /// Represents a AppleTVFactory - /// - public class AppleTVFactory : EssentialsDeviceFactory - { - public AppleTVFactory() - { - TypeNames = new List() { "appletv" }; } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new AppleTV Device"); - var irCont = IRPortHelper.GetIrOutputPortController(dc); - return new AppleTV(dc.Key, dc.Name, irCont); - } - } - - public static class AppleTvIrCommands - { - - public static string Up = "+"; - public static string Down = "-"; - public static string Left = IROutputStandardCommands.IROut_TRACK_MINUS; - public static string Right = IROutputStandardCommands.IROut_TRACK_PLUS; - public static string Enter = IROutputStandardCommands.IROut_ENTER; - public static string PlayPause = "PLAY/PAUSE"; - public static string Rewind = "REWIND"; - public static string Menu = "Menu"; - public static string FastForward = "FASTFORWARD"; } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTVFactory.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTVFactory.cs new file mode 100644 index 00000000..f5ef907b --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTVFactory.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common +{ + /// + /// Represents a AppleTVFactory + /// + public class AppleTVFactory : EssentialsDeviceFactory + { + /// + /// Initializes a new instance of the class + /// + public AppleTVFactory() + { + TypeNames = new List() { "appletv" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new AppleTV Device"); + var irCont = IRPortHelper.GetIrOutputPortController(dc); + return new AppleTV(dc.Key, dc.Name, irCont); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTvIrCommands.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTvIrCommands.cs new file mode 100644 index 00000000..2b3d1d14 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/AppleTvIrCommands.cs @@ -0,0 +1,56 @@ +using Crestron.SimplSharpPro; + +namespace PepperDash.Essentials.Devices.Common +{ + /// + /// Represents AppleTvIrCommands + /// + public static class AppleTvIrCommands + { + + /// + /// Up command + /// + public static string Up = "+"; + + /// + /// Down command + /// + public static string Down = "-"; + + /// + /// Left command + /// + public static string Left = IROutputStandardCommands.IROut_TRACK_MINUS; + + /// + /// Right command + /// + public static string Right = IROutputStandardCommands.IROut_TRACK_PLUS; + + /// + /// Enter command + /// + public static string Enter = IROutputStandardCommands.IROut_ENTER; + + /// + /// PlayPause command + /// + public static string PlayPause = "PLAY/PAUSE"; + + /// + /// Rewind command + /// + public static string Rewind = "REWIND"; + + /// + /// Menu command + /// + public static string Menu = "Menu"; + + /// + /// FastForward command + /// + public static string FastForward = "FASTFORWARD"; + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs index a08872f5..8b956a5d 100644 --- a/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/Roku.cs @@ -1,107 +1,106 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; +using Crestron.SimplSharpPro; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using Serilog.Events; namespace PepperDash.Essentials.Devices.Common { - [Description("Wrapper class for an IR-Controlled Roku")] - /// - /// Represents a Roku2 - /// + /// + /// Represents a Roku2 + /// Wrapper class for an IR-Controlled Roku + /// + [Description("Wrapper class for an IR-Controlled Roku")] public class Roku2 : EssentialsDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingSource, IRoutingOutputs { + /// + /// Gets or sets the IrPort + /// [Api] - /// - /// Gets or sets the IrPort - /// public IrOutputPortController IrPort { get; private set; } + + /// + /// Standard Driver Name + /// public const string StandardDriverName = "Roku XD_S.ir"; + /// + /// Gets or sets the DisplayUiType + /// [Api] - /// - /// Gets or sets the DisplayUiType - /// public uint DisplayUiType { get { return DisplayUiConstants.TypeRoku; } } + /// + /// Initializes a new instance of the class + /// public Roku2(string key, string name, IrOutputPortController portCont) : base(key, name) { IrPort = portCont; - DeviceManager.AddDevice(portCont);; + DeviceManager.AddDevice(portCont); ; - HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null, this); OutputPorts = new RoutingPortCollection { HdmiOut }; } #region IDPad Members + /// + /// Up method + /// [Api] - /// - /// Up method - /// public void Up(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease); } + /// + /// Down method + /// [Api] - /// - /// Down method - /// public void Down(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease); } + /// + /// Left method + /// [Api] - /// - /// Left method - /// public void Left(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease); } + /// + /// Right method + /// [Api] - /// - /// Right method - /// public void Right(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease); } + + /// + /// Select method + /// [Api] - /// - /// Select method - /// public void Select(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease); } + /// + /// Menu method + /// [Api] - /// - /// Menu method - /// public void Menu(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease); } + /// + /// Exit method + /// [Api] - /// - /// Exit method - /// public void Exit(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease); @@ -111,49 +110,46 @@ namespace PepperDash.Essentials.Devices.Common #region ITransport Members + /// + /// Play method + /// [Api] - /// - /// Play method - /// public void Play(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease); } + /// + /// Pause method + /// [Api] - /// - /// Pause method - /// public void Pause(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_PAUSE, pressRelease); } + /// + /// Rewind method + /// [Api] - /// - /// Rewind method - /// public void Rewind(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); } + /// + /// FFwd method + /// [Api] - /// - /// FFwd method - /// public void FFwd(bool pressRelease) { IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease); } /// - /// Not implemented + /// ChapMinus method - Not implemented /// /// - /// - /// ChapMinus method - /// public void ChapMinus(bool pressRelease) { } @@ -186,34 +182,18 @@ namespace PepperDash.Essentials.Devices.Common #region IRoutingOutputs Members + /// + /// HdmiOut + /// public RoutingOutputPort HdmiOut { get; private set; } + + /// + /// OutputPorts + /// public RoutingPortCollection OutputPorts { get; private set; } #endregion } - /// - /// Represents a Roku2Factory - /// - public class Roku2Factory : EssentialsDeviceFactory - { - public Roku2Factory() - { - TypeNames = new List() { "roku" }; - } - - /// - /// BuildDevice method - /// - /// - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Roku Device"); - var irCont = IRPortHelper.GetIrOutputPortController(dc); - return new Roku2(dc.Key, dc.Name, irCont); - - } - } - } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/Streaming/Roku2Factory.cs b/src/PepperDash.Essentials.Devices.Common/Streaming/Roku2Factory.cs new file mode 100644 index 00000000..acd330c4 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Streaming/Roku2Factory.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common +{ + /// + /// Represents a Roku2Factory + /// + public class Roku2Factory : EssentialsDeviceFactory + { + /// + /// Roku2Factory constructor + /// + public Roku2Factory() + { + TypeNames = new List() { "roku" }; + } + + /// + /// BuildDevice method + /// + /// + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Roku Device"); + var irCont = IRPortHelper.GetIrOutputPortController(dc); + return new Roku2(dc.Key, dc.Name, irCont); + + } + } + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/CallHistoryDataClasses.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/CallHistoryDataClasses.cs index 9a1f770c..8872172a 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/CallHistoryDataClasses.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/CallHistoryDataClasses.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; namespace PepperDash.Essentials.Devices.Common.VideoCodec { diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs index dfccd74b..e6e2be7e 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/RoomPresets.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; - -using PepperDash.Core; using PepperDash.Essentials.Core.Presets; namespace PepperDash.Essentials.Devices.Common.VideoCodec @@ -38,19 +36,19 @@ 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. /// /// - void SelectFarEndPreset(int preset); + void SelectFarEndPreset(int preset); } /// /// Static class for converting non-generic RoomPresets to generic CameraPresets. /// - public static class RoomPresets + public static class RoomPresets { /// /// Converts non-generic RoomPresets to generic CameraPresets diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceMode.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceMode.cs index ef960406..6d77551d 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceMode.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceMode.cs @@ -3,5 +3,23 @@ /// /// Enumeration of eExternalSourceMode values /// - public enum eExternalSourceMode {Ready, NotReady, Hidden, Error} + public enum eExternalSourceMode + { + /// + /// Ready state + /// + Ready, + /// + /// Not ready state + /// + NotReady, + /// + /// Hidden state + /// + Hidden, + /// + /// Error state + /// + Error + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceType.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceType.cs index a5cea36c..6d5811e3 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceType.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CiscoCodec/eExternalSourceType.cs @@ -3,5 +3,35 @@ /// /// Enumeration of eExternalSourceType values /// - public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other} + public enum eExternalSourceType + { + /// + /// Camera source type + /// + camera, + /// + /// Desktop source type + /// + desktop, + /// + /// Document camera source type + /// + document_camera, + /// + /// Media player source type + /// + mediaplayer, + /// + /// PC source type + /// + PC, + /// + /// Whiteboard source type + /// + whiteboard, + /// + /// Other source type + /// + other + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecCommandWithLabel.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecCommandWithLabel.cs new file mode 100644 index 00000000..a69fc77a --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecCommandWithLabel.cs @@ -0,0 +1,31 @@ +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + /// + /// Represents a CodecCommandWithLabel + /// + public class CodecCommandWithLabel + { + /// + /// Gets or sets the Command + /// + public string Command { get; private set; } + /// + /// Gets or sets the Label + /// + public string Label { get; private set; } + + /// + /// Constructor for + /// + /// Command string + /// Label string + public CodecCommandWithLabel(string command, string label) + { + Command = command; + Label = label; + } + } + + + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecPhonebookSyncState.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecPhonebookSyncState.cs new file mode 100644 index 00000000..c677c906 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/CodecPhonebookSyncState.cs @@ -0,0 +1,150 @@ +using System; +using PepperDash.Core; +using Serilog.Events; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + /// + /// Represents a CodecPhonebookSyncState + /// + public class CodecPhonebookSyncState : IKeyed + { + private bool _InitialSyncComplete; + + /// + /// Constructor for CodecPhonebookSyncState + /// + /// Key for the codec phonebook sync state + public CodecPhonebookSyncState(string key) + { + Key = key; + + CodecDisconnected(); + } + + /// + /// Gets or sets the InitialSyncComplete + /// + public bool InitialSyncComplete + { + get { return _InitialSyncComplete; } + private set + { + if (value == true) + { + InitialSyncCompleted?.Invoke(this, new EventArgs()); + } + _InitialSyncComplete = value; + } + } + + /// + /// Gets or sets the InitialPhonebookFoldersWasReceived + /// + public bool InitialPhonebookFoldersWasReceived { get; private set; } + + /// + /// Gets or sets the NumberOfContactsWasReceived + /// + public bool NumberOfContactsWasReceived { get; private set; } + + /// + /// Gets or sets the PhonebookRootEntriesWasRecieved + /// + public bool PhonebookRootEntriesWasRecieved { get; private set; } + + /// + /// Gets or sets the PhonebookHasFolders + /// + public bool PhonebookHasFolders { get; private set; } + + /// + /// Gets or sets the NumberOfContacts + /// + public int NumberOfContacts { get; private set; } + + #region IKeyed Members + + /// + /// Gets or sets the Key + /// + public string Key { get; private set; } + + #endregion + + /// + /// Event InitialSyncCompleted + /// + public event EventHandler InitialSyncCompleted; + + /// + /// InitialPhonebookFoldersReceived method + /// + public void InitialPhonebookFoldersReceived() + { + InitialPhonebookFoldersWasReceived = true; + + CheckSyncStatus(); + } + + /// + /// PhonebookRootEntriesReceived method + /// + public void PhonebookRootEntriesReceived() + { + PhonebookRootEntriesWasRecieved = true; + + CheckSyncStatus(); + } + + /// + /// SetPhonebookHasFolders method + /// + public void SetPhonebookHasFolders(bool value) + { + PhonebookHasFolders = value; + + Debug.LogMessage(LogEventLevel.Debug, this, "Phonebook has folders: {0}", PhonebookHasFolders); + } + + /// + /// SetNumberOfContacts method + /// + public void SetNumberOfContacts(int contacts) + { + NumberOfContacts = contacts; + NumberOfContactsWasReceived = true; + + Debug.LogMessage(LogEventLevel.Debug, this, "Phonebook contains {0} contacts.", NumberOfContacts); + + CheckSyncStatus(); + } + + /// + /// CodecDisconnected method + /// + public void CodecDisconnected() + { + InitialPhonebookFoldersWasReceived = false; + PhonebookHasFolders = false; + NumberOfContacts = 0; + NumberOfContactsWasReceived = false; + } + + private void CheckSyncStatus() + { + if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved) + { + InitialSyncComplete = true; + Debug.LogMessage(LogEventLevel.Debug, this, "Initial Phonebook Sync Complete!"); + } + else + { + InitialSyncComplete = false; + } + } + } + + + +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/ConvertiblePreset.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/ConvertiblePreset.cs index 4c01d94e..e75f436d 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/ConvertiblePreset.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/ConvertiblePreset.cs @@ -2,8 +2,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { + /// + /// Base class for presets that can be converted to PresetBase + /// public abstract class ConvertiblePreset { + /// + /// Converts the preset to a PresetBase + /// + /// public abstract PresetBase ConvertCodecPreset(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/CodecParticipants.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/CodecParticipants.cs new file mode 100644 index 00000000..a297c9e6 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/CodecParticipants.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Represents a CodecParticipants + /// + public class CodecParticipants + { + private List _currentParticipants; + + /// + /// Gets or sets the CurrentParticipants + /// + public List CurrentParticipants + { + get { return _currentParticipants; } + set + { + _currentParticipants = value; + OnParticipantsChanged(); + } + } + + /// + /// Gets the Host participant + /// + public Participant Host + { + get + { + return _currentParticipants.FirstOrDefault(p => p.IsHost); + } + } + + /// + /// Event fired when the participants list has changed + /// + public event EventHandler ParticipantsListHasChanged; + + /// + /// Initializes a new instance of the CodecParticipants class + /// + public CodecParticipants() + { + _currentParticipants = new List(); + } + + /// + /// OnParticipantsChanged method + /// + public void OnParticipantsChanged() + { + var handler = ParticipantsListHasChanged; + + if (handler == null) return; + + handler(this, new EventArgs()); + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 98a8e4f4..61a40048 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -1,14 +1,4 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; - -using Newtonsoft.Json; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec { @@ -17,10 +7,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasCodecLayouts { + /// + /// Feedback that indicates the current layout on the local display + /// StringFeedback LocalLayoutFeedback { get; } + /// + /// Toggles the local layout + /// void LocalLayoutToggle(); - void LocalLayoutToggleSingleProminent(); - void MinMaxLayoutToggle(); + + /// + /// Toggles the local layout to single prominent + /// + void LocalLayoutToggleSingleProminent(); + + /// + /// Toggle the MinMax layout + /// + void MinMaxLayoutToggle(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecSelfview.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecSelfview.cs index 3b079b7d..a52670bc 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecSelfview.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasCodecSelfview.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec { @@ -13,14 +7,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasCodecSelfView { + /// + /// Feedback that indicates whether Selfview is on + /// BoolFeedback SelfviewIsOnFeedback { get; } + /// + /// Setting that indicates whether the device shows selfview by default + /// bool ShowSelfViewByDefault { get; } + /// + /// Turns selfview on + /// void SelfViewModeOn(); + /// + /// Turns selfview off + /// void SelfViewModeOff(); + /// + /// Toggles selfview mode + /// void SelfViewModeToggle(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index 88ccfcac..6ec1f8da 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -1,12 +1,6 @@  using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { @@ -15,94 +9,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// public interface IHasMeetingInfo { + /// + /// Raised when meeting info changes + /// event EventHandler MeetingInfoChanged; + /// + /// Gets the current meeting information + /// MeetingInfo MeetingInfo { get; } } - - /// - /// Represents a MeetingInfo - /// - public class MeetingInfo - { - [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the Id - /// - public string Id { get; private set; } - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] - public string Name { get; private set; } - [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)] - public string Host { get; private set; } - [JsonProperty("password", NullValueHandling = NullValueHandling.Ignore)] - public string Password { get; private set; } - [JsonProperty("shareStatus", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the ShareStatus - /// - public string ShareStatus { get; private set; } - [JsonProperty("isHost", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the IsHost - /// - public Boolean IsHost { get; private set; } - [JsonProperty("isSharingMeeting", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the IsSharingMeeting - /// - public Boolean IsSharingMeeting { get; private set; } - [JsonProperty("waitingForHost", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the WaitingForHost - /// - public Boolean WaitingForHost { get; private set; } - [JsonProperty("isLocked", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the IsLocked - /// - public Boolean IsLocked { get; private set; } - [JsonProperty("isRecording", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the IsRecording - /// - public Boolean IsRecording { get; private set; } - [JsonProperty("canRecord", NullValueHandling = NullValueHandling.Ignore)] - /// - /// Gets or sets the CanRecord - /// - public Boolean CanRecord { get; private set; } - - - public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked, bool isRecording, bool canRecord) - { - Id = id; - Name = name; - Host = host; - Password = password; - ShareStatus = shareStatus; - IsHost = isHost; - IsSharingMeeting = isSharingMeeting; - WaitingForHost = waitingForHost; - IsLocked = isLocked; - IsRecording = isRecording; - CanRecord = CanRecord; - } - } - - /// - /// Represents a MeetingInfoEventArgs - /// - public class MeetingInfoEventArgs : EventArgs - { - /// - /// Gets or sets the Info - /// - public MeetingInfo Info { get; private set; } - - public MeetingInfoEventArgs(MeetingInfo info) - { - Info = info; - } - - } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingLock.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingLock.cs index e7344818..b133eebd 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingLock.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingLock.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { @@ -12,10 +7,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// public interface IHasMeetingLock { + /// + /// Feedback that indicates whether the meeting is locked + /// BoolFeedback MeetingIsLockedFeedback { get; } + /// + /// Locks the meeting + /// void LockMeeting(); + + /// + /// Unlocks the meeting + /// void UnLockMeeting(); + + /// + /// Toggles the meeting lock state + /// void ToggleMeetingLock(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecording.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecording.cs index 9946cdd1..96e23daa 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecording.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecording.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { @@ -12,24 +7,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// public interface IHasMeetingRecording { + /// + /// Feedback that indicates whether the meeting is being recorded + /// BoolFeedback MeetingIsRecordingFeedback { get; } + /// + /// Starts recording the meeting + /// void StartRecording(); - void StopRecording(); - void ToggleRecording(); - } - - /// - /// Defines the contract for IHasMeetingRecordingWithPrompt - /// - public interface IHasMeetingRecordingWithPrompt : IHasMeetingRecording - { - BoolFeedback RecordConsentPromptIsVisible { get; } /// - /// Used to agree or disagree to the meeting being recorded when prompted + /// Stops recording the meeting /// - /// - void RecordingPromptAcknowledgement(bool agree); + void StopRecording(); + + /// + /// Toggles recording the meeting + /// + void ToggleRecording(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecordingWithPrompt.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecordingWithPrompt.cs new file mode 100644 index 00000000..13d187c2 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasMeetingRecordingWithPrompt.cs @@ -0,0 +1,21 @@ +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Defines the contract for IHasMeetingRecordingWithPrompt + /// + public interface IHasMeetingRecordingWithPrompt : IHasMeetingRecording + { + /// + /// Feedback that indicates whether the recording consent prompt is visible + /// + BoolFeedback RecordConsentPromptIsVisible { get; } + + /// + /// Used to agree or disagree to the meeting being recorded when prompted + /// + /// + void RecordingPromptAcknowledgement(bool agree); + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantAudioMute.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantAudioMute.cs new file mode 100644 index 00000000..6ada2e46 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantAudioMute.cs @@ -0,0 +1,31 @@ +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Defines the contract for IHasParticipantAudioMute + /// + public interface IHasParticipantAudioMute : IHasParticipantVideoMute + { + /// + /// Mute audio of all participants + /// + void MuteAudioForAllParticipants(); + + /// + /// Mute audio for participant + /// + /// The user ID of the participant to mute + void MuteAudioForParticipant(int userId); + + /// + /// Unmute audio for participant + /// + /// The user ID of the participant to unmute + void UnmuteAudioForParticipant(int userId); + + /// + /// Toggles audio for participant + /// + /// The user ID of the participant to toggle + void ToggleAudioForParticipant(int userId); + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantPinUnpin.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantPinUnpin.cs new file mode 100644 index 00000000..9167e8a8 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantPinUnpin.cs @@ -0,0 +1,40 @@ +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Defines the contract for IHasParticipantPinUnpin + /// + public interface IHasParticipantPinUnpin : IHasParticipants + { + /// + /// Feedback that indicates the number of screens available for pinning participants + /// + IntFeedback NumberOfScreensFeedback { get; } + + /// + /// Gets the screen index to pin the user to + /// + int ScreenIndexToPinUserTo { get; } + + /// + /// Pins a participant to a screen + /// + /// The user ID of the participant to pin + /// The screen index to pin the user to + void PinParticipant(int userId, int screenIndex); + + /// + /// Unpins a participant + /// + /// The user ID of the participant to unpin + void UnPinParticipant(int userId); + + /// + /// Toggles the pin state of a participant + /// + /// The user ID of the participant to toggle + /// The screen index to pin the user to + void ToggleParticipantPinState(int userId, int screenIndex); + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantVideoMute.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantVideoMute.cs new file mode 100644 index 00000000..3e673cff --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipantVideoMute.cs @@ -0,0 +1,26 @@ +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Describes the ability to mute and unmute a participant's video in a meeting + /// + public interface IHasParticipantVideoMute : IHasParticipants + { + /// + /// Mute video of all participants + /// + /// The user ID of the participant to mute + void MuteVideoForParticipant(int userId); + + /// + /// Unmute video of all participants + /// + /// The user ID of the participant to unmute + void UnmuteVideoForParticipant(int userId); + + /// + /// Toggles video of a participant + /// + /// The user ID of the participant to toggle + void ToggleVideoForParticipant(int userId); + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipants.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipants.cs index 0f89eb91..6ff549af 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -1,156 +1,31 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using PepperDash.Core; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { /// /// Describes a device that has call participants /// public interface IHasParticipants { + /// + /// Gets the collection of participants + /// CodecParticipants Participants { get; } - /// - /// Removes the participant from the meeting - /// - /// - void RemoveParticipant(int userId); + /// + /// Removes the participant from the meeting + /// + /// + void RemoveParticipant(int userId); - /// - /// Sets the participant as the new host - /// - /// - void SetParticipantAsHost(int userId); + /// + /// Sets the participant as the new host + /// + /// + void SetParticipantAsHost(int userId); - /// - /// Admits a participant from the waiting room - /// - /// - void AdmitParticipantFromWaitingRoom(int userId); - } - - /// - /// Describes the ability to mute and unmute a participant's video in a meeting - /// - public interface IHasParticipantVideoMute : IHasParticipants - { - void MuteVideoForParticipant(int userId); - void UnmuteVideoForParticipant(int userId); - void ToggleVideoForParticipant(int userId); - } - - /// - /// Defines the contract for IHasParticipantAudioMute - /// - public interface IHasParticipantAudioMute : IHasParticipantVideoMute - { - /// - /// Mute audio of all participants - /// - void MuteAudioForAllParticipants(); - - void MuteAudioForParticipant(int userId); - void UnmuteAudioForParticipant(int userId); - void ToggleAudioForParticipant(int userId); - } - - /// - /// Defines the contract for IHasParticipantPinUnpin - /// - public interface IHasParticipantPinUnpin : IHasParticipants - { - IntFeedback NumberOfScreensFeedback { get; } - int ScreenIndexToPinUserTo { get; } - - void PinParticipant(int userId, int screenIndex); - void UnPinParticipant(int userId); - void ToggleParticipantPinState(int userId, int screenIndex); - } - - /// - /// Represents a CodecParticipants - /// - public class CodecParticipants - { - private List _currentParticipants; - - public List CurrentParticipants - { - get { return _currentParticipants; } - set - { - _currentParticipants = value; - OnParticipantsChanged(); - } - } - - public Participant Host - { - get - { - return _currentParticipants.FirstOrDefault(p => p.IsHost); - } - } - - public event EventHandler ParticipantsListHasChanged; - - public CodecParticipants() - { - _currentParticipants = new List(); - } - - /// - /// OnParticipantsChanged method - /// - public void OnParticipantsChanged() - { - var handler = ParticipantsListHasChanged; - - if (handler == null) return; - - handler(this, new EventArgs()); - } - } - - /// - /// Represents a Participant - /// - public class Participant - { - /// - /// Gets or sets the UserId - /// - public int UserId { get; set; } - /// - /// Gets or sets the IsHost - /// - public bool IsHost { get; set; } - public bool IsMyself { get; set; } - public string Name { get; set; } - public bool CanMuteVideo { get; set; } - public bool CanUnmuteVideo { get; set; } - public bool VideoMuteFb { get; set; } - public bool AudioMuteFb { get; set; } - /// - /// Gets or sets the HandIsRaisedFb - /// - public bool HandIsRaisedFb { get; set; } - /// - /// Gets or sets the IsPinnedFb - /// - public bool IsPinnedFb { get; set; } - /// - /// Gets or sets the ScreenIndexIsPinnedToFb - /// - public int ScreenIndexIsPinnedToFb { get; set; } - - public Participant() - { - // Initialize to -1 (no screen) - ScreenIndexIsPinnedToFb = -1; - } + /// + /// Admits a participant from the waiting room + /// + /// + void AdmitParticipantFromWaitingRoom(int userId); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs index cb52efc2..b2180c39 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs @@ -5,10 +5,35 @@ /// public interface IHasPresentationOnlyMeeting { + /// + /// Starts a presentation only meeting + /// void StartSharingOnlyMeeting(); + + /// + /// Starts a presentation only meeting with specified display mode + /// + /// The display mode for the meeting void StartSharingOnlyMeeting(eSharingMeetingMode displayMode); + + /// + /// Starts a presentation only meeting with specified display mode and duration + /// + /// The display mode for the meeting + /// The duration for the meeting void StartSharingOnlyMeeting(eSharingMeetingMode displayMode, uint duration); + + /// + /// Starts a presentation only meeting with specified display mode, duration, and password + /// + /// The display mode for the meeting + /// The duration for the meeting + /// The password for the meeting void StartSharingOnlyMeeting(eSharingMeetingMode displayMode, uint duration, string password); + + /// + /// Starts a normal meeting from a sharing only meeting + /// void StartNormalMeetingFromSharingOnlyMeeting(); } @@ -17,8 +42,17 @@ /// public enum eSharingMeetingMode { + /// + /// No specific sharing mode + /// None, + /// + /// Laptop sharing mode + /// Laptop, + /// + /// iOS sharing mode + /// Ios, } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewPosition.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewPosition.cs index dbb6d0ef..46c3d8f7 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewPosition.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewPosition.cs @@ -1,5 +1,4 @@ -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash.Essentials.Devices.Common.VideoCodec; namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { @@ -8,10 +7,19 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces /// public interface IHasSelfviewPosition { + /// + /// Gets the SelfviewPipPositionFeedback + /// StringFeedback SelfviewPipPositionFeedback { get; } + /// + /// Sets the selfview position + /// void SelfviewPipPositionSet(CodecCommandWithLabel position); + /// + /// Toggles the selfview position + /// void SelfviewPipPositionToggle(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewSize.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewSize.cs index 45365ce1..ab08a414 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewSize.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasSelfviewSize.cs @@ -2,15 +2,25 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { - /// - /// Defines the contract for IHasSelfviewSize - /// + /// + /// Defines the contract for IHasSelfviewSize + /// public interface IHasSelfviewSize { + /// + /// Gets the SelfviewPipSizeFeedback + /// StringFeedback SelfviewPipSizeFeedback { get; } + /// + /// Sets the selfview size + /// + /// The new selfview size void SelfviewPipSizeSet(CodecCommandWithLabel size); + /// + /// Toggles the selfview size + /// void SelfviewPipSizeToggle(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStandbyMode.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStandbyMode.cs index 6b2ebe38..d0f1333b 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStandbyMode.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStandbyMode.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec { @@ -13,10 +7,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasStandbyMode { + /// + /// Feedback that indicates whether Standby Mode is on + /// BoolFeedback StandbyIsOnFeedback { get; } + /// + /// Activates Standby Mode + /// void StandbyActivate(); + /// + /// Deactivates Standby Mode + /// void StandbyDeactivate(); } @@ -25,10 +28,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasHalfWakeMode : IHasStandbyMode { + /// + /// Feedback that indicates whether Half Wake Mode is on + /// BoolFeedback HalfWakeModeIsOnFeedback { get; } + /// + /// Feedback that indicates whether the device is entering Standby Mode + /// BoolFeedback EnteringStandbyModeFeedback { get; } + /// + /// Activates Half Wake Mode + /// void HalfwakeActivate(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStartMeeting.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStartMeeting.cs index 6af59534..357416e2 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStartMeeting.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasStartMeeting.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { /// /// Describes the ability to start an ad-hoc meeting diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasVideoCodec.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasVideoCodec.cs index f7b8f9ad..cdeb9190 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasVideoCodec.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IHasVideoCodec.cs @@ -1,25 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec { /// /// For rooms that have video codec /// - public interface IHasVideoCodec:IHasInCallFeedback,IPrivacy + public interface IHasVideoCodec : IHasInCallFeedback, IPrivacy { + /// + /// Gets the VideoCodecBase instance + /// VideoCodecBase VideoCodec { get; } - /// - /// Make this more specific - /// - //List ActiveCalls { get; } - /// /// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis /// diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IJoinCalls.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IJoinCalls.cs index 25a807a1..b2583a5d 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IJoinCalls.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/IJoinCalls.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.Codec; namespace PepperDash.Essentials.Devices.Common.VideoCodec { @@ -13,7 +7,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IJoinCalls { + /// + /// Joins a call + /// + /// The active call to join void JoinCall(CodecActiveCallItem activeCall); + + /// + /// Joins all calls + /// void JoinAllCalls(); } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfo.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfo.cs new file mode 100644 index 00000000..a65b6830 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfo.cs @@ -0,0 +1,106 @@ +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Represents a MeetingInfo + /// + public class MeetingInfo + { + + /// + /// Gets or sets the Id + /// + [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] + public string Id { get; private set; } + + /// + /// Gets or sets the Name + /// + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name { get; private set; } + + /// + /// Gets or sets the Host + /// + [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)] + public string Host { get; private set; } + + /// + /// Gets or sets the Password + /// + [JsonProperty("password", NullValueHandling = NullValueHandling.Ignore)] + public string Password { get; private set; } + + /// + /// Gets or sets the ShareStatus + /// + [JsonProperty("shareStatus", NullValueHandling = NullValueHandling.Ignore)] + public string ShareStatus { get; private set; } + + /// + /// Gets or sets the IsHost + /// + [JsonProperty("isHost", NullValueHandling = NullValueHandling.Ignore)] + public bool IsHost { get; private set; } + + /// + /// Gets or sets the IsSharingMeeting + /// + [JsonProperty("isSharingMeeting", NullValueHandling = NullValueHandling.Ignore)] + public bool IsSharingMeeting { get; private set; } + + /// + /// Gets or sets the WaitingForHost + /// + [JsonProperty("waitingForHost", NullValueHandling = NullValueHandling.Ignore)] + public bool WaitingForHost { get; private set; } + + /// + /// Gets or sets the IsLocked + /// + [JsonProperty("isLocked", NullValueHandling = NullValueHandling.Ignore)] + public bool IsLocked { get; private set; } + + /// + /// Gets or sets the IsRecording + /// + [JsonProperty("isRecording", NullValueHandling = NullValueHandling.Ignore)] + public bool IsRecording { get; private set; } + + /// + /// Gets or sets the CanRecord + /// + [JsonProperty("canRecord", NullValueHandling = NullValueHandling.Ignore)] + public bool CanRecord { get; private set; } + + /// + /// Constructor for MeetingInfo + /// + /// The unique identifier for the meeting + /// The name of the meeting + /// The host of the meeting + /// The password for the meeting + /// The share status of the meeting + /// Indicates whether the current user is the host + /// Indicates whether the meeting is currently being shared + /// Indicates whether the meeting is waiting for the host to join + /// Indicates whether the meeting is locked + /// Indicates whether the meeting is being recorded + /// Indicates whether the meeting can be recorded + public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked, bool isRecording, bool canRecord) + { + Id = id; + Name = name; + Host = host; + Password = password; + ShareStatus = shareStatus; + IsHost = isHost; + IsSharingMeeting = isSharingMeeting; + WaitingForHost = waitingForHost; + IsLocked = isLocked; + IsRecording = isRecording; + CanRecord = CanRecord; + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfoEventArgs.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfoEventArgs.cs new file mode 100644 index 00000000..f483a564 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/MeetingInfoEventArgs.cs @@ -0,0 +1,27 @@ + + +using System; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Represents a MeetingInfoEventArgs + /// + public class MeetingInfoEventArgs : EventArgs + { + /// + /// Gets or sets the Info + /// + public MeetingInfo Info { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The meeting information. + public MeetingInfoEventArgs(MeetingInfo info) + { + Info = info; + } + + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs new file mode 100644 index 00000000..2d266a95 --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs @@ -0,0 +1,72 @@ +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Represents a Participant + /// + public class Participant + { + /// + /// Gets or sets the UserId + /// + public int UserId { get; set; } + + /// + /// Gets or sets the IsHost + /// + public bool IsHost { get; set; } + + /// + /// Gets or sets the IsMyself + /// + public bool IsMyself { get; set; } + + /// + /// Gets or sets the Name + /// + public string Name { get; set; } + + /// + /// Gets or sets the Email + /// + public bool CanMuteVideo { get; set; } + + /// + /// Gets or sets the CanUnmuteVideo + /// + public bool CanUnmuteVideo { get; set; } + + /// + /// Gets or sets the CanMuteAudio + /// + public bool VideoMuteFb { get; set; } + + /// + /// Gets or sets the AudioMuteFb + /// + public bool AudioMuteFb { get; set; } + + /// + /// Gets or sets the HandIsRaisedFb + /// + public bool HandIsRaisedFb { get; set; } + + /// + /// Gets or sets the IsPinnedFb + /// + public bool IsPinnedFb { get; set; } + + /// + /// Gets or sets the ScreenIndexIsPinnedToFb + /// + public int ScreenIndexIsPinnedToFb { get; set; } + + /// + /// Initializes a new instance of the class + /// + public Participant() + { + // Initialize to -1 (no screen) + ScreenIndexIsPinnedToFb = -1; + } + } +} \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs index 8f004086..8b1be9e9 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs @@ -1,12 +1,4 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using Newtonsoft.Json; +using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.Codec { @@ -15,6 +7,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public interface iVideoCodecInfo { + /// + /// Gets the codec information + /// VideoCodecInfo CodecInfo { get; } } @@ -23,18 +18,39 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public abstract class VideoCodecInfo { + /// + /// Gets a value indicating whether the multi-site option is enabled + /// [JsonProperty("multiSiteOptionIsEnabled", NullValueHandling = NullValueHandling.Ignore)] public abstract bool MultiSiteOptionIsEnabled { get; } + /// + /// Gets the IP address of the codec + /// [JsonProperty("ipAddress", NullValueHandling = NullValueHandling.Ignore)] public abstract string IpAddress { get; } + /// + /// Gets the SIP phone number for the codec + /// [JsonProperty("sipPhoneNumber", NullValueHandling = NullValueHandling.Ignore)] public abstract string SipPhoneNumber { get; } + /// + /// Gets the E164 alias for the codec + /// [JsonProperty("e164Alias", NullValueHandling = NullValueHandling.Ignore)] public abstract string E164Alias { get; } + /// + /// Gets the H323 ID for the codec + /// [JsonProperty("h323Id", NullValueHandling = NullValueHandling.Ignore)] public abstract string H323Id { get; } + /// + /// Gets the SIP URI for the codec + /// [JsonProperty("sipUri", NullValueHandling = NullValueHandling.Ignore)] public abstract string SipUri { get; } + /// + /// Gets a value indicating whether auto-answer is enabled + /// [JsonProperty("autoAnswerEnabled", NullValueHandling = NullValueHandling.Ignore)] public abstract bool AutoAnswerEnabled { get; } } diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockCodecDirectory.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockCodecDirectory.cs index 9b9aa8d7..185f089f 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockCodecDirectory.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockCodecDirectory.cs @@ -1,16 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; -using PepperDash.Essentials.Core; +using System.Collections.Generic; using PepperDash.Essentials.Devices.Common.Codec; namespace PepperDash.Essentials.Devices.Common.VideoCodec { + /// + /// Mock video codec directory structure + /// public static class MockVideoCodecDirectory { /// @@ -18,13 +14,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public enum eFolderId { + /// + /// The United States folder + /// UnitedStates, + /// + /// The Canada folder + /// Canada, + /// + /// The New York folder + /// NewYork, + /// + /// The Boston folder + /// Boston, + /// + /// The San Francisco folder + /// SanFrancisco, + /// + /// The Denver folder + /// Denver, + /// + /// The Austin folder + /// Austin, + /// + /// The Calgary folder + /// Calgary } @@ -51,16 +71,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } - public static CodecDirectory DirectoryRoot + /// + /// The root of the directory structure + /// + public static CodecDirectory DirectoryRoot { get { var directory = new CodecDirectory(); - + directory.AddFoldersToDirectory - ( + ( new List() - { + { new DirectoryFolder() { FolderId = eFolderId.UnitedStates.ToString(), @@ -77,7 +100,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } ); - + directory.AddContactsToDirectory ( new List() @@ -97,23 +120,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } } - ); - + ); + return directory; - } + } } + /// + /// Contents of the United States folder + /// public static CodecDirectory UnitedStatesFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.UnitedStates.ToString(); - directory.AddFoldersToDirectory - ( - new List() - { + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.UnitedStates.ToString() + }; + directory.AddFoldersToDirectory + ( + new List() + { new DirectoryFolder() { FolderId = eFolderId.NewYork.ToString(), @@ -149,24 +176,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec ParentFolderId = eFolderId.UnitedStates.ToString(), Contacts = null } - } - ); + } + ); return directory; } } + /// + /// Contents of the New York folder + /// public static CodecDirectory NewYorkFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.NewYork.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.NewYork.ToString() + }; directory.AddContactsToDirectory - ( - new List() - { + ( + new List() + { new DirectoryContact() { ContactId = "nyc_1", @@ -215,24 +246,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } } - } - ); + } + ); return directory; } } + /// + /// Contents of the Boston folder + /// public static CodecDirectory BostonFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.Boston.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.Boston.ToString() + }; directory.AddContactsToDirectory - ( - new List() - { + ( + new List() + { new DirectoryContact() { ContactId = "bos_1", @@ -249,24 +284,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } } - } - ); + } + ); return directory; } } + /// + /// Contents of the San Francisco folder + /// public static CodecDirectory SanFranciscoFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.SanFrancisco.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.SanFrancisco.ToString() + }; directory.AddContactsToDirectory - ( - new List() - { + ( + new List() + { new DirectoryContact() { ContactId = "sfo_1", @@ -282,25 +321,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CallType = eContactMethodCallType.Video } } - } - } - ); + } + } + ); return directory; } } + /// + /// Contents of the Denver folder + /// public static CodecDirectory DenverFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.Denver.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.Denver.ToString() + }; directory.AddContactsToDirectory - ( - new List() - { + ( + new List() + { new DirectoryContact() { ContactId = "den_1", @@ -316,25 +359,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CallType = eContactMethodCallType.Video } } - } - } - ); + } + } + ); return directory; } } + /// + /// Contents of the Austin folder + /// public static CodecDirectory AustinFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.Austin.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.Austin.ToString() + }; directory.AddContactsToDirectory - ( - new List() - { + ( + new List() + { new DirectoryContact() { ContactId = "atx_1", @@ -350,25 +397,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CallType = eContactMethodCallType.Video } } - } - } - ); + } + } + ); return directory; } } + /// + /// Contents of the Canada folder + /// public static CodecDirectory CanadaFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.Canada.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.Canada.ToString() + }; directory.AddFoldersToDirectory - ( - new List() - { + ( + new List() + { new DirectoryFolder() { FolderId = eFolderId.Calgary.ToString(), @@ -376,24 +427,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec ParentFolderId = eFolderId.Canada.ToString(), Contacts = null } - } - ); + } + ); return directory; } } + /// + /// Contents of the Calgary folder + /// public static CodecDirectory CalgaryFolderContents { get { - var directory = new CodecDirectory(); - - directory.ResultsFolderId = eFolderId.Calgary.ToString(); + var directory = new CodecDirectory + { + ResultsFolderId = eFolderId.Calgary.ToString() + }; directory.AddContactsToDirectory - ( - new List() - { + ( + new List() + { new DirectoryContact() { ContactId = "cdn_1", @@ -409,14 +464,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CallType = eContactMethodCallType.Video } } - } - } - ); + } + } + ); return directory; } } - - } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVC.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVC.cs index 0387c416..e9f7908c 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVC.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVC.cs @@ -3,19 +3,17 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Routing; -using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.Cameras; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using PepperDash.Essentials.Devices.Common.Codec; using Serilog.Events; namespace PepperDash.Essentials.Devices.Common.VideoCodec @@ -47,10 +45,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public RoutingOutputPort HdmiOut { get; private set; } - /// - /// Gets or sets the CallFavorites - /// - public CodecCallFavorites CallFavorites { get; private set; } + /// + /// Gets or sets the CallFavorites + /// + public CodecCallFavorites CallFavorites { get; private set; } /// /// @@ -62,22 +60,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CodecInfo = new MockCodecInfo(); - // Get favoritesw + // Get favoritesw if (PropertiesConfig.Favorites != null) - { - CallFavorites = new CodecCallFavorites(); - CallFavorites.Favorites = PropertiesConfig.Favorites; - } + { + CallFavorites = new CodecCallFavorites(); + CallFavorites.Favorites = PropertiesConfig.Favorites; + } DirectoryBrowseHistory = new List(); // Debug helpers MuteFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Debug, this, "Mute={0}", _IsMuted); PrivacyModeIsOnFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Debug, this, "Privacy={0}", _PrivacyModeIsOn); - SharingSourceFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Debug, this, "SharingSource={0}", _SharingSource); + SharingSourceFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Debug, this, "SharingSource={0}", _SharingSource); VolumeLevelFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Debug, this, "Volume={0}", _VolumeLevel); - CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => DirectoryBrowseHistory.Count > 0); + CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback("currentDirectoryResultIsNotDirectoryRoot", () => DirectoryBrowseHistory.Count > 0); CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); @@ -105,38 +103,44 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CreateOsdSource(); SetIsReady(); - } + } + /// protected override Func MuteFeedbackFunc { get { return () => _IsMuted; } } bool _IsMuted; + /// protected override Func PrivacyModeIsOnFeedbackFunc { get { return () => _PrivacyModeIsOn; } } bool _PrivacyModeIsOn; - + + /// protected override Func SharingSourceFeedbackFunc { get { return () => _SharingSource; } } string _SharingSource; + /// protected override Func SharingContentIsOnFeedbackFunc { get { return () => _SharingIsOn; } } bool _SharingIsOn; + /// protected override Func VolumeLevelFeedbackFunc { get { return () => _VolumeLevel; } } int _VolumeLevel; + /// protected override Func StandbyIsOnFeedbackFunc { get { return () => _StandbyIsOn; } @@ -157,9 +161,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //foreach(var input in Status.Video. } - /// - /// Dial method - /// /// public override void Dial(string number) { @@ -177,9 +178,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec }, 2000); } - /// - /// Dial method - /// /// public override void Dial(Meeting meeting) { @@ -199,9 +197,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } - /// - /// EndCall method - /// /// public override void EndCall(CodecActiveCallItem call) { @@ -211,14 +206,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //ActiveCallCountFeedback.FireUpdate(); } - /// - /// EndAllCalls method - /// + /// public override void EndAllCalls() { Debug.LogMessage(LogEventLevel.Debug, this, "EndAllCalls"); - for(int i = ActiveCalls.Count - 1; i >= 0; i--) + for (int i = ActiveCalls.Count - 1; i >= 0; i--) { var call = ActiveCalls[i]; ActiveCalls.Remove(call); @@ -227,9 +220,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //ActiveCallCountFeedback.FireUpdate(); } - /// - /// AcceptCall method - /// + /// public override void AcceptCall(CodecActiveCallItem call) { @@ -239,9 +230,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec // should already be in active list } - /// - /// RejectCall method - /// /// public override void RejectCall(CodecActiveCallItem call) { @@ -251,65 +239,44 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //ActiveCallCountFeedback.FireUpdate(); } - /// - /// Makes horrible tones go out on the wire! - /// - /// - /// - /// SendDtmf method - /// + /// public override void SendDtmf(string s) { Debug.LogMessage(LogEventLevel.Debug, this, "SendDTMF: {0}", s); } - /// - /// - /// + /// public override void StartSharing() { _SharingIsOn = true; SharingContentIsOnFeedback.FireUpdate(); } - /// - /// - /// + /// public override void StopSharing() { _SharingIsOn = false; SharingContentIsOnFeedback.FireUpdate(); } + /// public override void StandbyActivate() { _StandbyIsOn = true; } - /// - /// StandbyDeactivate method - /// /// public override void StandbyDeactivate() { _StandbyIsOn = false; } - /// - /// LinkToApi method - /// + /// public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { throw new NotImplementedException(); } - /// - /// Called by routing to make it happen - /// - /// - /// - /// ExecuteSwitch method - /// /// public override void ExecuteSwitch(object selector) { @@ -317,40 +284,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec _SharingSource = selector.ToString(); } - /// - /// - /// + /// public override void MuteOff() { _IsMuted = false; MuteFeedback.FireUpdate(); } - /// - /// - /// + /// public override void MuteOn() { _IsMuted = true; MuteFeedback.FireUpdate(); } - /// - /// - /// + /// public override void MuteToggle() { _IsMuted = !_IsMuted; MuteFeedback.FireUpdate(); } - - /// - /// - /// - /// - /// - /// SetVolume method - /// + /// public override void SetVolume(ushort level) { @@ -358,29 +312,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec VolumeLevelFeedback.FireUpdate(); } - /// - /// - /// - /// - /// - /// VolumeDown method - /// /// public override void VolumeDown(bool pressRelease) { } - /// - /// - /// - /// + + /// public override void VolumeUp(bool pressRelease) { } - /// - /// - /// + /// public override void PrivacyModeOn() { Debug.LogMessage(LogEventLevel.Debug, this, "PrivacyMuteOn"); @@ -390,9 +333,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec PrivacyModeIsOnFeedback.FireUpdate(); } - /// - /// PrivacyModeOff method - /// + /// public override void PrivacyModeOff() { @@ -403,45 +344,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec PrivacyModeIsOnFeedback.FireUpdate(); } - /// - /// PrivacyModeToggle method - /// + /// public override void PrivacyModeToggle() { _PrivacyModeIsOn = !_PrivacyModeIsOn; - Debug.LogMessage(LogEventLevel.Debug, this, "PrivacyMuteToggle: {0}", _PrivacyModeIsOn); - PrivacyModeIsOnFeedback.FireUpdate(); + Debug.LogMessage(LogEventLevel.Debug, this, "PrivacyMuteToggle: {0}", _PrivacyModeIsOn); + PrivacyModeIsOnFeedback.FireUpdate(); } //******************************************************** // SIMULATION METHODS - /// - /// - /// - /// /// /// TestIncomingVideoCall method /// + /// public void TestIncomingVideoCall(string url) { Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingVideoCall from {0}", url); - var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type= eCodecCallType.Video, Direction = eCodecCallDirection.Incoming }; + var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type = eCodecCallType.Video, Direction = eCodecCallDirection.Incoming }; ActiveCalls.Add(call); SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call); //OnCallStatusChange(eCodecCallStatus.Unknown, eCodecCallStatus.Ringing, call); - + } - /// - /// - /// - /// /// /// TestIncomingAudioCall method /// + /// public void TestIncomingAudioCall(string url) { Debug.LogMessage(LogEventLevel.Debug, this, "TestIncomingAudioCall from {0}", url); @@ -451,7 +384,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //OnCallStatusChange(eCodecCallStatus.Unknown, eCodecCallStatus.Ringing, call); } - + /// /// TestFarEndHangup method /// @@ -464,6 +397,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #region IHasCallHistory Members + /// + /// CallHistory property + /// public CodecCallHistory CallHistory { get; private set; } /// @@ -471,12 +407,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry) { - + } #endregion - #region IHasScheduleAwareness Members + #region IHasScheduleAwareness Members /// /// GetSchedule method @@ -486,47 +422,59 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } - public CodecScheduleAwareness CodecSchedule - { - get { - // if the last meeting has past, generate a new list - if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0 - || _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now) - { - _CodecSchedule = new CodecScheduleAwareness(1000); - for (int i = 0; i < 5; i++) - { - var m = new Meeting(); + /// + /// CodecSchedule property + /// + public CodecScheduleAwareness CodecSchedule + { + get + { + // if the last meeting has past, generate a new list + if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0 + || _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now) + { + _CodecSchedule = new CodecScheduleAwareness(1000); + for (int i = 0; i < 5; i++) + { + var m = new Meeting(); m.MinutesBeforeMeeting = 5; m.Id = i.ToString(); m.Organizer = "Employee " + 1; - m.StartTime = DateTime.Now.AddMinutes(5).AddHours(i); - m.EndTime = DateTime.Now.AddHours(i).AddMinutes(50); - m.Title = "Meeting " + i; - m.Calls.Add(new Call() { Number = i + "meeting@fake.com"}); - _CodecSchedule.Meetings.Add(m); - } - } - return _CodecSchedule; - } - } - CodecScheduleAwareness _CodecSchedule; + m.StartTime = DateTime.Now.AddMinutes(5).AddHours(i); + m.EndTime = DateTime.Now.AddHours(i).AddMinutes(50); + m.Title = "Meeting " + i; + m.Calls.Add(new Call() { Number = i + "meeting@fake.com" }); + _CodecSchedule.Meetings.Add(m); + } + } + return _CodecSchedule; + } + } + CodecScheduleAwareness _CodecSchedule; - #endregion + #endregion #region IHasDirectory Members + /// + /// DirectoryResultReturned event. Fired when the directory result changes + /// public event EventHandler DirectoryResultReturned; - + /// + /// DirectoryRoot property. The root of the directory + /// public CodecDirectory DirectoryRoot { - get + get { return MockVideoCodecDirectory.DirectoryRoot; } } + /// + /// CurrentDirectoryResult property. The current directory result + /// public CodecDirectory CurrentDirectoryResult { get @@ -538,9 +486,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } + /// + /// PhonebookSyncState property. The current state of the phonebook synchronization + /// public CodecPhonebookSyncState PhonebookSyncState { - get + get { var syncState = new CodecPhonebookSyncState(Key + "PhonebookSync"); @@ -554,8 +505,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } /// - /// SearchDirectory method + /// Search the directory for contacts that contain the search string /// + /// The search string to use public void SearchDirectory(string searchString) { var searchResults = new CodecDirectory(); @@ -577,8 +529,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } /// - /// GetDirectoryFolderContents method + /// Get the contents of the specified folder /// + /// The ID of the folder to get the contents of public void GetDirectoryFolderContents(string folderId) { var folderDirectory = new CodecDirectory(); @@ -606,7 +559,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } /// - /// SetCurrentDirectoryToRoot method + /// Set the current directory to the root /// public void SetCurrentDirectoryToRoot() { @@ -616,7 +569,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } /// - /// GetDirectoryParentFolderContents method + /// Get the contents of the parent folder /// public void GetDirectoryParentFolderContents() { @@ -656,16 +609,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public void OnDirectoryResultReturned(CodecDirectory result) { CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); - - var handler = DirectoryResultReturned; - if (handler != null) + DirectoryResultReturned?.Invoke(this, new DirectoryEventArgs() { - handler(this, new DirectoryEventArgs() - { - Directory = result, - DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue - }); - } + Directory = result, + DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue + }); } #endregion @@ -686,11 +634,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Cameras.Add(farEndCamera); - SelectedCameraFeedback = new StringFeedback(() => SelectedCamera.Key); + SelectedCameraFeedback = new StringFeedback("selectedCamera", () => SelectedCamera.Key); - ControllingFarEndCameraFeedback = new BoolFeedback(() => SelectedCamera is IAmFarEndCamera); + ControllingFarEndCameraFeedback = new BoolFeedback("controllingFarEndCamera", () => SelectedCamera is IAmFarEndCamera); - CameraAutoModeIsOnFeedback = new BoolFeedback(() => _CameraAutoModeIsOn); + CameraAutoModeIsOnFeedback = new BoolFeedback("cameraAutoModeIsOn", () => _CameraAutoModeIsOn); SupportsCameraAutoMode = true; @@ -728,10 +676,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #region IHasCameras Members + /// + /// CameraSelected event. Fired when a camera is selected + /// public event EventHandler CameraSelected; /// - /// Gets or sets the Cameras + /// Gets the list of cameras associated with this codec /// public List Cameras { get; private set; } @@ -751,12 +702,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec _selectedCamera = value; SelectedCameraFeedback.FireUpdate(); ControllingFarEndCameraFeedback.FireUpdate(); - - var handler = CameraSelected; - if (handler != null) - { - handler(this, new CameraSelectedEventArgs(SelectedCamera)); - } + CameraSelected?.Invoke(this, new CameraSelectedEventArgs(SelectedCamera)); } } @@ -788,7 +734,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// Gets or sets the FarEndCamera /// public CameraBase FarEndCamera { get; private set; } - + /// /// Gets or sets the ControllingFarEndCameraFeedback /// @@ -823,7 +769,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public void CameraAutoModeToggle() { - if(_CameraAutoModeIsOn) + if (_CameraAutoModeIsOn) _CameraAutoModeIsOn = false; else _CameraAutoModeIsOn = true; @@ -835,12 +781,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// /// Gets or sets the CameraAutoModeIsOnFeedback /// - public BoolFeedback CameraAutoModeIsOnFeedback {get; private set;} + public BoolFeedback CameraAutoModeIsOnFeedback { get; private set; } #endregion #region IHasCameraPresets Members + /// + /// CodecRoomPresetsListHasChanged event. Fired when the presets list changes + /// public event EventHandler CodecRoomPresetsListHasChanged; /// @@ -883,11 +832,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec else NearEndPresets.Add(new CodecRoomPreset(preset, description, true, true)); - var handler = CodecRoomPresetsListHasChanged; - if (handler != null) - { - handler(this, new EventArgs()); - } + CodecRoomPresetsListHasChanged?.Invoke(this, new EventArgs()); // Update the config SetConfig(Config); @@ -903,6 +848,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #endregion + /// protected override void CustomSetConfig(DeviceConfig config) { PropertiesConfig.Presets = NearEndPresets; @@ -920,11 +866,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public class MockCodecInfo : VideoCodecInfo { + /// public override bool MultiSiteOptionIsEnabled { get { return true; } } + /// public override string E164Alias { get { return "someE164alias"; } @@ -975,14 +923,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public class MockVCFactory : EssentialsDeviceFactory { + /// public MockVCFactory() { TypeNames = new List() { "mockvc" }; } - /// - /// BuildDevice method - /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVCCamera.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVCCamera.cs index 8b39e457..5c7e89d8 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVCCamera.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVCCamera.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Devices.Common.VideoCodec; @@ -16,9 +11,17 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public class MockVCCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl, IBridgeAdvanced { + /// + /// Gets the parent video codec + /// protected VideoCodecBase ParentCodec { get; private set; } - + /// + /// Initializes a new instance of the MockVCCamera class + /// + /// The device key + /// The device name + /// The parent video codec public MockVCCamera(string key, string name, VideoCodecBase codec) : base(key, name) { @@ -173,9 +176,17 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// public class MockFarEndVCCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera, IBridgeAdvanced { + /// + /// Gets the parent video codec + /// protected VideoCodecBase ParentCodec { get; private set; } - + /// + /// Initializes a new instance of the MockFarEndVCCamera class + /// + /// The device key + /// The device name + /// The parent video codec public MockFarEndVCCamera(string key, string name, VideoCodecBase codec) : base(key, name) { diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs index c34053fc..0c5654d6 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs @@ -1,14 +1,5 @@ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Collections.Generic; using Newtonsoft.Json; - -using PepperDash.Core; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.Codec; namespace PepperDash.Essentials.Devices.Common.VideoCodec @@ -18,18 +9,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public class MockVcPropertiesConfig { - [JsonProperty("favorites")] /// /// Gets or sets the Favorites /// + [JsonProperty("favorites")] public List Favorites { get; set; } - [JsonProperty("presets")] /// /// Gets or sets the Presets /// + [JsonProperty("presets")] public List Presets { get; set; } + /// + /// Initializes a new instance of the class. + /// public MockVcPropertiesConfig() { Favorites = new List(); diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs index 8de3afa5..b0b5ef55 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs @@ -1,57 +1,68 @@ using System; using System.Collections.Generic; using System.Linq; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharp.Reflection; -using Crestron.SimplSharpPro.DeviceSupport; +using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Core.Intersystem; using PepperDash.Core.Intersystem.Tokens; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Bridges.JoinMaps; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Devices; using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; -using PepperDash.Essentials.Core.Bridges.JoinMaps; -using Feedback = PepperDash.Essentials.Core.Feedback; using Serilog.Events; -using PepperDash.Essentials.Core.Routing; -using System.Text; +using Feedback = PepperDash.Essentials.Core.Feedback; namespace PepperDash.Essentials.Devices.Common.VideoCodec { + /// + /// Base class for video codec devices + /// public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode { private const int XSigEncoding = 28591; - protected const int MaxParticipants = 50; + + /// + /// Maximum number of participants + /// + protected const int MaxParticipants = 50; private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); - private readonly IHasDirectory _directoryCodec; - private readonly BasicTriList _directoryTrilist; - private readonly VideoCodecControllerJoinMap _directoryJoinmap; - - protected string _timeFormatSpecifier; - protected string _dateFormatSpecifier; + /// + /// Time format specifier + /// + protected string _timeFormatSpecifier; + /// + /// Date format specifier + /// + protected string _dateFormatSpecifier; + /// + /// Initializes a new instance of the class. + /// protected VideoCodecBase(DeviceConfig config) : base(config) { - StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc); - PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); - VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); - MuteFeedback = new BoolFeedback(MuteFeedbackFunc); - SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); - SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc); + StandbyIsOnFeedback = new BoolFeedback("standbyIsOn", StandbyIsOnFeedbackFunc); + PrivacyModeIsOnFeedback = new BoolFeedback("privacyModeIsOn", PrivacyModeIsOnFeedbackFunc); + VolumeLevelFeedback = new IntFeedback("volumeLevel", VolumeLevelFeedbackFunc); + MuteFeedback = new BoolFeedback("mute", MuteFeedbackFunc); + SharingSourceFeedback = new StringFeedback("sharingSource", SharingSourceFeedbackFunc); + SharingContentIsOnFeedback = new BoolFeedback("sharingContentIsOn", SharingContentIsOnFeedbackFunc); - // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set - MeetingsToDisplayFeedback = new IntFeedback(() => MeetingsToDisplay); + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + MeetingsToDisplayFeedback = new IntFeedback("meetingsToDisplay", () => MeetingsToDisplay); InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); @@ -59,115 +70,177 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec ActiveCalls = new List(); } - /// - /// Gets or sets the Communication - /// + /// + /// Gets or sets the Communication + /// public IBasicCommunication Communication { get; protected set; } - /// - /// Gets or sets the OsdSource - /// + /// + /// Gets or sets the OsdSource + /// public DummyRoutingInputsDevice OsdSource { get; protected set; } - /// - /// Gets or sets the StandbyIsOnFeedback - /// + /// + /// Gets or sets the StandbyIsOnFeedback + /// public BoolFeedback StandbyIsOnFeedback { get; private set; } + /// + /// Gets or sets the PrivacyModeIsOnFeedbackFunc + /// protected abstract Func PrivacyModeIsOnFeedbackFunc { get; } + + /// + /// Gets or sets the VolumeLevelFeedbackFunc + /// protected abstract Func VolumeLevelFeedbackFunc { get; } + + /// + /// Gets or sets the MuteFeedbackFunc + /// protected abstract Func MuteFeedbackFunc { get; } + + /// + /// Gets or sets the StandbyIsOnFeedbackFunc + /// protected abstract Func StandbyIsOnFeedbackFunc { get; } + /// + /// Gets or sets the ActiveCalls + /// public List ActiveCalls { get; set; } - /// - /// Gets or sets the ShowSelfViewByDefault - /// + /// + /// Gets or sets the ShowSelfViewByDefault + /// public bool ShowSelfViewByDefault { get; protected set; } - /// - /// Gets or sets the SupportsCameraOff - /// - public bool SupportsCameraOff { get; protected set; } - /// - /// Gets or sets the SupportsCameraAutoMode - /// - public bool SupportsCameraAutoMode { get; protected set; } + /// + /// Gets or sets the SupportsCameraOff + /// + public bool SupportsCameraOff { get; protected set; } + /// + /// Gets or sets the SupportsCameraAutoMode + /// + public bool SupportsCameraAutoMode { get; protected set; } - /// - /// Gets or sets the IsReady - /// + /// + /// Gets or sets the IsReady + /// public bool IsReady { get; protected set; } + /// public virtual List Feedbacks { get { return new List - { - PrivacyModeIsOnFeedback, - SharingSourceFeedback - }; + { + PrivacyModeIsOnFeedback, + SharingSourceFeedback + }; } } + /// + /// Gets or sets the MeetingsToDisplay + /// protected abstract Func SharingSourceFeedbackFunc { get; } + + /// + /// Gets or sets the SharingContentIsOnFeedbackFunc + /// protected abstract Func SharingContentIsOnFeedbackFunc { get; } #region ICodecAudio Members + /// + /// Set Privacy Mode On + /// public abstract void PrivacyModeOn(); + + /// + /// Set Privacy Mode Off + /// public abstract void PrivacyModeOff(); + + /// + /// Toggles the Privacy Mode + /// public abstract void PrivacyModeToggle(); - /// - /// Gets or sets the PrivacyModeIsOnFeedback - /// + + /// + /// Gets or sets the PrivacyModeIsOnFeedback + /// public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } - - /// - /// Gets or sets the MuteFeedback - /// + /// + /// Gets or sets the MuteFeedback + /// public BoolFeedback MuteFeedback { get; private set; } + /// + /// Sets the Mute state to Off + /// public abstract void MuteOff(); + /// + /// Sets the Mute state to On + /// public abstract void MuteOn(); + /// + /// Sets the Volume level + /// public abstract void SetVolume(ushort level); - /// - /// Gets or sets the VolumeLevelFeedback - /// + /// + /// Gets or sets the VolumeLevelFeedback + /// public IntFeedback VolumeLevelFeedback { get; private set; } + /// + /// Toggles the Mute state + /// public abstract void MuteToggle(); + /// + /// Decreases the Volume level + /// public abstract void VolumeDown(bool pressRelease); - + /// + /// Increases the Volume level + /// public abstract void VolumeUp(bool pressRelease); #endregion #region IHasContentSharing Members + /// + /// Starts content sharing + /// public abstract void StartSharing(); + + /// + /// Stops content sharing + /// public abstract void StopSharing(); - /// - /// Gets or sets the AutoShareContentWhileInCall - /// + /// + /// Gets or sets the AutoShareContentWhileInCall + /// public bool AutoShareContentWhileInCall { get; protected set; } - /// - /// Gets or sets the SharingSourceFeedback - /// + /// + /// Gets or sets the SharingSourceFeedback + /// public StringFeedback SharingSourceFeedback { get; private set; } - /// - /// Gets or sets the SharingContentIsOnFeedback - /// + + /// + /// Gets or sets the SharingContentIsOnFeedback + /// public BoolFeedback SharingContentIsOnFeedback { get; private set; } #endregion @@ -191,60 +264,95 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } } + /// + /// Dials the specified number + /// public abstract void Dial(string number); + + /// + /// Ends the specified call + /// public abstract void EndCall(CodecActiveCallItem call); + + /// + /// Ends all active calls + /// public abstract void EndAllCalls(); + + /// + /// Accepts the specified call + /// public abstract void AcceptCall(CodecActiveCallItem call); + + /// + /// Rejects the specified call + /// public abstract void RejectCall(CodecActiveCallItem call); + + /// + /// Sends DTMF tones + /// public abstract void SendDtmf(string s); - /// - /// SendDtmf method - /// - /// - public virtual void SendDtmf(string s, CodecActiveCallItem call) { } + + /// + /// SendDtmf method + /// + public virtual void SendDtmf(string s, CodecActiveCallItem call) { } #endregion #region IRoutingInputsOutputs Members - /// - /// Gets or sets the InputPorts - /// + /// + /// Gets or sets the InputPorts + /// public RoutingPortCollection InputPorts { get; private set; } - /// - /// Gets or sets the OutputPorts - /// + /// + /// Gets or sets the OutputPorts + /// public RoutingPortCollection OutputPorts { get; private set; } #endregion #region IUsageTracking Members - /// - /// Gets or sets the UsageTracker - /// + /// + /// Gets or sets the UsageTracker + /// public UsageTracking UsageTracker { get; set; } #endregion #region iVideoCodecInfo Members + /// + /// Gets the CodecInfo + /// public VideoCodecInfo CodecInfo { get; protected set; } #endregion + /// + /// Fired when the Codec is ready to be used + /// public event EventHandler IsReadyChange; + + /// + /// Dials the specified meeting + /// + /// public abstract void Dial(Meeting meeting); - /// - /// Dial method - /// - /// + /// + /// Dial a contact + /// + /// The contact to dial public virtual void Dial(IInvitableContact contact) { } + /// public abstract void ExecuteSwitch(object selector); /// @@ -258,16 +366,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } /// - /// - /// - /// - /// + /// Sets the previous and new status for the call + /// /// protected virtual void OnCallStatusChange(CodecActiveCallItem item) { - CallStatusChange?.Invoke(this, new CodecCallStatusItemChangeEventArgs(item)); + CallStatusChange?.Invoke(this, new CodecCallStatusItemChangeEventArgs(item)); - PrivacyModeIsOnFeedback.FireUpdate(); + PrivacyModeIsOnFeedback.FireUpdate(); if (AutoShareContentWhileInCall) { @@ -297,8 +403,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec try { IsReady = true; - IsReadyChange?.Invoke(this, new EventArgs()); - } + IsReadyChange?.Invoke(this, new EventArgs()); + } catch (Exception e) { Debug.LogMessage(LogEventLevel.Verbose, this, "Error in SetIsReady() : {0}", e); @@ -307,13 +413,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } // **** DEBUGGING THINGS **** - /// - /// ListCalls method - /// - /// + /// + /// ListCalls method + /// public virtual void ListCalls() { - Debug.LogMessage(LogEventLevel.Debug, this, "Active Calls:"); + Debug.LogMessage(LogEventLevel.Debug, this, "Active Calls:"); var sb = new StringBuilder(); foreach (var c in ActiveCalls) @@ -323,22 +428,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.LogMessage(LogEventLevel.Debug, this, "\n{0}\n", sb.ToString()); } + /// + /// Activate standby + /// public abstract void StandbyActivate(); + /// + /// Deactivate standby + /// public abstract void StandbyDeactivate(); #region Implementation of IBridgeAdvanced + /// public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); /// /// Use this method when using a plain VideoCodecControllerJoinMap /// - /// - /// - /// - /// - /// + /// codec to link + /// trilist to link + /// join to start with + /// key for custom join maps + /// bridge controller protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { @@ -355,18 +467,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec LinkVideoCodecToApi(codec, trilist, joinMap); - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; - }; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + }; } /// /// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap /// - /// - /// - /// + /// codec to link + /// trilist to link + /// join map to use protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); @@ -381,16 +493,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec LinkVideoCodecVolumeToApi(trilist, joinMap); - LinkVideoCodecInfoToApi(trilist, joinMap); + LinkVideoCodecInfoToApi(trilist, joinMap); - // Register for this event to link any functions that require the codec to be ready first - codec.IsReadyChange += (o, a) => - { - if (codec is IHasCodecCameras) - { - LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); - } - }; + // Register for this event to link any functions that require the codec to be ready first + codec.IsReadyChange += (o, a) => + { + if (codec is IHasCodecCameras) + { + LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); + } + }; if (codec is ICommunicationMonitor) { @@ -451,10 +563,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); } - if (codec is IHasCallHistory) - { - LinkVideoCodecCallHistoryToApi(codec as IHasCallHistory, trilist, joinMap); - } + if (codec is IHasCallHistory) + { + LinkVideoCodecCallHistoryToApi(codec as IHasCallHistory, trilist, joinMap); + } trilist.OnlineStatusChange += (device, args) => { @@ -502,39 +614,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); } - if (codec is IHasCallHistory) - { - UpdateCallHistory((codec as IHasCallHistory), trilist, joinMap); - } + if (codec is IHasCallHistory) + { + UpdateCallHistory((codec as IHasCallHistory), trilist, joinMap); + } SharingContentIsOnFeedback.FireUpdate(); }; } - private void LinkVideoCodecInfoToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetBool(joinMap.MultiSiteOptionIsEnabled.JoinNumber, this.CodecInfo.MultiSiteOptionIsEnabled); - trilist.SetBool(joinMap.AutoAnswerEnabled.JoinNumber, this.CodecInfo.AutoAnswerEnabled); - trilist.SetString(joinMap.DeviceIpAddresss.JoinNumber, this.CodecInfo.IpAddress); - trilist.SetString(joinMap.SipPhoneNumber.JoinNumber, this.CodecInfo.SipPhoneNumber); - trilist.SetString(joinMap.E164Alias.JoinNumber, this.CodecInfo.E164Alias); - trilist.SetString(joinMap.H323Id.JoinNumber, this.CodecInfo.H323Id); - trilist.SetString(joinMap.SipUri.JoinNumber, this.CodecInfo.SipUri); + private void LinkVideoCodecInfoToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetBool(joinMap.MultiSiteOptionIsEnabled.JoinNumber, this.CodecInfo.MultiSiteOptionIsEnabled); + trilist.SetBool(joinMap.AutoAnswerEnabled.JoinNumber, this.CodecInfo.AutoAnswerEnabled); + trilist.SetString(joinMap.DeviceIpAddresss.JoinNumber, this.CodecInfo.IpAddress); + trilist.SetString(joinMap.SipPhoneNumber.JoinNumber, this.CodecInfo.SipPhoneNumber); + trilist.SetString(joinMap.E164Alias.JoinNumber, this.CodecInfo.E164Alias); + trilist.SetString(joinMap.H323Id.JoinNumber, this.CodecInfo.H323Id); + trilist.SetString(joinMap.SipUri.JoinNumber, this.CodecInfo.SipUri); - trilist.OnlineStatusChange += (o, a) => - { - if (a.DeviceOnLine) - { - trilist.SetBool(joinMap.MultiSiteOptionIsEnabled.JoinNumber, this.CodecInfo.MultiSiteOptionIsEnabled); - trilist.SetBool(joinMap.AutoAnswerEnabled.JoinNumber, this.CodecInfo.AutoAnswerEnabled); - trilist.SetString(joinMap.DeviceIpAddresss.JoinNumber, this.CodecInfo.IpAddress); - trilist.SetString(joinMap.SipPhoneNumber.JoinNumber, this.CodecInfo.SipPhoneNumber); - trilist.SetString(joinMap.E164Alias.JoinNumber, this.CodecInfo.E164Alias); - trilist.SetString(joinMap.H323Id.JoinNumber, this.CodecInfo.H323Id); - trilist.SetString(joinMap.SipUri.JoinNumber, this.CodecInfo.SipUri); - } - }; - } + trilist.OnlineStatusChange += (o, a) => + { + if (a.DeviceOnLine) + { + trilist.SetBool(joinMap.MultiSiteOptionIsEnabled.JoinNumber, this.CodecInfo.MultiSiteOptionIsEnabled); + trilist.SetBool(joinMap.AutoAnswerEnabled.JoinNumber, this.CodecInfo.AutoAnswerEnabled); + trilist.SetString(joinMap.DeviceIpAddresss.JoinNumber, this.CodecInfo.IpAddress); + trilist.SetString(joinMap.SipPhoneNumber.JoinNumber, this.CodecInfo.SipPhoneNumber); + trilist.SetString(joinMap.E164Alias.JoinNumber, this.CodecInfo.E164Alias); + trilist.SetString(joinMap.H323Id.JoinNumber, this.CodecInfo.H323Id); + trilist.SetString(joinMap.SipUri.JoinNumber, this.CodecInfo.SipUri); + } + }; + } private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { @@ -570,9 +682,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - if (!(codec is IHasCameraAutoMode autoCodec)) return; + if (!(codec is IHasCameraAutoMode autoCodec)) return; - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue); trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue); }; @@ -587,9 +699,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - if (!(codec is IHasCameraAutoMode autoModeCodec)) return; + if (!(codec is IHasCameraAutoMode autoModeCodec)) return; - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); } @@ -628,35 +740,35 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { - // make sure to update the values when the EISC comes online - trilist.OnlineStatusChange += (sender, args) => - { - if (sender.IsOnline) - { - UpdateParticipantsXSig(codec, trilist, joinMap); - } - }; + // make sure to update the values when the EISC comes online + trilist.OnlineStatusChange += (sender, args) => + { + if (sender.IsOnline) + { + UpdateParticipantsXSig(codec, trilist, joinMap); + } + }; - // set actions and update the values when the list changes + // set actions and update the values when the list changes codec.Participants.ParticipantsListHasChanged += (sender, args) => { - SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants); + SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants); - UpdateParticipantsXSig(codec, trilist, joinMap); + UpdateParticipantsXSig(codec, trilist, joinMap); }; - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; - // TODO [ ] Issue #868 - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, "\xFC"); - UpdateParticipantsXSig(codec, trilist, joinMap); - }; + // TODO [ ] Issue #868 + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, "\xFC"); + UpdateParticipantsXSig(codec, trilist, joinMap); + }; } - private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { + private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { string participantsXSig; if (codec.Participants.CurrentParticipants.Count == 0) @@ -672,48 +784,48 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); - } + } - /// - /// Sets the actions for each participant in the list - /// - private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List currentParticipants) - { - uint index = 0; // track the index of the participant in the + /// + /// Sets the actions for each participant in the list + /// + private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List currentParticipants) + { + uint index = 0; // track the index of the participant in the - foreach (var participant in currentParticipants) - { - var p = participant; - if (index > MaxParticipants) break; + foreach (var participant in currentParticipants) + { + var p = participant; + if (index > MaxParticipants) break; - if (this is IHasParticipantAudioMute audioMuteCodec) - { - trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index, - () => audioMuteCodec.ToggleAudioForParticipant(p.UserId)); + if (this is IHasParticipantAudioMute audioMuteCodec) + { + trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index, + () => audioMuteCodec.ToggleAudioForParticipant(p.UserId)); - trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index, - () => audioMuteCodec.ToggleVideoForParticipant(p.UserId)); - } + trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index, + () => audioMuteCodec.ToggleVideoForParticipant(p.UserId)); + } - if (this is IHasParticipantPinUnpin pinCodec) - { - trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index, - () => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo)); - } + if (this is IHasParticipantPinUnpin pinCodec) + { + trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index, + () => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo)); + } - index++; - } + index++; + } - // Clear out any previously set actions - while (index < MaxParticipants) - { - trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index); - trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index); - trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index); + // Clear out any previously set actions + while (index < MaxParticipants) + { + trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index); + trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index); + trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index); - index++; - } - } + index++; + } + } private string UpdateParticipantsXSig(List currentParticipants) { @@ -733,37 +845,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (meetingIndex >= maxParticipants * offset) break; - // Debug.LogMessage(LogEventLevel.Verbose, this, - //@"Updating Participant on xsig: - //Name: {0} (s{9}) - //AudioMute: {1} (d{10}) - //VideoMute: {2} (d{11}) - //CanMuteVideo: {3} (d{12}) - //CanUMuteVideo: {4} (d{13}) - //IsHost: {5} (d{14}) - //HandIsRaised: {6} (d{15}) - //IsPinned: {7} (d{16}) - //ScreenIndexIsPinnedTo: {8} (a{17}) - //", - // participant.Name, - // participant.AudioMuteFb, - // participant.VideoMuteFb, - // participant.CanMuteVideo, - // participant.CanUnmuteVideo, - // participant.IsHost, - // participant.HandIsRaisedFb, - // participant.IsPinnedFb, - // participant.ScreenIndexIsPinnedToFb, - // stringIndex + 1, - // digitalIndex + 1, - // digitalIndex + 2, - // digitalIndex + 3, - // digitalIndex + 4, - // digitalIndex + 5, - // digitalIndex + 6, - // digitalIndex + 7, - // analogIndex + 1 - // ); + // Debug.LogMessage(LogEventLevel.Verbose, this, + //@"Updating Participant on xsig: + //Name: {0} (s{9}) + //AudioMute: {1} (d{10}) + //VideoMute: {2} (d{11}) + //CanMuteVideo: {3} (d{12}) + //CanUMuteVideo: {4} (d{13}) + //IsHost: {5} (d{14}) + //HandIsRaised: {6} (d{15}) + //IsPinned: {7} (d{16}) + //ScreenIndexIsPinnedTo: {8} (a{17}) + //", + // participant.Name, + // participant.AudioMuteFb, + // participant.VideoMuteFb, + // participant.CanMuteVideo, + // participant.CanUnmuteVideo, + // participant.IsHost, + // participant.HandIsRaisedFb, + // participant.IsPinnedFb, + // participant.ScreenIndexIsPinnedToFb, + // stringIndex + 1, + // digitalIndex + 1, + // digitalIndex + 2, + // digitalIndex + 3, + // digitalIndex + 4, + // digitalIndex + 5, + // digitalIndex + 6, + // digitalIndex + 7, + // analogIndex + 1 + // ); //digitals @@ -772,10 +884,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); - tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); - tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb); + tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); + tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb); - Debug.LogMessage(LogEventLevel.Verbose, this, "Index: {0} byte value: {1}", digitalIndex + 7, ComTextHelper.GetEscapedText(tokenArray[digitalIndex + 6].GetBytes())); + Debug.LogMessage(LogEventLevel.Verbose, this, "Index: {0} byte value: {1}", digitalIndex + 7, ComTextHelper.GetEscapedText(tokenArray[digitalIndex + 6].GetBytes())); //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); @@ -812,12 +924,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec analogIndex += maxAnalogs; } - var returnString = GetXSigString(tokenArray); + var returnString = GetXSigString(tokenArray); - //Debug.LogMessage(LogEventLevel.Verbose, this, "{0}", ComTextHelper.GetEscapedText(Encoding.GetEncoding(28591).GetBytes(returnString))); + //Debug.LogMessage(LogEventLevel.Verbose, this, "{0}", ComTextHelper.GetEscapedText(Encoding.GetEncoding(28591).GetBytes(returnString))); - return returnString; + return returnString; } private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) @@ -833,7 +945,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, b => AutoShareContentWhileInCall = b); } - private List _currentMeetings = new List(); + private List _currentMeetings = new List(); private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { @@ -841,25 +953,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) => { - codec.CodecSchedule.MeetingWarningMinutes = i; + codec.CodecSchedule.MeetingWarningMinutes = i; }); - for (uint i = 0; i < joinMap.DialMeetingStart.JoinSpan; i++) - { - Debug.LogMessage(LogEventLevel.Debug, this, "Setting action to Dial Meeting {0} to digital join {1}", i + 1, joinMap.DialMeetingStart.JoinNumber + i); - var joinNumber = joinMap.DialMeetingStart.JoinNumber + i; - var mtg = i + 1; - var index = (int)i; + for (uint i = 0; i < joinMap.DialMeetingStart.JoinSpan; i++) + { + Debug.LogMessage(LogEventLevel.Debug, this, "Setting action to Dial Meeting {0} to digital join {1}", i + 1, joinMap.DialMeetingStart.JoinNumber + i); + var joinNumber = joinMap.DialMeetingStart.JoinNumber + i; + var mtg = i + 1; + var index = (int)i; - trilist.SetSigFalseAction(joinNumber, () => - { - Debug.LogMessage(LogEventLevel.Debug, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", - mtg, joinMap.DialMeetingStart.JoinNumber + i, index, _currentMeetings[index].Id, _currentMeetings[index].Title); - if (_currentMeetings[index] != null) - Dial(_currentMeetings[index]); - }); - } + trilist.SetSigFalseAction(joinNumber, () => + { + Debug.LogMessage(LogEventLevel.Debug, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeetingStart.JoinNumber + i, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + } codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap); codec.CodecSchedule.MeetingEventChange += (sender, args) => @@ -870,20 +982,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } }; - trilist.SetUShortSigAction(joinMap.MeetingsToDisplay.JoinNumber, m => MeetingsToDisplay = m); - MeetingsToDisplayFeedback.LinkInputSig(trilist.UShortInput[joinMap.MeetingsToDisplay.JoinNumber]); + trilist.SetUShortSigAction(joinMap.MeetingsToDisplay.JoinNumber, m => MeetingsToDisplay = m); + MeetingsToDisplayFeedback.LinkInputSig(trilist.UShortInput[joinMap.MeetingsToDisplay.JoinNumber]); - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; - // TODO [ ] Issue #868 - trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); - UpdateMeetingsList(codec, trilist, joinMap); - // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set - MeetingsToDisplayFeedback.LinkInputSig(trilist.UShortInput[joinMap.MeetingsToDisplay.JoinNumber]); - }; - } + // TODO [ ] Issue #868 + trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); + UpdateMeetingsList(codec, trilist, joinMap); + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + MeetingsToDisplayFeedback.LinkInputSig(trilist.UShortInput[joinMap.MeetingsToDisplay.JoinNumber]); + }; + } private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { @@ -891,175 +1003,178 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); - if (_currentMeetings.Count == 0) - { - var emptyXSigByteArray = XSigHelpers.ClearOutputs(); - var emptyXSigString = Encoding.GetEncoding(XSigEncoding) - .GetString(emptyXSigByteArray, 0, emptyXSigByteArray.Length); + if (_currentMeetings.Count == 0) + { + var emptyXSigByteArray = XSigHelpers.ClearOutputs(); + var emptyXSigString = Encoding.GetEncoding(XSigEncoding) + .GetString(emptyXSigByteArray, 0, emptyXSigByteArray.Length); - trilist.SetString(joinMap.Schedule.JoinNumber, emptyXSigString); - return; - } + trilist.SetString(joinMap.Schedule.JoinNumber, emptyXSigString); + return; + } var meetingsData = UpdateMeetingsListXSig(_currentMeetings); trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; - // TODO [ ] Issue #868 - trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); - UpdateMeetingsListXSig(_currentMeetings); - }; + // TODO [ ] Issue #868 + trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); + UpdateMeetingsListXSig(_currentMeetings); + }; } - // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set - private int _meetingsToDisplay = 3; - // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set - protected int MeetingsToDisplay - { - get { return _meetingsToDisplay; } - set { - _meetingsToDisplay = (ushort) (value == 0 ? 3 : value); - MeetingsToDisplayFeedback.FireUpdate(); - } - } - // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set - /// - /// Gets or sets the MeetingsToDisplayFeedback - /// - public IntFeedback MeetingsToDisplayFeedback { get; set; } + private int _meetingsToDisplay = 3; - private string UpdateMeetingsListXSig(List meetings) - { - // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set - //const int _meetingsToDisplay = 3; - const int maxDigitals = 2; - const int maxStrings = 7; - const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings * _meetingsToDisplay; //15 - var stringIndex = 0; - var meetingIndex = 0; + /// + /// Gets or sets the number of meetings to display on the XSIG + /// + protected int MeetingsToDisplay + { + get { return _meetingsToDisplay; } + set + { + _meetingsToDisplay = (ushort)(value == 0 ? 3 : value); + MeetingsToDisplayFeedback.FireUpdate(); + } + } - var tokenArray = new XSigToken[_meetingsToDisplay * offset]; - /* - * Digitals - * IsJoinable - 1 - * IsDialable - 2 - * - * Serials - * Organizer - 1 - * Title - 2 - * Start Date - 3 - * Start Time - 4 - * End Date - 5 - * End Time - 6 - * Id - 7 - */ - + /// + /// Gets or sets the MeetingsToDisplayFeedback + /// + public IntFeedback MeetingsToDisplayFeedback { get; set; } - foreach (var meeting in meetings) - { - var currentTime = DateTime.Now; + private string UpdateMeetingsListXSig(List meetings) + { + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + //const int _meetingsToDisplay = 3; + const int maxDigitals = 2; + const int maxStrings = 7; + const int offset = maxDigitals + maxStrings; + var digitalIndex = maxStrings * _meetingsToDisplay; //15 + var stringIndex = 0; + var meetingIndex = 0; - if (meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; + var tokenArray = new XSigToken[_meetingsToDisplay * offset]; + /* + * Digitals + * IsJoinable - 1 + * IsDialable - 2 + * + * Serials + * Organizer - 1 + * Title - 2 + * Start Date - 3 + * Start Time - 4 + * End Date - 5 + * End Time - 6 + * Id - 7 + */ - if (meetingIndex >= _meetingsToDisplay * offset) - { - Debug.LogMessage(LogEventLevel.Verbose, this, "Max Meetings reached"); - break; - } - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Dialable); + foreach (var meeting in meetings) + { + var currentTime = DateTime.Now; - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToString(_dateFormatSpecifier.NullIfEmpty() ?? "d", Global.Culture)); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToString(_timeFormatSpecifier.NullIfEmpty() ?? "t", Global.Culture)); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToString(_dateFormatSpecifier.NullIfEmpty() ?? "d", Global.Culture)); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToString(_timeFormatSpecifier.NullIfEmpty() ?? "t", Global.Culture)); - tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); + if (meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } + if (meetingIndex >= _meetingsToDisplay * offset) + { + Debug.LogMessage(LogEventLevel.Verbose, this, "Max Meetings reached"); + break; + } - while (meetingIndex < _meetingsToDisplay * offset) - { - Debug.LogMessage(LogEventLevel.Verbose, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", - meetingIndex, _meetingsToDisplay * offset); + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Dialable); - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToString(_dateFormatSpecifier.NullIfEmpty() ?? "d", Global.Culture)); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToString(_timeFormatSpecifier.NullIfEmpty() ?? "t", Global.Culture)); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToString(_dateFormatSpecifier.NullIfEmpty() ?? "d", Global.Culture)); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToString(_timeFormatSpecifier.NullIfEmpty() ?? "t", Global.Culture)); + tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); - tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty); + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } + while (meetingIndex < _meetingsToDisplay * offset) + { + Debug.LogMessage(LogEventLevel.Verbose, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", + meetingIndex, _meetingsToDisplay * offset); - return GetXSigString(tokenArray); - } + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); + tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + return GetXSigString(tokenArray); + } private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig( - trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]); + trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]); trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory); trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i, trilist, joinMap)); - //Special Change for protected directory clear + //Special Change for protected directory clear - trilist.SetBoolSigAction(joinMap.DirectoryClearSelected.JoinNumber, (b) => SelectDirectoryEntry(_directoryCodec, 0, _directoryTrilist, _directoryJoinmap)); + trilist.SetBoolSigAction(joinMap.DirectoryClearSelected.JoinNumber, (b) => SelectDirectoryEntry(codec, 0, trilist, joinMap)); - // Report feedback for number of contact methods for selected contact + // Report feedback for number of contact methods for selected contact trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents); - if (codec.DirectoryRoot != null) - { - var contactsCount = codec.DirectoryRoot.CurrentDirectoryResults.Where(c => c.ParentFolderId.Equals("root")).ToList().Count; - trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)contactsCount); + if (codec.DirectoryRoot != null) + { + var contactsCount = codec.DirectoryRoot.CurrentDirectoryResults.Where(c => c.ParentFolderId.Equals("root")).ToList().Count; + trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)contactsCount); Debug.LogMessage(LogEventLevel.Verbose, this, ">>> contactsCount: {0}", contactsCount); - var clearBytes = XSigHelpers.ClearOutputs(); + var clearBytes = XSigHelpers.ClearOutputs(); - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, - Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); - var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, - codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, + Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); + var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, + codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); - Debug.LogMessage(LogEventLevel.Verbose, this, "Directory XSig Length: {0}", directoryXSig.Length); + Debug.LogMessage(LogEventLevel.Verbose, this, "Directory XSig Length: {0}", directoryXSig.Length); - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); - } + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); + } codec.DirectoryResultReturned += (sender, args) => { var isRoot = codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false; - var argsCount = isRoot + var argsCount = isRoot ? args.Directory.CurrentDirectoryResults.Where(a => a.ParentFolderId.Equals("root")).ToList().Count : args.Directory.CurrentDirectoryResults.Count; @@ -1070,159 +1185,159 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetString(joinMap.DirectoryEntries.JoinNumber, Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); - var directoryXSig = UpdateDirectoryXSig(args.Directory, - codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); - Debug.LogMessage(LogEventLevel.Verbose, this, "Directory XSig Length: {0}", directoryXSig.Length); + var directoryXSig = UpdateDirectoryXSig(args.Directory, + codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); + Debug.LogMessage(LogEventLevel.Verbose, this, "Directory XSig Length: {0}", directoryXSig.Length); trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); }; - - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; - var clearBytes = XSigHelpers.ClearOutputs(); - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, - Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); - var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); - }; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + var clearBytes = XSigHelpers.ClearOutputs(); + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, + Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); + var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); + }; } private void SelectDirectoryEntry(IHasDirectory codec, ushort i, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { - if (i > codec.CurrentDirectoryResult.CurrentDirectoryResults.Count) return; - _selectedDirectoryItem = i == 0 ? null : codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1]; - trilist.SetUshort(joinMap.DirectorySelectRowFeedback.JoinNumber, i); + if (i > codec.CurrentDirectoryResult.CurrentDirectoryResults.Count) return; + _selectedDirectoryItem = i == 0 ? null : codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1]; + trilist.SetUshort(joinMap.DirectorySelectRowFeedback.JoinNumber, i); - if (_selectedDirectoryItem == null) trilist.SetBool(joinMap.DirectoryEntryIsContact.JoinNumber, false); + if (_selectedDirectoryItem == null) trilist.SetBool(joinMap.DirectoryEntryIsContact.JoinNumber, false); if (_selectedDirectoryItem is DirectoryFolder) { codec.GetDirectoryFolderContents(_selectedDirectoryItem.FolderId); - trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, 0); - trilist.SetString(joinMap.DirectorySelectedFolderName.JoinNumber, _selectedDirectoryItem.Name); - trilist.SetString(joinMap.DirectoryEntrySelectedName.JoinNumber, string.Empty); - trilist.ClearUShortSigAction(joinMap.SelectContactMethod.JoinNumber); - trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedLine.JoinNumber); - trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedContactMethod.JoinNumber); - trilist.SetBool(joinMap.DirectoryEntryIsContact.JoinNumber, false); - return; + trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, 0); + trilist.SetString(joinMap.DirectorySelectedFolderName.JoinNumber, _selectedDirectoryItem.Name); + trilist.SetString(joinMap.DirectoryEntrySelectedName.JoinNumber, string.Empty); + trilist.ClearUShortSigAction(joinMap.SelectContactMethod.JoinNumber); + trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedLine.JoinNumber); + trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedContactMethod.JoinNumber); + trilist.SetBool(joinMap.DirectoryEntryIsContact.JoinNumber, false); + return; } - // not a folder. Clear this value - trilist.SetString(joinMap.DirectorySelectedFolderName.JoinNumber, string.Empty); + // not a folder. Clear this value + trilist.SetString(joinMap.DirectorySelectedFolderName.JoinNumber, string.Empty); - var selectedContact = _selectedDirectoryItem as DirectoryContact; + var selectedContact = _selectedDirectoryItem as DirectoryContact; - if (selectedContact != null && selectedContact.ContactMethods.Count >= 1) - { - trilist.SetBool(joinMap.DirectoryEntryIsContact.JoinNumber, true); - } + if (selectedContact != null && selectedContact.ContactMethods.Count >= 1) + { + trilist.SetBool(joinMap.DirectoryEntryIsContact.JoinNumber, true); + } - trilist.SetString(joinMap.DirectoryEntrySelectedName.JoinNumber, - selectedContact != null ? selectedContact.Name : string.Empty); + trilist.SetString(joinMap.DirectoryEntrySelectedName.JoinNumber, + selectedContact != null ? selectedContact.Name : string.Empty); - // Allow auto dial of selected line. Always dials first contact method - if (!trilist.GetBool(joinMap.DirectoryDisableAutoDialSelectedLine.JoinNumber)) - { - if (_selectedDirectoryItem is IInvitableContact invitableEntry) - { - Dial(invitableEntry); - return; - } + // Allow auto dial of selected line. Always dials first contact method + if (!trilist.GetBool(joinMap.DirectoryDisableAutoDialSelectedLine.JoinNumber)) + { + if (_selectedDirectoryItem is IInvitableContact invitableEntry) + { + Dial(invitableEntry); + return; + } - trilist.SetString(joinMap.DirectoryEntrySelectedNumber.JoinNumber, - selectedContact != null ? selectedContact.ContactMethods[0].Number : string.Empty); + trilist.SetString(joinMap.DirectoryEntrySelectedNumber.JoinNumber, + selectedContact != null ? selectedContact.ContactMethods[0].Number : string.Empty); - if (!(_selectedDirectoryItem is DirectoryContact entryToDial)) return; + if (!(_selectedDirectoryItem is DirectoryContact entryToDial)) return; - Dial(entryToDial.ContactMethods[0].Number); - } - else - { - // If auto dial is disabled... + Dial(entryToDial.ContactMethods[0].Number); + } + else + { + // If auto dial is disabled... - if (!(_selectedDirectoryItem is DirectoryContact entryToDial)) - { - // Clear out values and actions from last selected item - trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, 0); - trilist.SetString(joinMap.DirectoryEntrySelectedName.JoinNumber, string.Empty); - trilist.ClearUShortSigAction(joinMap.SelectContactMethod.JoinNumber); - trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedLine.JoinNumber); - trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedContactMethod.JoinNumber); - return; - } + if (!(_selectedDirectoryItem is DirectoryContact entryToDial)) + { + // Clear out values and actions from last selected item + trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, 0); + trilist.SetString(joinMap.DirectoryEntrySelectedName.JoinNumber, string.Empty); + trilist.ClearUShortSigAction(joinMap.SelectContactMethod.JoinNumber); + trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedLine.JoinNumber); + trilist.ClearBoolSigAction(joinMap.DirectoryDialSelectedContactMethod.JoinNumber); + return; + } - trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, (ushort)entryToDial.ContactMethods.Count); + trilist.SetUshort(joinMap.SelectedContactMethodCount.JoinNumber, (ushort)entryToDial.ContactMethods.Count); - // Update the action to dial the selected contact method - trilist.SetUShortSigAction(joinMap.SelectContactMethod.JoinNumber, (u) => - { - if (u < 1 || u > entryToDial.ContactMethods.Count) return; + // Update the action to dial the selected contact method + trilist.SetUShortSigAction(joinMap.SelectContactMethod.JoinNumber, (u) => + { + if (u < 1 || u > entryToDial.ContactMethods.Count) return; - trilist.SetSigFalseAction(joinMap.DirectoryDialSelectedContactMethod.JoinNumber, () => Dial(entryToDial.ContactMethods[u - 1].Number)); - }); + trilist.SetSigFalseAction(joinMap.DirectoryDialSelectedContactMethod.JoinNumber, () => Dial(entryToDial.ContactMethods[u - 1].Number)); + }); - // Sets DirectoryDialSelectedLine join action to dial first contact method - trilist.SetSigFalseAction(joinMap.DirectoryDialSelectedLine.JoinNumber, () => Dial(entryToDial.ContactMethods[0].Number)); + // Sets DirectoryDialSelectedLine join action to dial first contact method + trilist.SetSigFalseAction(joinMap.DirectoryDialSelectedLine.JoinNumber, () => Dial(entryToDial.ContactMethods[0].Number)); - var clearBytes = XSigHelpers.ClearOutputs(); + var clearBytes = XSigHelpers.ClearOutputs(); - trilist.SetString(joinMap.ContactMethods.JoinNumber, - Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); - var contactMethodsXSig = UpdateContactMethodsXSig(entryToDial); + trilist.SetString(joinMap.ContactMethods.JoinNumber, + Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); + var contactMethodsXSig = UpdateContactMethodsXSig(entryToDial); - trilist.SetString(joinMap.ContactMethods.JoinNumber, contactMethodsXSig); - } + trilist.SetString(joinMap.ContactMethods.JoinNumber, contactMethodsXSig); + } } - /// - /// Generates the XSig data representing the available contact methods for the selected DirectoryContact - /// - /// - /// - private string UpdateContactMethodsXSig(DirectoryContact contact) - { - const int maxMethods = 10; - const int maxStrings = 3; - const int offset = maxStrings; - var stringIndex = 0; - var arrayIndex = 0; - // Create a new token array and set the size to the number of methods times the total number of signals - var tokenArray = new XSigToken[maxMethods * offset]; + /// + /// Generates the XSig data representing the available contact methods for the selected DirectoryContact + /// + /// + /// + private string UpdateContactMethodsXSig(DirectoryContact contact) + { + const int maxMethods = 10; + const int maxStrings = 3; + const int offset = maxStrings; + var stringIndex = 0; + var arrayIndex = 0; + // Create a new token array and set the size to the number of methods times the total number of signals + var tokenArray = new XSigToken[maxMethods * offset]; - Debug.LogMessage(LogEventLevel.Verbose, this, "Creating XSIG token array with size {0}", maxMethods * offset); + Debug.LogMessage(LogEventLevel.Verbose, this, "Creating XSIG token array with size {0}", maxMethods * offset); - // TODO: Add code to generate XSig data - foreach (var method in contact.ContactMethods) - { - if (arrayIndex >= maxMethods * offset) - break; + // TODO: Add code to generate XSig data + foreach (var method in contact.ContactMethods) + { + if (arrayIndex >= maxMethods * offset) + break; - //serials - tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, method.Number); - tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, method.ContactMethodId.ToString()); - tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, method.Device.ToString()); + //serials + tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, method.Number); + tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, method.ContactMethodId.ToString()); + tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, method.Device.ToString()); arrayIndex += offset; stringIndex += maxStrings; - } + } - while (arrayIndex < maxMethods) - { - tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty); + while (arrayIndex < maxMethods) + { + tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty); arrayIndex += offset; stringIndex += maxStrings; - } + } - return GetXSigString(tokenArray); - } + return GetXSigString(tokenArray); + } private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot) { @@ -1267,7 +1382,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec return GetXSigString(tokenArray); } - private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber, () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue)); @@ -1275,31 +1390,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //End All calls trilist.SetSigFalseAction(joinMap.EndAllCalls.JoinNumber, EndAllCalls); - //End a specific call, specified by index. Maximum 8 calls supported - for (int i = 0; i < joinMap.EndCallStart.JoinSpan; i++) - { - var callIndex = i; + //End a specific call, specified by index. Maximum 8 calls supported + for (int i = 0; i < joinMap.EndCallStart.JoinSpan; i++) + { + var callIndex = i; - trilist.SetSigFalseAction((uint)(joinMap.EndCallStart.JoinNumber + i), () => - { + trilist.SetSigFalseAction((uint)(joinMap.EndCallStart.JoinNumber + i), () => + { - if (callIndex < 0 || callIndex >= ActiveCalls.Count) - { - Debug.LogMessage(LogEventLevel.Verbose, this, "Cannot end call. No call found at index: {0}", callIndex); - return; - } + if (callIndex < 0 || callIndex >= ActiveCalls.Count) + { + Debug.LogMessage(LogEventLevel.Verbose, this, "Cannot end call. No call found at index: {0}", callIndex); + return; + } - var call = ActiveCalls[callIndex]; - if (call != null) - { - EndCall(call); - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "[End Call] Unable to find call at index '{0}'", i); - } - }); - } + var call = ActiveCalls[callIndex]; + if (call != null) + { + EndCall(call); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "[End Call] Unable to find call at index '{0}'", i); + } + }); + } trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); @@ -1311,18 +1426,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.LogMessage(LogEventLevel.Debug, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing); - if (args.CallItem.Direction == eCodecCallDirection.Incoming) - { - trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem)); - trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem)); - trilist.SetString(joinMap.IncomingCallName.JoinNumber, args.CallItem.Name); - trilist.SetString(joinMap.IncomingCallNumber.JoinNumber, args.CallItem.Number); - } - else - { - trilist.SetString(joinMap.IncomingCallName.JoinNumber, string.Empty); - trilist.SetString(joinMap.IncomingCallNumber.JoinNumber, string.Empty); - } + if (args.CallItem.Direction == eCodecCallDirection.Incoming) + { + trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem)); + trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem)); + trilist.SetString(joinMap.IncomingCallName.JoinNumber, args.CallItem.Name); + trilist.SetString(joinMap.IncomingCallNumber.JoinNumber, args.CallItem.Number); + } + else + { + trilist.SetString(joinMap.IncomingCallName.JoinNumber, string.Empty); + trilist.SetString(joinMap.IncomingCallNumber.JoinNumber, string.Empty); + } trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); @@ -1330,92 +1445,92 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetUshort(joinMap.ConnectedCallCount.JoinNumber, (ushort)ActiveCalls.Count); }; - if (this is IJoinCalls joinCodec) - { - trilist.SetSigFalseAction(joinMap.JoinAllCalls.JoinNumber, () => joinCodec.JoinAllCalls()); - - for (int i = 0; i < joinMap.JoinCallStart.JoinSpan; i++) - { - trilist.SetSigFalseAction((uint)(joinMap.JoinCallStart.JoinNumber + i), () => - { - var call = ActiveCalls[i]; - if (call != null) - { - joinCodec.JoinCall(call); - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "[Join Call] Unable to find call at index '{0}'", i); - } - }); - } - } - - if (this is IHasCallHold holdCodec) - { - trilist.SetSigFalseAction(joinMap.HoldAllCalls.JoinNumber, () => - { - foreach (var call in ActiveCalls) - { - holdCodec.HoldCall(call); - } - }); - - for (int i = 0; i < joinMap.HoldCallsStart.JoinSpan; i++) - { - var index = i; - - trilist.SetSigFalseAction((uint)(joinMap.HoldCallsStart.JoinNumber + index), () => - { - if (index < 0 || index >= ActiveCalls.Count) return; - - var call = ActiveCalls[index]; - if (call != null) - { - holdCodec.HoldCall(call); - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "[Hold Call] Unable to find call at index '{0}'", i); - } - }); - - trilist.SetSigFalseAction((uint)(joinMap.ResumeCallsStart.JoinNumber + index), () => - { - if (index < 0 || index >= ActiveCalls.Count) return; - - var call = ActiveCalls[index]; - if (call != null) - { - holdCodec.ResumeCall(call); - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "[Resume Call] Unable to find call at index '{0}'", i); - } - }); - } - } - - - - trilist.OnlineStatusChange += (device, args) => + if (this is IJoinCalls joinCodec) { - if (!args.DeviceOnLine) return; + trilist.SetSigFalseAction(joinMap.JoinAllCalls.JoinNumber, () => joinCodec.JoinAllCalls()); - // TODO [ ] #983 - Debug.LogMessage(LogEventLevel.Information, this, "LinkVideoCodecCallControlsToApi: device is {0}, IsInCall {1}", args.DeviceOnLine ? "online" : "offline", IsInCall); - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC"); - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; + for (int i = 0; i < joinMap.JoinCallStart.JoinSpan; i++) + { + trilist.SetSigFalseAction((uint)(joinMap.JoinCallStart.JoinNumber + i), () => + { + var call = ActiveCalls[i]; + if (call != null) + { + joinCodec.JoinCall(call); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "[Join Call] Unable to find call at index '{0}'", i); + } + }); + } + } + + if (this is IHasCallHold holdCodec) + { + trilist.SetSigFalseAction(joinMap.HoldAllCalls.JoinNumber, () => + { + foreach (var call in ActiveCalls) + { + holdCodec.HoldCall(call); + } + }); + + for (int i = 0; i < joinMap.HoldCallsStart.JoinSpan; i++) + { + var index = i; + + trilist.SetSigFalseAction((uint)(joinMap.HoldCallsStart.JoinNumber + index), () => + { + if (index < 0 || index >= ActiveCalls.Count) return; + + var call = ActiveCalls[index]; + if (call != null) + { + holdCodec.HoldCall(call); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "[Hold Call] Unable to find call at index '{0}'", i); + } + }); + + trilist.SetSigFalseAction((uint)(joinMap.ResumeCallsStart.JoinNumber + index), () => + { + if (index < 0 || index >= ActiveCalls.Count) return; + + var call = ActiveCalls[index]; + if (call != null) + { + holdCodec.ResumeCall(call); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "[Resume Call] Unable to find call at index '{0}'", i); + } + }); + } + } + + + + trilist.OnlineStatusChange += (device, args) => +{ + if (!args.DeviceOnLine) return; + + // TODO [ ] #983 + Debug.LogMessage(LogEventLevel.Information, this, "LinkVideoCodecCallControlsToApi: device is {0}, IsInCall {1}", args.DeviceOnLine ? "online" : "offline", IsInCall); + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC"); + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); +}; } private string UpdateCallStatusXSig() { const int maxCalls = 8; const int maxStrings = 6; - const int maxDigitals = 2; + const int maxDigitals = 2; const int offset = maxStrings + maxDigitals; var stringIndex = 0; var digitalIndex = maxStrings * maxCalls; @@ -1428,40 +1543,40 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (arrayIndex >= maxCalls * offset) break; //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, call.IsOnHold); + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, call.IsOnHold); //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString()); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, call.Type.ToString()); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, call.Status.ToString()); - if(call.Duration != null) - { - // May need to verify correct string format here - var dur = string.Format("{0:c}", call.Duration); - tokenArray[arrayIndex + 6] = new XSigSerialToken(stringIndex + 6, dur); - } + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString()); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, call.Type.ToString()); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, call.Status.ToString()); + if (call.Duration != null) + { + // May need to verify correct string format here + var dur = string.Format("{0:c}", call.Duration); + tokenArray[arrayIndex + 6] = new XSigSerialToken(stringIndex + 6, dur); + } arrayIndex += offset; stringIndex += maxStrings; - digitalIndex += maxDigitals; + digitalIndex += maxDigitals; } - while (arrayIndex < maxCalls * offset) + while (arrayIndex < maxCalls * offset) { //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); arrayIndex += offset; stringIndex += maxStrings; @@ -1473,55 +1588,55 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { - trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmfAction("0", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmfAction("1", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmfAction("2", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmfAction("3", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmfAction("4", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmfAction("5", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmfAction("6", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmfAction("7", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmfAction("8", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmfAction("9", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmfAction("*", trilist, joinMap)); - trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmfAction("#", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmfAction("0", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmfAction("1", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmfAction("2", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmfAction("3", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmfAction("4", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmfAction("5", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmfAction("6", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmfAction("7", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmfAction("8", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmfAction("9", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmfAction("*", trilist, joinMap)); + trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmfAction("#", trilist, joinMap)); } - /// - /// Sends the specified string as a DTMF command. - /// Reads the value of the SendDtmfToSpecificCallInstance digital join and SelectCall analog join to determine - /// Whther to send to a specific call index or to the last connected call - /// - /// - /// - /// - private void SendDtmfAction(string s, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - if (!trilist.GetBool(joinMap.SendDtmfToSpecificCallIndex.JoinNumber)) - { - SendDtmf(s); - } - else - { - var callIndex = trilist.GetUshort(joinMap.SelectCall.JoinNumber); - if (callIndex > 0 && callIndex <= 8) - { - var call = ActiveCalls[callIndex - 1]; - if (call != null && call.IsActiveCall) - { - SendDtmf(s, call); - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "Warning: No call found at index {0} or call is not active.", callIndex); - } - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "Warning: Invalid call index specified. Please use a value of 1-8."); - } - } - } + /// + /// Sends the specified string as a DTMF command. + /// Reads the value of the SendDtmfToSpecificCallInstance digital join and SelectCall analog join to determine + /// Whther to send to a specific call index or to the last connected call + /// + /// + /// + /// + private void SendDtmfAction(string s, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + if (!trilist.GetBool(joinMap.SendDtmfToSpecificCallIndex.JoinNumber)) + { + SendDtmf(s); + } + else + { + var callIndex = trilist.GetUshort(joinMap.SelectCall.JoinNumber); + if (callIndex > 0 && callIndex <= 8) + { + var call = ActiveCalls[callIndex - 1]; + if (call != null && call.IsActiveCall) + { + SendDtmf(s, call); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "Warning: No call found at index {0} or call is not active.", callIndex); + } + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "Warning: Invalid call index specified. Please use a value of 1-8."); + } + } + } private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { @@ -1537,45 +1652,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) => { - if (codec is IHasCameraOff offCodec) - { - if (offCodec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - return; - } + if (codec is IHasCameraOff offCodec) + { + if (offCodec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + return; + } - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - return; - } + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + return; + } - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); }; - if (codec is IHasCameraOff offModeCodec) - { - if (offModeCodec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - return; - } + if (codec is IHasCameraOff offModeCodec) + { + if (offModeCodec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + return; + } - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - return; - } + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + return; + } - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); } @@ -1595,9 +1710,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; - if (b) camera.TiltUp(); + if (b) camera.TiltUp(); else camera.TiltStop(); }); @@ -1605,27 +1720,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; - if (b) camera.TiltDown(); + if (b) camera.TiltDown(); else camera.TiltStop(); }); trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) => { if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; - if (b) camera.PanLeft(); + if (b) camera.PanLeft(); else camera.PanStop(); }); trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) => { if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; - if (b) camera.PanRight(); + if (b) camera.PanRight(); else camera.PanStop(); }); @@ -1633,9 +1748,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; - if (b) camera.ZoomIn(); + if (b) camera.ZoomIn(); else camera.ZoomStop(); }); @@ -1643,83 +1758,83 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraPtzControl camera)) return; - if (b) camera.ZoomOut(); + if (b) camera.ZoomOut(); else camera.ZoomStop(); }); - trilist.SetBoolSigAction(joinMap.CameraFocusNear.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; + trilist.SetBoolSigAction(joinMap.CameraFocusNear.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return; - if (b) camera.FocusNear(); - else camera.FocusStop(); - }); + if (b) camera.FocusNear(); + else camera.FocusStop(); + }); - trilist.SetBoolSigAction(joinMap.CameraFocusFar.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; + trilist.SetBoolSigAction(joinMap.CameraFocusFar.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return; - if (b) camera.FocusFar(); - else camera.FocusStop(); - }); + if (b) camera.FocusFar(); + else camera.FocusStop(); + }); - trilist.SetSigFalseAction(joinMap.CameraFocusAuto.JoinNumber, () => - { - if (codec.SelectedCamera == null) return; + trilist.SetSigFalseAction(joinMap.CameraFocusAuto.JoinNumber, () => + { + if (codec.SelectedCamera == null) return; - if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return; + if (!(codec.SelectedCamera is IHasCameraFocusControl camera)) return; - camera.TriggerAutoFocus(); - }); + camera.TriggerAutoFocus(); + }); - // Camera count - trilist.SetUshort(joinMap.CameraCount.JoinNumber, (ushort)codec.Cameras.Count); + // Camera count + trilist.SetUshort(joinMap.CameraCount.JoinNumber, (ushort)codec.Cameras.Count); - // Camera names - for (uint i = 0; i < joinMap.CameraNamesFb.JoinSpan; i++) - { - //Check the count first - if (i < codec.Cameras.Count && codec.Cameras[(int)i] != null) - { - trilist.SetString(joinMap.CameraNamesFb.JoinNumber + i, codec.Cameras[(int)i].Name); - } - else - { - trilist.SetString(joinMap.CameraNamesFb.JoinNumber + i, ""); - } - } + // Camera names + for (uint i = 0; i < joinMap.CameraNamesFb.JoinSpan; i++) + { + //Check the count first + if (i < codec.Cameras.Count && codec.Cameras[(int)i] != null) + { + trilist.SetString(joinMap.CameraNamesFb.JoinNumber + i, codec.Cameras[(int)i].Name); + } + else + { + trilist.SetString(joinMap.CameraNamesFb.JoinNumber + i, ""); + } + } //Camera Select trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) => { - if (i > 0 && i <= codec.Cameras.Count) - { - codec.SelectCamera(codec.Cameras[i - 1].Key); - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "Unable to select. No camera found at index {0}", i); - } + if (i > 0 && i <= codec.Cameras.Count) + { + codec.SelectCamera(codec.Cameras[i - 1].Key); + } + else + { + Debug.LogMessage(LogEventLevel.Information, this, "Unable to select. No camera found at index {0}", i); + } }); - // Set initial selected camera feedback - if (codec.SelectedCamera != null) - { - trilist.SetUshort(joinMap.CameraNumberSelect.JoinNumber, (ushort)codec.Cameras.FindIndex((c) => c.Key == codec.SelectedCamera.Key)); - } + // Set initial selected camera feedback + if (codec.SelectedCamera != null) + { + trilist.SetUshort(joinMap.CameraNumberSelect.JoinNumber, (ushort)codec.Cameras.FindIndex((c) => c.Key == codec.SelectedCamera.Key)); + } codec.CameraSelected += (sender, args) => { var i = (ushort)codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key); - trilist.SetUshort(joinMap.CameraNumberSelect.JoinNumber, (ushort)(i + 1)); + trilist.SetUshort(joinMap.CameraNumberSelect.JoinNumber, (ushort)(i + 1)); if (codec is IHasCodecRoomPresets) { @@ -1766,11 +1881,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec }); - // Far End Presets - trilist.SetUShortSigAction(joinMap.FarEndPresetSelect.JoinNumber, (i) => - { - presetCodec.SelectFarEndPreset(i); - }); + // Far End Presets + trilist.SetUShortSigAction(joinMap.FarEndPresetSelect.JoinNumber, (i) => + { + presetCodec.SelectFarEndPreset(i); + }); trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, @@ -1781,105 +1896,105 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); }); - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; - // TODO [ ] Issue #868 - trilist.SetString(joinMap.CameraPresetNames.JoinNumber, "\xFC"); - SetCameraPresetNames(presetCodec.NearEndPresets); - }; + // TODO [ ] Issue #868 + trilist.SetString(joinMap.CameraPresetNames.JoinNumber, "\xFC"); + SetCameraPresetNames(presetCodec.NearEndPresets); + }; } - // Following fields only used for Bridging - private int _selectedRecentCallItemIndex; - private DirectoryItem _selectedDirectoryItem; + // Following fields only used for Bridging + private int _selectedRecentCallItemIndex; + private DirectoryItem _selectedDirectoryItem; - private void LinkVideoCodecCallHistoryToApi(IHasCallHistory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.CallHistory.RecentCallsListHasChanged += (o, a) => - { - UpdateCallHistory(codec, trilist, joinMap); - }; + private void LinkVideoCodecCallHistoryToApi(IHasCallHistory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.CallHistory.RecentCallsListHasChanged += (o, a) => + { + UpdateCallHistory(codec, trilist, joinMap); + }; - // Selected item action and feedback - trilist.SetUShortSigAction(joinMap.SelectRecentCallItem.JoinNumber, (u) => - { - if (u == 0 || u > codec.CallHistory.RecentCalls.Count) - { - Debug.LogMessage(LogEventLevel.Verbose, this, "Recent Call History index out of range"); - return; - } + // Selected item action and feedback + trilist.SetUShortSigAction(joinMap.SelectRecentCallItem.JoinNumber, (u) => + { + if (u == 0 || u > codec.CallHistory.RecentCalls.Count) + { + Debug.LogMessage(LogEventLevel.Verbose, this, "Recent Call History index out of range"); + return; + } - _selectedRecentCallItemIndex = (int)(u - 1); - trilist.SetUshort(joinMap.SelectRecentCallItem.JoinNumber, u); + _selectedRecentCallItemIndex = (int)(u - 1); + trilist.SetUshort(joinMap.SelectRecentCallItem.JoinNumber, u); - var _selectedRecentCallItem = codec.CallHistory.RecentCalls[_selectedRecentCallItemIndex]; - - if (_selectedRecentCallItem != null) - { - trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, _selectedRecentCallItem.Name); - trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, _selectedRecentCallItem.Number); - trilist.SetSigFalseAction(joinMap.RemoveSelectedRecentCallItem.JoinNumber, () => codec.RemoveCallHistoryEntry(_selectedRecentCallItem)); - trilist.SetSigFalseAction(joinMap.DialSelectedRecentCallItem.JoinNumber, () => this.Dial(_selectedRecentCallItem.Number)); - } - else - { - trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, string.Empty); - trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, string.Empty); - trilist.ClearBoolSigAction(joinMap.RemoveSelectedRecentCallItem.JoinNumber); - trilist.ClearBoolSigAction(joinMap.DialSelectedRecentCallItem.JoinNumber); - } - }); - } + var _selectedRecentCallItem = codec.CallHistory.RecentCalls[_selectedRecentCallItemIndex]; + + if (_selectedRecentCallItem != null) + { + trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, _selectedRecentCallItem.Name); + trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, _selectedRecentCallItem.Number); + trilist.SetSigFalseAction(joinMap.RemoveSelectedRecentCallItem.JoinNumber, () => codec.RemoveCallHistoryEntry(_selectedRecentCallItem)); + trilist.SetSigFalseAction(joinMap.DialSelectedRecentCallItem.JoinNumber, () => this.Dial(_selectedRecentCallItem.Number)); + } + else + { + trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, string.Empty); + trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, string.Empty); + trilist.ClearBoolSigAction(joinMap.RemoveSelectedRecentCallItem.JoinNumber); + trilist.ClearBoolSigAction(joinMap.DialSelectedRecentCallItem.JoinNumber); + } + }); + } - private void UpdateCallHistory(IHasCallHistory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - // Clear out selected item - _selectedRecentCallItemIndex = 0; + private void UpdateCallHistory(IHasCallHistory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + // Clear out selected item + _selectedRecentCallItemIndex = 0; - trilist.SetUshort(joinMap.SelectRecentCallItem.JoinNumber, 0); - trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, string.Empty); - trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, string.Empty); - trilist.ClearBoolSigAction(joinMap.RemoveSelectedRecentCallItem.JoinNumber); - // + trilist.SetUshort(joinMap.SelectRecentCallItem.JoinNumber, 0); + trilist.SetString(joinMap.SelectedRecentCallName.JoinNumber, string.Empty); + trilist.SetString(joinMap.SelectedRecentCallNumber.JoinNumber, string.Empty); + trilist.ClearBoolSigAction(joinMap.RemoveSelectedRecentCallItem.JoinNumber); + // - trilist.SetUshort(joinMap.RecentCallCount.JoinNumber, (ushort)codec.CallHistory.RecentCalls.Count); + trilist.SetUshort(joinMap.RecentCallCount.JoinNumber, (ushort)codec.CallHistory.RecentCalls.Count); - // Update the call history joins - var maxItems = joinMap.RecentCallNamesStart.JoinSpan; + // Update the call history joins + var maxItems = joinMap.RecentCallNamesStart.JoinSpan; - // Create history - uint index = 0; - for (uint i = 0; i < maxItems && i < codec.CallHistory.RecentCalls.Count; i++) - { - trilist.SetString(joinMap.RecentCallNamesStart.JoinNumber + i, codec.CallHistory.RecentCalls[(int)i].Name); - trilist.SetString(joinMap.RecentCallTimesStart.JoinNumber + i, codec.CallHistory.RecentCalls[(int)i].StartTime.ToShortTimeString()); - trilist.SetUshort(joinMap.RecentCallOccurrenceType.JoinNumber + i, (ushort)codec.CallHistory.RecentCalls[(int)i].OccurrenceType); - //i++; - index = i; - } - - //foreach(var item in codec.CallHistory.RecentCalls) - //{ - // trilist.SetString(joinMap.RecentCallNamesStart.JoinNumber + i, item.Name); - // trilist.SetString(joinMap.RecentCallTimesStart.JoinNumber + i, item.StartTime.ToShortTimeString()); - // trilist.SetUshort(joinMap.RecentCallOccurrenceType.JoinNumber + i, (ushort)item.OccurrenceType); - // i++; - //} + // Create history + uint index = 0; + for (uint i = 0; i < maxItems && i < codec.CallHistory.RecentCalls.Count; i++) + { + trilist.SetString(joinMap.RecentCallNamesStart.JoinNumber + i, codec.CallHistory.RecentCalls[(int)i].Name); + trilist.SetString(joinMap.RecentCallTimesStart.JoinNumber + i, codec.CallHistory.RecentCalls[(int)i].StartTime.ToShortTimeString()); + trilist.SetUshort(joinMap.RecentCallOccurrenceType.JoinNumber + i, (ushort)codec.CallHistory.RecentCalls[(int)i].OccurrenceType); + //i++; + index = i; + } - // Clears existing items - for (uint j = index; j < maxItems; j++) - { - trilist.SetString(joinMap.RecentCallNamesStart.JoinNumber + j, string.Empty); - trilist.SetString(joinMap.RecentCallTimesStart.JoinNumber + j, string.Empty); - trilist.SetUshort(joinMap.RecentCallOccurrenceType.JoinNumber + j, 0); - } - } + //foreach(var item in codec.CallHistory.RecentCalls) + //{ + // trilist.SetString(joinMap.RecentCallNamesStart.JoinNumber + i, item.Name); + // trilist.SetString(joinMap.RecentCallTimesStart.JoinNumber + i, item.StartTime.ToShortTimeString()); + // trilist.SetUshort(joinMap.RecentCallOccurrenceType.JoinNumber + i, (ushort)item.OccurrenceType); + // i++; + //} - private string SetCameraPresetNames(IEnumerable presets) + // Clears existing items + for (uint j = index; j < maxItems; j++) + { + trilist.SetString(joinMap.RecentCallNamesStart.JoinNumber + j, string.Empty); + trilist.SetString(joinMap.RecentCallTimesStart.JoinNumber + j, string.Empty); + trilist.SetUshort(joinMap.RecentCallOccurrenceType.JoinNumber + j, 0); + } + } + + private string SetCameraPresetNames(IEnumerable presets) { return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); } @@ -1925,159 +2040,4 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #endregion } - - - /// - /// Represents a CodecPhonebookSyncState - /// - public class CodecPhonebookSyncState : IKeyed - { - private bool _InitialSyncComplete; - - public CodecPhonebookSyncState(string key) - { - Key = key; - - CodecDisconnected(); - } - - public bool InitialSyncComplete - { - get { return _InitialSyncComplete; } - private set - { - if (value == true) - { - InitialSyncCompleted?.Invoke(this, new EventArgs()); - } - _InitialSyncComplete = value; - } - } - - /// - /// Gets or sets the InitialPhonebookFoldersWasReceived - /// - public bool InitialPhonebookFoldersWasReceived { get; private set; } - - /// - /// Gets or sets the NumberOfContactsWasReceived - /// - public bool NumberOfContactsWasReceived { get; private set; } - - /// - /// Gets or sets the PhonebookRootEntriesWasRecieved - /// - public bool PhonebookRootEntriesWasRecieved { get; private set; } - - /// - /// Gets or sets the PhonebookHasFolders - /// - public bool PhonebookHasFolders { get; private set; } - - /// - /// Gets or sets the NumberOfContacts - /// - public int NumberOfContacts { get; private set; } - - #region IKeyed Members - - /// - /// Gets or sets the Key - /// - public string Key { get; private set; } - - #endregion - - public event EventHandler InitialSyncCompleted; - - /// - /// InitialPhonebookFoldersReceived method - /// - public void InitialPhonebookFoldersReceived() - { - InitialPhonebookFoldersWasReceived = true; - - CheckSyncStatus(); - } - - /// - /// PhonebookRootEntriesReceived method - /// - public void PhonebookRootEntriesReceived() - { - PhonebookRootEntriesWasRecieved = true; - - CheckSyncStatus(); - } - - /// - /// SetPhonebookHasFolders method - /// - public void SetPhonebookHasFolders(bool value) - { - PhonebookHasFolders = value; - - Debug.LogMessage(LogEventLevel.Debug, this, "Phonebook has folders: {0}", PhonebookHasFolders); - } - - /// - /// SetNumberOfContacts method - /// - public void SetNumberOfContacts(int contacts) - { - NumberOfContacts = contacts; - NumberOfContactsWasReceived = true; - - Debug.LogMessage(LogEventLevel.Debug, this, "Phonebook contains {0} contacts.", NumberOfContacts); - - CheckSyncStatus(); - } - - /// - /// CodecDisconnected method - /// - public void CodecDisconnected() - { - InitialPhonebookFoldersWasReceived = false; - PhonebookHasFolders = false; - NumberOfContacts = 0; - NumberOfContactsWasReceived = false; - } - - private void CheckSyncStatus() - { - if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved) - { - InitialSyncComplete = true; - Debug.LogMessage(LogEventLevel.Debug, this, "Initial Phonebook Sync Complete!"); - } - else - { - InitialSyncComplete = false; - } - } - } - /// - /// Represents a CodecCommandWithLabel - /// - public class CodecCommandWithLabel - { - /// - /// Gets or sets the Command - /// - public string Command { get; private set; } - /// - /// Gets or sets the Label - /// - public string Label { get; private set; } - - public CodecCommandWithLabel(string command, string label) - { - Command = command; - Label = label; - } - } - - - } \ No newline at end of file From 3a2a059ce1fcfda05540c6c4eaf0f56aae1f8630 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 9 Oct 2025 16:07:25 -0500 Subject: [PATCH 11/11] fix: appdebug now has option for setting all sink levels --- src/PepperDash.Core/Logging/Debug.cs | 153 +++++++++++++++------ src/PepperDash.Essentials/ControlSystem.cs | 4 - 2 files changed, 114 insertions(+), 43 deletions(-) diff --git a/src/PepperDash.Core/Logging/Debug.cs b/src/PepperDash.Core/Logging/Debug.cs index 37b0f14a..62a95f2c 100644 --- a/src/PepperDash.Core/Logging/Debug.cs +++ b/src/PepperDash.Core/Logging/Debug.cs @@ -40,20 +40,20 @@ namespace PepperDash.Core private static ILogger _logger; - private static readonly LoggingLevelSwitch _consoleLoggingLevelSwitch; + private static readonly LoggingLevelSwitch _consoleLogLevelSwitch; - private static readonly LoggingLevelSwitch _websocketLoggingLevelSwitch; + private static readonly LoggingLevelSwitch _websocketLogLevelSwitch; private static readonly LoggingLevelSwitch _errorLogLevelSwitch; - private static readonly LoggingLevelSwitch _fileLevelSwitch; + private static readonly LoggingLevelSwitch _fileLogLevelSwitch; /// /// Gets the minimum log level for the websocket sink. /// public static LogEventLevel WebsocketMinimumLogLevel { - get { return _websocketLoggingLevelSwitch.MinimumLevel; } + get { return _websocketLogLevelSwitch.MinimumLevel; } } private static readonly DebugWebsocketSink _websocketSink; @@ -138,13 +138,13 @@ namespace PepperDash.Core var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey); - _consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel); + _consoleLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel); - _websocketLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel); + _websocketLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel); _errorLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultErrorLogLevel); - _fileLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel); + _fileLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel); _websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true)); @@ -162,14 +162,14 @@ namespace PepperDash.Core .MinimumLevel.Verbose() .Enrich.FromLogContext() .Enrich.With(new CrestronEnricher()) - .WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLoggingLevelSwitch) - .WriteTo.Sink(_websocketSink, levelSwitch: _websocketLoggingLevelSwitch) + .WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLogLevelSwitch) + .WriteTo.Sink(_websocketSink, levelSwitch: _websocketLogLevelSwitch) .WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch) .WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath, rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Debug, retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 30 : 60, - levelSwitch: _fileLevelSwitch + levelSwitch: _fileLogLevelSwitch ); try @@ -237,10 +237,13 @@ namespace PepperDash.Core if (DoNotLoadConfigOnNextBoot) CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber)); - _consoleLoggingLevelSwitch.MinimumLevelChanged += (sender, args) => + _errorLogLevelSwitch.MinimumLevelChanged += (sender, args) => { - LogMessage(LogEventLevel.Information, "Console debug level set to {minimumLevel}", _consoleLoggingLevelSwitch.MinimumLevel); + LogMessage(LogEventLevel.Information, "Error log debug level set to {minimumLevel}", _errorLogLevelSwitch.MinimumLevel); }; + + // Set initial error log level based on platform && stored level. If appliance, use stored level, otherwise default to verbose + SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? _errorLogLevelSwitch.MinimumLevel : LogEventLevel.Verbose); } /// @@ -273,9 +276,9 @@ namespace PepperDash.Core { CrestronConsole.Print($"Unable to retrieve stored log level for {levelStoreKey}.\r\nError: {result}.\r\nSetting level to {LogEventLevel.Information}\r\n"); - CrestronDataStoreStatic.SetLocalIntValue(levelStoreKey, (int)LogEventLevel.Information); + CrestronDataStoreStatic.SetLocalIntValue(levelStoreKey, levelStoreKey == ErrorLogLevelStoreKey ? (int)LogEventLevel.Warning : (int)LogEventLevel.Information); - return LogEventLevel.Information; + return levelStoreKey == ErrorLogLevelStoreKey ? LogEventLevel.Warning : LogEventLevel.Information; } if (logLevel < 0 || logLevel > 5) @@ -284,6 +287,8 @@ namespace PepperDash.Core return LogEventLevel.Information; } + CrestronConsole.PrintLine($"Stored log level for {levelStoreKey} is {logLevel}"); + return (LogEventLevel)logLevel; } catch (Exception ex) @@ -349,7 +354,11 @@ namespace PepperDash.Core if (levelString.Trim() == "?") { CrestronConsole.ConsoleCommandResponse( - "Used to set the minimum level of debug messages to be printed to the console:\r\n" + + "Used to set the minimum level of debug messages:\r\n" + + "Usage: appdebug:P [sink] [level]\r\n" + + " sink: console (default), errorlog, file, all\r\n" + + " all: sets all sinks to the specified level\r\n" + + " level: 0-5 or LogEventLevel name\r\n" + $"{_logLevels[0]} = 0\r\n" + $"{_logLevels[1]} = 1\r\n" + $"{_logLevels[2]} = 2\r\n" + @@ -361,32 +370,88 @@ namespace PepperDash.Core if (string.IsNullOrEmpty(levelString.Trim())) { - CrestronConsole.ConsoleCommandResponse("AppDebug level = {0}", _consoleLoggingLevelSwitch.MinimumLevel); + CrestronConsole.ConsoleCommandResponse("Console log level = {0}\r\n", _consoleLogLevelSwitch.MinimumLevel); + CrestronConsole.ConsoleCommandResponse("File log level = {0}\r\n", _fileLogLevelSwitch.MinimumLevel); + CrestronConsole.ConsoleCommandResponse("Error log level = {0}\r\n", _errorLogLevelSwitch.MinimumLevel); return; } - if (int.TryParse(levelString, out var levelInt)) + // Parse tokens: first token is sink (defaults to console), second token is level + var tokens = levelString.Trim().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + + string sinkName; + string levelToken; + + if (tokens.Length == 1) + { + // Single token - assume it's a level for console sink + sinkName = "console"; + levelToken = tokens[0]; + } + else if (tokens.Length == 2) + { + // Two tokens - first is sink, second is level + sinkName = tokens[0].ToLowerInvariant(); + levelToken = tokens[1]; + } + else + { + CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]"); + return; + } + + // Parse the level using the same logic as before + LogEventLevel level; + + if (int.TryParse(levelToken, out var levelInt)) { if (levelInt < 0 || levelInt > 5) { - CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level. If using a number, value must be between 0-5"); + CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level. If using a number, value must be between 0-5"); return; } - SetDebugLevel((uint)levelInt); - return; - } - if (Enum.TryParse(levelString, true, out var levelEnum)) + if (!_logLevels.TryGetValue((uint)levelInt, out level)) + { + level = LogEventLevel.Information; + CrestronConsole.ConsoleCommandResponse($"{levelInt} not valid. Setting level to {level}"); + } + } + else if (Enum.TryParse(levelToken, true, out level)) { - SetDebugLevel(levelEnum); + // Successfully parsed as LogEventLevel enum + } + else + { + CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level"); return; } - CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level"); + // Set the level for the specified sink + switch (sinkName) + { + case "console": + SetDebugLevel(level); + break; + case "errorlog": + SetErrorLogMinimumDebugLevel(level); + break; + case "file": + SetFileMinimumDebugLevel(level); + break; + case "all": + SetDebugLevel(level); + SetErrorLogMinimumDebugLevel(level); + SetFileMinimumDebugLevel(level); + break; + default: + CrestronConsole.ConsoleCommandResponse($"Error: Unknown sink '{sinkName}'. Valid sinks: console, errorlog, file"); + break; + } } catch { - CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [0-5]"); + CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]"); } } @@ -416,10 +481,10 @@ namespace PepperDash.Core /// public static void SetDebugLevel(LogEventLevel level) { - _consoleLoggingLevelSwitch.MinimumLevel = level; + _consoleLogLevelSwitch.MinimumLevel = level; - CrestronConsole.ConsoleCommandResponse("[Application {0}], Debug level set to {1}\r\n", - InitialParametersClass.ApplicationNumber, _consoleLoggingLevelSwitch.MinimumLevel); + CrestronConsole.ConsoleCommandResponse("[Application {0}] Debug level set to {1}\r\n", + InitialParametersClass.ApplicationNumber, _consoleLogLevelSwitch.MinimumLevel); CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}"); @@ -436,14 +501,14 @@ namespace PepperDash.Core /// public static void SetWebSocketMinimumDebugLevel(LogEventLevel level) { - _websocketLoggingLevelSwitch.MinimumLevel = level; + _websocketLogLevelSwitch.MinimumLevel = level; var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint)level); if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS) LogMessage(LogEventLevel.Information, "Error saving websocket debug level setting: {erro}", err); - LogMessage(LogEventLevel.Information, "Websocket debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel); + LogMessage(LogEventLevel.Information, "Websocket debug level set to {0}", _websocketLogLevelSwitch.MinimumLevel); } /// @@ -453,12 +518,17 @@ namespace PepperDash.Core { _errorLogLevelSwitch.MinimumLevel = level; - var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level); + CrestronConsole.ConsoleCommandResponse("[Application {0}] Error log level set to {1}\r\n", + InitialParametersClass.ApplicationNumber, _errorLogLevelSwitch.MinimumLevel); + + CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}"); + + var err = CrestronDataStoreStatic.SetLocalIntValue(ErrorLogLevelStoreKey, (int)level); + + CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}"); if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS) - LogMessage(LogEventLevel.Information, "Error saving Error Log debug level setting: {error}", err); - - LogMessage(LogEventLevel.Information, "Error log debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel); + CrestronConsole.PrintLine($"Error saving error log debug level setting: {err}"); } /// @@ -466,14 +536,19 @@ namespace PepperDash.Core /// public static void SetFileMinimumDebugLevel(LogEventLevel level) { - _errorLogLevelSwitch.MinimumLevel = level; + _fileLogLevelSwitch.MinimumLevel = level; - var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level); + CrestronConsole.ConsoleCommandResponse("[Application {0}] File log level set to {1}\r\n", + InitialParametersClass.ApplicationNumber, _fileLogLevelSwitch.MinimumLevel); + + CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}"); + + var err = CrestronDataStoreStatic.SetLocalIntValue(FileLevelStoreKey, (int)level); + + CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}"); if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS) - LogMessage(LogEventLevel.Information, "Error saving File debug level setting: {error}", err); - - LogMessage(LogEventLevel.Information, "File debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel); + CrestronConsole.PrintLine($"Error saving file debug level setting: {err}"); } /// diff --git a/src/PepperDash.Essentials/ControlSystem.cs b/src/PepperDash.Essentials/ControlSystem.cs index b2fe1e19..28864e83 100644 --- a/src/PepperDash.Essentials/ControlSystem.cs +++ b/src/PepperDash.Essentials/ControlSystem.cs @@ -39,8 +39,6 @@ namespace PepperDash.Essentials DeviceManager.Initialize(this); SecretsManager.Initialize(); SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; - - Debug.SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? LogEventLevel.Warning : LogEventLevel.Verbose); } /// @@ -75,8 +73,6 @@ namespace PepperDash.Essentials private void StartSystem(object preventInitialization) { - Debug.SetErrorLogMinimumDebugLevel(LogEventLevel.Verbose); - DeterminePlatform(); if (Debug.DoNotLoadConfigOnNextBoot)