mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-13 11:44:54 +00:00
Compare commits
42 Commits
v2.14.0-IB
...
v2.15.3-mc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
557e39f2f2 | ||
|
|
7c6aa1c0ff | ||
|
|
f0f708294c | ||
|
|
a00d186c62 | ||
|
|
51da668dfd | ||
|
|
d2b7400039 | ||
|
|
2424838b7f | ||
|
|
9556edc064 | ||
|
|
f9088691fd | ||
|
|
e40b6a8b4c | ||
|
|
c3b39a87da | ||
|
|
06dc0e947e | ||
|
|
147997f460 | ||
|
|
49abec5eea | ||
|
|
6830efe42a | ||
|
|
d013068a0c | ||
|
|
52916d29f4 | ||
|
|
19e8489166 | ||
|
|
9d49fb8357 | ||
|
|
7889cba196 | ||
|
|
033aa1f3dd | ||
|
|
4f0d464ba4 | ||
|
|
0107422507 | ||
|
|
1a366790e7 | ||
|
|
bb4b2f88b6 | ||
|
|
a41aba1904 | ||
|
|
b47f1d6b77 | ||
|
|
fda4a5a816 | ||
|
|
9f70e3c721 | ||
|
|
ec6aeb17f6 | ||
|
|
91dc655103 | ||
|
|
bf31fb10eb | ||
|
|
5e21bad596 | ||
|
|
2368f0c8cc | ||
|
|
be58a0bc29 | ||
|
|
8406f69e0d | ||
|
|
116d83394a | ||
|
|
9b8e452eb4 | ||
|
|
c9d86bd5dd | ||
|
|
b2b257020f | ||
|
|
6f58e18d14 | ||
|
|
60fc0298ec |
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>2.12.1-local</Version>
|
||||
<Version>2.15.1-local</Version>
|
||||
<InformationalVersion>$(Version)</InformationalVersion>
|
||||
<Authors>PepperDash Technology</Authors>
|
||||
<Company>PepperDash Technology</Company>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Crestron.SimplSharpPro.DM.Streaming;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DM.Streaming;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
@@ -11,7 +12,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// subscribers when the port information is updated. Implementations of this interface should ensure that the <see
|
||||
/// cref="PortInformationChanged"/> event is raised whenever the <see cref="NetworkPorts"/> collection
|
||||
/// changes.</remarks>
|
||||
public interface INvxNetworkPortInformation
|
||||
public interface INvxNetworkPortInformation : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when the port information changes.
|
||||
|
||||
@@ -202,14 +202,15 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private static void ListDevices(string s)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "{0} Devices registered with Device Manager:", Devices.Count);
|
||||
CrestronConsole.ConsoleCommandResponse($"{Devices.Count} Devices registered with Device Manager:");
|
||||
|
||||
var sorted = Devices.Values.ToList();
|
||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||
|
||||
foreach (var d in sorted)
|
||||
{
|
||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||
Debug.LogMessage(LogEventLevel.Information, " [{0}] {1}", d.Key, name);
|
||||
CrestronConsole.ConsoleCommandResponse($" [{d.Key}] {name}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,17 +140,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
if (Camera is IHasCameraPresets presetsCamera)
|
||||
{
|
||||
for (int i = 1; i <= 6; i++)
|
||||
AddAction("/recallPreset", (id, content) =>
|
||||
{
|
||||
var preset = i;
|
||||
AddAction("/cameraPreset" + i, (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||
|
||||
presetsCamera.PresetSelect(msg.Value);
|
||||
});
|
||||
presetsCamera.PresetSelect(msg.Value);
|
||||
});
|
||||
|
||||
}
|
||||
AddAction("/storePreset", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<int>>();
|
||||
|
||||
presetsCamera.PresetStore(msg.Value, string.Empty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,9 +166,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
return;
|
||||
}
|
||||
|
||||
timerHandler(state.Value, cameraAction);
|
||||
timerHandler(Camera.Key, cameraAction);
|
||||
|
||||
cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -9,25 +9,34 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class MobileControlConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ServerUrl
|
||||
/// </summary>
|
||||
[JsonProperty("serverUrl")]
|
||||
public string ServerUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ClientAppUrl
|
||||
/// </summary>
|
||||
[JsonProperty("clientAppUrl")]
|
||||
public string ClientAppUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DirectServer
|
||||
/// </summary>
|
||||
[JsonProperty("directServer")]
|
||||
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
|
||||
|
||||
[JsonProperty("applicationConfig")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ApplicationConfig
|
||||
/// </summary>
|
||||
[JsonProperty("applicationConfig")]
|
||||
public MobileControlApplicationConfig ApplicationConfig { get; set; } = null;
|
||||
|
||||
[JsonProperty("enableApiServer")]
|
||||
/// <summary>
|
||||
/// Gets or sets the EnableApiServer
|
||||
/// </summary>
|
||||
[JsonProperty("enableApiServer")]
|
||||
public bool EnableApiServer { get; set; } = true;
|
||||
}
|
||||
|
||||
@@ -36,27 +45,42 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class MobileControlDirectServerPropertiesConfig
|
||||
{
|
||||
[JsonProperty("enableDirectServer")]
|
||||
/// <summary>
|
||||
/// Gets or sets the EnableDirectServer
|
||||
/// </summary>
|
||||
[JsonProperty("enableDirectServer")]
|
||||
public bool EnableDirectServer { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Port
|
||||
/// </summary>
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[JsonProperty("logging")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Logging
|
||||
/// </summary>
|
||||
[JsonProperty("logging")]
|
||||
public MobileControlLoggingConfig Logging { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the AutomaticallyForwardPortToCSLAN
|
||||
/// </summary>
|
||||
[JsonProperty("automaticallyForwardPortToCSLAN")]
|
||||
public bool? AutomaticallyForwardPortToCSLAN { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CSLanUiDeviceKeys
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A list of device keys for the CS LAN UI. These devices will get the CS LAN IP address instead of the LAN IP Address
|
||||
/// </remarks>
|
||||
[JsonProperty("csLanUiDeviceKeys")]
|
||||
public List<string> CSLanUiDeviceKeys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MobileControlDirectServerPropertiesConfig class.
|
||||
/// </summary>
|
||||
public MobileControlDirectServerPropertiesConfig()
|
||||
{
|
||||
Logging = new MobileControlLoggingConfig();
|
||||
@@ -68,26 +92,26 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class MobileControlLoggingConfig
|
||||
{
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the EnableRemoteLogging
|
||||
/// </summary>
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool EnableRemoteLogging { get; set; }
|
||||
|
||||
[JsonProperty("host")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Host
|
||||
/// </summary>
|
||||
[JsonProperty("host")]
|
||||
public string Host { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Port
|
||||
/// </summary>
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -95,16 +119,16 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class MobileControlRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Key
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
/// <summary>
|
||||
/// Gets or sets the RoomKey
|
||||
/// </summary>
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
}
|
||||
|
||||
@@ -113,53 +137,71 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class MobileControlSimplRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("eiscId")]
|
||||
/// <summary>
|
||||
/// Gets or sets the EiscId
|
||||
/// </summary>
|
||||
[JsonProperty("eiscId")]
|
||||
public string EiscId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a MobileControlApplicationConfig
|
||||
/// </summary>
|
||||
public class MobileControlApplicationConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ApiPath
|
||||
/// </summary>
|
||||
[JsonProperty("apiPath")]
|
||||
public string ApiPath { get; set; }
|
||||
|
||||
[JsonProperty("gatewayAppPath")]
|
||||
/// <summary>
|
||||
/// Gets or sets the GatewayAppPath
|
||||
/// </summary>
|
||||
[JsonProperty("gatewayAppPath")]
|
||||
public string GatewayAppPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the EnableDev
|
||||
/// </summary>
|
||||
[JsonProperty("enableDev")]
|
||||
public bool? EnableDev { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
/// <summary>
|
||||
/// Gets or sets the LogoPath
|
||||
/// </summary>
|
||||
[JsonProperty("logoPath")]
|
||||
public string LogoPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IconSet
|
||||
/// </summary>
|
||||
[JsonProperty("iconSet")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MCIconSet? IconSet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the LoginMode
|
||||
/// </summary>
|
||||
[JsonProperty("loginMode")]
|
||||
public string LoginMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Modes
|
||||
/// </summary>
|
||||
[JsonProperty("modes")]
|
||||
public Dictionary<string, McMode> Modes { get; set; }
|
||||
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Logging
|
||||
/// </summary>
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool Logging { get; set; }
|
||||
|
||||
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
||||
/// <summary>
|
||||
/// Gets or sets the PartnerMetadata
|
||||
/// </summary>
|
||||
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<MobileControlPartnerMetadata> PartnerMetadata { get; set; }
|
||||
}
|
||||
|
||||
@@ -168,22 +210,22 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class MobileControlPartnerMetadata
|
||||
{
|
||||
[JsonProperty("role")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Role
|
||||
/// </summary>
|
||||
[JsonProperty("role")]
|
||||
public string Role { get; set; }
|
||||
|
||||
[JsonProperty("description")]
|
||||
/// <summary>
|
||||
/// Gets or sets the Description
|
||||
/// </summary>
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
/// <summary>
|
||||
/// Gets or sets the LogoPath
|
||||
/// </summary>
|
||||
[JsonProperty("logoPath")]
|
||||
public string LogoPath { get; set; }
|
||||
}
|
||||
|
||||
@@ -192,21 +234,22 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public class McMode
|
||||
{
|
||||
[JsonProperty("listPageText")]
|
||||
/// <summary>
|
||||
/// Gets or sets the ListPageText
|
||||
/// </summary>
|
||||
[JsonProperty("listPageText")]
|
||||
public string ListPageText { get; set; }
|
||||
[JsonProperty("loginHelpText")]
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the LoginHelpText
|
||||
/// </summary>
|
||||
[JsonProperty("loginHelpText")]
|
||||
public string LoginHelpText { get; set; }
|
||||
|
||||
[JsonProperty("passcodePageText")]
|
||||
/// <summary>
|
||||
/// Gets or sets the PasscodePageText
|
||||
/// </summary>
|
||||
[JsonProperty("passcodePageText")]
|
||||
public string PasscodePageText { get; set; }
|
||||
}
|
||||
|
||||
@@ -215,8 +258,19 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public enum MCIconSet
|
||||
{
|
||||
/// <summary>
|
||||
/// Google icon set
|
||||
/// </summary>
|
||||
GOOGLE,
|
||||
|
||||
/// <summary>
|
||||
/// Habanero icon set
|
||||
/// </summary>
|
||||
HABANERO,
|
||||
|
||||
/// <summary>
|
||||
/// Neo icon set
|
||||
/// </summary>
|
||||
NEO
|
||||
}
|
||||
}
|
||||
@@ -244,13 +244,15 @@ namespace PepperDash.Essentials
|
||||
CrestronEnvironment.ProgramStatusEventHandler +=
|
||||
CrestronEnvironment_ProgramStatusEventHandler;
|
||||
|
||||
ApiOnlineAndAuthorized = new BoolFeedback(() =>
|
||||
ApiOnlineAndAuthorized = new BoolFeedback("apiOnlineAndAuthorized", () =>
|
||||
{
|
||||
if (_wsClient2 == null)
|
||||
return false;
|
||||
|
||||
return _wsClient2.IsAlive && IsAuthorized;
|
||||
});
|
||||
|
||||
Debug.SetFileMinimumDebugLevel(Serilog.Events.LogEventLevel.Debug);
|
||||
}
|
||||
|
||||
private void SetupDefaultRoomMessengers()
|
||||
@@ -1917,7 +1919,8 @@ namespace PepperDash.Essentials
|
||||
/// <param name="e"></param>
|
||||
private void HandleError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
this.LogError("Websocket error {0}", e.Message);
|
||||
this.LogError("Websocket error {message}", e.Message);
|
||||
this.LogError(e.Exception, "Websocket error");
|
||||
|
||||
IsAuthorized = false;
|
||||
StartServerReconnectTimer();
|
||||
@@ -1930,7 +1933,7 @@ namespace PepperDash.Essentials
|
||||
/// <param name="e"></param>
|
||||
private void HandleClose(object sender, CloseEventArgs e)
|
||||
{
|
||||
this.LogDebug(
|
||||
this.LogInformation(
|
||||
"Websocket close {code} {reason}, clean={wasClean}",
|
||||
e.Code,
|
||||
e.Reason,
|
||||
|
||||
@@ -190,12 +190,25 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
|
||||
RegisterForExtenders();
|
||||
|
||||
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
|
||||
var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
|
||||
var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
||||
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Appliance)
|
||||
{
|
||||
this.LogInformation("Not running on processor. Skipping CS LAN Configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
|
||||
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
|
||||
try
|
||||
{
|
||||
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
|
||||
var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
|
||||
var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
||||
|
||||
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
|
||||
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
this.LogInformation("This processor does not have a CS LAN");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -436,7 +449,7 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
|
||||
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
|
||||
|
||||
if(csIpAddress == null || csSubnetMask == null || url == null)
|
||||
if (csIpAddress == null || csSubnetMask == null || url == null)
|
||||
{
|
||||
this.LogWarning("CS IP Address Subnet Mask or url is null, cannot determine correct IP for URL");
|
||||
return url;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
@@ -41,8 +42,14 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
private HttpServer _server;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HttpServer instance
|
||||
/// </summary>
|
||||
public HttpServer Server => _server;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of UI client contexts
|
||||
/// </summary>
|
||||
public Dictionary<string, UiClientContext> UiClients { get; private set; }
|
||||
|
||||
private readonly MobileControlSystemController _parent;
|
||||
@@ -61,17 +68,20 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
private string lanIpAddress => CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter));
|
||||
private string LanIpAddress => CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter));
|
||||
|
||||
private System.Net.IPAddress csIpAddress;
|
||||
private readonly System.Net.IPAddress csIpAddress;
|
||||
|
||||
private System.Net.IPAddress csSubnetMask;
|
||||
private readonly System.Net.IPAddress csSubnetMask;
|
||||
|
||||
/// <summary>
|
||||
/// The path for the WebSocket messaging
|
||||
/// </summary>
|
||||
private readonly string _wsPath = "/mc/api/ui/join/";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the WebSocket path
|
||||
/// </summary>
|
||||
public string WsPath => _wsPath;
|
||||
|
||||
/// <summary>
|
||||
@@ -89,6 +99,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
/// </summary>
|
||||
public int Port { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user app URL prefix
|
||||
/// </summary>
|
||||
public string UserAppUrlPrefix
|
||||
{
|
||||
get
|
||||
@@ -101,6 +114,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the count of connected UI clients
|
||||
/// </summary>
|
||||
public int ConnectedUiClientsCount
|
||||
{
|
||||
get
|
||||
@@ -119,6 +135,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MobileControlWebsocketServer class.
|
||||
/// </summary>
|
||||
public MobileControlWebsocketServer(string key, int customPort, MobileControlSystemController parent)
|
||||
: base(key)
|
||||
{
|
||||
@@ -344,6 +363,11 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
// }) ? csIpAddress.ToString() : processorIp;
|
||||
//}
|
||||
|
||||
if (_parent.Config.DirectServer.CSLanUiDeviceKeys != null && _parent.Config.DirectServer.CSLanUiDeviceKeys.Any(k => k.Equals(touchpanel.Touchpanel.Key, StringComparison.InvariantCultureIgnoreCase)) && csIpAddress != null)
|
||||
{
|
||||
ip = csIpAddress.ToString();
|
||||
}
|
||||
|
||||
var appUrl = $"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
|
||||
|
||||
this.LogVerbose("Sending URL {appUrl}", appUrl);
|
||||
@@ -625,6 +649,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
CrestronConsole.ConsoleCommandResponse($"Token: {token}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the grant code against the room key
|
||||
/// </summary>
|
||||
public (string, string) ValidateGrantCode(string grantCode, string roomKey)
|
||||
{
|
||||
var bridge = _parent.GetRoomBridge(roomKey);
|
||||
@@ -638,6 +665,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
return ValidateGrantCode(grantCode, bridge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the grant code against the room key
|
||||
/// </summary>
|
||||
public (string, string) ValidateGrantCode(string grantCode, MobileControlBridgeBase bridge)
|
||||
{
|
||||
// TODO: Authenticate grant code passed in
|
||||
@@ -659,6 +689,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new client token for the specified bridge
|
||||
/// </summary>
|
||||
public (string, string) GenerateClientToken(MobileControlBridgeBase bridge, string touchPanelKey = "")
|
||||
{
|
||||
var key = Guid.NewGuid().ToString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Crestron.SimplSharp;
|
||||
@@ -41,29 +41,6 @@ namespace PepperDash.Essentials
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||
|
||||
Debug.SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? LogEventLevel.Warning : LogEventLevel.Verbose);
|
||||
|
||||
// AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
|
||||
}
|
||||
|
||||
private Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name).Name;
|
||||
if (assemblyName == "PepperDash_Core")
|
||||
{
|
||||
return Assembly.LoadFrom("PepperDashCore.dll");
|
||||
}
|
||||
|
||||
if (assemblyName == "PepperDash_Essentials_Core")
|
||||
{
|
||||
return Assembly.LoadFrom("PepperDash.Essentials.Core.dll");
|
||||
}
|
||||
|
||||
if (assemblyName == "Essentials Devices Common")
|
||||
{
|
||||
return Assembly.LoadFrom("PepperDash.Essentials.Devices.Common.dll");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -267,6 +244,8 @@ namespace PepperDash.Essentials
|
||||
// _ = new ProcessorExtensionDeviceFactory();
|
||||
// _ = new MobileControlFactory();
|
||||
|
||||
LoadAssets();
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Starting Essentials load from configuration");
|
||||
|
||||
var filesReady = SetupFilesystem();
|
||||
@@ -568,5 +547,142 @@ namespace PepperDash.Essentials
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadAssets()
|
||||
{
|
||||
var applicationDirectory = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Searching: {applicationDirectory:l} for embedded assets - {Destination}", applicationDirectory.FullName, Global.FilePathPrefix);
|
||||
|
||||
var zipFiles = applicationDirectory.GetFiles("assets*.zip");
|
||||
|
||||
if (zipFiles.Length > 1)
|
||||
{
|
||||
throw new Exception("Multiple assets zip files found. Cannot continue.");
|
||||
}
|
||||
|
||||
if (zipFiles.Length == 1)
|
||||
{
|
||||
var zipFile = zipFiles[0];
|
||||
var assetsRoot = System.IO.Path.GetFullPath(Global.FilePathPrefix);
|
||||
if (!assetsRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) && !assetsRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
assetsRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Information, "Found assets zip file: {zipFile:l}... Unzipping...", zipFile.FullName);
|
||||
using (var archive = ZipFile.OpenRead(zipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(Global.FilePathPrefix, entry.FullName);
|
||||
var fullDest = System.IO.Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(assetsRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException($"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a directory exists where a file should go, delete it
|
||||
if (Directory.Exists(destinationPath))
|
||||
Directory.Delete(destinationPath, true);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
|
||||
entry.ExtractToFile(destinationPath, true);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up zip files
|
||||
foreach (var file in zipFiles)
|
||||
{
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
var htmlZipFiles = applicationDirectory.GetFiles("htmlassets*.zip");
|
||||
|
||||
if (htmlZipFiles.Length > 1)
|
||||
{
|
||||
throw new Exception("Multiple htmlassets zip files found in application directory. Please ensure only one htmlassets*.zip file is present and retry.");
|
||||
}
|
||||
|
||||
|
||||
if (htmlZipFiles.Length == 1)
|
||||
{
|
||||
var htmlZipFile = htmlZipFiles[0];
|
||||
var programDir = new DirectoryInfo(Global.FilePathPrefix.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
var userOrNvramDir = programDir.Parent;
|
||||
var rootDir = userOrNvramDir?.Parent;
|
||||
if (rootDir == null)
|
||||
{
|
||||
throw new Exception($"Unable to determine root directory for html extraction. Current path: {Global.FilePathPrefix}");
|
||||
}
|
||||
var htmlDir = Path.Combine(rootDir.FullName, "html");
|
||||
var htmlRoot = System.IO.Path.GetFullPath(htmlDir);
|
||||
if (!htmlRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
||||
!htmlRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
htmlRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Information, "Found htmlassets zip file: {zipFile:l}... Unzipping...", htmlZipFile.FullName);
|
||||
using (var archive = ZipFile.OpenRead(htmlZipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(htmlDir, entry.FullName);
|
||||
var fullDest = System.IO.Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(htmlRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException($"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only delete the file if it exists and is a file, not a directory
|
||||
if (File.Exists(destinationPath))
|
||||
File.Delete(destinationPath);
|
||||
|
||||
var parentDir = Path.GetDirectoryName(destinationPath);
|
||||
if (!string.IsNullOrEmpty(parentDir))
|
||||
Directory.CreateDirectory(parentDir);
|
||||
|
||||
entry.ExtractToFile(destinationPath, true);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up html zip files
|
||||
foreach (var file in htmlZipFiles)
|
||||
{
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
var jsonFiles = applicationDirectory.GetFiles("*configurationFile*.json");
|
||||
|
||||
if (jsonFiles.Length > 1)
|
||||
{
|
||||
throw new Exception("Multiple configuration files found. Cannot continue.");
|
||||
}
|
||||
|
||||
if (jsonFiles.Length == 1)
|
||||
{
|
||||
var jsonFile = jsonFiles[0];
|
||||
var finalPath = Path.Combine(Global.FilePathPrefix, jsonFile.Name);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Found configuration file: {jsonFile:l}... Moving to: {Destination}", jsonFile.FullName, finalPath);
|
||||
|
||||
if (File.Exists(finalPath))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Removing existing configuration file: {Destination}", finalPath);
|
||||
File.Delete(finalPath);
|
||||
}
|
||||
|
||||
jsonFile.MoveTo(finalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug 4.7.2|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DocumentationFile>bin\$(Configuration)\PepperDashEssentials.xml</DocumentationFile>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DocumentationFile>bin\$(Configuration)\PepperDashEssentials.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Example Configuration\EssentialsHuddleSpaceRoom\configurationFile-HuddleSpace-2-Source.json">
|
||||
@@ -49,6 +49,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Crestron.SimplSharp.SDK.Program" Version="2.21.90" />
|
||||
<PackageReference Include="System.IO.Compression" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PepperDash.Core\PepperDash.Core.csproj" />
|
||||
|
||||
Reference in New Issue
Block a user