mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
Compare commits
2 Commits
copilot/fi
...
v2.8.0-fea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8455d4110 | ||
|
|
f006ed0076 |
9
.vscode/extensions.json
vendored
9
.vscode/extensions.json
vendored
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"ms-dotnettools.vscode-dotnet-runtime",
|
|
||||||
"ms-dotnettools.csharp",
|
|
||||||
"ms-dotnettools.csdevkit",
|
|
||||||
"vivaxy.vscode-conventional-commits",
|
|
||||||
"mhutchie.git-graph"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -11,35 +11,35 @@ namespace PepperDash.Core
|
|||||||
public class Device : IKeyName
|
public class Device : IKeyName
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unique Key
|
/// Unique Key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Key { get; protected set; }
|
public string Key { get; protected set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of the devie
|
/// Name of the devie
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; protected set; }
|
public string Name { get; protected set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enabled { get; protected set; }
|
public bool Enabled { get; protected set; }
|
||||||
|
|
||||||
///// <summary>
|
///// <summary>
|
||||||
///// A place to store reference to the original config object, if any. These values should
|
///// A place to store reference to the original config object, if any. These values should
|
||||||
///// NOT be used as properties on the device as they are all publicly-settable values.
|
///// NOT be used as properties on the device as they are all publicly-settable values.
|
||||||
///// </summary>
|
///// </summary>
|
||||||
//public DeviceConfig Config { get; private set; }
|
//public DeviceConfig Config { get; private set; }
|
||||||
///// <summary>
|
///// <summary>
|
||||||
///// Helper method to check if Config exists
|
///// Helper method to check if Config exists
|
||||||
///// </summary>
|
///// </summary>
|
||||||
//public bool HasConfig { get { return Config != null; } }
|
//public bool HasConfig { get { return Config != null; } }
|
||||||
|
|
||||||
List<Action> _PreActivationActions;
|
List<Action> _PreActivationActions;
|
||||||
List<Action> _PostActivationActions;
|
List<Action> _PostActivationActions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Device DefaultDevice { get { return _DefaultDevice; } }
|
public static Device DefaultDevice { get { return _DefaultDevice; } }
|
||||||
static Device _DefaultDevice = new Device("Default", "Default");
|
static Device _DefaultDevice = new Device("Default", "Default");
|
||||||
|
|
||||||
@@ -54,27 +54,27 @@ namespace PepperDash.Core
|
|||||||
Name = "";
|
Name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor with key and name
|
/// Constructor with key and name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
public Device(string key, string name) : this(key)
|
public Device(string key, string name) : this(key)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//public Device(DeviceConfig config)
|
//public Device(DeviceConfig config)
|
||||||
// : this(config.Key, config.Name)
|
// : this(config.Key, config.Name)
|
||||||
//{
|
//{
|
||||||
// Config = config;
|
// Config = config;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a pre activation action
|
/// Adds a pre activation action
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="act"></param>
|
/// <param name="act"></param>
|
||||||
public void AddPreActivationAction(Action act)
|
public void AddPreActivationAction(Action act)
|
||||||
{
|
{
|
||||||
if (_PreActivationActions == null)
|
if (_PreActivationActions == null)
|
||||||
@@ -82,10 +82,10 @@ namespace PepperDash.Core
|
|||||||
_PreActivationActions.Add(act);
|
_PreActivationActions.Add(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a post activation action
|
/// Adds a post activation action
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="act"></param>
|
/// <param name="act"></param>
|
||||||
public void AddPostActivationAction(Action act)
|
public void AddPostActivationAction(Action act)
|
||||||
{
|
{
|
||||||
if (_PostActivationActions == null)
|
if (_PostActivationActions == null)
|
||||||
@@ -93,58 +93,55 @@ namespace PepperDash.Core
|
|||||||
_PostActivationActions.Add(act);
|
_PostActivationActions.Add(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the preactivation actions
|
/// Executes the preactivation actions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PreActivate()
|
public void PreActivate()
|
||||||
{
|
{
|
||||||
if (_PreActivationActions != null)
|
if (_PreActivationActions != null)
|
||||||
_PreActivationActions.ForEach(a =>
|
_PreActivationActions.ForEach(a => {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
a.Invoke();
|
a.Invoke();
|
||||||
}
|
} catch (Exception e)
|
||||||
catch (Exception e)
|
{
|
||||||
{
|
|
||||||
Debug.LogMessage(e, "Error in PreActivationAction: " + e.Message, this);
|
Debug.LogMessage(e, "Error in PreActivationAction: " + e.Message, this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets this device ready to be used in the system. Runs any added pre-activation items, and
|
/// Gets this device ready to be used in the system. Runs any added pre-activation items, and
|
||||||
/// all post-activation at end. Classes needing additional logic to
|
/// all post-activation at end. Classes needing additional logic to
|
||||||
/// run should override CustomActivate()
|
/// run should override CustomActivate()
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Activate()
|
public bool Activate()
|
||||||
{
|
{
|
||||||
//if (_PreActivationActions != null)
|
//if (_PreActivationActions != null)
|
||||||
// _PreActivationActions.ForEach(a => a.Invoke());
|
// _PreActivationActions.ForEach(a => a.Invoke());
|
||||||
var result = CustomActivate();
|
var result = CustomActivate();
|
||||||
//if(result && _PostActivationActions != null)
|
//if(result && _PostActivationActions != null)
|
||||||
// _PostActivationActions.ForEach(a => a.Invoke());
|
// _PostActivationActions.ForEach(a => a.Invoke());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes the postactivation actions
|
/// Executes the postactivation actions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PostActivate()
|
public void PostActivate()
|
||||||
{
|
{
|
||||||
if (_PostActivationActions != null)
|
if (_PostActivationActions != null)
|
||||||
_PostActivationActions.ForEach(a =>
|
_PostActivationActions.ForEach(a => {
|
||||||
{
|
try
|
||||||
try
|
{
|
||||||
{
|
a.Invoke();
|
||||||
a.Invoke();
|
}
|
||||||
}
|
catch (Exception e)
|
||||||
catch (Exception e)
|
{
|
||||||
{
|
Debug.LogMessage(e, "Error in PostActivationAction: " + e.Message, this);
|
||||||
Debug.LogMessage(e, "Error in PostActivationAction: " + e.Message, this);
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called in between Pre and PostActivationActions when Activate() is called.
|
/// Called in between Pre and PostActivationActions when Activate() is called.
|
||||||
@@ -161,14 +158,14 @@ namespace PepperDash.Core
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual bool Deactivate() { return true; }
|
public virtual bool Deactivate() { return true; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize()
|
/// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize()
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Initialize()
|
public virtual void Initialize()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper method to check object for bool value false and fire an Action method
|
/// Helper method to check object for bool value false and fire an Action method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="o">Should be of type bool, others will be ignored</param>
|
/// <param name="o">Should be of type bool, others will be ignored</param>
|
||||||
@@ -178,15 +175,5 @@ namespace PepperDash.Core
|
|||||||
if (o is bool && !(bool)o) a();
|
if (o is bool && !(bool)o) a();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a string representation of the object, including its key and name.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>The returned string is formatted as "{Key} - {Name}". If the <c>Name</c> property is
|
|
||||||
/// null or empty, "---" is used in place of the name.</remarks>
|
|
||||||
/// <returns>A string that represents the object, containing the key and name in the format "{Key} - {Name}".</returns>
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return string.Format("{0} - {1}", Key, string.IsNullOrEmpty(Name) ? "---" : Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,14 +2,7 @@
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||||
{
|
{
|
||||||
/// <summary>
|
public interface IDisplay: IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName
|
||||||
/// Interface for display devices that can be controlled and monitored.
|
|
||||||
/// This interface combines functionality for feedback, routing, power control,
|
|
||||||
/// warming/cooling, usage tracking, and key name management.
|
|
||||||
/// It is designed to be implemented by devices that require these capabilities,
|
|
||||||
/// such as projectors, displays, and other visual output devices.
|
|
||||||
/// </summary>
|
|
||||||
public interface IDisplay : IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for devices that provide audio meter feedback.
|
|
||||||
/// This interface is used to standardize access to meter feedback across different devices.
|
|
||||||
/// </summary>
|
|
||||||
public interface IMeterFeedback
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the meter feedback for the device.
|
|
||||||
/// This property provides an IntFeedback that represents the current audio level or meter value.
|
|
||||||
/// </summary>
|
|
||||||
IntFeedback MeterFeedback { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
@@ -35,11 +33,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
|||||||
|
|
||||||
string SystemUuid { get; }
|
string SystemUuid { get; }
|
||||||
|
|
||||||
BoolFeedback ApiOnlineAndAuthorized { get; }
|
BoolFeedback ApiOnlineAndAuthorized { get;}
|
||||||
|
|
||||||
void SendMessageObject(IMobileControlMessage o);
|
void SendMessageObject(IMobileControlMessage o);
|
||||||
|
|
||||||
void AddAction<T>(T messenger, Action<string, string, JToken> action) where T : IMobileControlMessenger;
|
void AddAction<T>(T messenger, Action<string, string, JToken> action) where T:IMobileControlMessenger;
|
||||||
|
|
||||||
void RemoveAction(string key);
|
void RemoveAction(string key);
|
||||||
|
|
||||||
@@ -47,14 +45,14 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
|||||||
|
|
||||||
bool CheckForDeviceMessenger(string key);
|
bool CheckForDeviceMessenger(string key);
|
||||||
|
|
||||||
IMobileControlRoomMessenger GetRoomMessenger(string key);
|
IMobileControlRoomMessenger GetRoomMessenger(string key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes a mobile control messenger
|
/// Describes a mobile control messenger
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IMobileControlMessenger : IKeyed
|
public interface IMobileControlMessenger: IKeyed
|
||||||
{
|
{
|
||||||
IMobileControl AppServerController { get; }
|
IMobileControl AppServerController { get; }
|
||||||
string MessagePath { get; }
|
string MessagePath { get; }
|
||||||
@@ -106,47 +104,16 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
|||||||
|
|
||||||
public interface IMobileControlAction
|
public interface IMobileControlAction
|
||||||
{
|
{
|
||||||
IMobileControlMessenger Messenger { get; }
|
IMobileControlMessenger Messenger { get; }
|
||||||
|
|
||||||
Action<string, string, JToken> Action { get; }
|
Action<string,string, JToken> Action { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Describes a MobileControl Touchpanel Controller
|
|
||||||
/// </summary>
|
|
||||||
public interface IMobileControlTouchpanelController : IKeyed
|
public interface IMobileControlTouchpanelController : IKeyed
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The default room key for the controller
|
|
||||||
/// </summary>
|
|
||||||
string DefaultRoomKey { get; }
|
string DefaultRoomKey { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the application URL for the controller
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="url">The application URL</param>
|
|
||||||
void SetAppUrl(string url);
|
void SetAppUrl(string url);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the controller uses a direct server connection
|
|
||||||
/// </summary>
|
|
||||||
bool UseDirectServer { get; }
|
bool UseDirectServer { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the controller is a Zoom Room controller
|
|
||||||
/// </summary>
|
|
||||||
bool ZoomRoomController { get; }
|
bool ZoomRoomController { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Describes a MobileControl Crestron Touchpanel Controller
|
|
||||||
/// This interface extends the IMobileControlTouchpanelController to include connected IP information
|
|
||||||
/// </summary>
|
|
||||||
public interface IMobileControlCrestronTouchpanelController : IMobileControlTouchpanelController
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a collection of connected IP information for the touchpanel controller
|
|
||||||
/// </summary>
|
|
||||||
ReadOnlyCollection<ConnectedIpInformation> ConnectedIps { get; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
using Crestron.SimplSharpPro.DM.Streaming;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a collection of network port information and provides notifications when the information changes.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This interface is designed to provide access to a list of network port details and to notify
|
|
||||||
/// 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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when the port information changes.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This event is triggered whenever there is a change in the port information, such as
|
|
||||||
/// updates to port settings or status. Subscribers can handle this event to respond to such changes.</remarks>
|
|
||||||
event EventHandler PortInformationChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of network port information associated with the current instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>The collection provides information about the network ports, such as their status,
|
|
||||||
/// configuration, or other relevant details. The returned list is read-only and cannot be modified
|
|
||||||
/// directly.</remarks>
|
|
||||||
List<NvxNetworkPortInformation> NetworkPorts { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents information about a network port, including its configuration and associated system details.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This class provides properties to describe various attributes of a network port, such as its
|
|
||||||
/// name, description, VLAN configuration, and management IP address. It is typically used to store and retrieve
|
|
||||||
/// metadata about network ports in a managed environment.</remarks>
|
|
||||||
public class NvxNetworkPortInformation
|
|
||||||
{
|
|
||||||
private readonly DmNvxBaseClass.DmNvx35xNetwork.DmNvxNetworkLldpPort port;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the index of the device port.
|
|
||||||
/// </summary>
|
|
||||||
public uint DevicePortIndex { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the port used for communication.
|
|
||||||
/// </summary>
|
|
||||||
public string PortName => port.PortNameFeedback.StringValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the description of the port.
|
|
||||||
/// </summary>
|
|
||||||
public string PortDescription => port.PortNameDescriptionFeedback.StringValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the VLAN (Virtual Local Area Network).
|
|
||||||
/// </summary>
|
|
||||||
public string VlanName => port.VlanNameFeedback.StringValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the IP management address associated with the port.
|
|
||||||
/// </summary>
|
|
||||||
public string IpManagementAddress => port.IpManagementAddressFeedback.StringValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of the system as reported by the associated port.
|
|
||||||
/// </summary>
|
|
||||||
public string SystemName => port.SystemNameFeedback.StringValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the description of the system name.
|
|
||||||
/// </summary>
|
|
||||||
public string SystemNameDescription => port.SystemNameDescriptionFeedback.StringValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="NvxNetworkPortInformation"/> class with the specified network port
|
|
||||||
/// and device port index.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="port">The network port associated with the device. Cannot be <see langword="null"/>.</param>
|
|
||||||
/// <param name="devicePortIndex">The index of the device port.</param>
|
|
||||||
/// <exception cref="ArgumentNullException">Thrown if <paramref name="port"/> is <see langword="null"/>.</exception>
|
|
||||||
public NvxNetworkPortInformation(DmNvxBaseClass.DmNvx35xNetwork.DmNvxNetworkLldpPort port, uint devicePortIndex)
|
|
||||||
{
|
|
||||||
this.port = port ?? throw new ArgumentNullException(nameof(port), "Port cannot be null");
|
|
||||||
DevicePortIndex = devicePortIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for devices that provide state feedback.
|
|
||||||
/// This interface is used to standardize access to state feedback across different devices.
|
|
||||||
/// </summary>
|
|
||||||
public interface IStateFeedback
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the state feedback for the device.
|
|
||||||
/// This property provides a BoolFeedback that represents the current state (on/off) of the device.
|
|
||||||
/// </summary>
|
|
||||||
BoolFeedback StateFeedback { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,34 +5,19 @@ using PepperDash.Essentials.Core;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Represents a destination item in a routing system that can receive audio/video signals.
|
|
||||||
/// Contains information about the destination device, its properties, and location settings.
|
|
||||||
/// </summary>
|
|
||||||
public class DestinationListItem
|
public class DestinationListItem
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the key identifier for the sink device that this destination represents.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("sinkKey")]
|
[JsonProperty("sinkKey")]
|
||||||
public string SinkKey { get; set; }
|
public string SinkKey { get; set; }
|
||||||
|
|
||||||
private EssentialsDevice _sinkDevice;
|
private EssentialsDevice _sinkDevice;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the actual device instance for this destination.
|
|
||||||
/// Lazily loads the device from the DeviceManager using the SinkKey.
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public EssentialsDevice SinkDevice
|
public EssentialsDevice SinkDevice
|
||||||
{
|
{
|
||||||
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); }
|
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the preferred display name for this destination.
|
|
||||||
/// Returns the custom Name if set, otherwise returns the SinkDevice name, or "---" if no device is found.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("preferredName")]
|
[JsonProperty("preferredName")]
|
||||||
public string PreferredName
|
public string PreferredName
|
||||||
{
|
{
|
||||||
@@ -47,78 +32,31 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the custom name for this destination.
|
|
||||||
/// If set, this name will be used as the PreferredName instead of the device name.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("name")]
|
[JsonProperty("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this destination should be included in destination lists.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("includeInDestinationList")]
|
[JsonProperty("includeInDestinationList")]
|
||||||
public bool IncludeInDestinationList { get; set; }
|
public bool IncludeInDestinationList { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the display order for this destination in lists.
|
|
||||||
/// Lower values appear first in sorted lists.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("order")]
|
[JsonProperty("order")]
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the surface location identifier for this destination.
|
|
||||||
/// Used to specify which surface or screen this destination is located on.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("surfaceLocation")]
|
[JsonProperty("surfaceLocation")]
|
||||||
public int SurfaceLocation { get; set; }
|
public int SurfaceLocation { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the vertical location position for this destination.
|
|
||||||
/// Used for spatial positioning in multi-display configurations.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("verticalLocation")]
|
[JsonProperty("verticalLocation")]
|
||||||
public int VerticalLocation { get; set; }
|
public int VerticalLocation { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the horizontal location position for this destination.
|
|
||||||
/// Used for spatial positioning in multi-display configurations.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("horizontalLocation")]
|
[JsonProperty("horizontalLocation")]
|
||||||
public int HorizontalLocation { get; set; }
|
public int HorizontalLocation { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the signal type that this destination can receive (Audio, Video, AudioVideo, etc.).
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("sinkType")]
|
[JsonProperty("sinkType")]
|
||||||
public eRoutingSignalType SinkType { get; set; }
|
public eRoutingSignalType SinkType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this destination is used for codec content sharing.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("isCodecContentDestination")]
|
[JsonProperty("isCodecContentDestination")]
|
||||||
public bool isCodecContentDestination { get; set; }
|
public bool isCodecContentDestination { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this destination is used for program audio output.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("isProgramAudioDestination")]
|
[JsonProperty("isProgramAudioDestination")]
|
||||||
public bool isProgramAudioDestination { get; set; }
|
public bool isProgramAudioDestination { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this destination supports USB connections.
|
|
||||||
/// Indicates if the destination can handle USB functionality, such as USB signal routing or device connections.
|
|
||||||
/// This property is used to determine compatibility with USB-based devices or systems.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("supportsUsb")]
|
|
||||||
public bool SupportsUsb { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The key of the destination port associated with this destination item
|
|
||||||
/// This is used to identify the specific port on the destination device that this item refers to for advanced routing
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("destinationPortKey")]
|
|
||||||
public string DestinationPortKey { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
|
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse($"{dev}: {dev.CommunicationMonitor.Status}\r\n");
|
CrestronConsole.ConsoleCommandResponse($"{dev}: {dev.CommunicationMonitor.Status}{Environment.NewLine}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,20 +20,19 @@ namespace PepperDash.Essentials.Core
|
|||||||
public event EventHandler Initialized;
|
public event EventHandler Initialized;
|
||||||
|
|
||||||
private bool _isInitialized;
|
private bool _isInitialized;
|
||||||
public bool IsInitialized
|
public bool IsInitialized {
|
||||||
{
|
|
||||||
get { return _isInitialized; }
|
get { return _isInitialized; }
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
if (_isInitialized == value) return;
|
if (_isInitialized == value) return;
|
||||||
|
|
||||||
_isInitialized = value;
|
_isInitialized = value;
|
||||||
|
|
||||||
if (_isInitialized)
|
if (_isInitialized)
|
||||||
{
|
{
|
||||||
Initialized?.Invoke(this, new EventArgs());
|
Initialized?.Invoke(this, new EventArgs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EssentialsDevice(string key)
|
protected EssentialsDevice(string key)
|
||||||
@@ -81,9 +80,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Override this method to build and create custom Mobile Control Messengers during the Activation phase
|
/// Override this method to build and create custom Mobile Control Messengers during the Activation phase
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void CreateMobileControlMessengers()
|
protected virtual void CreateMobileControlMessengers() {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the type of source list item, which can be a route, off, or other.
|
///
|
||||||
/// This is used to categorize the source list items in a room.
|
|
||||||
/// The type is serialized to JSON and can be used to determine how the item should be displayed or handled in the UI.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum eSourceListItemType
|
public enum eSourceListItemType
|
||||||
{
|
{
|
||||||
@@ -168,26 +166,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonProperty("disableSimpleRouting")]
|
[JsonProperty("disableSimpleRouting")]
|
||||||
public bool DisableSimpleRouting { get; set; }
|
public bool DisableSimpleRouting { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The key of the device that provides video sync for this source item
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("syncProviderDeviceKey")]
|
|
||||||
public string SyncProviderDeviceKey { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates if the source supports USB connections
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("supportsUsb")]
|
|
||||||
public bool SupportsUsb { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The key of the source port associated with this source item
|
|
||||||
/// This is used to identify the specific port on the source device that this item refers to for advanced routing
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("sourcePortKey")]
|
|
||||||
public string SourcePortKey { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default constructor for SourceListItem, initializes the Icon to "Blank"
|
/// Default constructor for SourceListItem, initializes the Icon to "Blank"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -199,7 +177,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a string representation of the SourceListItem, including the SourceKey and Name
|
/// Returns a string representation of the SourceListItem, including the SourceKey and Name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns> A string representation of the SourceListItem</returns>
|
/// <returns></returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{SourceKey}:{Name}";
|
return $"{SourceKey}:{Name}";
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
|
<PackageReference Include="Crestron.SimplSharp.SDK.ProgramLibrary" Version="2.21.90" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />
|
<None Include="Crestron\CrestronGenericBaseDevice.cs.orig" />
|
||||||
|
|||||||
@@ -10,13 +10,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Represents a device that manages room combinations by controlling partitions and scenarios.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>The <see cref="EssentialsRoomCombiner"/> allows for dynamic configuration of room
|
|
||||||
/// combinations based on partition states and predefined scenarios. It supports both automatic and manual modes
|
|
||||||
/// for managing room combinations. In automatic mode, the device determines the current room combination scenario
|
|
||||||
/// based on partition sensor states. In manual mode, scenarios can be set explicitly by the user.</remarks>
|
|
||||||
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner
|
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner
|
||||||
{
|
{
|
||||||
private EssentialsRoomCombinerPropertiesConfig _propertiesConfig;
|
private EssentialsRoomCombinerPropertiesConfig _propertiesConfig;
|
||||||
@@ -25,9 +18,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
private List<IEssentialsRoom> _rooms;
|
private List<IEssentialsRoom> _rooms;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a list of rooms represented as key-name pairs.
|
|
||||||
/// </summary>
|
|
||||||
public List<IKeyName> Rooms
|
public List<IKeyName> Rooms
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -38,12 +28,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
private bool _isInAutoMode;
|
private bool _isInAutoMode;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether the system is operating in automatic mode.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Changing this property triggers an update event via
|
|
||||||
/// <c>IsInAutoModeFeedback.FireUpdate()</c>. Ensure that any event listeners are properly configured to handle
|
|
||||||
/// this update.</remarks>
|
|
||||||
public bool IsInAutoMode
|
public bool IsInAutoMode
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -62,36 +46,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether automatic mode is disabled.
|
|
||||||
/// </summary>
|
|
||||||
public bool DisableAutoMode
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _propertiesConfig.DisableAutoMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CTimer _scenarioChangeDebounceTimer;
|
private CTimer _scenarioChangeDebounceTimer;
|
||||||
|
|
||||||
private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s
|
private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s
|
||||||
|
|
||||||
private Mutex _scenarioChange = new Mutex();
|
private Mutex _scenarioChange = new Mutex();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="EssentialsRoomCombiner"/> class, which manages room combination
|
|
||||||
/// scenarios and partition states.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>The <see cref="EssentialsRoomCombiner"/> class is designed to handle dynamic room
|
|
||||||
/// combination scenarios based on partition states. It supports both automatic and manual modes for managing
|
|
||||||
/// room combinations. By default, the instance starts in automatic mode unless the <paramref name="props"/>
|
|
||||||
/// specifies otherwise. After activation, the room combiner initializes partition state providers and sets up
|
|
||||||
/// the initial room configuration. Additionally, it subscribes to the <see
|
|
||||||
/// cref="DeviceManager.AllDevicesInitialized"/> event to ensure proper initialization of dependent devices
|
|
||||||
/// before determining or setting the room combination scenario.</remarks>
|
|
||||||
/// <param name="key">The unique identifier for the room combiner instance.</param>
|
|
||||||
/// <param name="props">The configuration properties for the room combiner, including default settings and debounce times.</param>
|
|
||||||
public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props)
|
public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
@@ -286,16 +246,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
#region IEssentialsRoomCombiner Members
|
#region IEssentialsRoomCombiner Members
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when the room combination scenario changes.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This event is triggered whenever the configuration or state of the room combination
|
|
||||||
/// changes. Subscribers can use this event to update their logic or UI based on the new scenario.</remarks>
|
|
||||||
public event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
public event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current room combination scenario.
|
|
||||||
/// </summary>
|
|
||||||
public IRoomCombinationScenario CurrentScenario
|
public IRoomCombinationScenario CurrentScenario
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -304,25 +256,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the feedback indicating whether the system is currently in auto mode.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback IsInAutoModeFeedback { get; private set; }
|
public BoolFeedback IsInAutoModeFeedback { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enables auto mode for the room combiner and its partitions, allowing automatic room combination scenarios to
|
|
||||||
/// be determined.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Auto mode allows the room combiner to automatically adjust its configuration based on
|
|
||||||
/// the state of its partitions. If auto mode is disabled in the configuration, this method logs a warning and
|
|
||||||
/// does not enable auto mode.</remarks>
|
|
||||||
public void SetAutoMode()
|
public void SetAutoMode()
|
||||||
{
|
{
|
||||||
if(_propertiesConfig.DisableAutoMode)
|
|
||||||
{
|
|
||||||
this.LogWarning("Auto mode is disabled for this room combiner. Cannot set to auto mode.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IsInAutoMode = true;
|
IsInAutoMode = true;
|
||||||
|
|
||||||
foreach (var partition in Partitions)
|
foreach (var partition in Partitions)
|
||||||
@@ -333,12 +270,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
DetermineRoomCombinationScenario();
|
DetermineRoomCombinationScenario();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Switches the system to manual mode, disabling automatic operations.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This method sets the system to manual mode by updating the mode state and propagates
|
|
||||||
/// the change to all partitions. Once in manual mode, automatic operations are disabled for the system and its
|
|
||||||
/// partitions.</remarks>
|
|
||||||
public void SetManualMode()
|
public void SetManualMode()
|
||||||
{
|
{
|
||||||
IsInAutoMode = false;
|
IsInAutoMode = false;
|
||||||
@@ -349,11 +280,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles the current mode between automatic and manual.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>If the current mode is automatic, this method switches to manual mode. If the
|
|
||||||
/// current mode is manual, it switches to automatic mode.</remarks>
|
|
||||||
public void ToggleMode()
|
public void ToggleMode()
|
||||||
{
|
{
|
||||||
if (IsInAutoMode)
|
if (IsInAutoMode)
|
||||||
@@ -366,22 +292,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of room combination scenarios.
|
|
||||||
/// </summary>
|
|
||||||
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; private set; }
|
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of partition controllers managed by this instance.
|
|
||||||
/// </summary>
|
|
||||||
public List<IPartitionController> Partitions { get; private set; }
|
public List<IPartitionController> Partitions { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles the state of the partition identified by the specified partition key.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>If no partition with the specified key exists, the method performs no
|
|
||||||
/// action.</remarks>
|
|
||||||
/// <param name="partitionKey">The key of the partition whose state is to be toggled. This value cannot be null or empty.</param>
|
|
||||||
public void TogglePartitionState(string partitionKey)
|
public void TogglePartitionState(string partitionKey)
|
||||||
{
|
{
|
||||||
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey));
|
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey));
|
||||||
@@ -392,17 +306,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the room combination scenario based on the specified scenario key.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This method manually adjusts the partition states according to the specified
|
|
||||||
/// scenario. If the application is in auto mode, the operation will not proceed, and a log message will be
|
|
||||||
/// generated indicating that the mode must be set to manual first. If the specified scenario key does not
|
|
||||||
/// match any existing scenario, a debug log message will be generated. For each partition state in the
|
|
||||||
/// scenario, the corresponding partition will be updated to either "Present" or "Not Present" based on the
|
|
||||||
/// scenario's configuration. If a partition key in the scenario cannot be found, a debug log message will be
|
|
||||||
/// generated.</remarks>
|
|
||||||
/// <param name="scenarioKey">The key identifying the room combination scenario to apply. This must match the key of an existing scenario.</param>
|
|
||||||
public void SetRoomCombinationScenario(string scenarioKey)
|
public void SetRoomCombinationScenario(string scenarioKey)
|
||||||
{
|
{
|
||||||
if (IsInAutoMode)
|
if (IsInAutoMode)
|
||||||
@@ -451,32 +354,13 @@ namespace PepperDash.Essentials.Core
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides a factory for creating instances of <see cref="EssentialsRoomCombiner"/> devices.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This factory is responsible for constructing <see cref="EssentialsRoomCombiner"/> devices
|
|
||||||
/// based on the provided configuration. It supports the type name "essentialsroomcombiner" for device
|
|
||||||
/// creation.</remarks>
|
|
||||||
public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory<EssentialsRoomCombiner>
|
public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory<EssentialsRoomCombiner>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="EssentialsRoomCombinerFactory"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This factory is used to create instances of room combiners with the specified type
|
|
||||||
/// names. By default, the factory includes the type name "essentialsroomcombiner".</remarks>
|
|
||||||
public EssentialsRoomCombinerFactory()
|
public EssentialsRoomCombinerFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string> { "essentialsroomcombiner" };
|
TypeNames = new List<string> { "essentialsroomcombiner" };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates and initializes a new instance of the <see cref="EssentialsRoomCombiner"/> device.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This method uses the provided device configuration to extract the properties and
|
|
||||||
/// create an <see cref="EssentialsRoomCombiner"/> device. Ensure that the configuration contains valid
|
|
||||||
/// properties for the device to be created successfully.</remarks>
|
|
||||||
/// <param name="dc">The device configuration containing the key and properties required to build the device.</param>
|
|
||||||
/// <returns>A new instance of <see cref="EssentialsRoomCombiner"/> initialized with the specified configuration.</returns>
|
|
||||||
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new EssentialsRoomCombiner Device");
|
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new EssentialsRoomCombiner Device");
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
|
||||||
@@ -11,14 +17,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsRoomCombinerPropertiesConfig
|
public class EssentialsRoomCombinerPropertiesConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether the system operates in automatic mode.
|
|
||||||
/// <remarks>Some systems don't have partitions sensors, and show shouldn't allow auto mode to be turned on. When this is true in the configuration,
|
|
||||||
/// auto mode won't be allowed to be turned on.</remarks>
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("disableAutoMode")]
|
|
||||||
public bool DisableAutoMode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of partitions that device the rooms
|
/// The list of partitions that device the rooms
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -49,9 +47,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonProperty("defaultScenarioKey")]
|
[JsonProperty("defaultScenarioKey")]
|
||||||
public string defaultScenarioKey { get; set; }
|
public string defaultScenarioKey { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the debounce time, in seconds, for scenario changes.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("scenarioChangeDebounceTimeSeconds")]
|
[JsonProperty("scenarioChangeDebounceTimeSeconds")]
|
||||||
public int ScenarioChangeDebounceTimeSeconds { get; set; }
|
public int ScenarioChangeDebounceTimeSeconds { get; set; }
|
||||||
}
|
}
|
||||||
@@ -61,15 +56,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PartitionConfig : IKeyName
|
public class PartitionConfig : IKeyName
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the unique key associated with the object.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("key")]
|
[JsonProperty("key")]
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name associated with the object.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("name")]
|
[JsonProperty("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
@@ -91,21 +80,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RoomCombinationScenarioConfig : IKeyName
|
public class RoomCombinationScenarioConfig : IKeyName
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the key associated with the object.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("key")]
|
[JsonProperty("key")]
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name associated with the object.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("name")]
|
[JsonProperty("name")]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the collection of partition states.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("partitionStates")]
|
[JsonProperty("partitionStates")]
|
||||||
public List<PartitionState> PartitionStates { get; set; }
|
public List<PartitionState> PartitionStates { get; set; }
|
||||||
|
|
||||||
@@ -115,15 +95,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonProperty("uiMap")]
|
[JsonProperty("uiMap")]
|
||||||
public Dictionary<string, string> UiMap { get; set; }
|
public Dictionary<string, string> UiMap { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the list of actions to be performed during device activation.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("activationActions")]
|
[JsonProperty("activationActions")]
|
||||||
public List<DeviceActionWrapper> ActivationActions { get; set; }
|
public List<DeviceActionWrapper> ActivationActions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the list of actions to be performed when a device is deactivated.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("deactivationActions")]
|
[JsonProperty("deactivationActions")]
|
||||||
public List<DeviceActionWrapper> DeactivationActions { get; set; }
|
public List<DeviceActionWrapper> DeactivationActions { get; set; }
|
||||||
}
|
}
|
||||||
@@ -133,15 +107,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PartitionState
|
public class PartitionState
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the partition key used to group and organize data within a storage system.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("partitionKey")]
|
[JsonProperty("partitionKey")]
|
||||||
public string PartitionKey { get; set; }
|
public string PartitionKey { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether a partition is currently present.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("partitionSensedState")]
|
[JsonProperty("partitionSensedState")]
|
||||||
public bool PartitionPresent { get; set; }
|
public bool PartitionPresent { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,20 +28,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
BoolFeedback IsInAutoModeFeedback {get;}
|
BoolFeedback IsInAutoModeFeedback {get;}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the automatic mode is disabled.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("disableAutoMode")]
|
|
||||||
bool DisableAutoMode { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the system is operating in automatic mode.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("isInAutoMode")]
|
[JsonProperty("isInAutoMode")]
|
||||||
bool IsInAutoMode { get; }
|
bool IsInAutoMode { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of rooms associated with the current object.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("rooms")]
|
[JsonProperty("rooms")]
|
||||||
List<IKeyName> Rooms { get; }
|
List<IKeyName> Rooms { get; }
|
||||||
|
|
||||||
@@ -85,13 +74,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
void SetRoomCombinationScenario(string scenarioKey);
|
void SetRoomCombinationScenario(string scenarioKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a scenario for combining rooms, including activation, deactivation, and associated state.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This interface defines the behavior for managing room combination scenarios, including
|
|
||||||
/// activation and deactivation, tracking the active state, and managing related partition states and UI mappings.
|
|
||||||
/// Implementations of this interface are expected to handle the logic for room combinations based on the provided
|
|
||||||
/// partition states and UI mappings.</remarks>
|
|
||||||
public interface IRoomCombinationScenario : IKeyName
|
public interface IRoomCombinationScenario : IKeyName
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -100,9 +82,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
BoolFeedback IsActiveFeedback { get; }
|
BoolFeedback IsActiveFeedback { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity is active.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("isActive")]
|
[JsonProperty("isActive")]
|
||||||
bool IsActive { get; }
|
bool IsActive { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Routing
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The current sources for the room, keyed by eRoutingSignalType.
|
|
||||||
/// This allows for multiple sources to be tracked, such as audio and video.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This interface is used to provide access to the current sources in a room,
|
|
||||||
/// allowing for more complex routing scenarios where multiple signal types are involved.
|
|
||||||
/// </remarks>
|
|
||||||
public interface ICurrentSources
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current sources for the room, keyed by eRoutingSignalType.
|
|
||||||
/// This dictionary contains the current source for each signal type, such as audio, video, and control signals.
|
|
||||||
/// </summary>
|
|
||||||
Dictionary<eRoutingSignalType, SourceListItem> CurrentSources { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current source keys for the room, keyed by eRoutingSignalType.
|
|
||||||
/// This dictionary contains the keys for the current source for each signal type, such as audio, video, and control signals.
|
|
||||||
/// </summary>
|
|
||||||
Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,8 +9,6 @@ using PepperDash.Essentials.Core.Routing;
|
|||||||
using PepperDash.Essentials.Core.Routing;
|
using PepperDash.Essentials.Core.Routing;
|
||||||
using PepperDash.Essentials.Core.Routing.Interfaces
|
using PepperDash.Essentials.Core.Routing.Interfaces
|
||||||
*/
|
*/
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -23,24 +21,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// For rooms with a single presentation source, change event
|
/// For rooms with a single presentation source, change event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete("Use ICurrentSources instead")]
|
|
||||||
public interface IHasCurrentSourceInfoChange
|
public interface IHasCurrentSourceInfoChange
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The key for the current source info, used to look up the source in the SourceList
|
|
||||||
/// </summary>
|
|
||||||
string CurrentSourceInfoKey { get; set; }
|
string CurrentSourceInfoKey { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current source info for the room, used to look up the source in the SourceList
|
|
||||||
/// </summary>
|
|
||||||
SourceListItem CurrentSourceInfo { get; set; }
|
SourceListItem CurrentSourceInfo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event that is raised when the current source info changes.
|
|
||||||
/// This is used to notify the system of changes to the current source info.
|
|
||||||
/// The event handler receives the new source info and the type of change that occurred.
|
|
||||||
/// </summary>
|
|
||||||
event SourceInfoChangeHandler CurrentSourceChange;
|
event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
using PepperDash.Essentials.Core.Routing;
|
namespace PepperDash.Essentials.Core
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For fixed-source endpoint devices
|
/// For fixed-source endpoint devices
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For fixed-source endpoint devices with an input port
|
/// For fixed-source endpoint devices with an input port
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoutingSinkWithInputPort : IRoutingSink
|
public interface IRoutingSinkWithInputPort :IRoutingSink
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current input port for this routing sink.
|
/// Gets the current input port for this routing sink.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RoutingInputPort CurrentInputPort { get; }
|
RoutingInputPort CurrentInputPort { get; }
|
||||||
}
|
}
|
||||||
|
/*/// <summary>
|
||||||
/// <summary>
|
/// For fixed-source endpoint devices
|
||||||
/// Interface for routing sinks that have access to the current source information.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRoutingSinkWithCurrentSources : IRoutingSink, ICurrentSources
|
public interface IRoutingSink<TSelector> : IRoutingInputs<TSelector>, IHasCurrentSourceInfoChange
|
||||||
{
|
{
|
||||||
}
|
void UpdateRouteRequest<TOutputSelector>(RouteRequest<TSelector, TOutputSelector> request);
|
||||||
|
|
||||||
|
RouteRequest<TSelector, TOutputSelector> GetRouteRequest<TOutputSelector>();
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.Attributes
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Base class for HTTP method attributes
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
|
||||||
public abstract class HttpMethodAttribute : Attribute
|
|
||||||
{
|
|
||||||
public string Method { get; }
|
|
||||||
|
|
||||||
protected HttpMethodAttribute(string method)
|
|
||||||
{
|
|
||||||
Method = method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that a request handler supports HTTP GET operations
|
|
||||||
/// </summary>
|
|
||||||
public class HttpGetAttribute : HttpMethodAttribute
|
|
||||||
{
|
|
||||||
public HttpGetAttribute() : base("GET") { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that a request handler supports HTTP POST operations
|
|
||||||
/// </summary>
|
|
||||||
public class HttpPostAttribute : HttpMethodAttribute
|
|
||||||
{
|
|
||||||
public HttpPostAttribute() : base("POST") { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that a request handler supports HTTP PUT operations
|
|
||||||
/// </summary>
|
|
||||||
public class HttpPutAttribute : HttpMethodAttribute
|
|
||||||
{
|
|
||||||
public HttpPutAttribute() : base("PUT") { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that a request handler supports HTTP DELETE operations
|
|
||||||
/// </summary>
|
|
||||||
public class HttpDeleteAttribute : HttpMethodAttribute
|
|
||||||
{
|
|
||||||
public HttpDeleteAttribute() : base("DELETE") { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides OpenAPI operation metadata for a request handler
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
|
||||||
public class OpenApiOperationAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A brief summary of what the operation does
|
|
||||||
/// </summary>
|
|
||||||
public string Summary { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A verbose explanation of the operation behavior
|
|
||||||
/// </summary>
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unique string used to identify the operation
|
|
||||||
/// </summary>
|
|
||||||
public string OperationId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of tags for API documentation control
|
|
||||||
/// </summary>
|
|
||||||
public string[] Tags { get; set; }
|
|
||||||
|
|
||||||
public OpenApiOperationAttribute()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Describes a response from an API operation
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
|
||||||
public class OpenApiResponseAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The HTTP status code
|
|
||||||
/// </summary>
|
|
||||||
public int StatusCode { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A short description of the response
|
|
||||||
/// </summary>
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The content type of the response
|
|
||||||
/// </summary>
|
|
||||||
public string ContentType { get; set; } = "application/json";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type that represents the response schema
|
|
||||||
/// </summary>
|
|
||||||
public Type Type { get; set; }
|
|
||||||
|
|
||||||
public OpenApiResponseAttribute(int statusCode)
|
|
||||||
{
|
|
||||||
StatusCode = statusCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates that an operation requires a request body
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
|
||||||
public class OpenApiRequestBodyAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Determines if the request body is required
|
|
||||||
/// </summary>
|
|
||||||
public bool Required { get; set; } = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The content type of the request body
|
|
||||||
/// </summary>
|
|
||||||
public string ContentType { get; set; } = "application/json";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type that represents the request body schema
|
|
||||||
/// </summary>
|
|
||||||
public Type Type { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Description of the request body
|
|
||||||
/// </summary>
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
public OpenApiRequestBodyAttribute()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Describes a parameter for the operation
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
|
||||||
public class OpenApiParameterAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The name of the parameter
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The location of the parameter
|
|
||||||
/// </summary>
|
|
||||||
public ParameterLocation In { get; set; } = ParameterLocation.Path;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether this parameter is mandatory
|
|
||||||
/// </summary>
|
|
||||||
public bool Required { get; set; } = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A brief description of the parameter
|
|
||||||
/// </summary>
|
|
||||||
public string Description { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type of the parameter
|
|
||||||
/// </summary>
|
|
||||||
public Type Type { get; set; } = typeof(string);
|
|
||||||
|
|
||||||
public OpenApiParameterAttribute(string name)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The location of the parameter
|
|
||||||
/// </summary>
|
|
||||||
public enum ParameterLocation
|
|
||||||
{
|
|
||||||
Query,
|
|
||||||
Header,
|
|
||||||
Path,
|
|
||||||
Cookie
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -210,11 +210,6 @@ namespace PepperDash.Essentials.Core.Web
|
|||||||
RouteHandler = new GetRoutesHandler(_server.GetRouteCollection(), BasePath)
|
RouteHandler = new GetRoutesHandler(_server.GetRouteCollection(), BasePath)
|
||||||
});
|
});
|
||||||
|
|
||||||
AddRoute(new HttpCwsRoute("swagger") {
|
|
||||||
Name = "OpenAPI Documentation",
|
|
||||||
RouteHandler = new SwaggerHandler(_server.GetRouteCollection(), BasePath)
|
|
||||||
});
|
|
||||||
|
|
||||||
// If running on an appliance
|
// If running on an appliance
|
||||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,22 +2,12 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
using System;
|
using System;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "AppDebug",
|
|
||||||
Description = "Get or set application debug level settings",
|
|
||||||
OperationId = "appDebug")]
|
|
||||||
[OpenApiRequestBody(Description = "Debug level configuration")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
public class AppDebugRequestHandler : WebApiBaseRequestHandler
|
public class AppDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Crestron.SimplSharpPro.EthernetCommunication;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -14,15 +13,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
public class DebugSessionRequestHandler : WebApiBaseRequestHandler
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DebugSession",
|
|
||||||
Description = "Start or stop a WebSocket debug session",
|
|
||||||
OperationId = "debugSession")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
public class DebugSessionRequestHandler : WebApiBaseRequestHandler
|
|
||||||
{
|
{
|
||||||
public DebugSessionRequestHandler()
|
public DebugSessionRequestHandler()
|
||||||
: base(true)
|
: base(true)
|
||||||
|
|||||||
@@ -3,20 +3,10 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DevJson",
|
|
||||||
Description = "Send a command to a specific device",
|
|
||||||
OperationId = "sendDeviceCommand")]
|
|
||||||
[OpenApiParameter("deviceKey", Description = "The key of the device to send the command to")]
|
|
||||||
[OpenApiRequestBody(Description = "Device command data")]
|
|
||||||
[OpenApiResponse(200, Description = "Command executed successfully")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
public class DevJsonRequestHandler : WebApiBaseRequestHandler
|
public class DevJsonRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,17 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DevList",
|
|
||||||
Description = "Retrieve a list of all devices in the system",
|
|
||||||
OperationId = "getDevices")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(404, Description = "Not Found")]
|
|
||||||
public class DevListRequestHandler : WebApiBaseRequestHandler
|
public class DevListRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,19 +3,9 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DevMethods",
|
|
||||||
Description = "Retrieve available methods for a specific device",
|
|
||||||
OperationId = "getDeviceMethods")]
|
|
||||||
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Device not found")]
|
|
||||||
public class DevMethodsRequestHandler : WebApiBaseRequestHandler
|
public class DevMethodsRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,19 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DevProps",
|
|
||||||
Description = "Retrieve properties for a specific device",
|
|
||||||
OperationId = "getDeviceProperties")]
|
|
||||||
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Device not found")]
|
|
||||||
public class DevPropsRequestHandler : WebApiBaseRequestHandler
|
public class DevPropsRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DisableAllStreamDebug",
|
|
||||||
Description = "Disable stream debugging for all devices",
|
|
||||||
OperationId = "disableAllStreamDebug")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response")]
|
|
||||||
public class DisableAllStreamDebugRequestHandler : WebApiBaseRequestHandler
|
public class DisableAllStreamDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,19 +2,9 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "DoNotLoadConfigOnNextBoot",
|
|
||||||
Description = "Get or set flag to prevent configuration loading on next boot",
|
|
||||||
OperationId = "doNotLoadConfigOnNextBoot")]
|
|
||||||
[OpenApiRequestBody(Description = "Configuration loading flag")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
public class DoNotLoadConfigOnNextBootRequestHandler : WebApiBaseRequestHandler
|
public class DoNotLoadConfigOnNextBootRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,19 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "GetFeedbacksForDeviceKey",
|
|
||||||
Description = "Get feedback values from a specific device",
|
|
||||||
OperationId = "getDeviceFeedbacks")]
|
|
||||||
[OpenApiParameter("deviceKey", Description = "The key of the device to get feedbacks from")]
|
|
||||||
[OpenApiResponse(200, Description = "Device feedback values")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Device not found")]
|
|
||||||
public class GetFeedbacksForDeviceRequestHandler : WebApiBaseRequestHandler
|
public class GetFeedbacksForDeviceRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,19 +3,9 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "GetJoinMapsForBridgeKey",
|
|
||||||
Description = "Retrieve all join maps for a specific bridge",
|
|
||||||
OperationId = "getJoinMapForBridge")]
|
|
||||||
[OpenApiParameter("bridgeKey", Description = "The key of the bridge")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Bridge not found")]
|
|
||||||
public class GetJoinMapForBridgeKeyRequestHandler : WebApiBaseRequestHandler
|
public class GetJoinMapForBridgeKeyRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,21 +2,9 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "GetJoinMapsForDeviceKey",
|
|
||||||
Description = "Retrieve join map for a specific device within a bridge",
|
|
||||||
OperationId = "getJoinMapForDevice")]
|
|
||||||
[OpenApiParameter("bridgeKey", Description = "The key of the bridge")]
|
|
||||||
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Bridge not found")]
|
|
||||||
[OpenApiResponse(500, Description = "Device join map not found")]
|
|
||||||
public class GetJoinMapForDeviceKeyRequestHandler : WebApiBaseRequestHandler
|
public class GetJoinMapForDeviceKeyRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,16 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "GetPaths",
|
|
||||||
Description = "Get available API paths and routes",
|
|
||||||
OperationId = "getApiPaths")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response")]
|
|
||||||
public class GetRoutesHandler:WebApiBaseRequestHandler
|
public class GetRoutesHandler:WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
private HttpCwsRouteCollection routeCollection;
|
private HttpCwsRouteCollection routeCollection;
|
||||||
|
|||||||
@@ -1,23 +1,13 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
public class GetRoutingPortsHandler : WebApiBaseRequestHandler
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "Get Routing Ports for a device",
|
|
||||||
Description = "Retrieve routing input and output ports for a specific device",
|
|
||||||
OperationId = "getDeviceRoutingPorts")]
|
|
||||||
[OpenApiParameter("deviceKey", Description = "The key of the device")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Device not found")]
|
|
||||||
public class GetRoutingPortsHandler : WebApiBaseRequestHandler
|
|
||||||
{
|
{
|
||||||
public GetRoutingPortsHandler() : base(true) { }
|
public GetRoutingPortsHandler() : base(true) { }
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
public class GetTieLinesRequestHandler : WebApiBaseRequestHandler
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "Get TieLines",
|
|
||||||
Description = "Retrieve a list of all tie lines in the system",
|
|
||||||
OperationId = "getTieLines")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
public class GetTieLinesRequestHandler : WebApiBaseRequestHandler
|
|
||||||
{
|
{
|
||||||
public GetTieLinesRequestHandler() : base(true) { }
|
public GetTieLinesRequestHandler() : base(true) { }
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "GetTypesByFilter",
|
|
||||||
Description = "Retrieve device types filtered by a specific category",
|
|
||||||
OperationId = "getDeviceTypesByFilter")]
|
|
||||||
[OpenApiParameter("filter", Description = "The filter criteria for device types")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Filtered device types not found")]
|
|
||||||
public class GetTypesByFilterRequestHandler : WebApiBaseRequestHandler
|
public class GetTypesByFilterRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,18 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "GetTypes",
|
|
||||||
Description = "Retrieve a list of all available device types",
|
|
||||||
OperationId = "getDeviceTypes")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response", ContentType = "application/json")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Device factory not found")]
|
|
||||||
public class GetTypesRequestHandler : WebApiBaseRequestHandler
|
public class GetTypesRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,16 +3,9 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "Load Config",
|
|
||||||
Description = "Load configuration",
|
|
||||||
OperationId = "loadConfig")]
|
|
||||||
[OpenApiResponse(200, Description = "Configuration load initiated successfully")]
|
|
||||||
public class LoadConfigRequestHandler : WebApiBaseRequestHandler
|
public class LoadConfigRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,17 +2,9 @@
|
|||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "ReportVersions",
|
|
||||||
Description = "Get version information for loaded assemblies",
|
|
||||||
OperationId = "getVersions")]
|
|
||||||
[OpenApiResponse(200, Description = "List of loaded assemblies with version information")]
|
|
||||||
[OpenApiResponse(500, Description = "Internal Server Error")]
|
|
||||||
public class ReportVersionsRequestHandler : WebApiBaseRequestHandler
|
public class ReportVersionsRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,16 +3,9 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "Restart Program",
|
|
||||||
Description = "Restart the program",
|
|
||||||
OperationId = "restartProgram")]
|
|
||||||
[OpenApiResponse(200, Description = "Program restart initiated successfully")]
|
|
||||||
public class RestartProgramRequestHandler : WebApiBaseRequestHandler
|
public class RestartProgramRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,20 +3,9 @@ using Crestron.SimplSharp.WebScripting;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpPost]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "SetDeviceStreamDebug",
|
|
||||||
Description = "Configure stream debugging settings for a device",
|
|
||||||
OperationId = "setDeviceStreamDebug")]
|
|
||||||
[OpenApiRequestBody(Description = "Device stream debug configuration")]
|
|
||||||
[OpenApiResponse(200, Description = "Successful response")]
|
|
||||||
[OpenApiResponse(400, Description = "Bad Request")]
|
|
||||||
[OpenApiResponse(404, Description = "Device not found")]
|
|
||||||
[OpenApiResponse(500, Description = "Internal Server Error")]
|
|
||||||
public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
|
public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,16 +2,9 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
using PepperDash.Core.Web.RequestHandlers;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||||
{
|
{
|
||||||
[HttpGet]
|
|
||||||
[OpenApiOperation(
|
|
||||||
Summary = "ShowConfig",
|
|
||||||
Description = "Retrieve the current system configuration",
|
|
||||||
OperationId = "getConfig")]
|
|
||||||
[OpenApiResponse(200, Description = "Current system configuration")]
|
|
||||||
public class ShowConfigRequestHandler : WebApiBaseRequestHandler
|
public class ShowConfigRequestHandler : WebApiBaseRequestHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,470 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using Crestron.SimplSharp.WebScripting;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using PepperDash.Core.Web.RequestHandlers;
|
|
||||||
using PepperDash.Essentials.Core.Web.Attributes;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
|
||||||
{
|
|
||||||
public class SwaggerHandler : WebApiBaseRequestHandler
|
|
||||||
{
|
|
||||||
private HttpCwsRouteCollection routeCollection;
|
|
||||||
private string basePath;
|
|
||||||
|
|
||||||
public SwaggerHandler(HttpCwsRouteCollection routeCollection, string basePath)
|
|
||||||
{
|
|
||||||
this.routeCollection = routeCollection;
|
|
||||||
this.basePath = basePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void HandleGet(HttpCwsContext context)
|
|
||||||
{
|
|
||||||
var currentIp = CrestronEthernetHelper.GetEthernetParameter(
|
|
||||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
|
|
||||||
|
|
||||||
var hostname = CrestronEthernetHelper.GetEthernetParameter(
|
|
||||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
|
|
||||||
|
|
||||||
var serverUrl = CrestronEnvironment.DevicePlatform == eDevicePlatform.Server
|
|
||||||
? $"https://{hostname}/VirtualControl/Rooms/{InitialParametersClass.RoomId}/cws{basePath}"
|
|
||||||
: $"https://{currentIp}/cws{basePath}";
|
|
||||||
|
|
||||||
var openApiDoc = GenerateOpenApiDocument(serverUrl);
|
|
||||||
|
|
||||||
var response = JsonConvert.SerializeObject(openApiDoc, Formatting.Indented);
|
|
||||||
|
|
||||||
context.Response.StatusCode = 200;
|
|
||||||
context.Response.ContentType = "application/json";
|
|
||||||
context.Response.Headers.Add("Content-Type", "application/json");
|
|
||||||
context.Response.Write(response, false);
|
|
||||||
context.Response.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
private object GenerateOpenApiDocument(string serverUrl)
|
|
||||||
{
|
|
||||||
var paths = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
// Add paths based on existing routes
|
|
||||||
foreach (var route in routeCollection)
|
|
||||||
{
|
|
||||||
var pathKey = "/" + route.Url;
|
|
||||||
var pathItem = GeneratePathItem(route);
|
|
||||||
if (pathItem != null)
|
|
||||||
{
|
|
||||||
paths[pathKey] = pathItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
openapi = "3.0.3",
|
|
||||||
info = new
|
|
||||||
{
|
|
||||||
title = "PepperDash Essentials API",
|
|
||||||
description = "RESTful API for PepperDash Essentials control system",
|
|
||||||
version = "1.0.0",
|
|
||||||
contact = new
|
|
||||||
{
|
|
||||||
name = "PepperDash Technology",
|
|
||||||
url = "https://www.pepperdash.com"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
servers = new[]
|
|
||||||
{
|
|
||||||
new { url = serverUrl, description = "Essentials API Server" }
|
|
||||||
},
|
|
||||||
paths = paths,
|
|
||||||
components = new
|
|
||||||
{
|
|
||||||
schemas = GetSchemas()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private object GeneratePathItem(HttpCwsRoute route)
|
|
||||||
{
|
|
||||||
if (route.RouteHandler == null) return null;
|
|
||||||
|
|
||||||
var handlerType = route.RouteHandler.GetType();
|
|
||||||
var operations = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
// Get HTTP method attributes from the handler class
|
|
||||||
var httpMethodAttributes = handlerType.GetCustomAttributes(typeof(HttpMethodAttribute), false)
|
|
||||||
.Cast<HttpMethodAttribute>()
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// If no HTTP method attributes found, fall back to the original logic
|
|
||||||
if (!httpMethodAttributes.Any())
|
|
||||||
{
|
|
||||||
httpMethodAttributes = DetermineHttpMethodsFromRoute(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var methodAttr in httpMethodAttributes)
|
|
||||||
{
|
|
||||||
var operation = GenerateOperation(route, methodAttr.Method, handlerType);
|
|
||||||
if (operation != null)
|
|
||||||
{
|
|
||||||
operations[methodAttr.Method.ToLower()] = operation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return operations.Count > 0 ? operations : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<HttpMethodAttribute> DetermineHttpMethodsFromRoute(HttpCwsRoute route)
|
|
||||||
{
|
|
||||||
var methods = new List<HttpMethodAttribute>();
|
|
||||||
var routeName = route.Name?.ToLower() ?? "";
|
|
||||||
var routeUrl = route.Url?.ToLower() ?? "";
|
|
||||||
|
|
||||||
// Fallback logic for routes without attributes
|
|
||||||
if (routeName.Contains("get") || routeUrl.Contains("devices") || routeUrl.Contains("config") ||
|
|
||||||
routeUrl.Contains("versions") || routeUrl.Contains("types") || routeUrl.Contains("tielines") ||
|
|
||||||
routeUrl.Contains("apipaths") || routeUrl.Contains("feedbacks") || routeUrl.Contains("properties") ||
|
|
||||||
routeUrl.Contains("methods") || routeUrl.Contains("joinmap") || routeUrl.Contains("routingports"))
|
|
||||||
{
|
|
||||||
methods.Add(new HttpGetAttribute());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (routeName.Contains("command") || routeName.Contains("restart") || routeName.Contains("load") ||
|
|
||||||
routeName.Contains("debug") || routeName.Contains("disable"))
|
|
||||||
{
|
|
||||||
methods.Add(new HttpPostAttribute());
|
|
||||||
}
|
|
||||||
|
|
||||||
return methods;
|
|
||||||
}
|
|
||||||
|
|
||||||
private object GenerateOperation(HttpCwsRoute route, string method, Type handlerType)
|
|
||||||
{
|
|
||||||
var operation = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
// Get OpenApiOperation attribute
|
|
||||||
var operationAttr = handlerType.GetCustomAttribute<OpenApiOperationAttribute>();
|
|
||||||
if (operationAttr != null)
|
|
||||||
{
|
|
||||||
operation["summary"] = operationAttr.Summary ?? route.Name ?? "API Operation";
|
|
||||||
operation["operationId"] = operationAttr.OperationId ?? route.Name?.Replace(" ", "") ?? "operation";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(operationAttr.Description))
|
|
||||||
{
|
|
||||||
operation["description"] = operationAttr.Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operationAttr.Tags != null && operationAttr.Tags.Length > 0)
|
|
||||||
{
|
|
||||||
operation["tags"] = operationAttr.Tags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fallback to route name
|
|
||||||
operation["summary"] = route.Name ?? "API Operation";
|
|
||||||
operation["operationId"] = route.Name?.Replace(" ", "") ?? "operation";
|
|
||||||
|
|
||||||
// Add fallback description
|
|
||||||
var fallbackDescription = GetFallbackDescription(route);
|
|
||||||
if (!string.IsNullOrEmpty(fallbackDescription))
|
|
||||||
{
|
|
||||||
operation["description"] = fallbackDescription;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get response attributes
|
|
||||||
var responses = new Dictionary<string, object>();
|
|
||||||
var responseAttrs = handlerType.GetCustomAttributes<OpenApiResponseAttribute>().ToList();
|
|
||||||
|
|
||||||
if (responseAttrs.Any())
|
|
||||||
{
|
|
||||||
foreach (var responseAttr in responseAttrs)
|
|
||||||
{
|
|
||||||
var responseObj = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["description"] = responseAttr.Description ?? "Response"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(responseAttr.ContentType))
|
|
||||||
{
|
|
||||||
responseObj["content"] = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
[responseAttr.ContentType] = new { schema = new { type = "object" } }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
responses[responseAttr.StatusCode.ToString()] = responseObj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Default responses
|
|
||||||
responses["200"] = new
|
|
||||||
{
|
|
||||||
description = "Successful response",
|
|
||||||
content = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["application/json"] = new { schema = new { type = "object" } }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
responses["400"] = new { description = "Bad Request" };
|
|
||||||
responses["404"] = new { description = "Not Found" };
|
|
||||||
responses["500"] = new { description = "Internal Server Error" };
|
|
||||||
}
|
|
||||||
|
|
||||||
operation["responses"] = responses;
|
|
||||||
|
|
||||||
// Get parameter attributes
|
|
||||||
var parameterAttrs = handlerType.GetCustomAttributes<OpenApiParameterAttribute>().ToList();
|
|
||||||
var parameters = new List<object>();
|
|
||||||
|
|
||||||
// Add parameters from attributes
|
|
||||||
foreach (var paramAttr in parameterAttrs)
|
|
||||||
{
|
|
||||||
parameters.Add(new
|
|
||||||
{
|
|
||||||
name = paramAttr.Name,
|
|
||||||
@in = paramAttr.In.ToString().ToLower(),
|
|
||||||
required = paramAttr.Required,
|
|
||||||
schema = new { type = GetSchemaType(paramAttr.Type) },
|
|
||||||
description = paramAttr.Description ?? $"The {paramAttr.Name} parameter"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add parameters from URL path variables (fallback)
|
|
||||||
if (route.Url.Contains("{"))
|
|
||||||
{
|
|
||||||
var url = route.Url;
|
|
||||||
while (url.Contains("{"))
|
|
||||||
{
|
|
||||||
var start = url.IndexOf("{");
|
|
||||||
var end = url.IndexOf("}", start);
|
|
||||||
if (end > start)
|
|
||||||
{
|
|
||||||
var paramName = url.Substring(start + 1, end - start - 1);
|
|
||||||
|
|
||||||
// Only add if not already added from attributes
|
|
||||||
if (!parameters.Any(p => ((dynamic)p).name == paramName))
|
|
||||||
{
|
|
||||||
parameters.Add(new
|
|
||||||
{
|
|
||||||
name = paramName,
|
|
||||||
@in = "path",
|
|
||||||
required = true,
|
|
||||||
schema = new { type = "string" },
|
|
||||||
description = $"The {paramName} parameter"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
url = url.Substring(end + 1);
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameters.Count > 0)
|
|
||||||
{
|
|
||||||
operation["parameters"] = parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get request body attribute for POST operations
|
|
||||||
if (method == "POST")
|
|
||||||
{
|
|
||||||
var requestBodyAttr = handlerType.GetCustomAttribute<OpenApiRequestBodyAttribute>();
|
|
||||||
if (requestBodyAttr != null)
|
|
||||||
{
|
|
||||||
operation["requestBody"] = new
|
|
||||||
{
|
|
||||||
required = requestBodyAttr.Required,
|
|
||||||
description = requestBodyAttr.Description,
|
|
||||||
content = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
[requestBodyAttr.ContentType] = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["schema"] = requestBodyAttr.Type != null
|
|
||||||
? (object)new Dictionary<string, object> { ["$ref"] = $"#/components/schemas/{requestBodyAttr.Type.Name}" }
|
|
||||||
: new Dictionary<string, object> { ["type"] = "object" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (route.Name != null && route.Name.Contains("Command"))
|
|
||||||
{
|
|
||||||
// Fallback for command routes
|
|
||||||
operation["requestBody"] = new
|
|
||||||
{
|
|
||||||
required = true,
|
|
||||||
content = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["application/json"] = new
|
|
||||||
{
|
|
||||||
schema = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/DeviceCommand" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetSchemaType(Type type)
|
|
||||||
{
|
|
||||||
if (type == typeof(string)) return "string";
|
|
||||||
if (type == typeof(int) || type == typeof(long)) return "integer";
|
|
||||||
if (type == typeof(bool)) return "boolean";
|
|
||||||
if (type == typeof(double) || type == typeof(float)) return "number";
|
|
||||||
return "string"; // default
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetFallbackDescription(HttpCwsRoute route)
|
|
||||||
{
|
|
||||||
var routeName = route.Name?.ToLower() ?? "";
|
|
||||||
var routeUrl = route.Url?.ToLower() ?? "";
|
|
||||||
|
|
||||||
if (routeUrl.Contains("devices") && !routeUrl.Contains("{"))
|
|
||||||
{
|
|
||||||
return "Retrieve a list of all devices in the system";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("versions"))
|
|
||||||
{
|
|
||||||
return "Get version information for loaded assemblies";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("config"))
|
|
||||||
{
|
|
||||||
return "Retrieve the current system configuration";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("devicecommands"))
|
|
||||||
{
|
|
||||||
return "Send a command to a specific device";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("devicefeedbacks"))
|
|
||||||
{
|
|
||||||
return "Get feedback values from a specific device";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("deviceproperties"))
|
|
||||||
{
|
|
||||||
return "Get properties of a specific device";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("devicemethods"))
|
|
||||||
{
|
|
||||||
return "Get available methods for a specific device";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("types"))
|
|
||||||
{
|
|
||||||
return routeUrl.Contains("{") ? "Get types filtered by the specified filter" : "Get all available types";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("tielines"))
|
|
||||||
{
|
|
||||||
return "Get information about tielines in the system";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("joinmap"))
|
|
||||||
{
|
|
||||||
return "Get join map information for bridge or device";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("routingports"))
|
|
||||||
{
|
|
||||||
return "Get routing ports for a specific device";
|
|
||||||
}
|
|
||||||
else if (routeUrl.Contains("apipaths"))
|
|
||||||
{
|
|
||||||
return "Get available API paths and routes";
|
|
||||||
}
|
|
||||||
else if (routeName.Contains("restart"))
|
|
||||||
{
|
|
||||||
return "Restart the program";
|
|
||||||
}
|
|
||||||
else if (routeName.Contains("debug"))
|
|
||||||
{
|
|
||||||
return "Debug operation";
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, object> GetSchemas()
|
|
||||||
{
|
|
||||||
return new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["DeviceCommand"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["deviceKey"] = new { type = "string", description = "The key of the device" },
|
|
||||||
["methodName"] = new { type = "string", description = "The method to call on the device" },
|
|
||||||
["params"] = new { type = "array", items = new { type = "object" }, description = "Parameters for the method call" }
|
|
||||||
},
|
|
||||||
required = new[] { "deviceKey", "methodName" }
|
|
||||||
},
|
|
||||||
["Device"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["key"] = new { type = "string", description = "Device key" },
|
|
||||||
["name"] = new { type = "string", description = "Device name" },
|
|
||||||
["type"] = new { type = "string", description = "Device type" },
|
|
||||||
["isOnline"] = new { type = "boolean", description = "Device online status" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
["Feedback"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["BoolValues"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/BoolFeedback" } },
|
|
||||||
["IntValues"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/IntFeedback" } },
|
|
||||||
["SerialValues"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/StringFeedback" } }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
["BoolFeedback"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["FeedbackKey"] = new { type = "string" },
|
|
||||||
["Value"] = new { type = "boolean" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
["IntFeedback"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["FeedbackKey"] = new { type = "string" },
|
|
||||||
["Value"] = new { type = "integer" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
["StringFeedback"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["FeedbackKey"] = new { type = "string" },
|
|
||||||
["Value"] = new { type = "string" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
["ApiRoutes"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["url"] = new { type = "string", description = "Base URL for the API" },
|
|
||||||
["routes"] = new { type = "array", items = new Dictionary<string, object> { ["$ref"] = "#/components/schemas/Route" } }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
["Route"] = new
|
|
||||||
{
|
|
||||||
type = "object",
|
|
||||||
properties = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["name"] = new { type = "string", description = "Route name" },
|
|
||||||
["url"] = new { type = "string", description = "Route URL pattern" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,29 +3,60 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enum for camera control modes
|
||||||
|
/// </summary>
|
||||||
public enum eCameraControlMode
|
public enum eCameraControlMode
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manual control mode, where the camera is controlled directly by the user or system
|
||||||
|
/// </summary>
|
||||||
Manual = 0,
|
Manual = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Off control mode, where the camera is turned off or disabled
|
||||||
|
/// </summary>
|
||||||
Off,
|
Off,
|
||||||
|
/// <summary>
|
||||||
|
/// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
|
||||||
|
/// </summary>
|
||||||
Auto
|
Auto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface IHasCameras
|
/// <summary>
|
||||||
|
/// Interface for devices that have cameras
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasCameras : IKeyName
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when a camera is selected
|
||||||
|
/// </summary>
|
||||||
event EventHandler<CameraSelectedEventArgs> CameraSelected;
|
event EventHandler<CameraSelectedEventArgs> CameraSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of cameras on the device. This should be a list of CameraBase objects
|
||||||
|
/// </summary>
|
||||||
List<CameraBase> Cameras { get; }
|
List<CameraBase> Cameras { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently selected camera. This should be a CameraBase object
|
||||||
|
/// </summary>
|
||||||
CameraBase SelectedCamera { get; }
|
CameraBase SelectedCamera { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates the currently selected camera
|
||||||
|
/// </summary>
|
||||||
StringFeedback SelectedCameraFeedback { get; }
|
StringFeedback SelectedCameraFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
void SelectCamera(string key);
|
void SelectCamera(string key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +73,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraOff
|
public interface IHasCameraOff
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the camera is off
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CameraIsOffFeedback { get; }
|
BoolFeedback CameraIsOffFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turns the camera off, blanking the near end video
|
||||||
|
/// </summary>
|
||||||
void CameraOff();
|
void CameraOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,31 +89,71 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraMute
|
public interface IHasCameraMute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the camera is muted
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CameraIsMutedFeedback { get; }
|
BoolFeedback CameraIsMutedFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mutes the camera video, preventing it from being sent to the far end
|
||||||
|
/// </summary>
|
||||||
void CameraMuteOn();
|
void CameraMuteOn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unmutes the camera video, allowing it to be sent to the far end
|
||||||
|
/// </summary>
|
||||||
void CameraMuteOff();
|
void CameraMuteOff();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
|
||||||
|
/// </summary>
|
||||||
void CameraMuteToggle();
|
void CameraMuteToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
|
||||||
|
/// </summary>
|
||||||
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
|
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when a video unmute is requested, typically by the far end
|
||||||
|
/// </summary>
|
||||||
event EventHandler VideoUnmuteRequested;
|
event EventHandler VideoUnmuteRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event arguments for the CameraSelected event
|
||||||
|
/// </summary>
|
||||||
public class CameraSelectedEventArgs : EventArgs
|
public class CameraSelectedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The selected camera
|
||||||
|
/// </summary>
|
||||||
public CameraBase SelectedCamera { get; private set; }
|
public CameraBase SelectedCamera { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for CameraSelectedEventArgs
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="camera"></param>
|
||||||
public CameraSelectedEventArgs(CameraBase camera)
|
public CameraSelectedEventArgs(CameraBase camera)
|
||||||
{
|
{
|
||||||
SelectedCamera = camera;
|
SelectedCamera = camera;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have a far end camera control
|
||||||
|
/// </summary>
|
||||||
public interface IHasFarEndCameraControl
|
public interface IHasFarEndCameraControl
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
|
||||||
|
/// </summary>
|
||||||
CameraBase FarEndCamera { get; }
|
CameraBase FarEndCamera { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the far end camera is being controlled
|
||||||
|
/// </summary>
|
||||||
BoolFeedback ControllingFarEndCameraFeedback { get; }
|
BoolFeedback ControllingFarEndCameraFeedback { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -88,6 +166,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have camera controls
|
||||||
|
/// </summary>
|
||||||
public interface IHasCameraControls
|
public interface IHasCameraControls
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -108,8 +189,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraPanControl : IHasCameraControls
|
public interface IHasCameraPanControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pans the camera left
|
||||||
|
/// </summary>
|
||||||
void PanLeft();
|
void PanLeft();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pans the camera right
|
||||||
|
/// </summary>
|
||||||
void PanRight();
|
void PanRight();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera pan movement
|
||||||
|
/// </summary>
|
||||||
void PanStop();
|
void PanStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,8 +210,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraTiltControl : IHasCameraControls
|
public interface IHasCameraTiltControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tilts the camera down
|
||||||
|
/// </summary>
|
||||||
void TiltDown();
|
void TiltDown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tilts the camera up
|
||||||
|
/// </summary>
|
||||||
void TiltUp();
|
void TiltUp();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera tilt movement
|
||||||
|
/// </summary>
|
||||||
void TiltStop();
|
void TiltStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +231,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraZoomControl : IHasCameraControls
|
public interface IHasCameraZoomControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Zooms the camera in
|
||||||
|
/// </summary>
|
||||||
void ZoomIn();
|
void ZoomIn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zooms the camera out
|
||||||
|
/// </summary>
|
||||||
void ZoomOut();
|
void ZoomOut();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera zoom movement
|
||||||
|
/// </summary>
|
||||||
void ZoomStop();
|
void ZoomStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,25 +252,71 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraFocusControl : IHasCameraControls
|
public interface IHasCameraFocusControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Focuses the camera near
|
||||||
|
/// </summary>
|
||||||
void FocusNear();
|
void FocusNear();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Focuses the camera far
|
||||||
|
/// </summary>
|
||||||
void FocusFar();
|
void FocusFar();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera focus movement
|
||||||
|
/// </summary>
|
||||||
void FocusStop();
|
void FocusStop();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers the camera's auto focus functionality, if available.
|
||||||
|
/// </summary>
|
||||||
void TriggerAutoFocus();
|
void TriggerAutoFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have auto focus mode control
|
||||||
|
/// </summary>
|
||||||
public interface IHasAutoFocusMode
|
public interface IHasAutoFocusMode
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus mode to auto or manual, or toggles between them.
|
||||||
|
/// </summary>
|
||||||
void SetFocusModeAuto();
|
void SetFocusModeAuto();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus mode to manual, allowing for manual focus adjustments.
|
||||||
|
/// </summary>
|
||||||
void SetFocusModeManual();
|
void SetFocusModeManual();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the focus mode between auto and manual.
|
||||||
|
/// </summary>
|
||||||
void ToggleFocusMode();
|
void ToggleFocusMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have camera auto mode control
|
||||||
|
/// </summary>
|
||||||
public interface IHasCameraAutoMode : IHasCameraControls
|
public interface IHasCameraAutoMode : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
|
||||||
|
/// </summary>
|
||||||
void CameraAutoModeOn();
|
void CameraAutoModeOn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the camera's auto mode, allowing for manual control of camera settings.
|
||||||
|
/// </summary>
|
||||||
void CameraAutoModeOff();
|
void CameraAutoModeOff();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
|
||||||
|
/// </summary>
|
||||||
void CameraAutoModeToggle();
|
void CameraAutoModeToggle();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the camera's auto mode is currently enabled.
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CameraAutoModeIsOnFeedback { get; }
|
BoolFeedback CameraAutoModeIsOnFeedback { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,199 +1,110 @@
|
|||||||
using System;
|
using Crestron.SimplSharp;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
using PepperDash.Essentials.Core.Routing;
|
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||||
{
|
{
|
||||||
/// <summary>
|
public abstract class DisplayBase : EssentialsDevice, IDisplay
|
||||||
/// Abstract base class for display devices that provides common display functionality
|
|
||||||
/// including power control, input switching, and routing capabilities.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class DisplayBase : EssentialsDevice, IDisplay, ICurrentSources
|
|
||||||
{
|
{
|
||||||
private RoutingInputPort _currentInputPort;
|
private RoutingInputPort _currentInputPort;
|
||||||
|
public RoutingInputPort CurrentInputPort
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _currentInputPort;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected set
|
||||||
/// Gets or sets the current input port that is selected on the display.
|
{
|
||||||
/// </summary>
|
if (_currentInputPort == value) return;
|
||||||
public RoutingInputPort CurrentInputPort
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _currentInputPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected set
|
_currentInputPort = value;
|
||||||
{
|
|
||||||
if (_currentInputPort == value) return;
|
|
||||||
|
|
||||||
_currentInputPort = value;
|
InputChanged?.Invoke(this, _currentInputPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InputChanged?.Invoke(this, _currentInputPort);
|
public event InputChangedEventHandler InputChanged;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
/// Event that is raised when the input changes on the display.
|
|
||||||
/// </summary>
|
|
||||||
public event InputChangedEventHandler InputChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
/// Event that is raised when the current source information changes.
|
public SourceListItem CurrentSourceInfo
|
||||||
/// </summary>
|
{
|
||||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
get
|
||||||
|
{
|
||||||
|
return _CurrentSourceInfo;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
/// <summary>
|
var handler = CurrentSourceChange;
|
||||||
/// Gets or sets the key of the current source information.
|
|
||||||
/// </summary>
|
|
||||||
public string CurrentSourceInfoKey { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
if (handler != null)
|
||||||
/// Gets or sets the current source information for the display.
|
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
/// </summary>
|
|
||||||
public SourceListItem CurrentSourceInfo
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _CurrentSourceInfo;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == _CurrentSourceInfo) return;
|
|
||||||
|
|
||||||
var handler = CurrentSourceChange;
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
_CurrentSourceInfo = value;
|
|
||||||
|
|
||||||
if (handler != null)
|
|
||||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SourceListItem _CurrentSourceInfo;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public Dictionary<eRoutingSignalType, SourceListItem> CurrentSources { get; private set; }
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public Dictionary<eRoutingSignalType, string> CurrentSourceKeys { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback indicating whether the display is currently cooling down after being powered off.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback indicating whether the display is currently warming up after being powered on.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
public UsageTracking UsageTracker { get; set; }
|
||||||
/// Gets or sets the usage tracking instance for monitoring display usage statistics.
|
|
||||||
/// </summary>
|
|
||||||
public UsageTracking UsageTracker { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the warmup time in milliseconds for the display to become ready after power on.
|
|
||||||
/// </summary>
|
|
||||||
public uint WarmupTime { get; set; }
|
public uint WarmupTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the cooldown time in milliseconds for the display to fully power down.
|
|
||||||
/// </summary>
|
|
||||||
public uint CooldownTime { get; set; }
|
public uint CooldownTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Abstract function that must be implemented by derived classes to provide the cooling down feedback value.
|
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||||
/// Must be implemented by concrete sub-classes.
|
/// by concrete sub-classes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Abstract function that must be implemented by derived classes to provide the warming up feedback value.
|
|
||||||
/// Must be implemented by concrete sub-classes.
|
|
||||||
/// </summary>
|
|
||||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timer used for managing display warmup timing.
|
|
||||||
/// </summary>
|
|
||||||
protected CTimer WarmupTimer;
|
protected CTimer WarmupTimer;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timer used for managing display cooldown timing.
|
|
||||||
/// </summary>
|
|
||||||
protected CTimer CooldownTimer;
|
protected CTimer CooldownTimer;
|
||||||
|
|
||||||
#region IRoutingInputs Members
|
#region IRoutingInputs Members
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of input ports available on this display device.
|
|
||||||
/// </summary>
|
|
||||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
protected DisplayBase(string key, string name)
|
||||||
/// Initializes a new instance of the DisplayBase class.
|
: base(key, name)
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The unique key identifier for this display device.</param>
|
|
||||||
/// <param name="name">The friendly name for this display device.</param>
|
|
||||||
protected DisplayBase(string key, string name)
|
|
||||||
: base(key, name)
|
|
||||||
{
|
{
|
||||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||||
|
|
||||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||||
|
|
||||||
CurrentSources = new Dictionary<eRoutingSignalType, SourceListItem>
|
|
||||||
{
|
|
||||||
{ eRoutingSignalType.Audio, null },
|
|
||||||
{ eRoutingSignalType.Video, null },
|
|
||||||
};
|
|
||||||
|
|
||||||
CurrentSourceKeys = new Dictionary<eRoutingSignalType, string>
|
|
||||||
{
|
|
||||||
{ eRoutingSignalType.Audio, string.Empty },
|
|
||||||
{ eRoutingSignalType.Video, string.Empty },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Powers on the display device. Must be implemented by derived classes.
|
|
||||||
/// </summary>
|
|
||||||
public abstract void PowerOn();
|
public abstract void PowerOn();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Powers off the display device. Must be implemented by derived classes.
|
|
||||||
/// </summary>
|
|
||||||
public abstract void PowerOff();
|
public abstract void PowerOff();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles the power state of the display device. Must be implemented by derived classes.
|
|
||||||
/// </summary>
|
|
||||||
public abstract void PowerToggle();
|
public abstract void PowerToggle();
|
||||||
|
|
||||||
/// <summary>
|
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||||
/// Gets the collection of feedback objects for this display device.
|
|
||||||
/// </summary>
|
|
||||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new FeedbackCollection<Feedback>
|
return new FeedbackCollection<Feedback>
|
||||||
{
|
{
|
||||||
IsCoolingDownFeedback,
|
IsCoolingDownFeedback,
|
||||||
IsWarmingUpFeedback
|
IsWarmingUpFeedback
|
||||||
@@ -201,50 +112,30 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public abstract void ExecuteSwitch(object selector);
|
||||||
/// Executes a switch to the specified input on the display device. Must be implemented by derived classes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="selector">The selector object that identifies which input to switch to.</param>
|
|
||||||
public abstract void ExecuteSwitch(object selector);
|
|
||||||
|
|
||||||
/// <summary>
|
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||||
/// Links the display device to an API using a trilist, join start, join map key, and bridge.
|
EiscApiAdvanced bridge)
|
||||||
/// This overload uses serialized join map configuration.
|
{
|
||||||
/// </summary>
|
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||||
/// <param name="displayDevice">The display device to link.</param>
|
|
||||||
/// <param name="trilist">The BasicTriList for communication.</param>
|
|
||||||
/// <param name="joinStart">The starting join number for the device.</param>
|
|
||||||
/// <param name="joinMapKey">The key for the join map configuration.</param>
|
|
||||||
/// <param name="bridge">The EISC API bridge instance.</param>
|
|
||||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
|
||||||
EiscApiAdvanced bridge)
|
|
||||||
{
|
|
||||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
|
||||||
|
|
||||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
if (bridge != null)
|
if (bridge != null)
|
||||||
{
|
{
|
||||||
bridge.AddJoinMap(Key, joinMap);
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
Debug.LogMessage(LogEventLevel.Information,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkDisplayToApi(displayDevice, trilist, joinMap);
|
LinkDisplayToApi(displayDevice, trilist, joinMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Links the display device to an API using a trilist and join map.
|
|
||||||
/// This overload uses a pre-configured join map instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="displayDevice">The display device to link.</param>
|
|
||||||
/// <param name="trilist">The BasicTriList for communication.</param>
|
|
||||||
/// <param name="joinMap">The join map configuration for the device.</param>
|
|
||||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
|
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
@@ -377,96 +268,68 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
|||||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||||
/// Abstract base class for two-way display devices that provide feedback capabilities.
|
|
||||||
/// Extends DisplayBase with routing feedback and power control feedback functionality.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||||
/// Gets feedback for the current input selection on the display.
|
|
||||||
/// </summary>
|
|
||||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||||
/// Abstract function that must be implemented by derived classes to provide the current input feedback value.
|
|
||||||
/// Must be implemented by concrete sub-classes.
|
|
||||||
/// </summary>
|
|
||||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||||
/// Gets feedback indicating whether the display is currently powered on.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||||
/// Abstract function that must be implemented by derived classes to provide the power state feedback value.
|
|
||||||
/// Must be implemented by concrete sub-classes.
|
|
||||||
/// </summary>
|
|
||||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the default mock display instance for testing and development purposes.
|
public static MockDisplay DefaultDisplay
|
||||||
/// </summary>
|
{
|
||||||
public static MockDisplay DefaultDisplay
|
get
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
if (_DefaultDisplay == null)
|
if (_DefaultDisplay == null)
|
||||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||||
return _DefaultDisplay;
|
return _DefaultDisplay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static MockDisplay _DefaultDisplay;
|
static MockDisplay _DefaultDisplay;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the TwoWayDisplayBase class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The unique key identifier for this display device.</param>
|
|
||||||
/// <param name="name">The friendly name for this display device.</param>
|
|
||||||
public TwoWayDisplayBase(string key, string name)
|
public TwoWayDisplayBase(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||||
|
|
||||||
WarmupTime = 7000;
|
WarmupTime = 7000;
|
||||||
CooldownTime = 15000;
|
CooldownTime = 15000;
|
||||||
|
|
||||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||||
|
|
||||||
Feedbacks.Add(CurrentInputFeedback);
|
Feedbacks.Add(CurrentInputFeedback);
|
||||||
Feedbacks.Add(PowerIsOnFeedback);
|
Feedbacks.Add(PowerIsOnFeedback);
|
||||||
|
|
||||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (UsageTracker != null)
|
if (UsageTracker != null)
|
||||||
{
|
{
|
||||||
if (PowerIsOnFeedback.BoolValue)
|
if (PowerIsOnFeedback.BoolValue)
|
||||||
UsageTracker.StartDeviceUsage();
|
UsageTracker.StartDeviceUsage();
|
||||||
else
|
else
|
||||||
UsageTracker.EndDeviceUsage();
|
UsageTracker.EndDeviceUsage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||||
/// Event that is raised when a numeric switch change occurs on the display.
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raise an event when the status of a switch object changes.
|
/// Raise an event when the status of a switch object changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||||
{
|
{
|
||||||
var newEvent = NumericSwitchChange;
|
var newEvent = NumericSwitchChange;
|
||||||
if (newEvent != null) newEvent(this, e);
|
if (newEvent != null) newEvent(this, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,11 +6,14 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.AppServer.Messengers
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Messenger for a CameraBase device
|
||||||
|
/// </summary>
|
||||||
public class CameraBaseMessenger : MessengerBase
|
public class CameraBaseMessenger : MessengerBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Device being bridged
|
/// Device being bridged
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CameraBase Camera { get; set; }
|
public CameraBase Camera { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -45,6 +48,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers the actions for this messenger. This is called by the base class
|
||||||
|
/// </summary>
|
||||||
protected override void RegisterActions()
|
protected override void RegisterActions()
|
||||||
{
|
{
|
||||||
base.RegisterActions();
|
base.RegisterActions();
|
||||||
|
|||||||
@@ -2,69 +2,27 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.DeviceInfo;
|
using PepperDash.Essentials.Core.DeviceInfo;
|
||||||
using System.Timers;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.AppServer.Messengers
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Facilitates communication of device information by providing mechanisms for status updates and device
|
|
||||||
/// information reporting.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>The <see cref="DeviceInfoMessenger"/> class integrates with an <see
|
|
||||||
/// cref="IDeviceInfoProvider"/> to manage device-specific information. It uses a debounce timer to limit the
|
|
||||||
/// frequency of updates, ensuring efficient communication. The timer is initialized with a 1-second interval and
|
|
||||||
/// is disabled by default. This class also subscribes to device information change events and provides actions for
|
|
||||||
/// reporting full device status and triggering updates.</remarks>
|
|
||||||
public class DeviceInfoMessenger : MessengerBase
|
public class DeviceInfoMessenger : MessengerBase
|
||||||
{
|
{
|
||||||
private readonly IDeviceInfoProvider _deviceInfoProvider;
|
private readonly IDeviceInfoProvider _deviceInfoProvider;
|
||||||
|
|
||||||
private readonly Timer debounceTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="DeviceInfoMessenger"/> class, which facilitates communication
|
|
||||||
/// of device information.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>The messenger uses a debounce timer to limit the frequency of certain operations. The
|
|
||||||
/// timer is initialized with a 1-second interval and is disabled by default.</remarks>
|
|
||||||
/// <param name="key">A unique identifier for the messenger instance.</param>
|
|
||||||
/// <param name="messagePath">The path used for sending and receiving messages.</param>
|
|
||||||
/// <param name="device">An implementation of <see cref="IDeviceInfoProvider"/> that provides device-specific information.</param>
|
|
||||||
public DeviceInfoMessenger(string key, string messagePath, IDeviceInfoProvider device) : base(key, messagePath, device as Device)
|
public DeviceInfoMessenger(string key, string messagePath, IDeviceInfoProvider device) : base(key, messagePath, device as Device)
|
||||||
{
|
{
|
||||||
_deviceInfoProvider = device;
|
_deviceInfoProvider = device;
|
||||||
|
}
|
||||||
|
|
||||||
debounceTimer = new Timer(1000)
|
|
||||||
{
|
|
||||||
Enabled = false,
|
|
||||||
AutoReset = false
|
|
||||||
};
|
|
||||||
|
|
||||||
debounceTimer.Elapsed += DebounceTimer_Elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DebounceTimer_Elapsed(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
PostStatusMessage(JToken.FromObject(new
|
|
||||||
{
|
|
||||||
deviceInfo = _deviceInfoProvider.DeviceInfo
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers actions and event handlers for device information updates and status reporting.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This method sets up actions for handling device status updates and reporting full
|
|
||||||
/// device status. It also subscribes to the <see cref="IDeviceInfoProvider.DeviceInfoChanged"/> event to
|
|
||||||
/// trigger debounced updates when the device information changes.</remarks>
|
|
||||||
protected override void RegisterActions()
|
protected override void RegisterActions()
|
||||||
{
|
{
|
||||||
base.RegisterActions();
|
base.RegisterActions();
|
||||||
|
|
||||||
_deviceInfoProvider.DeviceInfoChanged += (o, a) =>
|
_deviceInfoProvider.DeviceInfoChanged += (o, a) =>
|
||||||
{
|
{
|
||||||
debounceTimer.Stop();
|
PostStatusMessage(JToken.FromObject(new
|
||||||
debounceTimer.Start();
|
{
|
||||||
|
deviceInfo = a.DeviceInfo
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
|
AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
|
||||||
@@ -76,12 +34,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a message containing the state information of a device, including detailed device information.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This class is used to encapsulate the state of a device along with its associated
|
|
||||||
/// information. It extends <see cref="DeviceStateMessageBase"/> to provide additional details about the
|
|
||||||
/// device.</remarks>
|
|
||||||
public class DeviceInfoStateMessage : DeviceStateMessageBase
|
public class DeviceInfoStateMessage : DeviceStateMessageBase
|
||||||
{
|
{
|
||||||
[JsonProperty("deviceInfo")]
|
[JsonProperty("deviceInfo")]
|
||||||
|
|||||||
@@ -8,42 +8,16 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.AppServer.Messengers
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Provides messaging functionality for managing room combination scenarios and partition states in an <see
|
|
||||||
/// cref="IEssentialsRoomCombiner"/> instance. Enables external systems to interact with the room combiner via
|
|
||||||
/// predefined actions and status updates.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This class facilitates communication with an <see cref="IEssentialsRoomCombiner"/> by
|
|
||||||
/// exposing actions for toggling modes, managing partitions, and setting room combination scenarios. It also
|
|
||||||
/// listens for feedback changes and broadcasts status updates to connected systems. Typical usage involves
|
|
||||||
/// registering actions for external commands and handling feedback events to synchronize state changes.</remarks>
|
|
||||||
public class IEssentialsRoomCombinerMessenger : MessengerBase
|
public class IEssentialsRoomCombinerMessenger : MessengerBase
|
||||||
{
|
{
|
||||||
private readonly IEssentialsRoomCombiner _roomCombiner;
|
private readonly IEssentialsRoomCombiner _roomCombiner;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="IEssentialsRoomCombinerMessenger"/> class, which facilitates
|
|
||||||
/// messaging for an <see cref="IEssentialsRoomCombiner"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This class is designed to enable communication and interaction with an <see
|
|
||||||
/// cref="IEssentialsRoomCombiner"/> through the specified messaging path. Ensure that the <paramref
|
|
||||||
/// name="roomCombiner"/> parameter is not null when creating an instance.</remarks>
|
|
||||||
/// <param name="key">The unique key identifying this messenger instance.</param>
|
|
||||||
/// <param name="messagePath">The path used for messaging operations.</param>
|
|
||||||
/// <param name="roomCombiner">The <see cref="IEssentialsRoomCombiner"/> instance associated with this messenger.</param>
|
|
||||||
public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner)
|
public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner)
|
||||||
: base(key, messagePath, roomCombiner as IKeyName)
|
: base(key, messagePath, roomCombiner as IKeyName)
|
||||||
{
|
{
|
||||||
_roomCombiner = roomCombiner;
|
_roomCombiner = roomCombiner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers actions and event handlers for managing room combination scenarios and partition states.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This method sets up various actions that can be triggered via specific endpoints,
|
|
||||||
/// such as toggling modes, setting room combination scenarios, and managing partition states. It also
|
|
||||||
/// subscribes to feedback events to update the status when changes occur in room combination scenarios or
|
|
||||||
/// partition states.</remarks>
|
|
||||||
protected override void RegisterActions()
|
protected override void RegisterActions()
|
||||||
{
|
{
|
||||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||||
@@ -133,7 +107,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
|
|
||||||
var message = new IEssentialsRoomCombinerStateMessage
|
var message = new IEssentialsRoomCombinerStateMessage
|
||||||
{
|
{
|
||||||
DisableAutoMode = _roomCombiner.DisableAutoMode,
|
|
||||||
IsInAutoMode = _roomCombiner.IsInAutoMode,
|
IsInAutoMode = _roomCombiner.IsInAutoMode,
|
||||||
CurrentScenario = _roomCombiner.CurrentScenario,
|
CurrentScenario = _roomCombiner.CurrentScenario,
|
||||||
Rooms = rooms,
|
Rooms = rooms,
|
||||||
@@ -159,48 +132,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents the state message for a room combiner system, providing information about the current configuration,
|
|
||||||
/// operational mode, and associated rooms, partitions, and scenarios.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>This class is used to encapsulate the state of a room combiner system, including its current
|
|
||||||
/// mode of operation, active room combination scenario, and the list of rooms and partitions involved. It is
|
|
||||||
/// typically serialized and transmitted to communicate the state of the system.</remarks>
|
|
||||||
public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase
|
public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether automatic mode is disabled.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("disableAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
|
||||||
public bool DisableAutoMode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether the system is operating in automatic mode.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public bool IsInAutoMode { get; set; }
|
public bool IsInAutoMode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the current room combination scenario.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public IRoomCombinationScenario CurrentScenario { get; set; }
|
public IRoomCombinationScenario CurrentScenario { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the collection of rooms associated with the entity.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public List<IKeyName> Rooms { get; set; }
|
public List<IKeyName> Rooms { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the collection of room combination scenarios.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; set; }
|
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the collection of partition controllers.
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public List<IPartitionController> Partitions { get; set; }
|
public List<IPartitionController> Partitions { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Messenger for devices that implement the IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
public class IHasCamerasMessenger : MessengerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Device being bridged that implements IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
public IHasCameras CameraController { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Messenger for devices that implement IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="cameraController"></param>
|
||||||
|
/// <param name="messagePath"></param>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
public IHasCamerasMessenger(string key, string messagePath , IHasCameras cameraController)
|
||||||
|
: base(key, messagePath, cameraController)
|
||||||
|
{
|
||||||
|
CameraController = cameraController ?? throw new ArgumentNullException("cameraController");
|
||||||
|
CameraController.CameraSelected += CameraController_CameraSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CameraController_CameraSelected(object sender, CameraSelectedEventArgs e)
|
||||||
|
{
|
||||||
|
PostStatusMessage(new IHasCamerasStateMessage
|
||||||
|
{
|
||||||
|
SelectedCamera = e.SelectedCamera
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers the actions for this messenger.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentException"></exception>
|
||||||
|
protected override void RegisterActions()
|
||||||
|
{
|
||||||
|
base.RegisterActions();
|
||||||
|
|
||||||
|
AddAction("/fullStatus", (id, context) =>
|
||||||
|
{
|
||||||
|
SendFullStatus();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAction("/selectCamera", (id, content) =>
|
||||||
|
{
|
||||||
|
var cameraKey = content?.ToObject<string>();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(cameraKey))
|
||||||
|
{
|
||||||
|
CameraController.SelectCamera(cameraKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Content must be a string representing the camera key");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendFullStatus()
|
||||||
|
{
|
||||||
|
var state = new IHasCamerasStateMessage
|
||||||
|
{
|
||||||
|
CameraList = CameraController.Cameras,
|
||||||
|
SelectedCamera = CameraController.SelectedCamera
|
||||||
|
};
|
||||||
|
|
||||||
|
PostStatusMessage(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State message for devices that implement the IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
public class IHasCamerasStateMessage : DeviceStateMessageBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// List of cameras available in the device.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public List<CameraBase> CameraList { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently selected camera on the device.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public CameraBase SelectedCamera { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -907,6 +907,19 @@ namespace PepperDash.Essentials
|
|||||||
messengerAdded = true;
|
messengerAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device is IHasCameras cameras)
|
||||||
|
{
|
||||||
|
this.LogVerbose("Adding IHasCamerasMessenger for {deviceKey}", device.Key
|
||||||
|
);
|
||||||
|
var messenger = new IHasCamerasMessenger(
|
||||||
|
$"{device.Key}-cameras-{Key}",
|
||||||
|
$"/device/{device.Key}",
|
||||||
|
cameras
|
||||||
|
);
|
||||||
|
AddDefaultDeviceMessenger(messenger);
|
||||||
|
messengerAdded = true;
|
||||||
|
}
|
||||||
|
|
||||||
this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key);
|
this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key);
|
||||||
|
|
||||||
if (device is EssentialsDevice)
|
if (device is EssentialsDevice)
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
using System;
|
using Crestron.SimplSharpPro;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Crestron.SimplSharpPro.UI;
|
using Crestron.SimplSharpPro.UI;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -14,105 +10,64 @@ using PepperDash.Essentials.Core.Config;
|
|||||||
using PepperDash.Essentials.Core.DeviceInfo;
|
using PepperDash.Essentials.Core.DeviceInfo;
|
||||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
using PepperDash.Essentials.Core.UI;
|
using PepperDash.Essentials.Core.UI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Touchpanel
|
namespace PepperDash.Essentials.Touchpanel
|
||||||
{
|
{
|
||||||
/// <summary>
|
//public interface IMobileControlTouchpanelController
|
||||||
/// Mobile Control touchpanel controller that provides app control, Zoom integration,
|
//{
|
||||||
/// and mobile control functionality for Crestron touchpanels.
|
// StringFeedback AppUrlFeedback { get; }
|
||||||
/// </summary>
|
// string DefaultRoomKey { get; }
|
||||||
public class MobileControlTouchpanelController : TouchpanelBase, IHasFeedback, ITswAppControl, ITswZoomControl, IDeviceInfoProvider, IMobileControlCrestronTouchpanelController, ITheme
|
// string DeviceKey { get; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
public class MobileControlTouchpanelController : TouchpanelBase, IHasFeedback, ITswAppControl, ITswZoomControl, IDeviceInfoProvider, IMobileControlTouchpanelController, ITheme
|
||||||
{
|
{
|
||||||
private readonly MobileControlTouchpanelProperties localConfig;
|
private readonly MobileControlTouchpanelProperties localConfig;
|
||||||
private IMobileControlRoomMessenger _bridge;
|
private IMobileControlRoomMessenger _bridge;
|
||||||
|
|
||||||
private string _appUrl;
|
private string _appUrl;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback for the current application URL.
|
|
||||||
/// </summary>
|
|
||||||
public StringFeedback AppUrlFeedback { get; private set; }
|
public StringFeedback AppUrlFeedback { get; private set; }
|
||||||
|
|
||||||
private readonly StringFeedback QrCodeUrlFeedback;
|
private readonly StringFeedback QrCodeUrlFeedback;
|
||||||
private readonly StringFeedback McServerUrlFeedback;
|
private readonly StringFeedback McServerUrlFeedback;
|
||||||
private readonly StringFeedback UserCodeFeedback;
|
private readonly StringFeedback UserCodeFeedback;
|
||||||
|
|
||||||
private readonly BoolFeedback _appOpenFeedback;
|
private readonly BoolFeedback _appOpenFeedback;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback indicating whether an application is currently open on the touchpanel.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback AppOpenFeedback => _appOpenFeedback;
|
public BoolFeedback AppOpenFeedback => _appOpenFeedback;
|
||||||
|
|
||||||
private readonly BoolFeedback _zoomIncomingCallFeedback;
|
private readonly BoolFeedback _zoomIncomingCallFeedback;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback indicating whether there is an incoming Zoom call.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback ZoomIncomingCallFeedback => _zoomIncomingCallFeedback;
|
public BoolFeedback ZoomIncomingCallFeedback => _zoomIncomingCallFeedback;
|
||||||
|
|
||||||
private readonly BoolFeedback _zoomInCallFeedback;
|
private readonly BoolFeedback _zoomInCallFeedback;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event that is raised when device information changes.
|
|
||||||
/// </summary>
|
|
||||||
public event DeviceInfoChangeHandler DeviceInfoChanged;
|
public event DeviceInfoChangeHandler DeviceInfoChanged;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback indicating whether a Zoom call is currently active.
|
|
||||||
/// </summary>
|
|
||||||
public BoolFeedback ZoomInCallFeedback => _zoomInCallFeedback;
|
public BoolFeedback ZoomInCallFeedback => _zoomInCallFeedback;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of feedback objects for this touchpanel controller.
|
|
||||||
/// </summary>
|
|
||||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
|
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the collection of Zoom-related feedback objects.
|
|
||||||
/// </summary>
|
|
||||||
public FeedbackCollection<Feedback> ZoomFeedbacks { get; private set; }
|
public FeedbackCollection<Feedback> ZoomFeedbacks { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the default room key for this touchpanel controller.
|
|
||||||
/// </summary>
|
|
||||||
public string DefaultRoomKey => _config.DefaultRoomKey;
|
public string DefaultRoomKey => _config.DefaultRoomKey;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether to use direct server communication.
|
|
||||||
/// </summary>
|
|
||||||
public bool UseDirectServer => localConfig.UseDirectServer;
|
public bool UseDirectServer => localConfig.UseDirectServer;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether this touchpanel acts as a Zoom Room controller.
|
|
||||||
/// </summary>
|
|
||||||
public bool ZoomRoomController => localConfig.ZoomRoomController;
|
public bool ZoomRoomController => localConfig.ZoomRoomController;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current theme for the touchpanel interface.
|
|
||||||
/// </summary>
|
|
||||||
public string Theme => localConfig.Theme;
|
public string Theme => localConfig.Theme;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets feedback for the current theme setting.
|
|
||||||
/// </summary>
|
|
||||||
public StringFeedback ThemeFeedback { get; private set; }
|
public StringFeedback ThemeFeedback { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets device information including MAC address and IP address.
|
|
||||||
/// </summary>
|
|
||||||
public DeviceInfo DeviceInfo => new DeviceInfo();
|
public DeviceInfo DeviceInfo => new DeviceInfo();
|
||||||
|
|
||||||
public ReadOnlyCollection<ConnectedIpInformation> ConnectedIps => Panel.ConnectedIpList;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the MobileControlTouchpanelController class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The unique key identifier for this touchpanel controller.</param>
|
|
||||||
/// <param name="name">The friendly name for this touchpanel controller.</param>
|
|
||||||
/// <param name="panel">The touchpanel hardware device.</param>
|
|
||||||
/// <param name="config">The configuration properties for this controller.</param>
|
|
||||||
public MobileControlTouchpanelController(string key, string name, BasicTriListWithSmartObject panel, MobileControlTouchpanelProperties config) : base(key, name, panel, config)
|
public MobileControlTouchpanelController(string key, string name, BasicTriListWithSmartObject panel, MobileControlTouchpanelProperties config) : base(key, name, panel, config)
|
||||||
{
|
{
|
||||||
localConfig = config;
|
localConfig = config;
|
||||||
@@ -184,10 +139,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
RegisterForExtenders();
|
RegisterForExtenders();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the theme setting for this touchpanel controller and persists the change to configuration.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="theme">The new theme identifier to apply.</param>
|
|
||||||
public void UpdateTheme(string theme)
|
public void UpdateTheme(string theme)
|
||||||
{
|
{
|
||||||
localConfig.Theme = theme;
|
localConfig.Theme = theme;
|
||||||
@@ -320,11 +271,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Performs custom activation setup for the touchpanel controller, including
|
|
||||||
/// registering messengers and linking to mobile control.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if activation was successful; otherwise, false.</returns>
|
|
||||||
public override bool CustomActivate()
|
public override bool CustomActivate()
|
||||||
{
|
{
|
||||||
var appMessenger = new ITswAppControlMessenger($"appControlMessenger-{Key}", $"/device/{Key}", this);
|
var appMessenger = new ITswAppControlMessenger($"appControlMessenger-{Key}", $"/device/{Key}", this);
|
||||||
@@ -354,20 +300,12 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
return base.CustomActivate();
|
return base.CustomActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles device extender signal changes for system reserved signals.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="currentDeviceExtender">The device extender that generated the signal change.</param>
|
|
||||||
/// <param name="args">The signal event arguments containing the changed signal information.</param>
|
|
||||||
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"System Device Extender args: ${args.Event}:${args.Sig}");
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, this, $"System Device Extender args: ${args.Event}:${args.Sig}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets up the panel drivers and signal mappings for the specified room.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="roomKey">The room key to configure the panel drivers for.</param>
|
|
||||||
protected override void SetupPanelDrivers(string roomKey)
|
protected override void SetupPanelDrivers(string roomKey)
|
||||||
{
|
{
|
||||||
AppUrlFeedback.LinkInputSig(Panel.StringInput[1]);
|
AppUrlFeedback.LinkInputSig(Panel.StringInput[1]);
|
||||||
@@ -428,10 +366,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
SetAppUrl(_bridge.AppUrl);
|
SetAppUrl(_bridge.AppUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the application URL and updates the corresponding feedback.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="url">The new application URL to set.</param>
|
|
||||||
public void SetAppUrl(string url)
|
public void SetAppUrl(string url)
|
||||||
{
|
{
|
||||||
_appUrl = url;
|
_appUrl = url;
|
||||||
@@ -457,9 +391,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hides the currently open application on the touchpanel.
|
|
||||||
/// </summary>
|
|
||||||
public void HideOpenApp()
|
public void HideOpenApp()
|
||||||
{
|
{
|
||||||
if (Panel is TswX70Base x70Panel)
|
if (Panel is TswX70Base x70Panel)
|
||||||
@@ -475,9 +406,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Opens an application on the touchpanel. Note: X60 panels do not support Zoom app opening.
|
|
||||||
/// </summary>
|
|
||||||
public void OpenApp()
|
public void OpenApp()
|
||||||
{
|
{
|
||||||
if (Panel is TswX70Base x70Panel)
|
if (Panel is TswX70Base x70Panel)
|
||||||
@@ -493,9 +421,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Closes the currently open application on the touchpanel.
|
|
||||||
/// </summary>
|
|
||||||
public void CloseOpenApp()
|
public void CloseOpenApp()
|
||||||
{
|
{
|
||||||
if (Panel is TswX70Base x70Panel)
|
if (Panel is TswX70Base x70Panel)
|
||||||
@@ -511,9 +436,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ends the current Zoom call on the touchpanel.
|
|
||||||
/// </summary>
|
|
||||||
public void EndZoomCall()
|
public void EndZoomCall()
|
||||||
{
|
{
|
||||||
if (Panel is TswX70Base x70Panel)
|
if (Panel is TswX70Base x70Panel)
|
||||||
@@ -529,10 +451,6 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the device information (MAC address and IP address) from the touchpanel
|
|
||||||
/// and raises the DeviceInfoChanged event.
|
|
||||||
/// </summary>
|
|
||||||
public void UpdateDeviceInfo()
|
public void UpdateDeviceInfo()
|
||||||
{
|
{
|
||||||
if (Panel is TswXX70Base x70Panel)
|
if (Panel is TswXX70Base x70Panel)
|
||||||
@@ -569,27 +487,14 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Factory class for creating MobileControlTouchpanelController instances from device configuration.
|
|
||||||
/// Supports various Crestron touchpanel models including TSW, TS, CrestronApp, XPanel, and DGE series.
|
|
||||||
/// </summary>
|
|
||||||
public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory<MobileControlTouchpanelController>
|
public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory<MobileControlTouchpanelController>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the MobileControlTouchpanelControllerFactory class.
|
|
||||||
/// Sets up supported device type names and minimum framework version requirements.
|
|
||||||
/// </summary>
|
|
||||||
public MobileControlTouchpanelControllerFactory()
|
public MobileControlTouchpanelControllerFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel", "mcdge1000" };
|
TypeNames = new List<string>() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel", "mcdge1000" };
|
||||||
MinimumEssentialsFrameworkVersion = "2.0.0";
|
MinimumEssentialsFrameworkVersion = "2.0.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Builds a MobileControlTouchpanelController device from the provided device configuration.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dc">The device configuration containing the device properties and settings.</param>
|
|
||||||
/// <returns>A configured MobileControlTouchpanelController instance.</returns>
|
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
var comm = CommFactory.GetControlPropertiesConfig(dc);
|
var comm = CommFactory.GetControlPropertiesConfig(dc);
|
||||||
@@ -652,7 +557,7 @@ namespace PepperDash.Essentials.Touchpanel
|
|||||||
return new Ts1070(id, Global.ControlSystem);
|
return new Ts1070(id, Global.ControlSystem);
|
||||||
else if (type == "dge1000")
|
else if (type == "dge1000")
|
||||||
return new Dge1000(id, Global.ControlSystem);
|
return new Dge1000(id, Global.ControlSystem);
|
||||||
else
|
else
|
||||||
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using Crestron.SimplSharp;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using Crestron.SimplSharp;
|
|
||||||
using Crestron.SimplSharp.WebScripting;
|
using Crestron.SimplSharp.WebScripting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
@@ -15,6 +9,12 @@ using PepperDash.Essentials.Core.Web;
|
|||||||
using PepperDash.Essentials.RoomBridges;
|
using PepperDash.Essentials.RoomBridges;
|
||||||
using PepperDash.Essentials.WebApiHandlers;
|
using PepperDash.Essentials.WebApiHandlers;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
using WebSocketSharp;
|
using WebSocketSharp;
|
||||||
using WebSocketSharp.Net;
|
using WebSocketSharp.Net;
|
||||||
using WebSocketSharp.Server;
|
using WebSocketSharp.Server;
|
||||||
@@ -60,7 +60,7 @@ 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 System.Net.IPAddress csIpAddress;
|
||||||
|
|
||||||
private System.Net.IPAddress csSubnetMask;
|
private System.Net.IPAddress csSubnetMask;
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
|
||||||
// Set the default port to be 50000 plus the slot number of the program
|
// Set the default port to be 50000 plus the slot number of the program
|
||||||
Port = 50000 + (int)Global.ControlSystem.ProgramNumber;
|
Port = 50000 + (int)Global.ControlSystem.ProgramNumber;
|
||||||
|
|
||||||
if (customPort != 0)
|
if (customPort != 0)
|
||||||
{
|
{
|
||||||
@@ -156,9 +156,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
|
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter);
|
||||||
var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId);
|
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);
|
var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
||||||
|
|
||||||
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
|
this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask);
|
||||||
@@ -298,6 +298,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
|
|
||||||
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
|
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
|
||||||
|
|
||||||
|
this.LogVerbose("Processor IP: {processorIp}", processorIp);
|
||||||
|
|
||||||
foreach (var touchpanel in touchpanels.Select(tp =>
|
foreach (var touchpanel in touchpanels.Select(tp =>
|
||||||
{
|
{
|
||||||
var token = _secret.Tokens.FirstOrDefault((t) => t.Value.TouchpanelKey.Equals(tp.Key, StringComparison.InvariantCultureIgnoreCase));
|
var token = _secret.Tokens.FirstOrDefault((t) => t.Value.TouchpanelKey.Equals(tp.Key, StringComparison.InvariantCultureIgnoreCase));
|
||||||
@@ -319,25 +321,11 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ip = processorIp;
|
var appUrl = $"http://{processorIp}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
|
||||||
if (touchpanel.Touchpanel is IMobileControlCrestronTouchpanelController crestronTouchpanel)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
var appUrl = $"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
|
|
||||||
|
|
||||||
this.LogVerbose("Sending URL {appUrl}", appUrl);
|
this.LogVerbose("Sending URL {appUrl}", appUrl);
|
||||||
|
|
||||||
touchpanel.Messenger.UpdateAppUrl($"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}");
|
touchpanel.Messenger.UpdateAppUrl($"http://{processorIp}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,7 +349,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
if (!Directory.Exists($"{userAppPath}{localConfigFolderName}"))
|
if (!Directory.Exists($"{userAppPath}{localConfigFolderName}"))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory($"{userAppPath}{localConfigFolderName}");
|
Directory.CreateDirectory($"{userAppPath}{localConfigFolderName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var sw = new StreamWriter(File.Open($"{userAppPath}{localConfigFolderName}{Global.DirectorySeparator}{appConfigFileName}", FileMode.Create, FileAccess.ReadWrite)))
|
using (var sw = new StreamWriter(File.Open($"{userAppPath}{localConfigFolderName}{Global.DirectorySeparator}{appConfigFileName}", FileMode.Create, FileAccess.ReadWrite)))
|
||||||
{
|
{
|
||||||
@@ -370,7 +358,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
|
|
||||||
this.LogDebug("LAN Adapter ID: {lanAdapterId}", lanAdapterId);
|
this.LogDebug("LAN Adapter ID: {lanAdapterId}", lanAdapterId);
|
||||||
|
|
||||||
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
|
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
|
||||||
|
|
||||||
var config = GetApplicationConfig(processorIp);
|
var config = GetApplicationConfig(processorIp);
|
||||||
|
|
||||||
@@ -390,7 +378,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csAdapterId == -1)
|
if(csAdapterId == -1)
|
||||||
{
|
{
|
||||||
this.LogDebug("CS LAN Adapter not found");
|
this.LogDebug("CS LAN Adapter not found");
|
||||||
return;
|
return;
|
||||||
@@ -401,8 +389,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
using (var sw = new StreamWriter(File.Open($"{userAppPath}{localConfigFolderName}{Global.DirectorySeparator}{appConfigCsFileName}", FileMode.Create, FileAccess.ReadWrite)))
|
using (var sw = new StreamWriter(File.Open($"{userAppPath}{localConfigFolderName}{Global.DirectorySeparator}{appConfigCsFileName}", FileMode.Create, FileAccess.ReadWrite)))
|
||||||
{
|
{
|
||||||
// Write the CS application configuration file. Used when a request comes in for the application config from the CS
|
// Write the CS application configuration file. Used when a request comes in for the application config from the CS
|
||||||
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);
|
||||||
|
|
||||||
var config = GetApplicationConfig(processorIp);
|
var config = GetApplicationConfig(processorIp);
|
||||||
|
|
||||||
var contents = JsonConvert.SerializeObject(config, Formatting.Indented);
|
var contents = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||||
@@ -412,7 +400,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MobileControlApplicationConfig GetApplicationConfig(string processorIp)
|
private MobileControlApplicationConfig GetApplicationConfig(string processorIp)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var config = new MobileControlApplicationConfig
|
var config = new MobileControlApplicationConfig
|
||||||
@@ -442,10 +430,10 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
this.LogError(ex, "Error getting application configuration");
|
this.LogError(ex, "Error getting application configuration");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -584,7 +572,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
|||||||
|
|
||||||
var values = s.Split(' ');
|
var values = s.Split(' ');
|
||||||
|
|
||||||
if (values.Length < 2)
|
if(values.Length < 2)
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("Invalid number of arguments. Please provide a room key and a grant code");
|
CrestronConsole.ConsoleCommandResponse("Invalid number of arguments. Please provide a room key and a grant code");
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user