From 06341b14f3022906d1913ca0f553e5c73c4ee1ee Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 24 Sep 2025 14:49:41 -0600 Subject: [PATCH] feat: Adds device interface support info to joinroom response in MC websocket server. Enhance MessengerBase and WebSocketServer functionality Updated MessengerBase with new methods for action management and message posting, along with improved documentation. Introduced DeviceMessageBase for better message representation. Enhanced MobileControlWebsocketServer to support device interfaces, adding DeviceInterfaceSupport to JoinResponse and a new DeviceInterfaceInfo class for detailed device information. --- .../Messengers/MessengerBase.cs | 59 ++++++++++++++++++- .../MobileControlWebsocketServer.cs | 47 ++++++++++++++- 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/MessengerBase.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/MessengerBase.cs index ad8e67a3..4d96cf81 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/MessengerBase.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/MessengerBase.cs @@ -15,12 +15,18 @@ namespace PepperDash.Essentials.AppServer.Messengers /// public abstract class MessengerBase : EssentialsDevice, IMobileControlMessenger { + /// + /// The device this messenger is associated with + /// protected IKeyName _device; private readonly List _deviceInterfaces; private readonly Dictionary> _actions = new Dictionary>(); + /// + /// Gets the DeviceKey + /// public string DeviceKey => _device?.Key ?? ""; @@ -50,6 +56,12 @@ namespace PepperDash.Essentials.AppServer.Messengers MessagePath = messagePath; } + /// + /// Constructor for a messenger associated with a device + /// + /// + /// + /// protected MessengerBase(string key, string messagePath, IKeyName device) : this(key, messagePath) { @@ -96,6 +108,11 @@ namespace PepperDash.Essentials.AppServer.Messengers action(id, content); } + /// + /// Adds an action for a given path + /// + /// + /// protected void AddAction(string path, Action action) { if (_actions.ContainsKey(path)) @@ -115,6 +132,10 @@ namespace PepperDash.Essentials.AppServer.Messengers return _actions.Keys.ToList(); } + /// + /// Removes an action for a given path + /// + /// protected void RemoveAction(string path) { if (!_actions.ContainsKey(path)) @@ -128,7 +149,6 @@ namespace PepperDash.Essentials.AppServer.Messengers /// /// Implemented in extending classes. Wire up API calls and feedback here /// - /// protected virtual void RegisterActions() { @@ -137,8 +157,8 @@ namespace PepperDash.Essentials.AppServer.Messengers /// /// Helper for posting status message /// - /// /// + /// Optional client id that will direct the message back to only that client protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null) { try @@ -169,6 +189,12 @@ namespace PepperDash.Essentials.AppServer.Messengers } } + /// + /// Helper for posting status message + /// + /// + /// + /// Optional client id that will direct the message back to only that client protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null) { try @@ -192,6 +218,12 @@ namespace PepperDash.Essentials.AppServer.Messengers } } + /// + /// Helper for posting status message + /// + /// + /// + /// Optional client id that will direct the message back to only that client protected void PostStatusMessage(JToken content, string type = "", string clientId = null) { try @@ -204,6 +236,10 @@ namespace PepperDash.Essentials.AppServer.Messengers } } + /// + /// Helper for posting event message + /// + /// protected void PostEventMessage(DeviceEventMessageBase message) { message.Key = _device.Key; @@ -217,6 +253,11 @@ namespace PepperDash.Essentials.AppServer.Messengers }); } + /// + /// Helper for posting event message + /// + /// + /// protected void PostEventMessage(DeviceEventMessageBase message, string eventType) { message.Key = _device.Key; @@ -232,6 +273,10 @@ namespace PepperDash.Essentials.AppServer.Messengers }); } + /// + /// Helper for posting event message with no content + /// + /// protected void PostEventMessage(string eventType) { AppServerController?.SendMessageObject(new MobileControlMessage @@ -243,6 +288,9 @@ namespace PepperDash.Essentials.AppServer.Messengers } + /// + /// Base class for device messages that include the type of message + /// public abstract class DeviceMessageBase { /// @@ -266,10 +314,11 @@ namespace PepperDash.Essentials.AppServer.Messengers [JsonProperty("messageType")] public string MessageType => GetType().Name; - [JsonProperty("messageBasePath")] /// /// Gets or sets the MessageBasePath /// + [JsonProperty("messageBasePath")] + public string MessageBasePath { get; set; } } @@ -284,6 +333,10 @@ namespace PepperDash.Essentials.AppServer.Messengers [JsonProperty("interfaces")] public List Interfaces { get; private set; } + /// + /// Sets the interfaces implemented by the device sending the message + /// + /// public void SetInterfaces(List interfaces) { Interfaces = interfaces; diff --git a/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs b/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs index db5cf06a..4cb9de84 100644 --- a/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs +++ b/src/PepperDash.Essentials.MobileControl/WebSocketServer/MobileControlWebsocketServer.cs @@ -972,6 +972,20 @@ namespace PepperDash.Essentials.WebSocketServer res.StatusCode = 200; res.ContentType = "application/json"; + var devices = DeviceManager.GetDevices(); + Dictionary deviceInterfaces = new Dictionary(); + + foreach (var device in devices) + { + var interfaces = device?.GetType().GetInterfaces().Select((i) => i.Name).ToList() ?? new List(); + deviceInterfaces.Add(device.Key, new DeviceInterfaceInfo + { + Key = device.Key, + Name = device is IKeyName ? (device as IKeyName).Name : "", + Interfaces = interfaces + }); + } + // Construct the response object JoinResponse jRes = new JoinResponse { @@ -985,7 +999,8 @@ namespace PepperDash.Essentials.WebSocketServer UserAppUrl = string.Format("http://{0}:{1}/mc/app", CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0), Port), - EnableDebug = false + EnableDebug = false, + DeviceInterfaceSupport = deviceInterfaces }; // Serialize to JSON and convert to Byte[] @@ -1361,6 +1376,12 @@ namespace PepperDash.Essentials.WebSocketServer [JsonProperty("config")] public object Config { get; set; } + /// + /// Gets or sets the DeviceInterfaceSupport + /// + [JsonProperty("deviceInterfaceSupport")] + public Dictionary DeviceInterfaceSupport { get; set; } + /// /// Gets or sets the CodeExpires @@ -1389,4 +1410,28 @@ namespace PepperDash.Essentials.WebSocketServer [JsonProperty("enableDebug")] public bool EnableDebug { get; set; } } + + /// + /// Represents info about a device including supproted interfaces + /// + public class DeviceInterfaceInfo : IKeyName + { + /// + /// Gets or sets the Key + /// + [JsonProperty("key")] + public string Key { get; set; } + + /// + /// Gets or sets the Name + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Gets or sets the Interfaces + /// + [JsonProperty("interfaces")] + public List Interfaces { get; set; } + } }