mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 04:34:56 +00:00
Compare commits
7 Commits
v2.17.0-mc
...
v2.17.0-mc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd70377c7f | ||
|
|
06341b14f3 | ||
|
|
b0a090062f | ||
|
|
9c0cab8218 | ||
|
|
c0af637108 | ||
|
|
258699fbcd | ||
|
|
738504e9fc |
@@ -53,8 +53,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
|
||||
Status = _communicationMonitor.CommunicationMonitor.Status
|
||||
}
|
||||
});
|
||||
},
|
||||
}, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PowerState = _powerControl.PowerIsOnFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(messageObj);
|
||||
PostStatusMessage(messageObj, id);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -20,9 +20,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/status", (id, content) =>
|
||||
SendFullStatus(id)
|
||||
);
|
||||
AddAction("/status", (id, content) => SendFullStatus(id));
|
||||
|
||||
AddAction("/shutdownPromptStatus", (id, content) => SendFullStatus(id));
|
||||
|
||||
|
||||
@@ -15,12 +15,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// </summary>
|
||||
public abstract class MessengerBase : EssentialsDevice, IMobileControlMessenger
|
||||
{
|
||||
/// <summary>
|
||||
/// The device this messenger is associated with
|
||||
/// </summary>
|
||||
protected IKeyName _device;
|
||||
|
||||
private readonly List<string> _deviceInterfaces;
|
||||
|
||||
private readonly Dictionary<string, Action<string, JToken>> _actions = new Dictionary<string, Action<string, JToken>>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DeviceKey
|
||||
/// </summary>
|
||||
public string DeviceKey => _device?.Key ?? "";
|
||||
|
||||
|
||||
@@ -50,6 +56,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
MessagePath = messagePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a messenger associated with a device
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
/// <param name="device"></param>
|
||||
protected MessengerBase(string key, string messagePath, IKeyName device)
|
||||
: this(key, messagePath)
|
||||
{
|
||||
@@ -96,6 +108,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
action(id, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an action for a given path
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="action"></param>
|
||||
protected void AddAction(string path, Action<string, JToken> action)
|
||||
{
|
||||
if (_actions.ContainsKey(path))
|
||||
@@ -115,6 +132,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
return _actions.Keys.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an action for a given path
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
protected void RemoveAction(string path)
|
||||
{
|
||||
if (!_actions.ContainsKey(path))
|
||||
@@ -128,7 +149,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Implemented in extending classes. Wire up API calls and feedback here
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected virtual void RegisterActions()
|
||||
{
|
||||
|
||||
@@ -137,8 +157,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Helper for posting status message
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="clientId">Optional client id that will direct the message back to only that client</param>
|
||||
protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null)
|
||||
{
|
||||
try
|
||||
@@ -169,6 +189,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for posting status message
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="deviceState"></param>
|
||||
/// <param name="clientId">Optional client id that will direct the message back to only that client</param>
|
||||
protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null)
|
||||
{
|
||||
try
|
||||
@@ -192,6 +218,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for posting status message
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="clientId">Optional client id that will direct the message back to only that client</param>
|
||||
protected void PostStatusMessage(JToken content, string type = "", string clientId = null)
|
||||
{
|
||||
try
|
||||
@@ -204,6 +236,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for posting event message
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
protected void PostEventMessage(DeviceEventMessageBase message)
|
||||
{
|
||||
message.Key = _device.Key;
|
||||
@@ -217,6 +253,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for posting event message
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="eventType"></param>
|
||||
protected void PostEventMessage(DeviceEventMessageBase message, string eventType)
|
||||
{
|
||||
message.Key = _device.Key;
|
||||
@@ -232,6 +273,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for posting event message with no content
|
||||
/// </summary>
|
||||
/// <param name="eventType"></param>
|
||||
protected void PostEventMessage(string eventType)
|
||||
{
|
||||
AppServerController?.SendMessageObject(new MobileControlMessage
|
||||
@@ -243,6 +288,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for device messages that include the type of message
|
||||
/// </summary>
|
||||
public abstract class DeviceMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
@@ -266,10 +314,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
[JsonProperty("messageType")]
|
||||
public string MessageType => GetType().Name;
|
||||
|
||||
[JsonProperty("messageBasePath")]
|
||||
/// <summary>
|
||||
/// Gets or sets the MessageBasePath
|
||||
/// </summary>
|
||||
[JsonProperty("messageBasePath")]
|
||||
|
||||
public string MessageBasePath { get; set; }
|
||||
}
|
||||
|
||||
@@ -284,6 +333,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
[JsonProperty("interfaces")]
|
||||
public List<string> Interfaces { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the interfaces implemented by the device sending the message
|
||||
/// </summary>
|
||||
/// <param name="interfaces"></param>
|
||||
public void SetInterfaces(List<string> interfaces)
|
||||
{
|
||||
Interfaces = interfaces;
|
||||
|
||||
@@ -105,35 +105,35 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Gets or sets the TimeZoneName
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("timeZoneName", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TimeZoneName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IoControllerVersion
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("ioControllerVersion", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string IoControllerVersion { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SnmpVersion
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("snmpVersion", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string SnmpVersion { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the BacnetVersion
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("bacnetVersion", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string BacnetVersion { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ControllerVersion
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("controllerVersion", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ControllerVersion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceInfo;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.UI;
|
||||
using Serilog.Events;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
@@ -190,12 +191,19 @@ 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);
|
||||
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);
|
||||
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
|
||||
this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogInformation("This processor does not have a CS LAN", this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -502,7 +510,7 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
_bridge.UserCodeChanged += UpdateFeedbacks;
|
||||
_bridge.AppUrlChanged += (s, a) =>
|
||||
{
|
||||
this.LogInformation("AppURL changed");
|
||||
this.LogInformation("AppURL changed: {appURL}", _bridge.AppUrl);
|
||||
SetAppUrl(_bridge.AppUrl);
|
||||
UpdateFeedbacks(s, a);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents info about a device including supproted interfaces
|
||||
/// </summary>
|
||||
public class DeviceInterfaceInfo : IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Key
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Interfaces
|
||||
/// </summary>
|
||||
[JsonProperty("interfaces")]
|
||||
public List<string> Interfaces { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a JoinResponse
|
||||
/// </summary>
|
||||
public class JoinResponse
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ClientId
|
||||
/// </summary>
|
||||
[JsonProperty("clientId")]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("systemUUid")]
|
||||
public string SystemUuid { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the RoomUuid
|
||||
/// </summary>
|
||||
[JsonProperty("roomUUid")]
|
||||
public string RoomUuid { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Config
|
||||
/// </summary>
|
||||
[JsonProperty("config")]
|
||||
public object Config { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CodeExpires
|
||||
/// </summary>
|
||||
[JsonProperty("codeExpires")]
|
||||
public DateTime CodeExpires { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserCode
|
||||
/// </summary>
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserAppUrl
|
||||
/// </summary>
|
||||
[JsonProperty("userAppUrl")]
|
||||
public string UserAppUrl { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the EnableDebug
|
||||
/// </summary>
|
||||
[JsonProperty("enableDebug")]
|
||||
public bool EnableDebug { get; set; }
|
||||
|
||||
///
|
||||
public Dictionary<string, DeviceInterfaceInfo> DeviceInterfaceSupport { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a JoinToken
|
||||
/// </summary>
|
||||
public class JoinToken
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Code
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
public string Uuid { get; set; }
|
||||
|
||||
public string TouchpanelKey { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Token
|
||||
/// </summary>
|
||||
public string Token { get; set; } = null;
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Automatically forwarding port {0} to CS LAN", Port);
|
||||
this.LogInformation("Automatically forwarding port {port} to CS LAN", Port);
|
||||
|
||||
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
|
||||
var csIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
||||
@@ -164,16 +164,17 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
if (result != CrestronEthernetHelper.PortForwardingUserPatRetCodes.NoErr)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Error, "Error adding port forwarding: {0}", result);
|
||||
this.LogError("Error adding port forwarding: {error}", result);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "This processor does not have a CS LAN", this);
|
||||
this.LogInformation("This processor does not have a CS LAN", this);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error automatically forwarding port to CS LAN");
|
||||
this.LogError("Error automatically forwarding port to CS LAN: {message}", ex.Message);
|
||||
this.LogDebug(ex, "Stack Trace");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +191,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
if (parent.Config.DirectServer.AutomaticallyForwardPortToCSLAN == false)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "This processor does not have a CS LAN", this);
|
||||
this.LogInformation("This processor does not have a CS LAN");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,13 +260,15 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
_server.OnPost += Server_OnPost;
|
||||
}
|
||||
|
||||
_server.Log.Output = (data, level) => this.LogInformation("WebSocket Server Log [{level}]: {data}", level, data);
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
|
||||
|
||||
_server.Start();
|
||||
|
||||
if (_server.IsListening)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Mobile Control WebSocket Server listening on port {port}", this, _server.Port);
|
||||
this.LogInformation("Mobile Control WebSocket Server listening on port {port}", _server.Port);
|
||||
}
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += OnProgramStop;
|
||||
@@ -278,7 +281,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception intializing websocket server", this);
|
||||
this.LogError("Exception initializing direct server: {message}", ex.Message);
|
||||
this.LogDebug(ex, "Stack Trace");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,22 +351,6 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
string ip = processorIp;
|
||||
|
||||
// Moved to the MobileControlTouchpanelController class in the GetUrlWithCorrectIp method
|
||||
// triggered by the Panel.IpInformationChange event so that we know we have the necessary info
|
||||
// to make the determination of which IP to use.
|
||||
//if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel && csIpAddress != null)
|
||||
//{
|
||||
// ip = crestronTouchpanel.ConnectedIps.Any(ipInfo =>
|
||||
// {
|
||||
// if (System.Net.IPAddress.TryParse(ipInfo.DeviceIpAddress, out var parsedIp))
|
||||
// {
|
||||
// return csIpAddress.IsInSameSubnet(parsedIp, csSubnetMask);
|
||||
// }
|
||||
// this.LogWarning("Invalid IP address: {deviceIpAddress}", ipInfo.DeviceIpAddress);
|
||||
// return false;
|
||||
// }) ? 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();
|
||||
@@ -477,7 +465,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Error getting application configuration");
|
||||
this.LogError("Error getting application configuration: {message}", ex.Message);
|
||||
this.LogDebug(ex, "Stack Trace");
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -513,15 +502,14 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
if (token.Value == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Token value is null", this);
|
||||
this.LogWarning("Token value is null");
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Adding token: {0} for room: {1}", this, token.Key, token.Value.RoomKey);
|
||||
this.LogInformation("Adding token: {key} for room: {roomKey}", token.Key, token.Value.RoomKey);
|
||||
|
||||
if (UiClients == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "UiClients is null", this);
|
||||
UiClients = new Dictionary<string, UiClientContext>();
|
||||
}
|
||||
|
||||
@@ -531,7 +519,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
if (UiClients.Count > 0)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Restored {uiClientCount} UiClients from secrets data", this, UiClients.Count);
|
||||
this.LogInformation("Restored {uiClientCount} UiClients from secrets data", UiClients.Count);
|
||||
|
||||
foreach (var client in UiClients)
|
||||
{
|
||||
@@ -541,36 +529,28 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
_server.AddWebSocketService(path, () =>
|
||||
{
|
||||
var c = new UiClient();
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Constructing UiClient with id: {key}", this, key);
|
||||
var c = new UiClient($"uiclient-{key}-{roomKey}");
|
||||
this.LogDebug("Constructing UiClient with id: {key}", key);
|
||||
|
||||
c.Controller = _parent;
|
||||
c.RoomKey = roomKey;
|
||||
UiClients[key].SetClient(c);
|
||||
return c;
|
||||
});
|
||||
|
||||
|
||||
//_server.WebSocketServices.AddService<UiClient>(path, (c) =>
|
||||
//{
|
||||
// Debug.Console(2, this, "Constructing UiClient with id: {0}", key);
|
||||
// c.Controller = _parent;
|
||||
// c.RoomKey = roomKey;
|
||||
// UiClients[key].SetClient(c);
|
||||
//});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "No secret found");
|
||||
this.LogWarning("No secret found");
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Debug, "{uiClientCount} UiClients restored from secrets data", this, UiClients.Count);
|
||||
this.LogDebug("{uiClientCount} UiClients restored from secrets data", UiClients.Count);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception retrieving secret", this);
|
||||
this.LogError("Exception retrieving secret: {message}", ex.Message);
|
||||
this.LogDebug(ex, "Stack Trace");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +563,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
if (_secret == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Error, "Secret is null", this);
|
||||
this.LogError("Secret is null");
|
||||
|
||||
_secret = new ServerTokenSecrets(string.Empty);
|
||||
}
|
||||
@@ -601,7 +581,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception updating secret", this);
|
||||
this.LogError("Exception updating secret: {message}", ex.Message);
|
||||
this.LogDebug(ex, "Stack Trace");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,18 +685,18 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
_server.AddWebSocketService(path, () =>
|
||||
{
|
||||
var c = new UiClient();
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Constructing UiClient with id: {0}", this, key);
|
||||
var c = new UiClient($"uiclient-{key}-{bridge.RoomKey}");
|
||||
this.LogVerbose("Constructing UiClient with id: {key}", key);
|
||||
c.Controller = _parent;
|
||||
c.RoomKey = bridge.RoomKey;
|
||||
UiClients[key].SetClient(c);
|
||||
return c;
|
||||
});
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Added new WebSocket UiClient service at path: {path}", this, path);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Token: {@token}", this, token);
|
||||
this.LogInformation("Added new WebSocket UiClient service at path: {path}", path);
|
||||
this.LogInformation("Token: {@token}", token);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "{serviceCount} websocket services present", this, _server.WebSocketServices.Count);
|
||||
this.LogVerbose("{serviceCount} websocket services present", _server.WebSocketServices.Count);
|
||||
|
||||
UpdateSecret();
|
||||
|
||||
@@ -729,7 +710,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
if (s == "?" || string.IsNullOrEmpty(s))
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(@"Removes all clients from the server. To execute add 'confirm' to command");
|
||||
CrestronConsole.ConsoleCommandResponse(@"Remove all clients from the server. To execute add 'confirm' to command");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -883,7 +864,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the OnGet handler", this);
|
||||
this.LogError("Exception in OnGet handler: {message}", ex.Message);
|
||||
this.LogDebug(ex, "Stack Trace");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,6 +954,20 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "application/json";
|
||||
|
||||
var devices = DeviceManager.GetDevices();
|
||||
Dictionary<string, DeviceInterfaceInfo> deviceInterfaces = new Dictionary<string, DeviceInterfaceInfo>();
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
var interfaces = device?.GetType().GetInterfaces().Select((i) => i.Name).ToList() ?? new List<string>();
|
||||
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 +981,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[]
|
||||
@@ -1171,7 +1168,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogVerbose("File not found: {filePath}", filePath);
|
||||
this.LogWarning("File not found: {filePath}", filePath);
|
||||
res.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
res.Close();
|
||||
return;
|
||||
@@ -1241,152 +1238,4 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Version
|
||||
/// </summary>
|
||||
public class Version
|
||||
{
|
||||
[JsonProperty("serverVersion")]
|
||||
public string ServerVersion { get; set; }
|
||||
|
||||
[JsonProperty("serverIsRunningOnProcessorHardware")]
|
||||
public bool ServerIsRunningOnProcessorHardware { get; private set; }
|
||||
|
||||
public Version()
|
||||
{
|
||||
ServerIsRunningOnProcessorHardware = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a UiClientContext
|
||||
/// </summary>
|
||||
public class UiClientContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Client
|
||||
/// </summary>
|
||||
public UiClient Client { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Token
|
||||
/// </summary>
|
||||
public JoinToken Token { get; private set; }
|
||||
|
||||
public UiClientContext(JoinToken token)
|
||||
{
|
||||
Token = token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SetClient method
|
||||
/// </summary>
|
||||
public void SetClient(UiClient client)
|
||||
{
|
||||
Client = client;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a ServerTokenSecrets
|
||||
/// </summary>
|
||||
public class ServerTokenSecrets
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the GrantCode
|
||||
/// </summary>
|
||||
public string GrantCode { get; set; }
|
||||
|
||||
public Dictionary<string, JoinToken> Tokens { get; set; }
|
||||
|
||||
public ServerTokenSecrets(string grantCode)
|
||||
{
|
||||
GrantCode = grantCode;
|
||||
Tokens = new Dictionary<string, JoinToken>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a JoinToken
|
||||
/// </summary>
|
||||
public class JoinToken
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Code
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
public string Uuid { get; set; }
|
||||
|
||||
public string TouchpanelKey { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Token
|
||||
/// </summary>
|
||||
public string Token { get; set; } = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a JoinResponse
|
||||
/// </summary>
|
||||
public class JoinResponse
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ClientId
|
||||
/// </summary>
|
||||
[JsonProperty("clientId")]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("systemUUid")]
|
||||
public string SystemUuid { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the RoomUuid
|
||||
/// </summary>
|
||||
[JsonProperty("roomUUid")]
|
||||
public string RoomUuid { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Config
|
||||
/// </summary>
|
||||
[JsonProperty("config")]
|
||||
public object Config { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CodeExpires
|
||||
/// </summary>
|
||||
[JsonProperty("codeExpires")]
|
||||
public DateTime CodeExpires { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserCode
|
||||
/// </summary>
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserAppUrl
|
||||
/// </summary>
|
||||
[JsonProperty("userAppUrl")]
|
||||
public string UserAppUrl { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the EnableDebug
|
||||
/// </summary>
|
||||
[JsonProperty("enableDebug")]
|
||||
public bool EnableDebug { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a ServerTokenSecrets
|
||||
/// </summary>
|
||||
public class ServerTokenSecrets
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the GrantCode
|
||||
/// </summary>
|
||||
public string GrantCode { get; set; }
|
||||
|
||||
public Dictionary<string, JoinToken> Tokens { get; set; }
|
||||
|
||||
public ServerTokenSecrets(string grantCode)
|
||||
{
|
||||
GrantCode = grantCode;
|
||||
Tokens = new Dictionary<string, JoinToken>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,27 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.RoomBridges;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using WebSocketSharp;
|
||||
using WebSocketSharp.Server;
|
||||
using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the behaviour to associate with a UiClient for WebSocket communication
|
||||
/// </summary>
|
||||
public class UiClient : WebSocketBehavior
|
||||
public class UiClient : WebSocketBehavior, IKeyed
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Key { get; private set; }
|
||||
|
||||
public MobileControlSystemController Controller { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
@@ -41,17 +45,18 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
public UiClient()
|
||||
public UiClient(string key)
|
||||
{
|
||||
|
||||
Key = key;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnOpen()
|
||||
{
|
||||
base.OnOpen();
|
||||
|
||||
var url = Context.WebSocket.Url;
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "New WebSocket Connection from: {0}", null, url);
|
||||
this.LogInformation("New WebSocket Connection from: {url}", url);
|
||||
|
||||
var match = Regex.Match(url.AbsoluteUri, "(?:ws|wss):\\/\\/.*(?:\\/mc\\/api\\/ui\\/join\\/)(.*)");
|
||||
|
||||
@@ -117,6 +122,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
Controller.SendMessageObjectToDirectClient(message);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnMessage(MessageEventArgs e)
|
||||
{
|
||||
base.OnMessage(e);
|
||||
@@ -128,18 +134,21 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnClose(CloseEventArgs e)
|
||||
{
|
||||
base.OnClose(e);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Closing: {0} reason: {1}", null, e.Code, e.Reason);
|
||||
this.LogInformation("WebSocket UiClient Closing: {code} reason: {reason}", e.Code, e.Reason);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnError(ErrorEventArgs e)
|
||||
{
|
||||
base.OnError(e);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Error: {exception} message: {message}", e.Exception, e.Message);
|
||||
this.LogError("WebSocket UiClient Error: {message}", e.Message);
|
||||
this.LogDebug(e.Exception, "Stack Trace");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a UiClientContext
|
||||
/// </summary>
|
||||
public class UiClientContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Client
|
||||
/// </summary>
|
||||
public UiClient Client { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Token
|
||||
/// </summary>
|
||||
public JoinToken Token { get; private set; }
|
||||
|
||||
public UiClientContext(JoinToken token)
|
||||
{
|
||||
Token = token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SetClient method
|
||||
/// </summary>
|
||||
public void SetClient(UiClient client)
|
||||
{
|
||||
Client = client;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Version
|
||||
/// </summary>
|
||||
public class Version
|
||||
{
|
||||
[JsonProperty("serverVersion")]
|
||||
public string ServerVersion { get; set; }
|
||||
|
||||
[JsonProperty("serverIsRunningOnProcessorHardware")]
|
||||
public bool ServerIsRunningOnProcessorHardware { get; private set; }
|
||||
|
||||
public Version()
|
||||
{
|
||||
ServerIsRunningOnProcessorHardware = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user