diff --git a/src/PepperDash.Essentials.MobileControl/ClientSpecificUpdateRequest.cs b/src/PepperDash.Essentials.MobileControl/ClientSpecificUpdateRequest.cs index beddd2f6..b974a9aa 100644 --- a/src/PepperDash.Essentials.MobileControl/ClientSpecificUpdateRequest.cs +++ b/src/PepperDash.Essentials.MobileControl/ClientSpecificUpdateRequest.cs @@ -3,10 +3,15 @@ using System; namespace PepperDash.Essentials { /// - /// Represents a ClientSpecificUpdateRequest + /// Send an update request for a specific client /// + [Obsolete] public class ClientSpecificUpdateRequest { + /// + /// Initialize an instance of the class. + /// + /// public ClientSpecificUpdateRequest(Action action) { ResponseMethod = action; diff --git a/src/PepperDash.Essentials.MobileControl/IDelayedConfiguration.cs b/src/PepperDash.Essentials.MobileControl/IDelayedConfiguration.cs index 2d191c89..abeef999 100644 --- a/src/PepperDash.Essentials.MobileControl/IDelayedConfiguration.cs +++ b/src/PepperDash.Essentials.MobileControl/IDelayedConfiguration.cs @@ -7,8 +7,9 @@ namespace PepperDash.Essentials /// public interface IDelayedConfiguration { - - + /// + /// Event triggered when the configuration is ready. Used when Mobile Control is interacting with a SIMPL program. + /// event EventHandler ConfigurationIsReady; } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlAction.cs b/src/PepperDash.Essentials.MobileControl/MobileControlAction.cs index 2e402dfb..16a9bd40 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlAction.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlAction.cs @@ -1,6 +1,6 @@ -using Newtonsoft.Json.Linq; +using System; +using Newtonsoft.Json.Linq; using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using System; namespace PepperDash.Essentials { @@ -10,12 +10,20 @@ namespace PepperDash.Essentials public class MobileControlAction : IMobileControlAction { /// - /// Gets or sets the Messenger + /// Gets the Messenger /// public IMobileControlMessenger Messenger { get; private set; } + /// + /// Action to execute when this path is matched + /// public Action Action { get; private set; } + /// + /// Initialize an instance of the class + /// + /// Messenger associated with this action + /// Action to take when this path is matched public MobileControlAction(IMobileControlMessenger messenger, Action handler) { Messenger = messenger; diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlDeviceFactory.cs b/src/PepperDash.Essentials.MobileControl/MobileControlDeviceFactory.cs index c4aa673b..6147b14e 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlDeviceFactory.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlDeviceFactory.cs @@ -1,28 +1,25 @@ -using PepperDash.Core; -using PepperDash.Core.Logging; +using System; +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; -using System.Linq; namespace PepperDash.Essentials { /// - /// Represents a MobileControlDeviceFactory + /// Factory to create a Mobile Control System Controller /// public class MobileControlDeviceFactory : EssentialsDeviceFactory { + /// + /// Create the factory for a Mobile Control System Controller + /// public MobileControlDeviceFactory() { TypeNames = new List { "appserver", "mobilecontrol", "webserver" }; } - /// - /// BuildDevice method - /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlEssentialsConfig.cs b/src/PepperDash.Essentials.MobileControl/MobileControlEssentialsConfig.cs index 7183ec84..d0415287 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlEssentialsConfig.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlEssentialsConfig.cs @@ -6,29 +6,35 @@ using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials { /// - /// Represents a MobileControlEssentialsConfig + /// Configuration class for sending data to Mobile Control Edge or a client using the Direct Server /// public class MobileControlEssentialsConfig : EssentialsConfig { + /// + /// Current versions for the system + /// [JsonProperty("runtimeInfo")] public MobileControlRuntimeInfo RuntimeInfo { get; set; } + /// + /// Create Configuration for Mobile Control. Used as part of the data sent to a client + /// + /// The base configuration public MobileControlEssentialsConfig(EssentialsConfig config) : base() { - // TODO: Consider using Reflection to iterate properties - this.Devices = config.Devices; - this.Info = config.Info; - this.JoinMaps = config.JoinMaps; - this.Rooms = config.Rooms; - this.SourceLists = config.SourceLists; - this.DestinationLists = config.DestinationLists; - this.SystemUrl = config.SystemUrl; - this.TemplateUrl = config.TemplateUrl; - this.TieLines = config.TieLines; + Devices = config.Devices; + Info = config.Info; + JoinMaps = config.JoinMaps; + Rooms = config.Rooms; + SourceLists = config.SourceLists; + DestinationLists = config.DestinationLists; + SystemUrl = config.SystemUrl; + TemplateUrl = config.TemplateUrl; + TieLines = config.TieLines; - if (this.Info == null) - this.Info = new InfoConfig(); + if (Info == null) + Info = new InfoConfig(); RuntimeInfo = new MobileControlRuntimeInfo(); } @@ -46,15 +52,21 @@ namespace PepperDash.Essentials [JsonProperty("pluginVersion")] public string PluginVersion { get; set; } + /// + /// Essentials Version + /// [JsonProperty("essentialsVersion")] public string EssentialsVersion { get; set; } + /// + /// PepperDash Core Version + /// [JsonProperty("pepperDashCoreVersion")] public string PepperDashCoreVersion { get; set; } /// - /// Gets or sets the EssentialsPlugins + /// List of Plugins loaded on this system /// [JsonProperty("essentialsPlugins")] public List EssentialsPlugins { get; set; } diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlFactory.cs b/src/PepperDash.Essentials.MobileControl/MobileControlFactory.cs index 393b3385..4f3c5433 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlFactory.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlFactory.cs @@ -7,10 +7,13 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials { /// - /// Represents a MobileControlFactory + /// Factory class for the Mobile Control App Controller /// public class MobileControlFactory { + /// + /// Create an instance of the class. + /// public MobileControlFactory() { var assembly = Assembly.GetExecutingAssembly(); diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs index 392b5543..d2aef597 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs @@ -91,10 +91,16 @@ namespace PepperDash.Essentials /// public MobileControlApiService ApiService { get; private set; } + /// + /// Get Room Bridges associated with this controller + /// public List RoomBridges => _roomBridges; private readonly MobileControlWebsocketServer _directServer; + /// + /// Get the Direct Server instance associated with this controller + /// public MobileControlWebsocketServer DirectServer => _directServer; private readonly CCriticalSection _wsCriticalSection = new CCriticalSection(); @@ -104,10 +110,14 @@ namespace PepperDash.Essentials /// public string SystemUrl; //set only from SIMPL Bridge! + /// public bool Connected => _wsClient2 != null && _wsClient2.IsAlive; private IEssentialsRoomCombiner _roomCombiner; + /// + /// Gets the SystemUuid from configuration or SIMPL Bridge + /// public string SystemUuid { get @@ -169,6 +179,9 @@ namespace PepperDash.Essentials private DateTime _lastAckMessage; + /// + /// Gets the LastAckMessage timestamp + /// public DateTime LastAckMessage => _lastAckMessage; private CTimer _pingTimer; @@ -177,11 +190,11 @@ namespace PepperDash.Essentials private LogLevel _wsLogLevel = LogLevel.Error; /// - /// + /// Initializes a new instance of the class. /// - /// - /// - /// + /// The unique key for this controller. + /// The name of the controller. + /// The configuration settings for the controller. public MobileControlSystemController(string key, string name, MobileControlConfig config) : base(key, name) { @@ -1192,6 +1205,9 @@ namespace PepperDash.Essentials /// public string Host { get; private set; } + /// + /// Gets the configured Client App URL + /// public string ClientAppUrl => Config.ClientAppUrl; private void OnRoomCombinationScenarioChanged( @@ -1203,7 +1219,7 @@ namespace PepperDash.Essentials } /// - /// CheckForDeviceMessenger method + /// Checks if a device messenger exists for the given key. /// public bool CheckForDeviceMessenger(string key) { @@ -1211,13 +1227,13 @@ namespace PepperDash.Essentials } /// - /// AddDeviceMessenger method + /// Add the provided messenger to the messengers collection /// public void AddDeviceMessenger(IMobileControlMessenger messenger) { if (_messengers.ContainsKey(messenger.Key)) { - this.LogWarning("Messenger with key {messengerKey) already added", messenger.Key); + this.LogWarning("Messenger with key {messengerKey} already added", messenger.Key); return; } @@ -1291,9 +1307,6 @@ namespace PepperDash.Essentials messenger.RegisterWithAppServer(this); } - /// - /// Initialize method - /// /// public override void Initialize() { @@ -1338,7 +1351,7 @@ namespace PepperDash.Essentials #region IMobileControl Members /// - /// GetAppServer method + /// Gets the App Server instance /// public static IMobileControl GetAppServer() { @@ -1356,16 +1369,10 @@ namespace PepperDash.Essentials } } - /// - /// Generates the url and creates the websocket client - /// private bool CreateWebsocket() { - if (_wsClient2 != null) - { - _wsClient2.Close(); - _wsClient2 = null; - } + _wsClient2?.Close(); + _wsClient2 = null; if (string.IsNullOrEmpty(SystemUuid)) { @@ -1402,7 +1409,7 @@ namespace PepperDash.Essentials } /// - /// LinkSystemMonitorToAppServer method + /// Link the System Monitor to this App server /// public void LinkSystemMonitorToAppServer() { @@ -1429,14 +1436,6 @@ namespace PepperDash.Essentials private void SetWebsocketDebugLevel(string cmdparameters) { - // if (CrestronEnvironment.ProgramCompatibility == eCrestronSeries.Series4) - // { - // this.LogInformation( - // "Setting websocket log level not currently allowed on 4 series." - // ); - // return; // Web socket log level not currently allowed in series4 - // } - if (string.IsNullOrEmpty(cmdparameters)) { this.LogInformation("Current Websocket debug level: {webSocketDebugLevel}", _wsLogLevel); @@ -1474,10 +1473,6 @@ namespace PepperDash.Essentials } } - /// - /// Sends message to server to indicate the system is shutting down - /// - /// private void CrestronEnvironment_ProgramStatusEventHandler( eProgramStatusEventType programEventType ) @@ -1510,6 +1505,9 @@ namespace PepperDash.Essentials } } + /// + /// Get action paths for the current actions + /// public List<(string, string)> GetActionDictionaryPaths() { var paths = new List<(string, string)>(); @@ -1582,24 +1580,24 @@ namespace PepperDash.Essentials } } + /// + /// Get the room bridge with the provided key + /// + /// The key of the room bridge public MobileControlBridgeBase GetRoomBridge(string key) { return _roomBridges.FirstOrDefault((r) => r.RoomKey.Equals(key)); } /// - /// GetRoomMessenger method + /// Get the room messenger with the provided key /// + /// The Key of the rooom messenger public IMobileControlRoomMessenger GetRoomMessenger(string key) { return _roomBridges.FirstOrDefault((r) => r.RoomKey.Equals(key)); } - /// - /// - /// - /// - /// private void Bridge_ConfigurationIsReady(object sender, EventArgs e) { this.LogDebug("Bridge ready. Registering"); @@ -1620,10 +1618,6 @@ namespace PepperDash.Essentials } } - /// - /// - /// - /// private void ReconnectToServerTimerCallback(object o) { this.LogDebug("Attempting to reconnect to server..."); @@ -1631,9 +1625,6 @@ namespace PepperDash.Essentials ConnectWebsocketClient(); } - /// - /// Verifies system connection with servers - /// private void AuthorizeSystem(string code) { if ( @@ -1678,9 +1669,6 @@ namespace PepperDash.Essentials }); } - /// - /// Dumps info in response to console command. - /// private void ShowInfo() { var url = Config != null ? Host : "No config"; @@ -1753,9 +1741,6 @@ namespace PepperDash.Essentials var clientNo = 1; foreach (var clientContext in _directServer.UiClientContexts) { - var isAlive = false; - var duration = "Not Connected"; - var clients = _directServer.UiClients.Values.Where(c => c.Token == clientContext.Value.Token.Token); CrestronConsole.ConsoleCommandResponse( @@ -1793,7 +1778,7 @@ namespace PepperDash.Essentials } /// - /// RegisterSystemToServer method + /// Register this system to the Mobile Control Edge Server /// public void RegisterSystemToServer() { @@ -1817,9 +1802,6 @@ namespace PepperDash.Essentials ConnectWebsocketClient(); } - /// - /// Connects the Websocket Client - /// private void ConnectWebsocketClient() { try @@ -1860,9 +1842,6 @@ namespace PepperDash.Essentials } } - /// - /// Attempts to connect the websocket - /// private void TryConnect() { try @@ -1892,9 +1871,6 @@ namespace PepperDash.Essentials } } - /// - /// Gracefully handles conect failures by reconstructing the ws client and starting the reconnect timer - /// private void HandleConnectFailure() { _wsClient2 = null; @@ -1926,11 +1902,6 @@ namespace PepperDash.Essentials StartServerReconnectTimer(); } - /// - /// - /// - /// - /// private void HandleOpen(object sender, EventArgs e) { StopServerReconnectTimer(); @@ -1939,11 +1910,6 @@ namespace PepperDash.Essentials SendMessageObject(new MobileControlMessage { Type = "hello" }); } - /// - /// - /// - /// - /// private void HandleMessage(object sender, MessageEventArgs e) { if (e.IsPing) @@ -1960,11 +1926,6 @@ namespace PepperDash.Essentials } } - /// - /// - /// - /// - /// private void HandleError(object sender, ErrorEventArgs e) { this.LogError("Websocket error {0}", e.Message); @@ -1973,11 +1934,6 @@ namespace PepperDash.Essentials StartServerReconnectTimer(); } - /// - /// - /// - /// - /// private void HandleClose(object sender, CloseEventArgs e) { this.LogDebug( @@ -1998,9 +1954,6 @@ namespace PepperDash.Essentials StartServerReconnectTimer(); } - /// - /// After a "hello" from the server, sends config and stuff - /// private void SendInitialMessage() { this.LogInformation("Sending initial join message"); @@ -2027,7 +1980,7 @@ namespace PepperDash.Essentials } /// - /// GetConfigWithPluginVersion method + /// Get the Essentials configuration with version data /// public MobileControlEssentialsConfig GetConfigWithPluginVersion() { @@ -2062,8 +2015,13 @@ namespace PepperDash.Essentials } /// - /// SetClientUrl method + /// Set the Client URL for a given room /// + /// new App URL + /// room key. Default is null + /// + /// If roomKey is null, the URL will be set for the entire system. + /// public void SetClientUrl(string path, string roomKey = null) { var message = new MobileControlMessage @@ -2079,9 +2037,6 @@ namespace PepperDash.Essentials /// Sends any object type to server /// /// - /// - /// SendMessageObject method - /// public void SendMessageObject(IMobileControlMessage o) { @@ -2105,8 +2060,9 @@ namespace PepperDash.Essentials /// - /// SendMessageObjectToDirectClient method + /// Send a message to a client using the Direct Server /// + /// object to send public void SendMessageObjectToDirectClient(object o) { if ( @@ -2119,10 +2075,6 @@ namespace PepperDash.Essentials } } - - /// - /// Disconnects the Websocket Client and stops the heartbeat timer - /// private void CleanUpWebsocketClient() { if (_wsClient2 == null) @@ -2180,9 +2132,6 @@ namespace PepperDash.Essentials } } - /// - /// - /// private void StartServerReconnectTimer() { StopServerReconnectTimer(); @@ -2193,9 +2142,6 @@ namespace PepperDash.Essentials this.LogDebug("Reconnect Timer Started."); } - /// - /// Does what it says - /// private void StopServerReconnectTimer() { if (_serverReconnectTimer == null) @@ -2206,10 +2152,6 @@ namespace PepperDash.Essentials _serverReconnectTimer = null; } - /// - /// Resets reconnect timer and updates usercode - /// - /// private void HandleHeartBeat(JToken content) { SendMessageObject(new MobileControlMessage { Type = "/system/heartbeatAck" }); @@ -2319,16 +2261,13 @@ namespace PepperDash.Essentials } /// - /// HandleClientMessage method + /// Enqueue an incoming message for processing /// public void HandleClientMessage(string message) { _receiveQueue.Enqueue(new ProcessStringMessage(message, ParseStreamRx)); } - /// - /// - /// private void ParseStreamRx(string messageText) { if (string.IsNullOrEmpty(messageText)) @@ -2415,10 +2354,6 @@ namespace PepperDash.Essentials } } - /// - /// - /// - /// private void TestHttpRequest(string s) { { diff --git a/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlBridgeBase.cs b/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlBridgeBase.cs index ac1a851c..634255fe 100644 --- a/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlBridgeBase.cs +++ b/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlBridgeBase.cs @@ -1,23 +1,35 @@ -using PepperDash.Core; +using System; +using PepperDash.Core; using PepperDash.Core.Logging; using PepperDash.Essentials.AppServer.Messengers; using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using System; namespace PepperDash.Essentials.RoomBridges { /// - /// + /// Base class for a Mobile Control Bridge that's used to control a room /// public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoomMessenger { + /// + /// Triggered when the user Code changes + /// public event EventHandler UserCodeChanged; + /// + /// Triggered when a user should be prompted for the new code + /// public event EventHandler UserPromptedForCode; + /// + /// Triggered when a client joins to control this room + /// public event EventHandler ClientJoined; + /// + /// Triggered when the App URL for this room changes + /// public event EventHandler AppUrlChanged; /// @@ -49,15 +61,32 @@ namespace PepperDash.Essentials.RoomBridges /// public string McServerUrl { get; private set; } + /// + /// Room Name + /// public abstract string RoomName { get; } + /// + /// Room key + /// public abstract string RoomKey { get; } + /// + /// Create an instance of the class + /// + /// The unique key for this bridge + /// The message path for this bridge protected MobileControlBridgeBase(string key, string messagePath) : base(key, messagePath) { } + /// + /// Create an instance of the class + /// + /// The unique key for this bridge + /// The message path for this bridge + /// The device associated with this bridge protected MobileControlBridgeBase(string key, string messagePath, IKeyName device) : base(key, messagePath, device) { @@ -110,6 +139,10 @@ namespace PepperDash.Essentials.RoomBridges SetUserCode(code); } + /// + /// Update the App Url with the provided URL + /// + /// The new App URL public virtual void UpdateAppUrl(string url) { AppUrl = url; @@ -137,16 +170,25 @@ namespace PepperDash.Essentials.RoomBridges OnUserCodeChanged(); } + /// + /// Trigger the UserCodeChanged event + /// protected void OnUserCodeChanged() { UserCodeChanged?.Invoke(this, new EventArgs()); } + /// + /// Trigger the UserPromptedForCode event + /// protected void OnUserPromptedForCode() { UserPromptedForCode?.Invoke(this, new EventArgs()); } + /// + /// Trigger the ClientJoined event + /// protected void OnClientJoined() { ClientJoined?.Invoke(this, new EventArgs()); diff --git a/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs b/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs index f0463f27..742251db 100644 --- a/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs +++ b/src/PepperDash.Essentials.MobileControl/RoomBridges/MobileControlEssentialsRoomBridge.cs @@ -41,24 +41,37 @@ namespace PepperDash.Essentials.RoomBridges /// public string DefaultRoomKey { get; private set; } /// - /// + /// Gets the name of the room /// public override string RoomName { get { return Room.Name; } } + /// + /// Gets the key of the room + /// public override string RoomKey { get { return Room.Key; } } + /// + /// Initializes a new instance of the class with the specified room + /// + /// The essentials room to bridge public MobileControlEssentialsRoomBridge(IEssentialsRoom room) : this($"mobileControlBridge-{room.Key}", room.Key, room) { Room = room; } + /// + /// Initializes a new instance of the class with the specified parameters + /// + /// The unique key for this bridge + /// The key of the room to bridge + /// The essentials room to bridge public MobileControlEssentialsRoomBridge(string key, string roomKey, IEssentialsRoom room) : base(key, $"/room/{room.Key}", room as Device) { DefaultRoomKey = roomKey; @@ -66,7 +79,9 @@ namespace PepperDash.Essentials.RoomBridges AddPreActivationAction(GetRoom); } - + /// + /// Registers all message handling actions with the AppServer for this room bridge + /// protected override void RegisterActions() { // we add actions to the messaging system with a path, and a related action. Custom action @@ -284,6 +299,9 @@ namespace PepperDash.Essentials.RoomBridges Room = tempRoom; } + /// + /// Handles user code changes and generates QR code URL + /// protected override void UserCodeChange() { Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Server user code changed: {userCode}", this, UserCode); @@ -807,18 +825,33 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)] public RoomConfiguration Configuration { get; set; } + /// + /// Gets or sets the activity mode of the room + /// [JsonProperty("activityMode", NullValueHandling = NullValueHandling.Ignore)] public int? ActivityMode { get; set; } + /// + /// Gets or sets whether advanced sharing is active + /// [JsonProperty("advancedSharingActive", NullValueHandling = NullValueHandling.Ignore)] public bool? AdvancedSharingActive { get; set; } + /// + /// Gets or sets whether the room is powered on + /// [JsonProperty("isOn", NullValueHandling = NullValueHandling.Ignore)] public bool? IsOn { get; set; } + /// + /// Gets or sets whether the room is warming up + /// [JsonProperty("isWarmingUp", NullValueHandling = NullValueHandling.Ignore)] public bool? IsWarmingUp { get; set; } + /// + /// Gets or sets whether the room is cooling down + /// [JsonProperty("isCoolingDown", NullValueHandling = NullValueHandling.Ignore)] public bool? IsCoolingDown { get; set; } @@ -834,9 +867,15 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)] public ShareState Share { get; set; } + /// + /// Gets or sets the volume controls collection + /// [JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)] public Dictionary Volumes { get; set; } + /// + /// Gets or sets whether the room is in a call + /// [JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)] public bool? IsInCall { get; set; } } @@ -853,9 +892,15 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("currentShareText", NullValueHandling = NullValueHandling.Ignore)] public string CurrentShareText { get; set; } + /// + /// Gets or sets whether sharing is enabled + /// [JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)] public bool? Enabled { get; set; } + /// + /// Gets or sets whether content is currently being shared + /// [JsonProperty("isSharing", NullValueHandling = NullValueHandling.Ignore)] public bool? IsSharing { get; set; } } @@ -865,24 +910,45 @@ namespace PepperDash.Essentials.RoomBridges /// public class RoomConfiguration { + /// + /// Gets or sets whether the room has video conferencing capabilities + /// [JsonProperty("hasVideoConferencing", NullValueHandling = NullValueHandling.Ignore)] public bool? HasVideoConferencing { get; set; } + /// + /// Gets or sets whether the video codec is a Zoom Room + /// [JsonProperty("videoCodecIsZoomRoom", NullValueHandling = NullValueHandling.Ignore)] public bool? VideoCodecIsZoomRoom { get; set; } + /// + /// Gets or sets whether the room has audio conferencing capabilities + /// [JsonProperty("hasAudioConferencing", NullValueHandling = NullValueHandling.Ignore)] public bool? HasAudioConferencing { get; set; } + /// + /// Gets or sets whether the room has environmental controls (lighting, shades, etc.) + /// [JsonProperty("hasEnvironmentalControls", NullValueHandling = NullValueHandling.Ignore)] public bool? HasEnvironmentalControls { get; set; } + /// + /// Gets or sets whether the room has camera controls + /// [JsonProperty("hasCameraControls", NullValueHandling = NullValueHandling.Ignore)] public bool? HasCameraControls { get; set; } + /// + /// Gets or sets whether the room has set-top box controls + /// [JsonProperty("hasSetTopBoxControls", NullValueHandling = NullValueHandling.Ignore)] public bool? HasSetTopBoxControls { get; set; } + /// + /// Gets or sets whether the room has routing controls + /// [JsonProperty("hasRoutingControls", NullValueHandling = NullValueHandling.Ignore)] public bool? HasRoutingControls { get; set; } @@ -949,6 +1015,9 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)] public string DefaultDisplayKey { get; set; } + /// + /// Gets or sets the destinations dictionary keyed by destination type + /// [JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)] public Dictionary Destinations { get; set; } @@ -959,9 +1028,15 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)] public List EnvironmentalDevices { get; set; } + /// + /// Gets or sets the source list for the room + /// [JsonProperty("sourceList", NullValueHandling = NullValueHandling.Ignore)] public Dictionary SourceList { get; set; } + /// + /// Gets or sets the destination list for the room + /// [JsonProperty("destinationList", NullValueHandling = NullValueHandling.Ignore)] public Dictionary DestinationList { get; set; } @@ -972,6 +1047,9 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("audioControlPointList", NullValueHandling = NullValueHandling.Ignore)] public AudioControlPointListItem AudioControlPointList { get; set; } + /// + /// Gets or sets the camera list for the room + /// [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)] public Dictionary CameraList { get; set; } @@ -1004,9 +1082,15 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)] public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; } + /// + /// Gets or sets whether the room supports advanced sharing features + /// [JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)] public bool? SupportsAdvancedSharing { get; set; } + /// + /// Gets or sets whether the user can change the share mode + /// [JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)] public bool? UserCanChangeShareMode { get; set; } @@ -1017,6 +1101,9 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("roomCombinerKey", NullValueHandling = NullValueHandling.Ignore)] public string RoomCombinerKey { get; set; } + /// + /// Initializes a new instance of the class + /// public RoomConfiguration() { Destinations = new Dictionary(); @@ -1046,6 +1133,11 @@ namespace PepperDash.Essentials.RoomBridges [JsonProperty("deviceType", NullValueHandling = NullValueHandling.Ignore)] public eEnvironmentalDeviceTypes DeviceType { get; private set; } + /// + /// Initializes a new instance of the class + /// + /// The device key + /// The environmental device type public EnvironmentalDeviceConfiguration(string key, eEnvironmentalDeviceTypes type) { DeviceKey = key; @@ -1054,14 +1146,29 @@ namespace PepperDash.Essentials.RoomBridges } /// - /// Enumeration of eEnvironmentalDeviceTypes values + /// Enumeration of environmental device types /// public enum eEnvironmentalDeviceTypes { + /// + /// No environmental device type specified + /// None, + /// + /// Lighting device type + /// Lighting, + /// + /// Shade device type + /// Shade, + /// + /// Shade controller device type + /// ShadeController, + /// + /// Relay device type + /// Relay, } diff --git a/src/PepperDash.Essentials.MobileControl/Services/MobileControlApiService.cs b/src/PepperDash.Essentials.MobileControl/Services/MobileControlApiService.cs index 4a84f8f1..508fb776 100644 --- a/src/PepperDash.Essentials.MobileControl/Services/MobileControlApiService.cs +++ b/src/PepperDash.Essentials.MobileControl/Services/MobileControlApiService.cs @@ -1,18 +1,22 @@ -using PepperDash.Core; -using System; +using System; using System.Net.Http; using System.Threading.Tasks; +using PepperDash.Core; namespace PepperDash.Essentials.Services { /// - /// Represents a MobileControlApiService + /// Service for interacting with a Mobile Control Edge server instance /// public class MobileControlApiService { private readonly HttpClient _client; + /// + /// Create an instance of the class. + /// + /// Mobile Control Edge API URL public MobileControlApiService(string apiUrl) { var handler = new HttpClientHandler @@ -24,6 +28,13 @@ namespace PepperDash.Essentials.Services _client = new HttpClient(handler); } + /// + /// Send authorization request to Mobile Control Edge Server + /// + /// Mobile Control Edge API URL + /// Grant code for authorization + /// System UUID for authorization + /// Authorization response public async Task SendAuthorizationRequest(string apiUrl, string grantCode, string systemUuid) { try diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITheme.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITheme.cs index e5ba76cf..c7efbf4c 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITheme.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITheme.cs @@ -7,8 +7,15 @@ namespace PepperDash.Essentials.Touchpanel /// public interface ITheme : IKeyed { + /// + /// Current theme + /// string Theme { get; } + /// + /// Set the theme with the given value + /// + /// The theme to set void UpdateTheme(string theme); } } diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControl.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControl.cs index 3beb92c5..055ad80c 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControl.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControl.cs @@ -8,12 +8,24 @@ namespace PepperDash.Essentials.Touchpanel /// public interface ITswAppControl : IKeyed { + /// + /// Updates when the Zoom Room Control Application opens or closes + /// BoolFeedback AppOpenFeedback { get; } + /// + /// Hide the Zoom App and show the User Control Application + /// void HideOpenApp(); + /// + /// Close the Zoom App and show the User Control Application + /// void CloseOpenApp(); + /// + /// Open the Zoom App + /// void OpenApp(); } @@ -22,10 +34,19 @@ namespace PepperDash.Essentials.Touchpanel /// public interface ITswZoomControl : IKeyed { + /// + /// Updates when Zoom has an incoming call + /// BoolFeedback ZoomIncomingCallFeedback { get; } + /// + /// Updates when Zoom is in a call + /// BoolFeedback ZoomInCallFeedback { get; } + /// + /// End a Zoom Call + /// void EndZoomCall(); } } diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControlMessenger.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControlMessenger.cs index f9581c74..d4c55f87 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControlMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswAppControlMessenger.cs @@ -7,17 +7,24 @@ using PepperDash.Essentials.AppServer.Messengers; namespace PepperDash.Essentials.Touchpanel { /// - /// Represents a ITswAppControlMessenger + /// Messenger for controlling the Zoom App on a TSW Panel that supports the Zoom Room Control Application /// public class ITswAppControlMessenger : MessengerBase { private readonly ITswAppControl _appControl; + /// + /// Create an instance of the class. + /// + /// The key for this messenger + /// The message path for this messenger + /// The device for this messenger public ITswAppControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device) { _appControl = device as ITswAppControl; } + /// protected override void RegisterActions() { if (_appControl == null) @@ -43,14 +50,14 @@ namespace PepperDash.Essentials.Touchpanel }; } - private void SendFullStatus() + private void SendFullStatus(string id = null) { var message = new TswAppStateMessage { AppOpen = _appControl.AppOpenFeedback.BoolValue, }; - PostStatusMessage(message); + PostStatusMessage(message, id); } } @@ -59,6 +66,9 @@ namespace PepperDash.Essentials.Touchpanel /// public class TswAppStateMessage : DeviceStateMessageBase { + /// + /// True if the Zoom app is open on a TSW panel + /// [JsonProperty("appOpen", NullValueHandling = NullValueHandling.Ignore)] public bool? AppOpen { get; set; } } diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswZoomControlMessenger.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswZoomControlMessenger.cs index 48c7fb7f..13d1dc59 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswZoomControlMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/ITswZoomControlMessenger.cs @@ -8,17 +8,24 @@ using PepperDash.Essentials.AppServer.Messengers; namespace PepperDash.Essentials.Touchpanel { /// - /// Represents a ITswZoomControlMessenger + /// Messenger to handle /// public class ITswZoomControlMessenger : MessengerBase { private readonly ITswZoomControl _zoomControl; + /// + /// Create in instance of the class for the given device + /// + /// The key for this messenger + /// The message path for this messenger + /// The device for this messenger public ITswZoomControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device) { _zoomControl = device as ITswZoomControl; } + /// protected override void RegisterActions() { if (_zoomControl == null) @@ -27,7 +34,9 @@ namespace PepperDash.Essentials.Touchpanel return; } - AddAction($"/fullStatus", (id, context) => SendFullStatus()); + AddAction($"/fullStatus", (id, context) => SendFullStatus(id)); + + AddAction($"/zoomStatus", (id, content) => SendFullStatus(id)); AddAction($"/endCall", (id, context) => _zoomControl.EndZoomCall()); @@ -53,7 +62,7 @@ namespace PepperDash.Essentials.Touchpanel }; } - private void SendFullStatus() + private void SendFullStatus(string id = null) { var message = new TswZoomStateMessage { @@ -61,7 +70,7 @@ namespace PepperDash.Essentials.Touchpanel IncomingCall = _zoomControl?.ZoomIncomingCallFeedback.BoolValue }; - PostStatusMessage(message); + PostStatusMessage(message, id); } } @@ -70,9 +79,16 @@ namespace PepperDash.Essentials.Touchpanel /// public class TswZoomStateMessage : DeviceStateMessageBase { + /// + /// True if the panel is in a Zoom call + /// [JsonProperty("inCall", NullValueHandling = NullValueHandling.Ignore)] public bool? InCall { get; set; } + /// + /// True if there is an incoming Zoom call + /// + [JsonProperty("incomingCall", NullValueHandling = NullValueHandling.Ignore)] public bool? IncomingCall { get; set; } } diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/ThemeMessenger.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/ThemeMessenger.cs index 089665d9..0f02bc59 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/ThemeMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/ThemeMessenger.cs @@ -7,17 +7,24 @@ using PepperDash.Essentials.AppServer.Messengers; namespace PepperDash.Essentials.Touchpanel { /// - /// Represents a ThemeMessenger + /// Messenger to save the current theme (light/dark) and send to a device /// public class ThemeMessenger : MessengerBase { private readonly ITheme _tpDevice; + /// + /// Create an instance of the class + /// + /// The key for this messenger + /// The path for this messenger + /// The device for this messenger public ThemeMessenger(string key, string path, ITheme device) : base(key, path, device as Device) { _tpDevice = device; } + /// protected override void RegisterActions() { AddAction("/fullStatus", (id, content) => diff --git a/src/PepperDash.Essentials.MobileControl/UserCodeChanged.cs b/src/PepperDash.Essentials.MobileControl/UserCodeChanged.cs index ab899167..6c510d14 100644 --- a/src/PepperDash.Essentials.MobileControl/UserCodeChanged.cs +++ b/src/PepperDash.Essentials.MobileControl/UserCodeChanged.cs @@ -3,12 +3,19 @@ using System; namespace PepperDash.Essentials { /// - /// Represents a UserCodeChanged + /// Defines the action to take when the User code changes /// public class UserCodeChanged { + /// + /// Action to take when the User Code changes + /// public Action UpdateUserCode { get; private set; } + /// + /// create an instance of the class + /// + /// action to take when the User Code changes public UserCodeChanged(Action updateMethod) { UpdateUserCode = updateMethod; diff --git a/src/PepperDash.Essentials.MobileControl/Volumes.cs b/src/PepperDash.Essentials.MobileControl/Volumes.cs index 84accd26..44febbfc 100644 --- a/src/PepperDash.Essentials.MobileControl/Volumes.cs +++ b/src/PepperDash.Essentials.MobileControl/Volumes.cs @@ -15,15 +15,17 @@ namespace PepperDash.Essentials [JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)] public Volume Master { get; set; } + /// + /// Aux Faders as configured in the room + /// [JsonProperty("auxFaders", NullValueHandling = NullValueHandling.Ignore)] public Dictionary AuxFaders { get; set; } + /// + /// Count of aux faders for this system + /// [JsonProperty("numberOfAuxFaders", NullValueHandling = NullValueHandling.Ignore)] public int? NumberOfAuxFaders { get; set; } - - public Volumes() - { - } } /// @@ -31,16 +33,21 @@ namespace PepperDash.Essentials /// public class Volume { - /// /// Gets or sets the Key /// [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)] public string Key { get; set; } + /// + /// Level for this volume object + /// [JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)] public int? Level { get; set; } + /// + /// True if this volume control is muted + /// [JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)] public bool? Muted { get; set; } @@ -51,12 +58,21 @@ namespace PepperDash.Essentials [JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)] public string Label { get; set; } + /// + /// True if this volume object has mute control + /// [JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)] public bool? HasMute { get; set; } + /// + /// True if this volume object has Privacy mute control + /// [JsonProperty("hasPrivacyMute", NullValueHandling = NullValueHandling.Ignore)] public bool? HasPrivacyMute { get; set; } + /// + /// True if the privacy mute is muted + /// [JsonProperty("privacyMuted", NullValueHandling = NullValueHandling.Ignore)] public bool? PrivacyMuted { get; set; } @@ -68,6 +84,15 @@ namespace PepperDash.Essentials [JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)] public string MuteIcon { get; set; } + /// + /// Create an instance of the class + /// + /// The key for this volume object + /// The level for this volume object + /// True if this volume control is muted + /// The label for this volume object + /// True if this volume object has mute control + /// The mute icon for this volume object public Volume(string key, int level, bool muted, string label, bool hasMute, string muteIcon) : this(key) { @@ -78,18 +103,32 @@ namespace PepperDash.Essentials MuteIcon = muteIcon; } + /// + /// Create an instance of the class + /// + /// The key for this volume object + /// The level for this volume object public Volume(string key, int level) : this(key) { Level = level; } + /// + /// Create an instance of the class + /// + /// The key for this volume object + /// True if this volume control is muted public Volume(string key, bool muted) : this(key) { Muted = muted; } + /// + /// Create an instance of the class + /// + /// The key for this volume object public Volume(string key) { Key = key; diff --git a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/ActionPathsHandler.cs b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/ActionPathsHandler.cs index 84d0318a..1c204e8e 100644 --- a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/ActionPathsHandler.cs +++ b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/ActionPathsHandler.cs @@ -12,11 +12,20 @@ namespace PepperDash.Essentials.WebApiHandlers public class ActionPathsHandler : WebApiBaseRequestHandler { private readonly MobileControlSystemController mcController; + + /// + /// Create an instance of the class. + /// + /// public ActionPathsHandler(MobileControlSystemController controller) : base(true) { mcController = controller; } + /// + /// Handle a request to get the action paths + /// + /// Request Context protected override void HandleGet(HttpCwsContext context) { var response = JsonConvert.SerializeObject(new ActionPathsResponse(mcController)); @@ -37,9 +46,16 @@ namespace PepperDash.Essentials.WebApiHandlers [JsonIgnore] private readonly MobileControlSystemController mcController; + /// + /// Registered action paths for this system + /// [JsonProperty("actionPaths")] public List ActionPaths => mcController.GetActionDictionaryPaths().Select((path) => new ActionPath { MessengerKey = path.Item1, Path = path.Item2 }).ToList(); + /// + /// Create an instance of the class. + /// + /// public ActionPathsResponse(MobileControlSystemController mcController) { this.mcController = mcController; diff --git a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileAuthRequestHandler.cs b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileAuthRequestHandler.cs index 352c56e5..5d9e9766 100644 --- a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileAuthRequestHandler.cs +++ b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileAuthRequestHandler.cs @@ -1,10 +1,10 @@ -using Crestron.SimplSharp.WebScripting; +using System; +using System.Threading.Tasks; +using Crestron.SimplSharp.WebScripting; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Core.Web.RequestHandlers; using PepperDash.Essentials.Core.Web; -using System; -using System.Threading.Tasks; namespace PepperDash.Essentials.WebApiHandlers { @@ -15,11 +15,20 @@ namespace PepperDash.Essentials.WebApiHandlers { private readonly MobileControlSystemController mcController; + /// + /// Create an instance of the class. + /// + /// public MobileAuthRequestHandler(MobileControlSystemController controller) : base(true) { mcController = controller; } + /// + /// Handle authorization request for this processor + /// + /// request context + /// Task protected override async Task HandlePost(HttpCwsContext context) { try diff --git a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileInfoHandler.cs b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileInfoHandler.cs index ddd319e3..363076c0 100644 --- a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileInfoHandler.cs +++ b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/MobileInfoHandler.cs @@ -11,16 +11,25 @@ using PepperDash.Essentials.WebSocketServer; namespace PepperDash.Essentials.WebApiHandlers { /// - /// Represents a MobileInfoHandler + /// Represents a MobileInfoHandler. Used with the Essentials CWS API /// public class MobileInfoHandler : WebApiBaseRequestHandler { private readonly MobileControlSystemController mcController; + + /// + /// Create an instance of the class. + /// + /// public MobileInfoHandler(MobileControlSystemController controller) : base(true) { mcController = controller; } + /// + /// Get Mobile Control Information + /// + /// protected override void HandleGet(HttpCwsContext context) { try @@ -50,14 +59,22 @@ namespace PepperDash.Essentials.WebApiHandlers [JsonIgnore] private readonly MobileControlSystemController mcController; + /// + /// Edge Server. Null if edge server is disabled + /// [JsonProperty("edgeServer", NullValueHandling = NullValueHandling.Ignore)] public MobileControlEdgeServer EdgeServer => mcController.Config.EnableApiServer ? new MobileControlEdgeServer(mcController) : null; - + /// + /// Direct server. Null if the direct server is disabled + /// [JsonProperty("directServer", NullValueHandling = NullValueHandling.Ignore)] public MobileControlDirectServer DirectServer => mcController.Config.DirectServer.EnableDirectServer ? new MobileControlDirectServer(mcController.DirectServer) : null; - + /// + /// Create in instace of the class. + /// + /// public InformationResponse(MobileControlSystemController controller) { mcController = controller; @@ -72,24 +89,46 @@ namespace PepperDash.Essentials.WebApiHandlers [JsonIgnore] private readonly MobileControlSystemController mcController; + /// + /// Mobile Control Edge Server address for this system + /// [JsonProperty("serverAddress")] public string ServerAddress => mcController.Config == null ? "No Config" : mcController.Host; + /// + /// System Name for this system + /// [JsonProperty("systemName")] public string SystemName => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].RoomName : "No Config"; + /// + /// System URL for this system + /// [JsonProperty("systemUrl")] public string SystemUrl => ConfigReader.ConfigObject.SystemUrl; + /// + /// User code to use in MC UI for this system + /// [JsonProperty("userCode")] public string UserCode => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].UserCode : "Not available"; + /// + /// True if connected to edge server + /// [JsonProperty("connected")] public bool Connected => mcController.Connected; + /// + /// Seconds since last comms with edge server + /// [JsonProperty("secondsSinceLastAck")] public int SecondsSinceLastAck => (DateTime.Now - mcController.LastAckMessage).Seconds; + /// + /// Create an instance of the class. + /// + /// controller to use for this public MobileControlEdgeServer(MobileControlSystemController controller) { mcController = controller; @@ -104,25 +143,43 @@ namespace PepperDash.Essentials.WebApiHandlers [JsonIgnore] private readonly MobileControlWebsocketServer directServer; + /// + /// URL to use to interact with this server + /// [JsonProperty("userAppUrl")] public string UserAppUrl => $"{directServer.UserAppUrlPrefix}/[insert_client_token]"; + /// + /// TCP/IP Port this server is configured to use + /// [JsonProperty("serverPort")] public int ServerPort => directServer.Port; + /// + /// Count of defined tokens for this server + /// [JsonProperty("tokensDefined")] public int TokensDefined => directServer.UiClientContexts.Count; + /// + /// Count of connected clients + /// [JsonProperty("clientsConnected")] public int ClientsConnected => directServer.ConnectedUiClientsCount; + /// + /// List of tokens and connected clients for this server + /// [JsonProperty("clients")] public List Clients => directServer.UiClientContexts .Select(context => (context, clients: directServer.UiClients.Where(client => client.Value.Token == context.Value.Token.Token).Select(c => c.Value).ToList())) .Select((clientTuple, i) => new MobileControlDirectClient(clientTuple.clients, clientTuple.context, i, directServer.UserAppUrlPrefix)) .ToList(); - + /// + /// Create an instance of the class. + /// + /// public MobileControlDirectServer(MobileControlWebsocketServer server) { directServer = server; @@ -146,23 +203,41 @@ namespace PepperDash.Essentials.WebApiHandlers [JsonIgnore] private readonly string urlPrefix; + /// + /// Client number for this client + /// [JsonProperty("clientNumber")] public string ClientNumber => $"{clientNumber}"; + /// + /// Room Key for this client + /// [JsonProperty("roomKey")] public string RoomKey => context.Token.RoomKey; + /// + /// Touchpanel Key, if defined, for this client + /// [JsonProperty("touchpanelKey")] public string TouchpanelKey => context.Token.TouchpanelKey; + /// + /// URL for this client + /// [JsonProperty("url")] public string Url => $"{urlPrefix}{Key}"; + /// + /// Token for this client + /// [JsonProperty("token")] public string Token => Key; private readonly List clients; + /// + /// List of status for all connected UI Clients + /// [JsonProperty("clientStatus")] public List ClientStatus => clients.Select(c => new ClientStatus(c)).ToList(); @@ -183,14 +258,27 @@ namespace PepperDash.Essentials.WebApiHandlers } } + /// + /// Report the status of a UiClient + /// public class ClientStatus { private readonly UiClient client; + /// + /// True if client is connected + /// public bool Connected => client != null && client.Context.WebSocket.IsAlive; + /// + /// Get the time this client has been connected + /// public double Duration => client == null ? 0 : client.ConnectedDuration.TotalSeconds; + /// + /// Create an instance of the class for the specified client + /// + /// client to report on public ClientStatus(UiClient client) { this.client = client; diff --git a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/UiClientHandler.cs b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/UiClientHandler.cs index 23b79d93..2f972ddf 100644 --- a/src/PepperDash.Essentials.MobileControl/WebApiHandlers/UiClientHandler.cs +++ b/src/PepperDash.Essentials.MobileControl/WebApiHandlers/UiClientHandler.cs @@ -14,11 +14,20 @@ namespace PepperDash.Essentials.WebApiHandlers public class UiClientHandler : WebApiBaseRequestHandler { private readonly MobileControlWebsocketServer server; + + /// + /// Essentials CWS API handler for the MC Direct Server + /// + /// Direct Server instance public UiClientHandler(MobileControlWebsocketServer directServer) : base(true) { server = directServer; } + /// + /// Create a client for the Direct Server + /// + /// HTTP Context for this request protected override void HandlePost(HttpCwsContext context) { var req = context.Request; @@ -65,6 +74,10 @@ namespace PepperDash.Essentials.WebApiHandlers res.End(); } + /// + /// Handle DELETE request for a Client + /// + /// protected override void HandleDelete(HttpCwsContext context) { var req = context.Request; diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinResponse.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinResponse.cs index ba214db4..1529d0fe 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinResponse.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinResponse.cs @@ -17,9 +17,15 @@ namespace PepperDash.Essentials.WebSocketServer [JsonProperty("clientId")] public string ClientId { get; set; } + /// + /// Room Key for this client + /// [JsonProperty("roomKey")] public string RoomKey { get; set; } + /// + /// System UUID for this system + /// [JsonProperty("systemUUid")] public string SystemUuid { get; set; } diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinToken.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinToken.cs index 7352dc6f..63fdcdd4 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinToken.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/JoinToken.cs @@ -14,10 +14,19 @@ namespace PepperDash.Essentials.WebSocketServer /// public string Code { get; set; } + /// + /// Room Key this token is associated with + /// public string RoomKey { get; set; } + /// + /// Unique ID for this token + /// public string Uuid { get; set; } + /// + /// Touchpanel Key this token is associated with, if this is a touch panel token + /// public string TouchpanelKey { get; set; } = ""; /// diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs index f62e136a..759886ff 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs @@ -315,6 +315,9 @@ namespace PepperDash.Essentials.WebSocketServer } } + /// + /// Set the internal logging level for the Websocket Server + /// public void SetWebsocketLogLevel(LogLevel level) { CrestronConsole.ConsoleCommandResponse($"Setting direct server debug level to {level}", level.ToString()); diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/ServerTokenSecrets.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/ServerTokenSecrets.cs index 3fa2fb0c..ad9a1d66 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/ServerTokenSecrets.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/ServerTokenSecrets.cs @@ -13,8 +13,15 @@ namespace PepperDash.Essentials.WebSocketServer /// public string GrantCode { get; set; } + /// + /// Gets or sets the Tokens for this server + /// public Dictionary Tokens { get; set; } + /// + /// Initialize a new instance of the class with the provided grant code + /// + /// The grant code for this server public ServerTokenSecrets(string grantCode) { GrantCode = grantCode; diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/UiClientContext.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/UiClientContext.cs index 6782306f..ffc09e90 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/UiClientContext.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/UiClientContext.cs @@ -14,6 +14,10 @@ namespace PepperDash.Essentials.WebSocketServer /// public JoinToken Token { get; private set; } + /// + /// Initialize an instance of the class with the provided token + /// + /// token for this client public UiClientContext(JoinToken token) { Token = token; diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/Version.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/Version.cs index 5552e29b..1255f624 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/Version.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/Version.cs @@ -8,12 +8,25 @@ namespace PepperDash.Essentials.WebSocketServer /// public class Version { + /// + /// Server version this Websocket is connected to + /// [JsonProperty("serverVersion")] public string ServerVersion { get; set; } + /// + /// True if the server is on a processor + /// + [JsonProperty("serverIsRunningOnProcessorHardware")] public bool ServerIsRunningOnProcessorHardware { get; private set; } + /// + /// Initialize an instance of the class + /// + /// + /// the property is set to true by default. + /// public Version() { ServerIsRunningOnProcessorHardware = true; diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/WebSocketServerSecretProvider.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/WebSocketServerSecretProvider.cs index cf125d29..3dd67bd8 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/WebSocketServerSecretProvider.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/WebSocketServerSecretProvider.cs @@ -13,25 +13,28 @@ namespace PepperDash.Essentials.WebSocketServer } /// - /// Represents a WebSocketServerSecret + /// Stores a secret value using the provided secret store provider /// public class WebSocketServerSecret : ISecret { /// - /// Gets or sets the Provider + /// Gets the Secret Provider associated with this secret /// public ISecretProvider Provider { get; private set; } /// - /// Gets or sets the Key + /// Gets the Key associated with this secret /// public string Key { get; private set; } /// - /// Gets or sets the Value + /// Gets the Value associated with this secret /// public object Value { get; private set; } + /// + /// Initialize and instance of the class + /// public WebSocketServerSecret(string key, object value, ISecretProvider provider) { Key = key;