using System; using System.Collections.Generic; using System.Linq; using Crestron.SimplSharp.WebScripting; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Core.Web.RequestHandlers; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.WebSocketServer; namespace PepperDash.Essentials.WebApiHandlers { /// /// 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 { var response = new InformationResponse(mcController); context.Response.StatusCode = 200; context.Response.ContentType = "application/json"; context.Response.Write(JsonConvert.SerializeObject(response), false); context.Response.End(); } catch (Exception ex) { Debug.LogMessage(ex, "exception showing mobile info"); context.Response.StatusCode = 500; context.Response.End(); } } } /// /// Represents a InformationResponse /// public class InformationResponse { [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 an instance of the class. /// /// public InformationResponse(MobileControlSystemController controller) { mcController = controller; } } /// /// Represents a MobileControlEdgeServer /// public class MobileControlEdgeServer { [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; } } /// /// Represents a MobileControlDirectServer /// public class MobileControlDirectServer { [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; } } /// /// Represents a MobileControlDirectClient /// public class MobileControlDirectClient { [JsonIgnore] private readonly UiClientContext context; [JsonIgnore] private readonly string Key; [JsonIgnore] private readonly int clientNumber; [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(); /// /// Create an instance of the class. /// /// List of Websocket Clients /// Context for the client /// Index of the client /// URL prefix for the client public MobileControlDirectClient(List clients, KeyValuePair context, int index, string urlPrefix) { this.context = context.Value; Key = context.Key; clientNumber = index; this.urlPrefix = urlPrefix; this.clients = clients; } } /// /// 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; } } }