mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 12:44:58 +00:00
feat: add CWS endpoint to get routing devices & tielines together
This commit is contained in:
@@ -10,71 +10,71 @@ using Serilog.Events;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web
|
namespace PepperDash.Essentials.Core.Web
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a EssentialsWebApi
|
/// Represents a EssentialsWebApi
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsWebApi : EssentialsDevice
|
public class EssentialsWebApi : EssentialsDevice
|
||||||
{
|
{
|
||||||
private readonly WebApiServer _server;
|
private readonly WebApiServer _server;
|
||||||
|
|
||||||
///<example>
|
///<example>
|
||||||
/// http(s)://{ipaddress}/cws/{basePath}
|
/// http(s)://{ipaddress}/cws/{basePath}
|
||||||
/// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath}
|
/// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath}
|
||||||
/// </example>
|
/// </example>
|
||||||
private readonly string _defaultBasePath = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
|
private readonly string _defaultBasePath = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
|
||||||
? string.Format("/app{0:00}/api", InitialParametersClass.ApplicationNumber)
|
? string.Format("/app{0:00}/api", InitialParametersClass.ApplicationNumber)
|
||||||
: "/api";
|
: "/api";
|
||||||
|
|
||||||
private const int DebugTrace = 0;
|
private const int DebugTrace = 0;
|
||||||
private const int DebugInfo = 1;
|
private const int DebugInfo = 1;
|
||||||
private const int DebugVerbose = 2;
|
private const int DebugVerbose = 2;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the BasePath
|
/// Gets or sets the BasePath
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BasePath { get; private set; }
|
public string BasePath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tracks if CWS is registered
|
/// Tracks if CWS is registered
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsRegistered
|
public bool IsRegistered
|
||||||
{
|
{
|
||||||
get { return _server.IsRegistered; }
|
get { return _server.IsRegistered; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
public EssentialsWebApi(string key, string name)
|
public EssentialsWebApi(string key, string name)
|
||||||
: this(key, name, null)
|
: this(key, name, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="config"></param>
|
/// <param name="config"></param>
|
||||||
public EssentialsWebApi(string key, string name, EssentialsWebApiPropertiesConfig config)
|
public EssentialsWebApi(string key, string name, EssentialsWebApiPropertiesConfig config)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
Key = key;
|
Key = key;
|
||||||
|
|
||||||
if (config == null)
|
if (config == null)
|
||||||
BasePath = _defaultBasePath;
|
BasePath = _defaultBasePath;
|
||||||
else
|
else
|
||||||
BasePath = string.IsNullOrEmpty(config.BasePath) ? _defaultBasePath : config.BasePath;
|
BasePath = string.IsNullOrEmpty(config.BasePath) ? _defaultBasePath : config.BasePath;
|
||||||
|
|
||||||
_server = new WebApiServer(Key, Name, BasePath);
|
_server = new WebApiServer(Key, Name, BasePath);
|
||||||
|
|
||||||
SetupRoutes();
|
SetupRoutes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupRoutes()
|
private void SetupRoutes()
|
||||||
{
|
{
|
||||||
var routes = new List<HttpCwsRoute>
|
var routes = new List<HttpCwsRoute>
|
||||||
{
|
{
|
||||||
new HttpCwsRoute("versions")
|
new HttpCwsRoute("versions")
|
||||||
@@ -177,6 +177,11 @@ namespace PepperDash.Essentials.Core.Web
|
|||||||
Name = "Get Routing Ports for a device",
|
Name = "Get Routing Ports for a device",
|
||||||
RouteHandler = new GetRoutingPortsHandler()
|
RouteHandler = new GetRoutingPortsHandler()
|
||||||
},
|
},
|
||||||
|
new HttpCwsRoute("routingDevicesAndTieLines")
|
||||||
|
{
|
||||||
|
Name = "Get Routing Devices and TieLines",
|
||||||
|
RouteHandler = new GetRoutingDevicesAndTieLinesHandler()
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
AddRoute(routes);
|
AddRoute(routes);
|
||||||
@@ -211,78 +216,79 @@ namespace PepperDash.Essentials.Core.Web
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
AddRoute(new HttpCwsRoute("apiPaths") {
|
AddRoute(new HttpCwsRoute("apiPaths")
|
||||||
|
{
|
||||||
Name = "GetPaths",
|
Name = "GetPaths",
|
||||||
RouteHandler = new GetRoutesHandler(_server.GetRouteCollection(), BasePath)
|
RouteHandler = new GetRoutesHandler(_server.GetRouteCollection(), BasePath)
|
||||||
});
|
});
|
||||||
|
|
||||||
// If running on an appliance
|
// If running on an appliance
|
||||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
WEBSERVER [ON | OFF | TIMEOUT <VALUE IN SECONDS> | MAXSESSIONSPERUSER <Number of sessions>]
|
WEBSERVER [ON | OFF | TIMEOUT <VALUE IN SECONDS> | MAXSESSIONSPERUSER <Number of sessions>]
|
||||||
*/
|
*/
|
||||||
var response = string.Empty;
|
var response = string.Empty;
|
||||||
CrestronConsole.SendControlSystemCommand("webserver", ref response);
|
CrestronConsole.SendControlSystemCommand("webserver", ref response);
|
||||||
if (response.Contains("OFF")) return;
|
if (response.Contains("OFF")) return;
|
||||||
|
|
||||||
var is4Series = eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4);
|
var is4Series = eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4);
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Starting Essentials Web API on {0} Appliance", is4Series ? "4-series" : "3-series");
|
Debug.LogMessage(LogEventLevel.Verbose, "Starting Essentials Web API on {0} Appliance", is4Series ? "4-series" : "3-series");
|
||||||
|
|
||||||
_server.Start();
|
_server.Start();
|
||||||
|
|
||||||
GetPaths();
|
GetPaths();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically start CWS when running on a server (Linux OS, Virtual Control)
|
// Automatically start CWS when running on a server (Linux OS, Virtual Control)
|
||||||
Debug.LogMessage(LogEventLevel.Verbose, "Starting Essentials Web API on Virtual Control Server");
|
Debug.LogMessage(LogEventLevel.Verbose, "Starting Essentials Web API on Virtual Control Server");
|
||||||
|
|
||||||
_server.Start();
|
_server.Start();
|
||||||
|
|
||||||
GetPaths();
|
GetPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Print the available pahts
|
/// Print the available pahts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// http(s)://{ipaddress}/cws/{basePath}
|
/// http(s)://{ipaddress}/cws/{basePath}
|
||||||
/// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath}
|
/// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath}
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetPaths method
|
/// GetPaths method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void GetPaths()
|
public void GetPaths()
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, new string('-', 50));
|
Debug.LogMessage(LogEventLevel.Information, this, new string('-', 50));
|
||||||
|
|
||||||
var currentIp = CrestronEthernetHelper.GetEthernetParameter(
|
var currentIp = CrestronEthernetHelper.GetEthernetParameter(
|
||||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
|
||||||
|
|
||||||
var hostname = CrestronEthernetHelper.GetEthernetParameter(
|
var hostname = CrestronEthernetHelper.GetEthernetParameter(
|
||||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
|
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
|
||||||
|
|
||||||
var path = CrestronEnvironment.DevicePlatform == eDevicePlatform.Server
|
var path = CrestronEnvironment.DevicePlatform == eDevicePlatform.Server
|
||||||
? $"https://{hostname}/VirtualControl/Rooms/{InitialParametersClass.RoomId}/cws{BasePath}"
|
? $"https://{hostname}/VirtualControl/Rooms/{InitialParametersClass.RoomId}/cws{BasePath}"
|
||||||
: $"https://{currentIp}/cws{BasePath}";
|
: $"https://{currentIp}/cws{BasePath}";
|
||||||
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Server:{path:l}", path);
|
|
||||||
|
|
||||||
var routeCollection = _server.GetRouteCollection();
|
Debug.LogMessage(LogEventLevel.Information, this, "Server:{path:l}", path);
|
||||||
if (routeCollection == null)
|
|
||||||
{
|
var routeCollection = _server.GetRouteCollection();
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Server route collection is null");
|
if (routeCollection == null)
|
||||||
return;
|
{
|
||||||
}
|
Debug.LogMessage(LogEventLevel.Information, this, "Server route collection is null");
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Configured Routes:");
|
return;
|
||||||
foreach (var route in routeCollection)
|
}
|
||||||
{
|
Debug.LogMessage(LogEventLevel.Information, this, "Configured Routes:");
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "{routeName:l}: {routePath:l}/{routeUrl:l}", route.Name, path, route.Url);
|
foreach (var route in routeCollection)
|
||||||
}
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, new string('-', 50));
|
Debug.LogMessage(LogEventLevel.Information, this, "{routeName:l}: {routePath:l}/{routeUrl:l}", route.Name, path, route.Url);
|
||||||
}
|
}
|
||||||
}
|
Debug.LogMessage(LogEventLevel.Information, this, new string('-', 50));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp.WebScripting;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles HTTP requests to retrieve routing devices and tielines information
|
||||||
|
/// </summary>
|
||||||
|
public class GetRoutingDevicesAndTieLinesHandler : WebApiBaseRequestHandler
|
||||||
|
{
|
||||||
|
public GetRoutingDevicesAndTieLinesHandler() : base(true) { }
|
||||||
|
|
||||||
|
protected override void HandleGet(HttpCwsContext context)
|
||||||
|
{
|
||||||
|
var devices = new List<RoutingDeviceInfo>();
|
||||||
|
|
||||||
|
// Get all devices from DeviceManager
|
||||||
|
foreach (var device in DeviceManager.AllDevices)
|
||||||
|
{
|
||||||
|
var deviceInfo = new RoutingDeviceInfo
|
||||||
|
{
|
||||||
|
Key = device.Key,
|
||||||
|
Name = (device as IKeyName)?.Name ?? device.Key
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if device implements IRoutingInputs
|
||||||
|
if (device is IRoutingInputs inputDevice)
|
||||||
|
{
|
||||||
|
deviceInfo.HasInputs = true;
|
||||||
|
deviceInfo.InputPorts = inputDevice.InputPorts.Select(p => new PortInfo
|
||||||
|
{
|
||||||
|
Key = p.Key,
|
||||||
|
SignalType = p.Type.ToString(),
|
||||||
|
ConnectionType = p.ConnectionType.ToString(),
|
||||||
|
IsInternal = p.IsInternal
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if device implements IRoutingOutputs
|
||||||
|
if (device is IRoutingOutputs outputDevice)
|
||||||
|
{
|
||||||
|
deviceInfo.HasOutputs = true;
|
||||||
|
deviceInfo.OutputPorts = outputDevice.OutputPorts.Select(p => new PortInfo
|
||||||
|
{
|
||||||
|
Key = p.Key,
|
||||||
|
SignalType = p.Type.ToString(),
|
||||||
|
ConnectionType = p.ConnectionType.ToString(),
|
||||||
|
IsInternal = p.IsInternal
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if device implements IRoutingInputsOutputs
|
||||||
|
if (device is IRoutingInputsOutputs)
|
||||||
|
{
|
||||||
|
deviceInfo.HasInputsAndOutputs = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only include devices that have routing capabilities
|
||||||
|
if (deviceInfo.HasInputs || deviceInfo.HasOutputs)
|
||||||
|
{
|
||||||
|
devices.Add(deviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all tielines
|
||||||
|
var tielines = TieLineCollection.Default.Select(tl => new TieLineInfo
|
||||||
|
{
|
||||||
|
SourceDeviceKey = tl.SourcePort.ParentDevice.Key,
|
||||||
|
SourcePortKey = tl.SourcePort.Key,
|
||||||
|
DestinationDeviceKey = tl.DestinationPort.ParentDevice.Key,
|
||||||
|
DestinationPortKey = tl.DestinationPort.Key,
|
||||||
|
SignalType = tl.Type.ToString(),
|
||||||
|
IsInternal = tl.IsInternal
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var response = new RoutingSystemInfo
|
||||||
|
{
|
||||||
|
Devices = devices,
|
||||||
|
TieLines = tielines
|
||||||
|
};
|
||||||
|
|
||||||
|
var jsonResponse = JsonConvert.SerializeObject(response, Formatting.Indented);
|
||||||
|
|
||||||
|
context.Response.StatusCode = 200;
|
||||||
|
context.Response.StatusDescription = "OK";
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.ContentEncoding = Encoding.UTF8;
|
||||||
|
context.Response.Write(jsonResponse, false);
|
||||||
|
context.Response.End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the complete routing system information including devices and tielines
|
||||||
|
/// </summary>
|
||||||
|
public class RoutingSystemInfo
|
||||||
|
{
|
||||||
|
[JsonProperty("devices")]
|
||||||
|
public List<RoutingDeviceInfo> Devices { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("tieLines")]
|
||||||
|
public List<TieLineInfo> TieLines { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a routing device with its ports information
|
||||||
|
/// </summary>
|
||||||
|
public class RoutingDeviceInfo
|
||||||
|
{
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("hasInputs")]
|
||||||
|
public bool HasInputs { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("hasOutputs")]
|
||||||
|
public bool HasOutputs { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("hasInputsAndOutputs")]
|
||||||
|
public bool HasInputsAndOutputs { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("inputPorts", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public List<PortInfo> InputPorts { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("outputPorts", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public List<PortInfo> OutputPorts { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a routing port with its properties
|
||||||
|
/// </summary>
|
||||||
|
public class PortInfo
|
||||||
|
{
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("signalType")]
|
||||||
|
public string SignalType { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("connectionType")]
|
||||||
|
public string ConnectionType { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("isInternal")]
|
||||||
|
public bool IsInternal { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a tieline connection between two ports
|
||||||
|
/// </summary>
|
||||||
|
public class TieLineInfo
|
||||||
|
{
|
||||||
|
[JsonProperty("sourceDeviceKey")]
|
||||||
|
public string SourceDeviceKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("sourcePortKey")]
|
||||||
|
public string SourcePortKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("destinationDeviceKey")]
|
||||||
|
public string DestinationDeviceKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("destinationPortKey")]
|
||||||
|
public string DestinationPortKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("signalType")]
|
||||||
|
public string SignalType { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("isInternal")]
|
||||||
|
public bool IsInternal { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user