mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-12 12:05:00 +00:00
Compare commits
22 Commits
unique-cli
...
v2.10.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dbac7d1c8 | ||
|
|
799d4c127c | ||
|
|
a6cd9a0571 | ||
|
|
da30424657 | ||
|
|
311452beac | ||
|
|
789113008e | ||
|
|
660836bd5a | ||
|
|
97b2ffed9c | ||
|
|
2bbefa062d | ||
|
|
3421b2f28c | ||
|
|
82889e9794 | ||
|
|
1dcd4e328c | ||
|
|
e76369726d | ||
|
|
2bf0f2092b | ||
|
|
c1eccfd790 | ||
|
|
f1a89161bc | ||
|
|
e59c50d0aa | ||
|
|
9d313d8c7c | ||
|
|
9813673b66 | ||
|
|
ddbcc13c50 | ||
|
|
2a70fc678e | ||
|
|
056614cba1 |
9
.vscode/extensions.json
vendored
Normal file
9
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"ms-dotnettools.vscode-dotnet-runtime",
|
||||
"ms-dotnettools.csharp",
|
||||
"ms-dotnettools.csdevkit",
|
||||
"vivaxy.vscode-conventional-commits",
|
||||
"mhutchie.git-graph"
|
||||
]
|
||||
}
|
||||
@@ -2,7 +2,14 @@
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IDisplay: IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IKeyName
|
||||
/// <summary>
|
||||
/// 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
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
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,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
@@ -33,11 +35,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
|
||||
string SystemUuid { get; }
|
||||
|
||||
BoolFeedback ApiOnlineAndAuthorized { get;}
|
||||
BoolFeedback ApiOnlineAndAuthorized { get; }
|
||||
|
||||
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);
|
||||
|
||||
@@ -45,14 +47,14 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
|
||||
bool CheckForDeviceMessenger(string key);
|
||||
|
||||
IMobileControlRoomMessenger GetRoomMessenger(string key);
|
||||
IMobileControlRoomMessenger GetRoomMessenger(string key);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a mobile control messenger
|
||||
/// </summary>
|
||||
public interface IMobileControlMessenger: IKeyed
|
||||
public interface IMobileControlMessenger : IKeyed
|
||||
{
|
||||
IMobileControl AppServerController { get; }
|
||||
string MessagePath { get; }
|
||||
@@ -104,16 +106,47 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// The default room key for the controller
|
||||
/// </summary>
|
||||
string DefaultRoomKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the application URL for the controller
|
||||
/// </summary>
|
||||
/// <param name="url">The application URL</param>
|
||||
void SetAppUrl(string url);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the controller uses a direct server connection
|
||||
/// </summary>
|
||||
bool UseDirectServer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the controller is a Zoom Room controller
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
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,19 +5,34 @@ using 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the key identifier for the sink device that this destination represents.
|
||||
/// </summary>
|
||||
[JsonProperty("sinkKey")]
|
||||
public string SinkKey { get; set; }
|
||||
|
||||
private EssentialsDevice _sinkDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actual device instance for this destination.
|
||||
/// Lazily loads the device from the DeviceManager using the SinkKey.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public EssentialsDevice SinkDevice
|
||||
{
|
||||
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")]
|
||||
public string PreferredName
|
||||
{
|
||||
@@ -32,31 +47,78 @@ 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")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this destination should be included in destination lists.
|
||||
/// </summary>
|
||||
[JsonProperty("includeInDestinationList")]
|
||||
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")]
|
||||
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")]
|
||||
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")]
|
||||
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")]
|
||||
public int HorizontalLocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the signal type that this destination can receive (Audio, Video, AudioVideo, etc.).
|
||||
/// </summary>
|
||||
[JsonProperty("sinkType")]
|
||||
public eRoutingSignalType SinkType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this destination is used for codec content sharing.
|
||||
/// </summary>
|
||||
[JsonProperty("isCodecContentDestination")]
|
||||
public bool isCodecContentDestination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this destination is used for program audio output.
|
||||
/// </summary>
|
||||
[JsonProperty("isProgramAudioDestination")]
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <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>
|
||||
public enum eSourceListItemType
|
||||
{
|
||||
@@ -166,6 +168,26 @@ namespace PepperDash.Essentials.Core
|
||||
[JsonProperty("disableSimpleRouting")]
|
||||
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>
|
||||
/// Default constructor for SourceListItem, initializes the Icon to "Blank"
|
||||
/// </summary>
|
||||
@@ -177,7 +199,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
/// Returns a string representation of the SourceListItem, including the SourceKey and Name
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <returns> A string representation of the SourceListItem</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{SourceKey}:{Name}";
|
||||
|
||||
29
src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs
Normal file
29
src/PepperDash.Essentials.Core/Routing/ICurrentSources.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
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,6 +9,8 @@ using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Core.Routing.Interfaces
|
||||
*/
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
@@ -21,10 +23,24 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
/// For rooms with a single presentation source, change event
|
||||
/// </summary>
|
||||
[Obsolete("Use ICurrentSources instead")]
|
||||
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; }
|
||||
|
||||
/// <summary>
|
||||
/// The current source info for the room, used to look up the source in the SourceList
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,29 @@
|
||||
namespace PepperDash.Essentials.Core
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// For fixed-source endpoint devices
|
||||
/// </summary>
|
||||
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For fixed-source endpoint devices with an input port
|
||||
/// </summary>
|
||||
public interface IRoutingSinkWithInputPort :IRoutingSink
|
||||
public interface IRoutingSinkWithInputPort : IRoutingSink
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current input port for this routing sink.
|
||||
/// </summary>
|
||||
RoutingInputPort CurrentInputPort { get; }
|
||||
}
|
||||
/*/// <summary>
|
||||
/// For fixed-source endpoint devices
|
||||
/// </summary>
|
||||
public interface IRoutingSink<TSelector> : IRoutingInputs<TSelector>, IHasCurrentSourceInfoChange
|
||||
{
|
||||
void UpdateRouteRequest<TOutputSelector>(RouteRequest<TSelector, TOutputSelector> request);
|
||||
|
||||
RouteRequest<TSelector, TOutputSelector> GetRouteRequest<TOutputSelector>();
|
||||
}*/
|
||||
/// <summary>
|
||||
/// Interface for routing sinks that have access to the current source information.
|
||||
/// </summary>
|
||||
public interface IRoutingSinkWithCurrentSources : IRoutingSink, ICurrentSources
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,110 +1,199 @@
|
||||
using Crestron.SimplSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
{
|
||||
public abstract class DisplayBase : EssentialsDevice, IDisplay
|
||||
/// <summary>
|
||||
/// 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;
|
||||
public RoutingInputPort CurrentInputPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentInputPort;
|
||||
}
|
||||
private RoutingInputPort _currentInputPort;
|
||||
|
||||
protected set
|
||||
{
|
||||
if (_currentInputPort == value) return;
|
||||
/// <summary>
|
||||
/// Gets or sets the current input port that is selected on the display.
|
||||
/// </summary>
|
||||
public RoutingInputPort CurrentInputPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentInputPort;
|
||||
}
|
||||
|
||||
_currentInputPort = value;
|
||||
protected set
|
||||
{
|
||||
if (_currentInputPort == value) return;
|
||||
|
||||
InputChanged?.Invoke(this, _currentInputPort);
|
||||
}
|
||||
}
|
||||
_currentInputPort = value;
|
||||
|
||||
public event InputChangedEventHandler InputChanged;
|
||||
InputChanged?.Invoke(this, _currentInputPort);
|
||||
}
|
||||
}
|
||||
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
/// <summary>
|
||||
/// Event that is raised when the input changes on the display.
|
||||
/// </summary>
|
||||
public event InputChangedEventHandler InputChanged;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
/// <summary>
|
||||
/// Event that is raised when the current source information changes.
|
||||
/// </summary>
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
/// <summary>
|
||||
/// Gets or sets the key of the current source information.
|
||||
/// </summary>
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
/// <summary>
|
||||
/// Gets or sets the current source information for the display.
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_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; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether the display is currently warming up after being powered on.
|
||||
/// </summary>
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the cooldown time in milliseconds for the display to fully power down.
|
||||
/// </summary>
|
||||
public uint CooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||
/// by concrete sub-classes
|
||||
/// Abstract function that must be implemented by derived classes to provide the cooling down feedback value.
|
||||
/// Must be implemented by concrete sub-classes.
|
||||
/// </summary>
|
||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for managing display warmup timing.
|
||||
/// </summary>
|
||||
protected CTimer WarmupTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for managing display cooldown timing.
|
||||
/// </summary>
|
||||
protected CTimer CooldownTimer;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of input ports available on this display device.
|
||||
/// </summary>
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DisplayBase 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>
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
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();
|
||||
|
||||
/// <summary>
|
||||
/// Powers off the display device. Must be implemented by derived classes.
|
||||
/// </summary>
|
||||
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 virtual FeedbackCollection<Feedback> Feedbacks
|
||||
/// <summary>
|
||||
/// Gets the collection of feedback objects for this display device.
|
||||
/// </summary>
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
@@ -112,30 +201,50 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
/// <summary>
|
||||
/// 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);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||
/// <summary>
|
||||
/// Links the display device to an API using a trilist, join start, join map key, and bridge.
|
||||
/// This overload uses serialized join map configuration.
|
||||
/// </summary>
|
||||
/// <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))
|
||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
@@ -268,68 +377,96 @@ namespace PepperDash.Essentials.Devices.Common.Displays
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||
/// <summary>
|
||||
/// 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
|
||||
{
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets feedback for the current input selection on the display.
|
||||
/// </summary>
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether the display is currently powered on.
|
||||
/// </summary>
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
|
||||
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
/// <summary>
|
||||
/// Gets the default mock display instance for testing and development purposes.
|
||||
/// </summary>
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _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)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
/// <summary>
|
||||
/// Event that is raised when a numeric switch change occurs on the display.
|
||||
/// </summary>
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,51 +3,29 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the content of a source selection message
|
||||
/// </summary>
|
||||
public class SourceSelectMessageContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the key of the source list item to select
|
||||
/// </summary>
|
||||
|
||||
[JsonProperty("sourceListItemKey")]
|
||||
public string SourceListItemKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key of the source list containing the item
|
||||
/// </summary>
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a direct routing operation between a source and destination
|
||||
/// </summary>
|
||||
public class DirectRoute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the key of the source device
|
||||
/// </summary>
|
||||
|
||||
[JsonProperty("sourceKey")]
|
||||
public string SourceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key of the destination device
|
||||
/// </summary>
|
||||
[JsonProperty("destinationKey")]
|
||||
public string DestinationKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of routing signal (Audio, Video, etc.)
|
||||
/// </summary>
|
||||
[JsonProperty("signalType")]
|
||||
public eRoutingSignalType SignalType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for press and hold actions with boolean state parameter
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="b">The state of the press and hold action</param>
|
||||
/// <param name="b"></param>
|
||||
public delegate void PressAndHoldAction(bool b);
|
||||
}
|
||||
|
||||
@@ -1,35 +1,22 @@
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using System.Linq;
|
||||
using DisplayBase = PepperDash.Essentials.Devices.Common.Displays.DisplayBase;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger that provides mobile control interface for display devices
|
||||
/// </summary>
|
||||
public class DisplayBaseMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The display device this messenger is associated with
|
||||
/// </summary>
|
||||
private readonly DisplayBase display;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DisplayBaseMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing display control messages</param>
|
||||
/// <param name="device">The display device to control</param>
|
||||
public DisplayBaseMessenger(string key, string messagePath, DisplayBase device) : base(key, messagePath, device)
|
||||
{
|
||||
display = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,28 +4,15 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger that provides mobile control interface for devices with channel control functionality
|
||||
/// </summary>
|
||||
public class IChannelMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The channel control device this messenger is associated with
|
||||
/// </summary>
|
||||
private readonly IChannel channelDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IChannelMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing channel control messages</param>
|
||||
/// <param name="device">The device that implements channel control functionality</param>
|
||||
public IChannelMessenger(string key, string messagePath, IChannel device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
channelDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,25 +4,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement IColor interface
|
||||
/// </summary>
|
||||
public class IColorMessenger : MessengerBase
|
||||
{
|
||||
private readonly IColor colorDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IColorMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements IColor</param>
|
||||
public IColorMessenger(string key, string messagePath, IColor device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
colorDevice = device as IColor;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,28 +4,15 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger that provides mobile control interface for devices with directional pad functionality
|
||||
/// </summary>
|
||||
public class IDPadMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The directional pad device this messenger is associated with
|
||||
/// </summary>
|
||||
private readonly IDPad dpadDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IDPadMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing directional pad messages</param>
|
||||
/// <param name="device">The device that implements directional pad functionality</param>
|
||||
public IDPadMessenger(string key, string messagePath, IDPad device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
dpadDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,25 +4,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement IDvr interface
|
||||
/// </summary>
|
||||
public class IDvrMessenger : MessengerBase
|
||||
{
|
||||
private readonly IDvr dvrDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IDvrMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements IDvr</param>
|
||||
public IDvrMessenger(string key, string messagePath, IDvr device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
dvrDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,28 +4,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger that provides mobile control interface for devices with power control functionality
|
||||
/// </summary>
|
||||
public class IHasPowerMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The power control device this messenger is associated with
|
||||
/// </summary>
|
||||
private readonly IHasPowerControl powerDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IHasPowerMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing power control messages</param>
|
||||
/// <param name="device">The device that implements power control functionality</param>
|
||||
public IHasPowerMessenger(string key, string messagePath, IHasPowerControl device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
powerDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,28 +4,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger that provides mobile control interface for devices with numeric keypad functionality
|
||||
/// </summary>
|
||||
public class INumericKeypadMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The numeric keypad device this messenger is associated with
|
||||
/// </summary>
|
||||
private readonly INumericKeypad keypadDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the INumericKeypadMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing numeric keypad messages</param>
|
||||
/// <param name="device">The device that implements numeric keypad functionality</param>
|
||||
public INumericKeypadMessenger(string key, string messagePath, INumericKeypad device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
keypadDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -4,25 +4,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement ISetTopBoxControls interface
|
||||
/// </summary>
|
||||
public class ISetTopBoxControlsMessenger : MessengerBase
|
||||
{
|
||||
private readonly ISetTopBoxControls stbDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ISetTopBoxControlsMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements ISetTopBoxControls</param>
|
||||
public ISetTopBoxControlsMessenger(string key, string messagePath, ISetTopBoxControls device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
stbDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -43,9 +32,6 @@ namespace PepperDash.Essentials.Room.MobileControl
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for set top box controls
|
||||
/// </summary>
|
||||
public class SetTopBoxControlsState : DeviceStateMessageBase
|
||||
{
|
||||
|
||||
|
||||
@@ -4,28 +4,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.MobileControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger that provides mobile control interface for devices with transport control functionality
|
||||
/// </summary>
|
||||
public class ITransportMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The transport control device this messenger is associated with
|
||||
/// </summary>
|
||||
private readonly ITransport transportDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ITransportMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing transport control messages</param>
|
||||
/// <param name="device">The device that implements transport control functionality</param>
|
||||
public ITransportMessenger(string key, string messagePath, ITransport device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
transportDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
@@ -29,16 +29,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
codec.CallStatusChange += Codec_CallStatusChange;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling audio codec operations.
|
||||
/// Includes call control, status reporting, and audio codec management.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject(id));
|
||||
AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject());
|
||||
AddAction("/dial", (id, content) =>
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
@@ -101,7 +97,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// Helper method to build call status for vtc
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private void SendAtcFullMessageObject(string id = null)
|
||||
private void SendAtcFullMessageObject()
|
||||
{
|
||||
var info = Codec.CodecInfo;
|
||||
|
||||
@@ -113,7 +109,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
phoneNumber = info.PhoneNumber
|
||||
}
|
||||
}), clientId: id
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for camera control operations.
|
||||
/// Handles camera movement, zoom, preset management, and camera status reporting.
|
||||
/// </summary>
|
||||
public class CameraBaseMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
@@ -49,15 +45,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling camera control operations.
|
||||
/// Includes camera movement, zoom, preset management, and full status reporting.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject(id));
|
||||
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
|
||||
|
||||
|
||||
if (Camera is IHasCameraPtzControl ptzCamera)
|
||||
@@ -174,7 +166,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Helper method to update the full status of the camera
|
||||
/// </summary>
|
||||
private void SendCameraFullMessageObject(string id = null)
|
||||
private void SendCameraFullMessageObject()
|
||||
{
|
||||
var presetList = new List<CameraPreset>();
|
||||
|
||||
@@ -189,7 +181,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
cameraMode = GetCameraMode(),
|
||||
hasPresets = Camera is IHasCameraPresets,
|
||||
presets = presetList
|
||||
}), clientId: id
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using System.Timers;
|
||||
using Independentsoft.Exchange;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceInfo;
|
||||
using System.Timers;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Facilitates communication of device information by providing mechanisms for status updates and device
|
||||
/// information reporting.
|
||||
/// <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
|
||||
@@ -22,42 +21,42 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
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>
|
||||
/// <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)
|
||||
{
|
||||
_deviceInfoProvider = device;
|
||||
|
||||
debounceTimer = new Timer(1000)
|
||||
{
|
||||
Enabled = false,
|
||||
AutoReset = false
|
||||
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>
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -71,23 +70,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
|
||||
{
|
||||
DeviceInfo = _deviceInfoProvider.DeviceInfo
|
||||
}, id));
|
||||
}));
|
||||
|
||||
AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a message containing the state information of a device, including detailed device information.
|
||||
/// <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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the device information.
|
||||
/// </summary>
|
||||
[JsonProperty("deviceInfo")]
|
||||
public DeviceInfo DeviceInfo { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,40 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for device preset management operations.
|
||||
/// Handles preset selection, recall, and preset list management.
|
||||
/// </summary>
|
||||
public class DevicePresetsModelMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITvPresetsProvider _presetsDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DevicePresetsModelMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="messagePath">The message path for preset control messages.</param>
|
||||
/// <param name="presetsDevice">The device that provides preset functionality.</param>
|
||||
public DevicePresetsModelMessenger(string key, string messagePath, ITvPresetsProvider presetsDevice)
|
||||
: base(key, messagePath, presetsDevice as Device)
|
||||
{
|
||||
_presetsDevice = presetsDevice;
|
||||
}
|
||||
|
||||
private void SendPresets(string id = null)
|
||||
private void SendPresets()
|
||||
{
|
||||
PostStatusMessage(new PresetStateMessage
|
||||
{
|
||||
Favorites = _presetsDevice.TvPresets.PresetsList
|
||||
}, id);
|
||||
});
|
||||
}
|
||||
|
||||
private void RecallPreset(ISetTopBoxNumericKeypad device, string channel)
|
||||
@@ -50,10 +40,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling device preset operations.
|
||||
/// Includes preset selection, recall, and full status reporting.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
|
||||
{
|
||||
@@ -62,7 +48,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
this.LogInformation("getting full status for client {id}", id);
|
||||
try
|
||||
{
|
||||
SendPresets(id);
|
||||
SendPresets();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -97,32 +83,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a preset channel message for device preset operations.
|
||||
/// </summary>
|
||||
public class PresetChannelMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the preset channel information.
|
||||
/// </summary>
|
||||
[JsonProperty("preset")]
|
||||
public PresetChannel Preset;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the device key associated with the preset.
|
||||
/// </summary>
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a preset state message containing favorite presets.
|
||||
/// </summary>
|
||||
public class PresetStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the list of favorite preset channels.
|
||||
/// </summary>
|
||||
[JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<PresetChannel> Favorites { get; set; } = new List<PresetChannel>();
|
||||
}
|
||||
|
||||
@@ -1,33 +1,23 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for device volume control operations.
|
||||
/// Handles volume level adjustment, mute control, and volume status reporting.
|
||||
/// </summary>
|
||||
public class DeviceVolumeMessenger : MessengerBase
|
||||
{
|
||||
private readonly IBasicVolumeWithFeedback _localDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeviceVolumeMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="messagePath">The message path for volume control messages.</param>
|
||||
/// <param name="device">The device that provides volume control functionality.</param>
|
||||
public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeWithFeedback device)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
_localDevice = device;
|
||||
}
|
||||
|
||||
private void SendStatus(string id = null)
|
||||
private void SendStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -47,7 +37,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
messageObj.Volume.Units = volumeAdvanced.Units;
|
||||
}
|
||||
|
||||
PostStatusMessage(messageObj, id);
|
||||
PostStatusMessage(messageObj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -58,13 +48,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling volume control operations.
|
||||
/// Includes volume level adjustment, mute control, and full status reporting.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendStatus());
|
||||
|
||||
AddAction("/level", (id, content) =>
|
||||
{
|
||||
@@ -156,56 +142,29 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a volume state message containing volume information.
|
||||
/// </summary>
|
||||
public class VolumeStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the volume information.
|
||||
/// </summary>
|
||||
[JsonProperty("volume", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Volume Volume { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents volume control information including level, mute status, and units.
|
||||
/// </summary>
|
||||
public class Volume
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the volume level.
|
||||
/// </summary>
|
||||
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the device has mute capability.
|
||||
/// </summary>
|
||||
[JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasMute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the device is currently muted.
|
||||
/// </summary>
|
||||
[JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Muted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the volume label for display purposes.
|
||||
/// </summary>
|
||||
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the raw volume value as a string.
|
||||
/// </summary>
|
||||
[JsonProperty("rawValue", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string RawValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the volume level units.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
[JsonProperty("units", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eVolumeLevelUnits? Units { get; set; }
|
||||
|
||||
@@ -2,34 +2,24 @@
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic messenger for basic device communication
|
||||
/// </summary>
|
||||
public class GenericMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the GenericMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="device">Device to communicate with</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
public GenericMessenger(string key, EssentialsDevice device, string messagePath) : base(key, messagePath, device)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new DeviceStateMessageBase();
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,29 +6,15 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for communication monitoring operations.
|
||||
/// Handles communication status reporting and monitoring feedback.
|
||||
/// </summary>
|
||||
public class ICommunicationMonitorMessenger : MessengerBase
|
||||
{
|
||||
private readonly ICommunicationMonitor _communicationMonitor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ICommunicationMonitorMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="messagePath">The message path for communication monitor messages.</param>
|
||||
/// <param name="device">The device that provides communication monitoring functionality.</param>
|
||||
public ICommunicationMonitorMessenger(string key, string messagePath, ICommunicationMonitor device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
_communicationMonitor = device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling communication monitoring operations.
|
||||
/// Includes full status reporting for communication monitoring data.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -42,7 +28,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
|
||||
Status = _communicationMonitor.CommunicationMonitor.Status
|
||||
}
|
||||
}, id);
|
||||
});
|
||||
});
|
||||
|
||||
_communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) =>
|
||||
@@ -64,17 +50,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// </summary>
|
||||
public class CommunicationMonitorState : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the communication monitor properties.
|
||||
/// </summary>
|
||||
[JsonProperty("commMonitor", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CommunicationMonitorProps CommunicationMonitor { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the properties of a communication monitor.
|
||||
/// </summary>
|
||||
public class CommunicationMonitorProps
|
||||
{ /// <summary>
|
||||
/// For devices that implement ICommunicationMonitor, reports the online status of the device
|
||||
|
||||
@@ -1,34 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for DSP preset management operations.
|
||||
/// Handles DSP preset selection, recall, and preset list management.
|
||||
/// </summary>
|
||||
public class IDspPresetsMessenger : MessengerBase
|
||||
{
|
||||
private readonly IDspPresets device;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IDspPresetsMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="messagePath">The message path for DSP preset control messages.</param>
|
||||
/// <param name="device">The device that provides DSP preset functionality.</param>
|
||||
public IDspPresetsMessenger(string key, string messagePath, IDspPresets device)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling DSP preset operations.
|
||||
/// Includes preset selection, recall, and full status reporting.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -40,7 +26,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
Presets = device.Presets
|
||||
};
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
PostStatusMessage(message);
|
||||
});
|
||||
|
||||
AddAction("/recallPreset", (id, content) =>
|
||||
@@ -56,14 +42,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a DSP presets state message containing available presets.
|
||||
/// </summary>
|
||||
public class IHasDspPresetsStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the dictionary of available DSP presets.
|
||||
/// </summary>
|
||||
[JsonProperty("presets")]
|
||||
public Dictionary<string, IKeyName> Presets { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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>
|
||||
/// 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
|
||||
@@ -21,15 +21,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
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>
|
||||
/// <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)
|
||||
: base(key, messagePath, roomCombiner as IKeyName)
|
||||
@@ -37,8 +37,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
_roomCombiner = roomCombiner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions and event handlers for managing room combination scenarios and partition states.
|
||||
/// <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
|
||||
@@ -46,7 +46,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// partition states.</remarks>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/setAutoMode", (id, content) =>
|
||||
{
|
||||
@@ -120,7 +120,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -141,7 +141,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
Partitions = _roomCombiner.Partitions
|
||||
};
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -159,47 +159,47 @@ 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>
|
||||
/// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether automatic mode is disabled.
|
||||
/// <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>
|
||||
/// Gets or sets a value indicating whether the system is operating in automatic mode.
|
||||
/// </summary>
|
||||
[JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool IsInAutoMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current room combination scenario.
|
||||
/// <summary>
|
||||
/// Gets or sets the current room combination scenario.
|
||||
/// </summary>
|
||||
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public IRoomCombinationScenario CurrentScenario { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of rooms associated with the entity.
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of rooms associated with the entity.
|
||||
/// </summary>
|
||||
[JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IKeyName> Rooms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of room combination scenarios.
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of room combination scenarios.
|
||||
/// </summary>
|
||||
[JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of partition controllers.
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of partition controllers.
|
||||
/// </summary>
|
||||
[JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IPartitionController> Partitions { get; set; }
|
||||
|
||||
@@ -5,25 +5,14 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement IHasCurrentSourceInfoChange interface
|
||||
/// </summary>
|
||||
public class IHasCurrentSourceInfoMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHasCurrentSourceInfoChange sourceDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IHasCurrentSourceInfoMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements IHasCurrentSourceInfoChange</param>
|
||||
public IHasCurrentSourceInfoMessenger(string key, string messagePath, IHasCurrentSourceInfoChange device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
sourceDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -36,7 +25,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
CurrentSource = sourceDevice.CurrentSourceInfo
|
||||
};
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
PostStatusMessage(message);
|
||||
});
|
||||
|
||||
sourceDevice.CurrentSourceChange += (sender, e) =>
|
||||
@@ -57,20 +46,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for current source information
|
||||
/// </summary>
|
||||
public class CurrentSourceStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the current source key
|
||||
/// </summary>
|
||||
[JsonProperty("currentSourceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentSourceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current source information
|
||||
/// </summary>
|
||||
[JsonProperty("currentSource")]
|
||||
public SourceListItem CurrentSource { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,40 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement IHasInputs interface
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Type of the key used for inputs</typeparam>
|
||||
public class IHasInputsMessenger<TKey> : MessengerBase
|
||||
{
|
||||
private readonly IHasInputs<TKey> itemDevice;
|
||||
{
|
||||
private readonly IHasInputs<TKey> itemDevice;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a messenger for a device that implements IHasInputs<typeparamref name="TKey"/>
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements IHasInputs</param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
/// <param name="device"></param>
|
||||
public IHasInputsMessenger(string key, string messagePath, IHasInputs<TKey> device) : base(key, messagePath, device)
|
||||
{
|
||||
itemDevice = device;
|
||||
itemDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, context) =>
|
||||
{
|
||||
SendFullStatus(id);
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
itemDevice.Inputs.ItemsUpdated += (sender, args) =>
|
||||
@@ -64,7 +59,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -79,7 +74,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
};
|
||||
|
||||
PostStatusMessage(stateObject, id);
|
||||
PostStatusMessage(stateObject);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -88,34 +83,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for devices with inputs
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Type of the key used for inputs</typeparam>
|
||||
public class IHasInputsStateMessage<TKey> : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the inputs
|
||||
/// </summary>
|
||||
[JsonProperty("inputs")]
|
||||
public Inputs<TKey> Inputs { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of inputs
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Type of the key used for inputs</typeparam>
|
||||
public class Inputs<TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the items dictionary
|
||||
/// </summary>
|
||||
[JsonProperty("items")]
|
||||
public Dictionary<TKey, ISelectableItem> Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current item
|
||||
/// </summary>
|
||||
[JsonProperty("currentItem")]
|
||||
public TKey CurrentItem { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,48 +5,31 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for power control operations with feedback.
|
||||
/// Handles power on/off commands and power state feedback reporting.
|
||||
/// </summary>
|
||||
public class IHasPowerControlWithFeedbackMessenger : MessengerBase
|
||||
{
|
||||
private readonly IHasPowerControlWithFeedback _powerControl;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IHasPowerControlWithFeedbackMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="messagePath">The message path for power control messages.</param>
|
||||
/// <param name="powerControl">The device that provides power control functionality.</param>
|
||||
public IHasPowerControlWithFeedbackMessenger(string key, string messagePath, IHasPowerControlWithFeedback powerControl)
|
||||
: base(key, messagePath, powerControl as IKeyName)
|
||||
{
|
||||
_powerControl = powerControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the full power control status to connected clients.
|
||||
/// </summary>
|
||||
public void SendFullStatus(string id = null)
|
||||
public void SendFullStatus()
|
||||
{
|
||||
var messageObj = new PowerControlWithFeedbackStateMessage
|
||||
{
|
||||
PowerState = _powerControl.PowerIsOnFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(messageObj, id);
|
||||
PostStatusMessage(messageObj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling power control operations.
|
||||
/// Includes power on, power off, power toggle, and full status reporting.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
_powerControl.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; ;
|
||||
}
|
||||
@@ -61,14 +44,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a power control state message containing power state information.
|
||||
/// </summary>
|
||||
public class PowerControlWithFeedbackStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the power state of the device.
|
||||
/// </summary>
|
||||
[JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? PowerState { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement IHasScheduleAwareness interface
|
||||
/// </summary>
|
||||
public class IHasScheduleAwarenessMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the schedule source device
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IHasScheduleAwarenessMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="scheduleSource">Device that implements IHasScheduleAwareness</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
public IHasScheduleAwarenessMessenger(string key, IHasScheduleAwareness scheduleSource, string messagePath)
|
||||
: base(key, messagePath, scheduleSource as IKeyName)
|
||||
{
|
||||
@@ -31,10 +19,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
ScheduleSource.CodecSchedule.MeetingEventChange += new EventHandler<MeetingEventArgs>(CodecSchedule_MeetingEventChange);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject(id));
|
||||
AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject());
|
||||
}
|
||||
|
||||
private void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e)
|
||||
@@ -58,60 +45,36 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Helper method to send the full schedule data
|
||||
/// </summary>
|
||||
private void SendFullScheduleObject(string id = null)
|
||||
private void SendFullScheduleObject()
|
||||
{
|
||||
PostStatusMessage(new FullScheduleMessage
|
||||
{
|
||||
Meetings = ScheduleSource.CodecSchedule.Meetings,
|
||||
MeetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes
|
||||
}, id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full schedule message containing meetings and warning minutes
|
||||
/// </summary>
|
||||
public class FullScheduleMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the list of meetings
|
||||
/// </summary>
|
||||
[JsonProperty("meetings", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<Meeting> Meetings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the meeting warning minutes
|
||||
/// </summary>
|
||||
[JsonProperty("meetingWarningMinutes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int MeetingWarningMinutes { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message containing meeting change information
|
||||
/// </summary>
|
||||
public class MeetingChangeMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the meeting change details
|
||||
/// </summary>
|
||||
[JsonProperty("meetingChange", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MeetingChange MeetingChange { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a meeting change with type and meeting details
|
||||
/// </summary>
|
||||
public class MeetingChange
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the change type
|
||||
/// </summary>
|
||||
[JsonProperty("changeType", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ChangeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the meeting details
|
||||
/// </summary>
|
||||
[JsonProperty("meeting", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Meeting Meeting { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
@@ -19,19 +19,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
device.HumidityFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new IHumiditySensorStateMessage
|
||||
{
|
||||
Humidity = string.Format("{0}%", device.HumidityFeedback.UShortValue)
|
||||
};
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement ILevelControls interface
|
||||
/// </summary>
|
||||
public class ILevelControlsMessenger : MessengerBase
|
||||
{
|
||||
private ILevelControls levelControlsDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ILevelControlsMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements ILevelControls</param>
|
||||
public ILevelControlsMessenger(string key, string messagePath, ILevelControls device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
levelControlsDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -37,7 +26,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
Levels = levelControlsDevice.LevelControlPoints.ToDictionary(kv => kv.Key, kv => new Volume { Level = kv.Value.VolumeLevelFeedback.IntValue, Muted = kv.Value.MuteFeedback.BoolValue })
|
||||
};
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
PostStatusMessage(message);
|
||||
});
|
||||
|
||||
foreach (var levelControl in levelControlsDevice.LevelControlPoints)
|
||||
@@ -85,32 +74,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for level controls
|
||||
/// </summary>
|
||||
public class LevelControlStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the level controls
|
||||
/// </summary>
|
||||
[JsonProperty("levelControls")]
|
||||
public Dictionary<string, Volume> Levels { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request message for level control operations
|
||||
/// </summary>
|
||||
public class LevelControlRequestMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the control key
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level
|
||||
/// </summary>
|
||||
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public ushort? Level { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
@@ -16,19 +16,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
public class IMatrixRoutingMessenger : MessengerBase
|
||||
{
|
||||
private readonly IMatrixRouting matrixDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the IMatrixRoutingMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements IMatrixRouting</param>
|
||||
public IMatrixRoutingMessenger(string key, string messagePath, IMatrixRouting device) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
matrixDevice = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
@@ -45,7 +37,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -90,159 +82,86 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for matrix routing information
|
||||
/// </summary>
|
||||
public class MatrixStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the outputs dictionary
|
||||
/// </summary>
|
||||
[JsonProperty("outputs")]
|
||||
public Dictionary<string, RoutingOutput> Outputs;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the inputs dictionary
|
||||
/// </summary>
|
||||
[JsonProperty("inputs")]
|
||||
public Dictionary<string, RoutingInput> Inputs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a routing input slot
|
||||
/// </summary>
|
||||
public class RoutingInput
|
||||
{
|
||||
private IRoutingInputSlot _input;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transmit device key
|
||||
/// </summary>
|
||||
[JsonProperty("txDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TxDeviceKey => _input?.TxDeviceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the slot number
|
||||
/// </summary>
|
||||
[JsonProperty("slotNumber", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? SlotNumber => _input?.SlotNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported signal types
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("supportedSignalTypes", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public eRoutingSignalType? SupportedSignalTypes => _input?.SupportedSignalTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name
|
||||
/// </summary>
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name => _input?.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the online status
|
||||
/// </summary>
|
||||
[JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOnline => _input?.IsOnline.BoolValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video sync detected status
|
||||
/// </summary>
|
||||
[JsonProperty("videoSyncDetected", NullValueHandling = NullValueHandling.Ignore)]
|
||||
|
||||
public bool? VideoSyncDetected => _input?.VideoSyncDetected;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key
|
||||
/// </summary>
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key => _input?.Key;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RoutingInput class
|
||||
/// </summary>
|
||||
/// <param name="input">The input slot</param>
|
||||
public RoutingInput(IRoutingInputSlot input)
|
||||
{
|
||||
_input = input;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a routing output slot
|
||||
/// </summary>
|
||||
public class RoutingOutput
|
||||
{
|
||||
private IRoutingOutputSlot _output;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RoutingOutput class
|
||||
/// </summary>
|
||||
/// <param name="output">The output slot</param>
|
||||
|
||||
public RoutingOutput(IRoutingOutputSlot output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the receive device key
|
||||
/// </summary>
|
||||
[JsonProperty("rxDeviceKey")]
|
||||
public string RxDeviceKey => _output.RxDeviceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current routes
|
||||
/// </summary>
|
||||
[JsonProperty("currentRoutes")]
|
||||
public Dictionary<string, RoutingInput> CurrentRoutes => _output.CurrentRoutes.ToDictionary(kvp => kvp.Key.ToString(), kvp => new RoutingInput(kvp.Value));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the slot number
|
||||
/// </summary>
|
||||
[JsonProperty("slotNumber")]
|
||||
public int SlotNumber => _output.SlotNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported signal types
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
[JsonProperty("supportedSignalTypes")]
|
||||
public eRoutingSignalType SupportedSignalTypes => _output.SupportedSignalTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name => _output.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key
|
||||
/// </summary>
|
||||
[JsonProperty("key")]
|
||||
public string Key => _output.Key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request for matrix routing
|
||||
/// </summary>
|
||||
public class MatrixRouteRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the output key
|
||||
/// </summary>
|
||||
[JsonProperty("outputKey")]
|
||||
public string OutputKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the input key
|
||||
/// </summary>
|
||||
[JsonProperty("inputKey")]
|
||||
public string InputKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the route type
|
||||
/// </summary>
|
||||
[JsonProperty("routeType")]
|
||||
public eRoutingSignalType RouteType { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/raise", (id, content) =>
|
||||
{
|
||||
@@ -50,7 +50,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PostStatusMessage(JToken.FromObject(state));
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new ScreenLiftStateMessage
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
DisplayDeviceKey = device.DisplayDeviceKey
|
||||
};
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for routing actions
|
||||
/// </summary>
|
||||
public class RunRouteActionMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
@@ -17,13 +14,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// </summary>
|
||||
public IRunRouteAction RoutingDevice { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RunRouteActionMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="routingDevice">Device that implements IRunRouteAction</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when routingDevice is null</exception>
|
||||
public RunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath)
|
||||
: base(key, messagePath, routingDevice as IKeyName)
|
||||
{
|
||||
@@ -41,10 +31,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
SendRoutingFullMessageObject();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject(id));
|
||||
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject());
|
||||
|
||||
AddAction("/source", (id, content) =>
|
||||
{
|
||||
@@ -70,7 +59,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Helper method to update full status of the routing device
|
||||
/// </summary>
|
||||
private void SendRoutingFullMessageObject(string id = null)
|
||||
private void SendRoutingFullMessageObject()
|
||||
{
|
||||
if (RoutingDevice is IRoutingSink sinkDevice)
|
||||
{
|
||||
@@ -82,19 +71,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PostStatusMessage(new RoutingStateMessage
|
||||
{
|
||||
SelectedSourceKey = sourceKey
|
||||
}, id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message class for routing state
|
||||
/// </summary>
|
||||
public class RoutingStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the selected source key
|
||||
/// </summary>
|
||||
[JsonProperty("selectedSourceKey")]
|
||||
public string SelectedSourceKey { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement ISelectableItems interface
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Type of the key used for selectable items</typeparam>
|
||||
public class ISelectableItemsMessenger<TKey> : MessengerBase
|
||||
{
|
||||
{
|
||||
private readonly ISelectableItems<TKey> itemDevice;
|
||||
|
||||
private readonly string _propName;
|
||||
@@ -20,24 +16,23 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Constructs a messenger for a device that implements ISelectableItems<typeparamref name="TKey"/>
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="device">Device that implements ISelectableItems</param>
|
||||
/// <param name="propName">Property name for JSON serialization</param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="propName"></param>
|
||||
public ISelectableItemsMessenger(string key, string messagePath, ISelectableItems<TKey> device, string propName) : base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
itemDevice = device;
|
||||
_propName = propName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, context) =>
|
||||
{
|
||||
SendFullStatus(id);
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
itemDevice.ItemsUpdated += (sender, args) =>
|
||||
@@ -67,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -79,7 +74,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
CurrentItem = itemDevice.CurrentItem
|
||||
};
|
||||
|
||||
PostStatusMessage(stateObject, id);
|
||||
PostStatusMessage(stateObject);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -88,21 +83,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for selectable items
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Type of the key used for selectable items</typeparam>
|
||||
public class ISelectableItemsStateMessage<TKey> : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the items dictionary
|
||||
/// </summary>
|
||||
[JsonProperty("items")]
|
||||
public Dictionary<TKey, ISelectableItem> Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current item
|
||||
/// </summary>
|
||||
[JsonProperty("currentItem")]
|
||||
public TKey CurrentItem { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,26 +5,16 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for the shutdown prompt timer
|
||||
/// </summary>
|
||||
public class IShutdownPromptTimerMessenger : MessengerBase
|
||||
{
|
||||
private readonly IShutdownPromptTimer _room;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IShutdownPromptTimerMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="room">Room that implements IShutdownPromptTimer</param>
|
||||
public IShutdownPromptTimerMessenger(string key, string messagePath, IShutdownPromptTimer room)
|
||||
: base(key, messagePath, room as IKeyName)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/status", (id, content) =>
|
||||
@@ -75,7 +65,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var status = new IShutdownPromptTimerStateMessage
|
||||
{
|
||||
@@ -84,7 +74,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PercentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
|
||||
};
|
||||
|
||||
PostStatusMessage(status, id);
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for ISwitchedOutput devices
|
||||
/// </summary>
|
||||
public class ISwitchedOutputMessenger : MessengerBase
|
||||
{
|
||||
|
||||
private readonly ISwitchedOutput device;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ISwitchedOutputMessenger"/> class.
|
||||
/// This messenger provides mobile control interface for switched output devices.
|
||||
/// It allows sending commands to turn the output on or off, and provides feedback on the
|
||||
/// current state of the output.
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="device">Device that implements ISwitchedOutput</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
public ISwitchedOutputMessenger(string key, ISwitchedOutput device, string messagePath)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/on", (id, content) =>
|
||||
{
|
||||
@@ -52,29 +39,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
device.OutputIsOnFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new ISwitchedOutputStateMessage
|
||||
{
|
||||
IsOn = device.OutputIsOnFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for ISwitchedOutput devices
|
||||
/// This message contains the current state of the switched output, specifically whether it is on or off.
|
||||
/// It is used to communicate the state of the output to clients that subscribe to this messenger.
|
||||
/// </summary>
|
||||
public class ISwitchedOutputStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the switched output is currently on.
|
||||
/// This property is used to convey the current state of the output to clients.
|
||||
/// A value of true indicates that the output is on, while false indicates it is off.
|
||||
/// </summary>
|
||||
[JsonProperty("isOn")]
|
||||
public bool IsOn { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,32 +4,22 @@ using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for devices that implement ITechPassword interface
|
||||
/// </summary>
|
||||
public class ITechPasswordMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITechPassword _room;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ITechPasswordMessenger class
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="room">Room that implements ITechPassword</param>
|
||||
public ITechPasswordMessenger(string key, string messagePath, ITechPassword room)
|
||||
: base(key, messagePath, room as IKeyName)
|
||||
{
|
||||
_room = room;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
|
||||
AddAction("/status", (id, content) =>
|
||||
{
|
||||
SendFullStatus(id);
|
||||
SendFullStatus();
|
||||
});
|
||||
|
||||
AddAction("/validateTechPassword", (id, content) =>
|
||||
@@ -62,56 +52,35 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var status = new ITechPasswordStateMessage
|
||||
{
|
||||
TechPasswordLength = _room.TechPasswordLength
|
||||
};
|
||||
|
||||
PostStatusMessage(status, id);
|
||||
PostStatusMessage(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for tech password information
|
||||
/// </summary>
|
||||
public class ITechPasswordStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the tech password length
|
||||
/// </summary>
|
||||
[JsonProperty("techPasswordLength", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? TechPasswordLength { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event message for tech password validation result
|
||||
/// </summary>
|
||||
public class ITechPasswordEventMessage : DeviceEventMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets whether the password is valid
|
||||
/// </summary>
|
||||
[JsonProperty("isValid", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsValid { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Content for setting tech password
|
||||
/// </summary>
|
||||
internal class SetTechPasswordContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the old password
|
||||
/// </summary>
|
||||
[JsonProperty("oldPassword")]
|
||||
public string OldPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the new password
|
||||
/// </summary>
|
||||
[JsonProperty("newPassword")]
|
||||
public string NewPassword { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,37 +1,25 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for temperature sensor devices
|
||||
/// </summary>
|
||||
public class ITemperatureSensorMessenger : MessengerBase
|
||||
{
|
||||
private readonly ITemperatureSensor device;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ITemperatureSensorMessenger class
|
||||
/// This messenger provides a mobile control interface for temperature sensor devices.
|
||||
/// It allows clients to retrieve the current temperature and change the temperature format between Celsius and Fahrenheit.
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="device">Device that implements ITemperatureSensor</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
public ITemperatureSensorMessenger(string key, ITemperatureSensor device, string messagePath)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/setTemperatureUnitsToCelcius", (id, content) =>
|
||||
{
|
||||
@@ -47,7 +35,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
device.TemperatureInCFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
|
||||
}
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
// format the temperature to a string with one decimal place
|
||||
var tempString = string.Format("{0}.{1}", device.TemperatureFeedback.UShortValue / 10, device.TemperatureFeedback.UShortValue % 10);
|
||||
@@ -58,27 +46,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
TemperatureInCelsius = device.TemperatureInCFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for temperature sensor devices
|
||||
/// </summary>
|
||||
public class ITemperatureSensorStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the current temperature reading from the sensor.
|
||||
/// The temperature is represented as a string formatted to one decimal place.
|
||||
/// For example, "22.5" for 22.5 degrees.
|
||||
/// </summary>
|
||||
[JsonProperty("temperature")]
|
||||
public string Temperature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the temperature is in Celsius.
|
||||
/// This property is true if the temperature is in Celsius, and false if it is in Fahrenheit.
|
||||
/// </summary>
|
||||
[JsonProperty("temperatureInCelsius")]
|
||||
public bool TemperatureInCelsius { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,25 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Lighting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for lighting scenes devices
|
||||
/// </summary>
|
||||
public class ILightingScenesMessenger : MessengerBase
|
||||
{
|
||||
private ILightingScenes lightingScenesDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ILightingScenesMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="device">Device that implements ILightingScenes</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when device is null</exception>
|
||||
public ILightingScenesMessenger(string key, ILightingScenes device, string messagePath)
|
||||
: base(key, messagePath, device as IKeyName)
|
||||
{
|
||||
@@ -38,12 +28,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/selectScene", (id, content) =>
|
||||
{
|
||||
@@ -51,14 +40,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
lightingScenesDevice.SelectScene(s);
|
||||
});
|
||||
|
||||
if (!(lightingScenesDevice is ILightingScenesDynamic lightingScenesDynamic))
|
||||
if(!(lightingScenesDevice is ILightingScenesDynamic lightingScenesDynamic))
|
||||
return;
|
||||
|
||||
lightingScenesDynamic.LightingScenesUpdated += (s, e) => SendFullStatus();
|
||||
}
|
||||
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new LightingBaseStateMessage
|
||||
{
|
||||
@@ -66,7 +55,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
CurrentLightingScene = lightingScenesDevice.CurrentLightingScene
|
||||
};
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,57 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a messaging bridge between mobile control clients and Essentials devices.
|
||||
/// This abstract base class handles message routing, action registration, and status updates.
|
||||
/// Provides a messaging bridge
|
||||
/// </summary>
|
||||
public abstract class MessengerBase : EssentialsDevice, IMobileControlMessenger
|
||||
{
|
||||
/// <summary>
|
||||
/// The device that this messenger is associated with
|
||||
/// </summary>
|
||||
protected IKeyName _device;
|
||||
|
||||
/// <summary>
|
||||
/// List of interfaces implemented by the associated device
|
||||
/// </summary>
|
||||
private readonly List<string> _deviceInterfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of registered actions, keyed by path
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Action<string, JToken>> _actions = new Dictionary<string, Action<string, JToken>>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key of the associated device
|
||||
/// </summary>
|
||||
public string DeviceKey => _device?.Key ?? "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mobile control app server controller
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
public IMobileControl AppServerController { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message path for this messenger
|
||||
/// </summary>
|
||||
public string MessagePath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MessengerBase class
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing messages</param>
|
||||
/// <exception cref="ArgumentException">Thrown when messagePath is null or empty</exception>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
protected MessengerBase(string key, string messagePath)
|
||||
: base(key)
|
||||
{
|
||||
@@ -63,12 +47,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
MessagePath = messagePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MessengerBase class with an associated device
|
||||
/// </summary>
|
||||
/// <param name="key">The unique key for this messenger</param>
|
||||
/// <param name="messagePath">The message path for routing messages</param>
|
||||
/// <param name="device">The device to associate with this messenger</param>
|
||||
protected MessengerBase(string key, string messagePath, IKeyName device)
|
||||
: this(key, messagePath)
|
||||
{
|
||||
@@ -78,7 +56,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the interfaces implented on the device
|
||||
/// Gets the interfaces implmented on the device
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <returns></returns>
|
||||
@@ -115,11 +93,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
action(id, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an action to be executed when a message is received at the specified path
|
||||
/// </summary>
|
||||
/// <param name="path">The path to register the action for</param>
|
||||
/// <param name="action">The action to execute when the path is matched</param>
|
||||
protected void AddAction(string path, Action<string, JToken> action)
|
||||
{
|
||||
if (_actions.ContainsKey(path))
|
||||
@@ -131,19 +104,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
_actions.Add(path, action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all registered action paths
|
||||
/// </summary>
|
||||
/// <returns>A list of action paths</returns>
|
||||
public List<string> GetActionPaths()
|
||||
{
|
||||
return _actions.Keys.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an action from the specified path
|
||||
/// </summary>
|
||||
/// <param name="path">The path to remove the action from</param>
|
||||
protected void RemoveAction(string path)
|
||||
{
|
||||
if (!_actions.ContainsKey(path))
|
||||
@@ -157,6 +122,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Implemented in extending classes. Wire up API calls and feedback here
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected virtual void RegisterActions()
|
||||
{
|
||||
|
||||
@@ -165,8 +131,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <summary>
|
||||
/// Helper for posting status message
|
||||
/// </summary>
|
||||
/// <param name="message">The device state message to post</param>
|
||||
/// <param name="clientId">Optional client ID to send the message to a specific client</param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="message"></param>
|
||||
protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null)
|
||||
{
|
||||
try
|
||||
@@ -187,22 +153,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
message.Name = _device.Name;
|
||||
|
||||
var token = JToken.FromObject(message);
|
||||
|
||||
var token = JToken.FromObject(message);
|
||||
|
||||
PostStatusMessage(token, MessagePath, clientId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Exception posting status message for {messagePath} to {clientId}", MessagePath, clientId ?? "all clients");
|
||||
this.LogError(ex, "Exception posting status message for {messagePath} to {clientId}", MessagePath, clientId ?? "all clients");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts a status message with a specific message type
|
||||
/// </summary>
|
||||
/// <param name="type">The message type to send</param>
|
||||
/// <param name="deviceState">The device state message to post</param>
|
||||
/// <param name="clientId">Optional client ID to send the message to a specific client</param>
|
||||
protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null)
|
||||
{
|
||||
try
|
||||
@@ -222,16 +182,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Exception posting status message for {type} to {clientId}", type, clientId ?? "all clients");
|
||||
this.LogError(ex, "Exception posting status message for {type} to {clientId}", type, clientId ?? "all clients");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts a status message with JSON content
|
||||
/// </summary>
|
||||
/// <param name="content">The JSON content to send</param>
|
||||
/// <param name="type">The message type (defaults to MessagePath if empty)</param>
|
||||
/// <param name="clientId">Optional client ID to send the message to a specific client</param>
|
||||
protected void PostStatusMessage(JToken content, string type = "", string clientId = null)
|
||||
{
|
||||
try
|
||||
@@ -244,10 +198,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts an event message for the device
|
||||
/// </summary>
|
||||
/// <param name="message">The device event message to post</param>
|
||||
protected void PostEventMessage(DeviceEventMessageBase message)
|
||||
{
|
||||
message.Key = _device.Key;
|
||||
@@ -261,11 +211,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts an event message with a specific event type
|
||||
/// </summary>
|
||||
/// <param name="message">The device event message to post</param>
|
||||
/// <param name="eventType">The event type to use</param>
|
||||
protected void PostEventMessage(DeviceEventMessageBase message, string eventType)
|
||||
{
|
||||
message.Key = _device.Key;
|
||||
@@ -281,10 +226,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts an event message with only an event type
|
||||
/// </summary>
|
||||
/// <param name="eventType">The event type to post</param>
|
||||
protected void PostEventMessage(string eventType)
|
||||
{
|
||||
AppServerController?.SendMessageObject(new MobileControlMessage
|
||||
@@ -296,9 +237,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for device messages containing common properties like key, name, and message type
|
||||
/// </summary>
|
||||
public abstract class DeviceMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
@@ -319,28 +257,21 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
[JsonProperty("messageType")]
|
||||
public string MessageType => GetType().Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base path for the message
|
||||
/// </summary>
|
||||
[JsonProperty("messageBasePath")]
|
||||
public string MessageBasePath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for state messages that includes the type of message and the implemented interfaces
|
||||
/// Base class for state messages that includes the type of message and the implmented interfaces
|
||||
/// </summary>
|
||||
public class DeviceStateMessageBase : DeviceMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The interfaces implented by the device sending the messsage
|
||||
/// The interfaces implmented by the device sending the messsage
|
||||
/// </summary>
|
||||
[JsonProperty("interfaces")]
|
||||
public List<string> Interfaces { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the interfaces implemented by the device
|
||||
/// </summary>
|
||||
/// <param name="interfaces">List of interface names to set</param>
|
||||
public void SetInterfaces(List<string> interfaces)
|
||||
{
|
||||
Interfaces = interfaces;
|
||||
|
||||
@@ -1,34 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Static handler for managing press and hold button actions with automatic timeout functionality
|
||||
/// </summary>
|
||||
public static class PressAndHoldHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// The interval in milliseconds for button heartbeat timeout
|
||||
/// </summary>
|
||||
private const long ButtonHeartbeatInterval = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of active timers for pressed actions, keyed by device key
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, CTimer> _pushedActions = new Dictionary<string, CTimer>();
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of action handlers for different button states
|
||||
/// </summary>
|
||||
private static readonly Dictionary<string, Action<string, Action<bool>>> _pushedActionHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// Static constructor that initializes the action handlers for different button states
|
||||
/// </summary>
|
||||
static PressAndHoldHandler()
|
||||
{
|
||||
_pushedActionHandlers = new Dictionary<string, Action<string, Action<bool>>>
|
||||
@@ -39,11 +24,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a timer for a device key and executes the action with true state
|
||||
/// </summary>
|
||||
/// <param name="deviceKey">The unique key for the device</param>
|
||||
/// <param name="action">The action to execute with boolean state</param>
|
||||
private static void AddTimer(string deviceKey, Action<bool> action)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to add timer for {deviceKey}", deviceKey);
|
||||
@@ -70,11 +50,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
_pushedActions.Add(deviceKey, cancelTimer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets an existing timer for the specified device key
|
||||
/// </summary>
|
||||
/// <param name="deviceKey">The unique key for the device</param>
|
||||
/// <param name="action">The action associated with the timer</param>
|
||||
private static void ResetTimer(string deviceKey, Action<bool> action)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to reset timer for {deviceKey}", deviceKey);
|
||||
@@ -90,11 +65,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
cancelTimer.Reset(ButtonHeartbeatInterval);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops and removes the timer for the specified device key
|
||||
/// </summary>
|
||||
/// <param name="deviceKey">The unique key for the device</param>
|
||||
/// <param name="action">The action to execute with false state before stopping</param>
|
||||
private static void StopTimer(string deviceKey, Action<bool> action)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Attempting to stop timer for {deviceKey}", deviceKey);
|
||||
@@ -112,11 +82,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
_pushedActions.Remove(deviceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the appropriate press and hold handler for the specified value
|
||||
/// </summary>
|
||||
/// <param name="value">The button state value (pressed, held, released)</param>
|
||||
/// <returns>The handler action for the specified state, or null if not found</returns>
|
||||
public static Action<string, Action<bool>> GetPressAndHoldHandler(string value)
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Getting press and hold handler for {value}", value);
|
||||
@@ -132,12 +97,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
return handler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles press and hold messages by parsing the content and executing the appropriate handler
|
||||
/// </summary>
|
||||
/// <param name="deviceKey">The unique key for the device</param>
|
||||
/// <param name="content">The JSON content containing the button state</param>
|
||||
/// <param name="action">The action to execute with boolean state</param>
|
||||
public static void HandlePressAndHold(string deviceKey, JToken content, Action<bool> action)
|
||||
{
|
||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
@@ -1,30 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Messenger for managing scheduled events in a room.
|
||||
/// This class handles saving scheduled events and sending the current schedule state to clients.
|
||||
/// It listens for changes in the scheduled events and updates clients accordingly.
|
||||
/// </summary>
|
||||
public class RoomEventScheduleMessenger : MessengerBase
|
||||
{
|
||||
private readonly IRoomEventSchedule _room;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoomEventScheduleMessenger"/> class.
|
||||
/// This constructor sets up the messenger with a unique key, message path, and the room event schedule interface.
|
||||
/// It registers actions for saving scheduled events and sending the current schedule state.
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="room">Room event schedule interface</param>
|
||||
|
||||
public RoomEventScheduleMessenger(string key, string messagePath, IRoomEventSchedule room)
|
||||
: base(key, messagePath, room as IKeyName)
|
||||
{
|
||||
@@ -33,7 +21,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/saveScheduledEvents", (id, content) => SaveScheduledEvents(content.ToObject<List<ScheduledEventConfig>>()));
|
||||
@@ -41,7 +28,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
var events = _room.GetScheduledEvents();
|
||||
|
||||
SendFullStatus(events, id);
|
||||
SendFullStatus(events);
|
||||
});
|
||||
|
||||
_room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
|
||||
@@ -65,11 +52,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogException(ex, "Exception saving event");
|
||||
this.LogException(ex,"Exception saving event");
|
||||
}
|
||||
}
|
||||
|
||||
private void SendFullStatus(List<ScheduledEventConfig> events, string id = null)
|
||||
private void SendFullStatus(List<ScheduledEventConfig> events)
|
||||
{
|
||||
|
||||
var message = new RoomEventScheduleStateMessage
|
||||
@@ -77,22 +64,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
ScheduleEvents = events,
|
||||
};
|
||||
|
||||
PostStatusMessage(message, id);
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the state message for room event schedules.
|
||||
/// This message contains a list of scheduled events configured for the room.
|
||||
/// It is used to communicate the current schedule state to clients.
|
||||
/// </summary>
|
||||
public class RoomEventScheduleStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the list of scheduled events for the room.
|
||||
/// This property contains the configuration of scheduled events that are set up in the room.
|
||||
/// Each event includes details such as the event name, start time, end time, and recurrence pattern.
|
||||
/// </summary>
|
||||
[JsonProperty("scheduleEvents")]
|
||||
public List<ScheduledEventConfig> ScheduleEvents { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,39 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// SIMPL messenger for audio-only conference devices that provides audio calling functionality
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class SIMPLAtcMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The EISC (Ethernet Intersystem Communication) device
|
||||
/// </summary>
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the join map for SIMPL ATC operations
|
||||
/// </summary>
|
||||
public SIMPLAtcJoinMap JoinMap { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The current active call item for audio calls
|
||||
///
|
||||
/// </summary>
|
||||
private readonly CodecActiveCallItem _currentCallItem;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SIMPLAtcMessenger class
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="eisc">The EISC device for communication</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="eisc"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public SIMPLAtcMessenger(string key, BasicTriList eisc, string messagePath)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
@@ -45,7 +38,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the current status of the audio conference device to connected clients
|
||||
///
|
||||
/// </summary>
|
||||
private void SendFullStatus()
|
||||
{
|
||||
@@ -60,8 +53,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions and feedback handlers for the SIMPL ATC messenger
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
//EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s }));
|
||||
@@ -139,7 +133,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the current calls list to connected clients
|
||||
///
|
||||
/// </summary>
|
||||
private void SendCallsList()
|
||||
{
|
||||
@@ -151,9 +145,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current call list based on the call status
|
||||
/// Turns the
|
||||
/// </summary>
|
||||
/// <returns>A list containing the current call item if connected, or an empty list if disconnected</returns>
|
||||
/// <returns></returns>
|
||||
private List<CodecActiveCallItem> GetCurrentCallList()
|
||||
{
|
||||
return _currentCallItem.Status == eCodecCallStatus.Disconnected
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for camera control operations in SIMPL-based systems.
|
||||
/// Handles camera movement, zoom, preset management, and mode control.
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class SIMPLCameraMessenger : MessengerBase
|
||||
{
|
||||
@@ -20,13 +16,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
private readonly CameraControllerJoinMap _joinMap;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SIMPLCameraMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="eisc">The basic tri-list for SIMPL communication.</param>
|
||||
/// <param name="messagePath">The message path for camera control messages.</param>
|
||||
/// <param name="joinStart">The starting join number for SIMPL signal mapping.</param>
|
||||
|
||||
public SIMPLCameraMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
@@ -42,10 +32,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling camera control operations.
|
||||
/// Includes camera movement, zoom, preset management, and mode control actions.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
|
||||
|
||||
@@ -1,35 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for direct routing operations in SIMPL-based systems.
|
||||
/// Handles source selection, destination routing, and advanced sharing mode functionality.
|
||||
/// </summary>
|
||||
public class SimplDirectRouteMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the join map for SIMPL direct route actions.
|
||||
/// </summary>
|
||||
public MobileControlSIMPLRunDirectRouteActionJoinMap JoinMap { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the dictionary of destination items for routing operations.
|
||||
/// </summary>
|
||||
public Dictionary<string, DestinationListItem> DestinationList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimplDirectRouteMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="eisc">The basic tri-list for SIMPL communication.</param>
|
||||
/// <param name="messagePath">The message path for routing messages.</param>
|
||||
public SimplDirectRouteMessenger(string key, BasicTriList eisc, string messagePath) : base(key, messagePath)
|
||||
{
|
||||
_eisc = eisc;
|
||||
@@ -41,10 +25,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling direct route messaging operations.
|
||||
/// Includes audio source selection, full status reporting, and advanced sharing mode controls.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
Debug.Console(2, "********** Direct Route Messenger CustomRegisterWithAppServer **********");
|
||||
@@ -112,10 +92,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers routing actions for each destination in the destination list.
|
||||
/// Sets up feedback handlers and source selection actions for individual destinations.
|
||||
/// </summary>
|
||||
public void RegisterForDestinationPaths()
|
||||
{
|
||||
//handle routing feedback from SIMPL
|
||||
@@ -138,11 +114,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates the source selection for a specific destination and posts a status message.
|
||||
/// </summary>
|
||||
/// <param name="sourceKey">The key of the selected source.</param>
|
||||
/// <param name="destKey">The key of the destination being updated.</param>
|
||||
private void UpdateSourceForDestination(string sourceKey, string destKey)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
|
||||
@@ -6,34 +6,21 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for routing operations in SIMPL-based systems.
|
||||
/// Handles source selection and routing status feedback.
|
||||
/// </summary>
|
||||
|
||||
public class SIMPLRouteMessenger : MessengerBase
|
||||
{
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
private readonly uint _joinStart;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the string join mappings for SIMPL routing operations.
|
||||
/// </summary>
|
||||
public class StringJoin
|
||||
{
|
||||
/// <summary>
|
||||
/// Join number for current source information (1).
|
||||
/// 1
|
||||
/// </summary>
|
||||
public const uint CurrentSource = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SIMPLRouteMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="eisc">The basic tri-list for SIMPL communication.</param>
|
||||
/// <param name="messagePath">The message path for routing messages.</param>
|
||||
/// <param name="joinStart">The starting join number for SIMPL signal mapping.</param>
|
||||
public SIMPLRouteMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
@@ -43,10 +30,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
_eisc.SetStringSigAction(_joinStart + StringJoin.CurrentSource, SendRoutingFullMessageObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling routing operations and status reporting.
|
||||
/// Includes full status requests and source selection actions.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus",
|
||||
@@ -60,11 +43,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters this messenger from the mobile control app server.
|
||||
/// Removes all registered actions and clears SIMPL signal actions.
|
||||
/// </summary>
|
||||
/// <param name="appServerController">The mobile control app server controller.</param>
|
||||
public void CustomUnregisterWithAppServer(IMobileControl appServerController)
|
||||
{
|
||||
appServerController.RemoveAction(MessagePath + "/fullStatus");
|
||||
|
||||
@@ -1,51 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// SIMPL messenger for video conference devices that provides video calling and camera control functionality
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class SIMPLVtcMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The EISC (Ethernet Intersystem Communication) device
|
||||
/// </summary>
|
||||
private readonly BasicTriList _eisc;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the join map for SIMPL VTC operations
|
||||
/// </summary>
|
||||
public SIMPLVtcJoinMap JoinMap { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current active call item for video calls
|
||||
/// </summary>
|
||||
private readonly CodecActiveCallItem _currentCallItem;
|
||||
|
||||
/// <summary>
|
||||
/// The incoming call item for video calls
|
||||
/// </summary>
|
||||
private CodecActiveCallItem _incomingCallItem;
|
||||
|
||||
/// <summary>
|
||||
/// The previous directory length for tracking changes
|
||||
/// </summary>
|
||||
private ushort _previousDirectoryLength = 701;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SIMPLVtcMessenger class
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key">Unique identifier for the messenger</param>
|
||||
/// <param name="eisc">The EISC device for communication</param>
|
||||
/// <param name="messagePath">Path for message routing</param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="eisc"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public SIMPLVtcMessenger(string key, BasicTriList eisc, string messagePath)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
@@ -57,8 +39,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions and feedback handlers for the SIMPL VTC messenger
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
_eisc.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
|
||||
|
||||
@@ -1,39 +1,25 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Shades;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for shade control operations.
|
||||
/// Handles shade open, close, and stop commands for shades that support these operations.
|
||||
/// </summary>
|
||||
public class IShadesOpenCloseStopMessenger : MessengerBase
|
||||
{
|
||||
private readonly IShadesOpenCloseStop device;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IShadesOpenCloseStopMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="shades">The shade device that provides open/close/stop functionality.</param>
|
||||
/// <param name="messagePath">The message path for shade control messages.</param>
|
||||
public IShadesOpenCloseStopMessenger(string key, IShadesOpenCloseStop shades, string messagePath)
|
||||
: base(key, messagePath, shades as IKeyName)
|
||||
{
|
||||
device = shades;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling shade control operations.
|
||||
/// Includes shade open, close, stop, and full status reporting.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/shadeUp", (id, content) =>
|
||||
{
|
||||
@@ -86,7 +72,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var state = new ShadeBaseStateMessage();
|
||||
|
||||
@@ -96,30 +82,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue;
|
||||
}
|
||||
|
||||
PostStatusMessage(state, id);
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a shade state message containing shade status and control information.
|
||||
/// </summary>
|
||||
public class ShadeBaseStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the label for the middle button control.
|
||||
/// </summary>
|
||||
[JsonProperty("middleButtonLabel", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string MiddleButtonLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the shade is open.
|
||||
/// </summary>
|
||||
[JsonProperty("isOpen", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsOpen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the shade is closed.
|
||||
/// </summary>
|
||||
[JsonProperty("isClosed", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsClosed { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,28 +1,17 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Monitoring;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for system monitoring operations.
|
||||
/// Handles system performance metrics, program status reporting, and monitoring data communication.
|
||||
/// </summary>
|
||||
public class SystemMonitorMessenger : MessengerBase
|
||||
{
|
||||
private readonly SystemMonitorController systemMonitor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SystemMonitorMessenger"/> class.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="sysMon">The system monitor controller for monitoring operations.</param>
|
||||
/// <param name="messagePath">The message path for system monitor messages.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when sysMon is null.</exception>
|
||||
public SystemMonitorMessenger(string key, SystemMonitorController sysMon, string messagePath)
|
||||
: base(key, messagePath, sysMon)
|
||||
{
|
||||
@@ -64,20 +53,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
SendSystemMonitorStatusMessage();
|
||||
}
|
||||
|
||||
private void SendFullStatusMessage(string id = null)
|
||||
private void SendFullStatusMessage()
|
||||
{
|
||||
SendSystemMonitorStatusMessage(id);
|
||||
SendSystemMonitorStatusMessage();
|
||||
|
||||
foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo), id);
|
||||
PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void SendSystemMonitorStatusMessage(string id = null)
|
||||
private void SendSystemMonitorStatusMessage()
|
||||
{
|
||||
// This takes a while, launch a new thread
|
||||
|
||||
|
||||
Task.Run(() => PostStatusMessage(JToken.FromObject(new SystemMonitorStateMessage
|
||||
{
|
||||
|
||||
@@ -87,58 +76,33 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
SnmpVersion = systemMonitor.SnmpVersionFeedback.StringValue,
|
||||
BacnetVersion = systemMonitor.BaCnetAppVersionFeedback.StringValue,
|
||||
ControllerVersion = systemMonitor.ControllerVersionFeedback.StringValue
|
||||
}), id
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling system monitor operations.
|
||||
/// Includes full status reporting for system monitoring data.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatusMessage(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatusMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the system monitor state message containing system information and version details.
|
||||
/// </summary>
|
||||
public class SystemMonitorStateMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the system time zone offset.
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int TimeZone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the system time zone name.
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string TimeZoneName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IO controller version information.
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string IoControllerVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SNMP version information.
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string SnmpVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the BACnet version information.
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string BacnetVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the controller version information.
|
||||
/// </summary>
|
||||
[JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ControllerVersion { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,27 +5,10 @@ using PepperDash.Essentials.Devices.Common.Displays;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides messaging capabilities for two-way display control operations.
|
||||
/// Handles display input changes, power state, and cooling/warming status.
|
||||
/// This class extends the MessengerBase to facilitate communication between the display and the mobile control interface.
|
||||
/// </summary>
|
||||
public class TwoWayDisplayBaseMessenger : MessengerBase
|
||||
{
|
||||
private readonly TwoWayDisplayBase _display;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TwoWayDisplayBaseMessenger"/> class.
|
||||
/// This constructor sets up the messenger with a key, message path, and the display instance
|
||||
/// that it will control and monitor.
|
||||
/// The display instance should implement the TwoWayDisplayBase interface to provide the necessary feedback and
|
||||
/// control methods for the display device.
|
||||
/// The messenger will listen for changes in the display's state and send updates to the mobile control interface.
|
||||
/// It also allows for sending commands to the display, such as changing inputs or toggling power states.
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for this messenger instance.</param>
|
||||
/// <param name="messagePath">The message path for display control messages.</param>
|
||||
/// <param name="display">The display instance to control and monitor.</param>
|
||||
public TwoWayDisplayBaseMessenger(string key, string messagePath, TwoWayDisplayBase display)
|
||||
: base(key, messagePath, display)
|
||||
{
|
||||
@@ -34,8 +17,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
#region Overrides of MessengerBase
|
||||
|
||||
|
||||
private void SendFullStatus(string id = null)
|
||||
public void SendFullStatus()
|
||||
{
|
||||
var messageObj = new TwoWayDisplayBaseStateMessage
|
||||
{
|
||||
@@ -43,20 +25,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
CurrentInput = _display.CurrentInputFeedback.StringValue
|
||||
};
|
||||
|
||||
PostStatusMessage(messageObj, id);
|
||||
PostStatusMessage(messageObj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers actions for handling two-way display operations.
|
||||
/// This includes sending full status updates and handling input changes, cooling, and warming feedback.
|
||||
/// The actions are registered to respond to specific commands sent from the mobile control interface.
|
||||
/// </summary>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
base.RegisterActions();
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
//_display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
|
||||
_display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange;
|
||||
_display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange;
|
||||
_display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange;
|
||||
@@ -71,6 +49,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//private void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
//{
|
||||
// PostStatusMessage(JToken.FromObject(new
|
||||
// {
|
||||
// powerState = feedbackEventArgs.BoolValue
|
||||
// })
|
||||
// );
|
||||
//}
|
||||
|
||||
private void IsWarmingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
@@ -13,6 +9,9 @@ using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
@@ -22,18 +21,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
public class VideoCodecBaseMessenger : MessengerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The video codec device being managed by this messenger.
|
||||
///
|
||||
/// </summary>
|
||||
protected VideoCodecBase Codec { get; private set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VideoCodecBaseMessenger"/> class.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key">The unique identifier for the messenger.</param>
|
||||
/// <param name="codec">The video codec device to be managed.</param>
|
||||
/// <param name="messagePath">The message path for communication.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when codec is null</exception>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="codec"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
|
||||
: base(key, messagePath, codec)
|
||||
{
|
||||
@@ -71,6 +70,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PostEventMessage(eventMsg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -94,10 +98,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the event when a directory result is returned from the codec.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The directory event arguments.</param>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void DirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
||||
{
|
||||
if (Codec is IHasDirectory)
|
||||
@@ -105,9 +109,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the current directory structure to the mobile control interface.
|
||||
/// Posts the current directory
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory structure to send.</param>
|
||||
protected void SendDirectory(CodecDirectory directory)
|
||||
{
|
||||
try
|
||||
@@ -131,6 +134,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Codec_IsReadyChange(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -143,14 +151,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
PostStatusMessage(state);
|
||||
|
||||
SendFullStatus();
|
||||
}
|
||||
catch (Exception ex)
|
||||
} catch (Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Error sending codec ready status");
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Called from base's RegisterWithAppServer method
|
||||
/// </summary>
|
||||
/// <param name="appServerController"></param>
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
try
|
||||
@@ -159,7 +169,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
|
||||
AddAction("/isReady", (id, content) => SendIsReady());
|
||||
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
|
||||
AddAction("/fullStatus", (id, content) => SendFullStatus());
|
||||
|
||||
AddAction("/dial", (id, content) =>
|
||||
{
|
||||
@@ -359,8 +369,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
catch (Exception ex)
|
||||
} catch (Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Error posting sharing source");
|
||||
}
|
||||
@@ -376,8 +385,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
catch (Exception ex)
|
||||
} catch (Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Error posting sharing content");
|
||||
}
|
||||
@@ -427,13 +435,15 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
MapCameraActions();
|
||||
PostSelectedCamera();
|
||||
}
|
||||
catch (Exception ex)
|
||||
} catch(Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Exception handling camera selected event");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps the camera control actions to the current selected camera on the codec
|
||||
/// </summary>
|
||||
private void MapCameraActions()
|
||||
{
|
||||
if (Codec is IHasCameras cameraCodec && cameraCodec.SelectedCamera != null)
|
||||
@@ -589,7 +599,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
try
|
||||
{
|
||||
var codec = Codec as IHasCallHistory;
|
||||
var codec = (Codec as IHasCallHistory);
|
||||
|
||||
if (codec != null)
|
||||
{
|
||||
@@ -611,11 +621,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab a call with string ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private CodecActiveCallItem GetCallWithId(string id)
|
||||
{
|
||||
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
private void GetDirectory(string id)
|
||||
{
|
||||
if (!(Codec is IHasDirectory dirCodec))
|
||||
@@ -625,7 +644,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
dirCodec.GetDirectoryFolderContents(id);
|
||||
}
|
||||
|
||||
private void GetDirectoryRoot(string id = null)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void GetDirectoryRoot()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -653,6 +675,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the parent folder contents
|
||||
/// </summary>
|
||||
private void GetPreviousDirectory()
|
||||
{
|
||||
if (!(Codec is IHasDirectory dirCodec))
|
||||
@@ -663,11 +688,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
dirCodec.GetDirectoryParentFolderContents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for codec changes
|
||||
/// </summary>
|
||||
private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
SendFullStatus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void SendIsReady()
|
||||
{
|
||||
try
|
||||
@@ -688,9 +719,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status of the video codec.
|
||||
/// Helper method to build call status for vtc
|
||||
/// </summary>
|
||||
/// <returns> The current status of the video codec.</returns>
|
||||
/// <returns></returns>
|
||||
protected VideoCodecBaseStateMessage GetStatus()
|
||||
{
|
||||
try
|
||||
@@ -749,18 +780,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the full status of the codec.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier for the status message.</param>
|
||||
protected virtual void SendFullStatus(string id = null)
|
||||
protected virtual void SendFullStatus()
|
||||
{
|
||||
if (!Codec.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => PostStatusMessage(GetStatus(), id));
|
||||
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(GetStatus()));
|
||||
}
|
||||
|
||||
private void PostReceivingContent(bool receivingContent)
|
||||
@@ -773,8 +800,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
};
|
||||
|
||||
PostStatusMessage(state);
|
||||
}
|
||||
catch (Exception ex)
|
||||
} catch(Exception ex)
|
||||
{
|
||||
this.LogError(ex, "Error posting receiving content");
|
||||
}
|
||||
@@ -798,6 +824,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void PostCameraMode()
|
||||
{
|
||||
try
|
||||
@@ -899,324 +928,164 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
public class VideoCodecBaseStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The list of active calls on the codec.
|
||||
/// </summary>
|
||||
[JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CodecActiveCallItem> Calls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current mode of the camera.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CameraMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera self-view is enabled.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraSelfView", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraSelfViewIsOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status of the cameras.
|
||||
/// </summary>
|
||||
[JsonProperty("cameras", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CameraStatus Cameras { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera supports auto mode.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraSupportsAutoMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraSupportsAutoMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera supports off mode.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraSupportsOffMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current dial string for the codec.
|
||||
/// </summary>
|
||||
[JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CurrentDialString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current directory for the codec.
|
||||
/// </summary>
|
||||
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CodecDirectory CurrentDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the selected folder name in the directory.
|
||||
/// </summary>
|
||||
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string DirectorySelectedFolderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec has active camera streams.
|
||||
/// </summary>
|
||||
[JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasCameras { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec has a directory.
|
||||
/// </summary>
|
||||
[JsonProperty("hasDirectory", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec supports directory search functionality.
|
||||
/// </summary>
|
||||
[JsonProperty("hasDirectorySearch", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasDirectorySearch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec has presets.
|
||||
/// </summary>
|
||||
[JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasPresets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec has recent calls.
|
||||
/// </summary>
|
||||
[JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasRecents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the initial phonebook sync is complete.
|
||||
/// </summary>
|
||||
[JsonProperty("initialPhonebookSyncComplete", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? InitialPhonebookSyncComplete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information about the video codec.
|
||||
/// </summary>
|
||||
[JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public VideoCodecInfo Info { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec is currently in a call.
|
||||
/// </summary>
|
||||
[JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsInCall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec is ready.
|
||||
/// </summary>
|
||||
[JsonProperty("isReady", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsReady { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec is a Zoom Room.
|
||||
/// </summary>
|
||||
[JsonProperty("isZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsZoomRoom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the meeting information for the codec, if available.
|
||||
/// </summary>
|
||||
[JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MeetingInfo MeetingInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of presets for the codec.
|
||||
/// </summary>
|
||||
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CodecRoomPreset> Presets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the privacy mode is currently enabled.
|
||||
/// </summary>
|
||||
[JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? PrivacyModeIsOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec is currently receiving content.
|
||||
/// </summary>
|
||||
[JsonProperty("receivingContent", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? ReceivingContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of recent calls for the codec, if available.
|
||||
/// </summary>
|
||||
[JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CodecCallHistory.CallHistoryEntry> RecentCalls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec is currently sharing content.
|
||||
/// </summary>
|
||||
[JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? SharingContentIsOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source of the shared content, if available.
|
||||
/// </summary>
|
||||
[JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string SharingSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the cameras should be shown when not in a call.
|
||||
/// </summary>
|
||||
[JsonProperty("showCamerasWhenNotInCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? ShowCamerasWhenNotInCall { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the self-view is shown by default.
|
||||
/// </summary>
|
||||
[JsonProperty("showSelfViewByDefault", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? ShowSelfViewByDefault { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec is currently in standby mode.
|
||||
/// </summary>
|
||||
[JsonProperty("standbyIsOn", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? StandbyIsOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the codec supports ad-hoc meetings.
|
||||
/// </summary>
|
||||
[JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? SupportsAdHocMeeting { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the status of the camera.
|
||||
/// </summary>
|
||||
public class CameraStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the camera manual control is supported.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraManualIsSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera auto control is supported.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraAutoIsSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera off control is supported.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CameraOffIsSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the current mode of the camera.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string CameraMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the list of cameras available.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CameraBase> Cameras { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the currently selected camera.
|
||||
/// </summary>
|
||||
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Camera SelectedCamera { get; set; }
|
||||
public Camera SelectedCamera { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a camera in the video codec system.
|
||||
/// </summary>
|
||||
public class Camera
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier for the camera.
|
||||
/// </summary>
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the camera.
|
||||
/// </summary>
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera is a far-end camera.
|
||||
/// </summary>
|
||||
[JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IsFarEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the capabilities of the camera.
|
||||
/// </summary>
|
||||
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CameraCapabilities Capabilities { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the capabilities of the camera.
|
||||
/// </summary>
|
||||
public class CameraCapabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can pan.
|
||||
/// </summary>
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanPan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can tilt.
|
||||
/// </summary>
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanTilt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can zoom.
|
||||
/// </summary>
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanZoom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can focus.
|
||||
/// </summary>
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? CanFocus { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a video codec event message.
|
||||
/// </summary>
|
||||
public class VideoCodecBaseEventMessage : DeviceEventMessageBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a password prompt event message.
|
||||
/// </summary>
|
||||
public class PasswordPromptEventMessage : VideoCodecBaseEventMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// The message to display in the password prompt.
|
||||
/// </summary>
|
||||
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the last password attempt was incorrect.
|
||||
/// </summary>
|
||||
[JsonProperty("lastAttemptWasIncorrect", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool LastAttemptWasIncorrect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the login attempt failed.
|
||||
/// </summary>
|
||||
[JsonProperty("loginAttemptFailed", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool LoginAttemptFailed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the login attempt was cancelled.
|
||||
/// </summary>
|
||||
[JsonProperty("loginAttemptCancelled", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool LoginAttemptCancelled { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,26 +4,14 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.AppServer.Messengers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mobile control message that can be sent between clients and the system
|
||||
/// </summary>
|
||||
public class MobileControlMessage : IMobileControlMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the message type/path for routing
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client ID this message is intended for (null for broadcast)
|
||||
/// </summary>
|
||||
[JsonProperty("clientId")]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the JSON content of the message
|
||||
/// </summary>
|
||||
[JsonProperty("content")]
|
||||
public JToken Content { get; set; }
|
||||
}
|
||||
|
||||
@@ -2,15 +2,8 @@
|
||||
|
||||
namespace PepperDash.Essentials.AppServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic container for simple mobile control message content with a single value
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value contained in the message</typeparam>
|
||||
public class MobileControlSimpleContent<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the message content
|
||||
/// </summary>
|
||||
[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public T Value { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core.Queues;
|
||||
using PepperDash.Essentials.WebSocketServer;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class MessageToClients : IQueueMessage
|
||||
{
|
||||
private readonly MobileControlWebsocketServer _server;
|
||||
private readonly object msgToSend;
|
||||
|
||||
public MessageToClients(object msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
public MessageToClients(DeviceStateMessageBase msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
#region Implementation of IQueueMessage
|
||||
|
||||
public void Dispatch()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_server == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Server is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
|
||||
|
||||
var clientSpecificMessage = msgToSend as MobileControlMessage;
|
||||
if (clientSpecificMessage.ClientId != null)
|
||||
{
|
||||
var clientId = clientSpecificMessage.ClientId;
|
||||
|
||||
_server.LogVerbose("Message TX To client {clientId} Message: {message}", clientId, message);
|
||||
|
||||
_server.SendMessageToClient(clientId, message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_server.SendMessageToAllClients(message);
|
||||
|
||||
_server.LogVerbose("Message TX To all clients: {message}", message);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
//Swallowing this exception, as it occurs on shutdown and there's no need to print out a scary stack trace
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the Transmit Processor");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.Net.Http;
|
||||
using Crestron.SimplSharp.WebScripting;
|
||||
@@ -36,6 +30,12 @@ using PepperDash.Essentials.RoomBridges;
|
||||
using PepperDash.Essentials.Services;
|
||||
using PepperDash.Essentials.WebApiHandlers;
|
||||
using PepperDash.Essentials.WebSocketServer;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using WebSocketSharp;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
@@ -570,7 +570,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
this.LogVerbose(
|
||||
"Adding ISetTopBoxControlMessenger for {deviceKey}"
|
||||
);
|
||||
);
|
||||
|
||||
var messenger = new ISetTopBoxControlsMessenger(
|
||||
$"{device.Key}-stb-{Key}",
|
||||
@@ -587,7 +587,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
this.LogVerbose(
|
||||
"Adding IChannelMessenger for {deviceKey}", device.Key
|
||||
);
|
||||
);
|
||||
|
||||
var messenger = new IChannelMessenger(
|
||||
$"{device.Key}-channel-{Key}",
|
||||
@@ -602,7 +602,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (device is IColor colorDevice)
|
||||
{
|
||||
this.LogVerbose("Adding IColorMessenger for {deviceKey}", device.Key);
|
||||
this.LogVerbose("Adding IColorMessenger for {deviceKey}", device.Key);
|
||||
|
||||
var messenger = new IColorMessenger(
|
||||
$"{device.Key}-color-{Key}",
|
||||
@@ -617,7 +617,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (device is IDPad dPadDevice)
|
||||
{
|
||||
this.LogVerbose("Adding IDPadMessenger for {deviceKey}", device.Key);
|
||||
this.LogVerbose("Adding IDPadMessenger for {deviceKey}", device.Key);
|
||||
|
||||
var messenger = new IDPadMessenger(
|
||||
$"{device.Key}-dPad-{Key}",
|
||||
@@ -632,7 +632,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (device is INumericKeypad nkDevice)
|
||||
{
|
||||
this.LogVerbose("Adding INumericKeyapdMessenger for {deviceKey}", device.Key);
|
||||
this.LogVerbose("Adding INumericKeyapdMessenger for {deviceKey}", device.Key);
|
||||
|
||||
var messenger = new INumericKeypadMessenger(
|
||||
$"{device.Key}-numericKeypad-{Key}",
|
||||
@@ -647,7 +647,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (device is IHasPowerControl pcDevice)
|
||||
{
|
||||
this.LogVerbose("Adding IHasPowerControlMessenger for {deviceKey}", device.Key);
|
||||
this.LogVerbose("Adding IHasPowerControlMessenger for {deviceKey}", device.Key);
|
||||
|
||||
var messenger = new IHasPowerMessenger(
|
||||
$"{device.Key}-powerControl-{Key}",
|
||||
@@ -681,7 +681,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
this.LogVerbose(
|
||||
"Adding ITransportMessenger for {deviceKey}", device.Key
|
||||
);
|
||||
);
|
||||
|
||||
var messenger = new ITransportMessenger(
|
||||
$"{device.Key}-transport-{Key}",
|
||||
@@ -1619,12 +1619,12 @@ Mobile Control Direct Server Information:
|
||||
Tokens Defined: {0}
|
||||
Clients Connected: {1}
|
||||
",
|
||||
_directServer.UiClientContexts.Count,
|
||||
_directServer.UiClients.Count,
|
||||
_directServer.ConnectedUiClientsCount
|
||||
);
|
||||
|
||||
var clientNo = 1;
|
||||
foreach (var clientContext in _directServer.UiClientContexts)
|
||||
foreach (var clientContext in _directServer.UiClients)
|
||||
{
|
||||
var isAlive = false;
|
||||
var duration = "Not Connected";
|
||||
@@ -2238,7 +2238,7 @@ Mobile Control Direct Server Infromation:
|
||||
{
|
||||
this.LogInformation("-- Warning: Incoming message has no registered handler {type}", message.Type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var handler in handlers)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using Newtonsoft.Json;
|
||||
@@ -10,64 +14,105 @@ using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceInfo;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
//public interface IMobileControlTouchpanelController
|
||||
//{
|
||||
// StringFeedback AppUrlFeedback { get; }
|
||||
// string DefaultRoomKey { get; }
|
||||
// string DeviceKey { get; }
|
||||
//}
|
||||
|
||||
|
||||
public class MobileControlTouchpanelController : TouchpanelBase, IHasFeedback, ITswAppControl, ITswZoomControl, IDeviceInfoProvider, IMobileControlTouchpanelController, ITheme
|
||||
/// <summary>
|
||||
/// Mobile Control touchpanel controller that provides app control, Zoom integration,
|
||||
/// and mobile control functionality for Crestron touchpanels.
|
||||
/// </summary>
|
||||
public class MobileControlTouchpanelController : TouchpanelBase, IHasFeedback, ITswAppControl, ITswZoomControl, IDeviceInfoProvider, IMobileControlCrestronTouchpanelController, ITheme
|
||||
{
|
||||
private readonly MobileControlTouchpanelProperties localConfig;
|
||||
private IMobileControlRoomMessenger _bridge;
|
||||
|
||||
private string _appUrl;
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback for the current application URL.
|
||||
/// </summary>
|
||||
public StringFeedback AppUrlFeedback { get; private set; }
|
||||
|
||||
private readonly StringFeedback QrCodeUrlFeedback;
|
||||
private readonly StringFeedback McServerUrlFeedback;
|
||||
private readonly StringFeedback UserCodeFeedback;
|
||||
|
||||
private readonly BoolFeedback _appOpenFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether an application is currently open on the touchpanel.
|
||||
/// </summary>
|
||||
public BoolFeedback AppOpenFeedback => _appOpenFeedback;
|
||||
|
||||
private readonly BoolFeedback _zoomIncomingCallFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether there is an incoming Zoom call.
|
||||
/// </summary>
|
||||
public BoolFeedback ZoomIncomingCallFeedback => _zoomIncomingCallFeedback;
|
||||
|
||||
private readonly BoolFeedback _zoomInCallFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when device information changes.
|
||||
/// </summary>
|
||||
public event DeviceInfoChangeHandler DeviceInfoChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback indicating whether a Zoom call is currently active.
|
||||
/// </summary>
|
||||
public BoolFeedback ZoomInCallFeedback => _zoomInCallFeedback;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of feedback objects for this touchpanel controller.
|
||||
/// </summary>
|
||||
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of Zoom-related feedback objects.
|
||||
/// </summary>
|
||||
public FeedbackCollection<Feedback> ZoomFeedbacks { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default room key for this touchpanel controller.
|
||||
/// </summary>
|
||||
public string DefaultRoomKey => _config.DefaultRoomKey;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to use direct server communication.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current theme for the touchpanel interface.
|
||||
/// </summary>
|
||||
public string Theme => localConfig.Theme;
|
||||
|
||||
/// <summary>
|
||||
/// Gets feedback for the current theme setting.
|
||||
/// </summary>
|
||||
public StringFeedback ThemeFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets device information including MAC address and IP address.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
localConfig = config;
|
||||
@@ -139,6 +184,10 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
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)
|
||||
{
|
||||
localConfig.Theme = theme;
|
||||
@@ -271,6 +320,11 @@ 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()
|
||||
{
|
||||
var appMessenger = new ITswAppControlMessenger($"appControlMessenger-{Key}", $"/device/{Key}", this);
|
||||
@@ -300,12 +354,20 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
AppUrlFeedback.LinkInputSig(Panel.StringInput[1]);
|
||||
@@ -366,6 +428,10 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
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)
|
||||
{
|
||||
_appUrl = url;
|
||||
@@ -391,6 +457,9 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides the currently open application on the touchpanel.
|
||||
/// </summary>
|
||||
public void HideOpenApp()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
@@ -406,6 +475,9 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens an application on the touchpanel. Note: X60 panels do not support Zoom app opening.
|
||||
/// </summary>
|
||||
public void OpenApp()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
@@ -421,6 +493,9 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the currently open application on the touchpanel.
|
||||
/// </summary>
|
||||
public void CloseOpenApp()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
@@ -436,6 +511,9 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ends the current Zoom call on the touchpanel.
|
||||
/// </summary>
|
||||
public void EndZoomCall()
|
||||
{
|
||||
if (Panel is TswX70Base x70Panel)
|
||||
@@ -451,6 +529,10 @@ 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()
|
||||
{
|
||||
if (Panel is TswXX70Base x70Panel)
|
||||
@@ -487,14 +569,27 @@ 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>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MobileControlTouchpanelControllerFactory class.
|
||||
/// Sets up supported device type names and minimum framework version requirements.
|
||||
/// </summary>
|
||||
public MobileControlTouchpanelControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel", "mcdge1000" };
|
||||
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)
|
||||
{
|
||||
var comm = CommFactory.GetControlPropertiesConfig(dc);
|
||||
@@ -557,7 +652,7 @@ namespace PepperDash.Essentials.Touchpanel
|
||||
return new Ts1070(id, Global.ControlSystem);
|
||||
else if (type == "dge1000")
|
||||
return new Dge1000(id, Global.ControlSystem);
|
||||
else
|
||||
else
|
||||
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Warning, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.Core.Queues;
|
||||
using PepperDash.Essentials.WebSocketServer;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using WebSocketSharp;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
@@ -62,4 +65,66 @@ namespace PepperDash.Essentials
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class MessageToClients : IQueueMessage
|
||||
{
|
||||
private readonly MobileControlWebsocketServer _server;
|
||||
private readonly object msgToSend;
|
||||
|
||||
public MessageToClients(object msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
public MessageToClients(DeviceStateMessageBase msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
#region Implementation of IQueueMessage
|
||||
|
||||
public void Dispatch()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_server == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Server is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
|
||||
|
||||
var clientSpecificMessage = msgToSend as MobileControlMessage;
|
||||
if (clientSpecificMessage.ClientId != null)
|
||||
{
|
||||
var clientId = clientSpecificMessage.ClientId;
|
||||
|
||||
_server.LogVerbose("Message TX To client {clientId} Message: {message}", clientId, message);
|
||||
|
||||
_server.SendMessageToClient(clientId, message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_server.SendMessageToAllClients(message);
|
||||
|
||||
_server.LogVerbose("Message TX To all clients: {message}", message);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
//Swallowing this exception, as it occurs on shutdown and there's no need to print out a scary stack trace
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the Transmit Processor");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp.WebScripting;
|
||||
using Crestron.SimplSharp.WebScripting;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Web.RequestHandlers;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.WebSocketServer;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.WebApiHandlers
|
||||
{
|
||||
@@ -99,13 +99,13 @@ namespace PepperDash.Essentials.WebApiHandlers
|
||||
public int ServerPort => directServer.Port;
|
||||
|
||||
[JsonProperty("tokensDefined")]
|
||||
public int TokensDefined => directServer.UiClientContexts.Count;
|
||||
public int TokensDefined => directServer.UiClients.Count;
|
||||
|
||||
[JsonProperty("clientsConnected")]
|
||||
public int ClientsConnected => directServer.ConnectedUiClientsCount;
|
||||
|
||||
[JsonProperty("clients")]
|
||||
public List<MobileControlDirectClient> Clients => directServer.UiClientContexts.Select((c, i) => { return new MobileControlDirectClient(c, i, directServer.UserAppUrlPrefix); }).ToList();
|
||||
public List<MobileControlDirectClient> Clients => directServer.UiClients.Select((c, i) => { return new MobileControlDirectClient(c, i, directServer.UserAppUrlPrefix); }).ToList();
|
||||
|
||||
public MobileControlDirectServer(MobileControlWebsocketServer server)
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace PepperDash.Essentials.WebApiHandlers
|
||||
|
||||
|
||||
|
||||
if (!server.UiClientContexts.TryGetValue(request.Token, out UiClientContext clientContext))
|
||||
if (!server.UiClients.TryGetValue(request.Token, out UiClientContext clientContext))
|
||||
{
|
||||
var response = new ClientResponse
|
||||
{
|
||||
@@ -131,7 +131,7 @@ namespace PepperDash.Essentials.WebApiHandlers
|
||||
return;
|
||||
}
|
||||
|
||||
server.UiClientContexts.Remove(request.Token);
|
||||
server.UiClients.Remove(request.Token);
|
||||
|
||||
server.UpdateSecret();
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the structure of the join response
|
||||
/// </summary>
|
||||
public class JoinResponse
|
||||
{
|
||||
[JsonProperty("clientId")]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("systemUUid")]
|
||||
public string SystemUuid { get; set; }
|
||||
|
||||
[JsonProperty("roomUUid")]
|
||||
public string RoomUuid { get; set; }
|
||||
|
||||
[JsonProperty("config")]
|
||||
public object Config { get; set; }
|
||||
|
||||
[JsonProperty("codeExpires")]
|
||||
public DateTime CodeExpires { get; set; }
|
||||
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode { get; set; }
|
||||
|
||||
[JsonProperty("userAppUrl")]
|
||||
public string UserAppUrl { get; set; }
|
||||
|
||||
[JsonProperty("enableDebug")]
|
||||
public bool EnableDebug { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Independentsoft.Exchange;
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a join token with the associated properties
|
||||
/// </summary>
|
||||
public class JoinToken
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
public string Uuid { get; set; }
|
||||
|
||||
public string TouchpanelKey { get; set; } = "";
|
||||
|
||||
public string Token { get; set; } = null;
|
||||
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
public class MobileControlWebsocketServer : EssentialsDevice
|
||||
{
|
||||
private int nextClientId = 0;
|
||||
private readonly string userAppPath = Global.FilePathPrefix + "mcUserApp" + Global.DirectorySeparator;
|
||||
|
||||
private readonly string localConfigFolderName = "_local-config";
|
||||
@@ -41,9 +40,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
public HttpServer Server => _server;
|
||||
|
||||
public Dictionary<string, UiClientContext> UiClientContexts { get; private set; }
|
||||
|
||||
public Dictionary<string, UiClient> UiClients { get; private set; } = new Dictionary<string, UiClient>();
|
||||
public Dictionary<string, UiClientContext> UiClients { get; private set; }
|
||||
|
||||
private readonly MobileControlSystemController _parent;
|
||||
|
||||
@@ -107,7 +104,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
foreach (var client in UiClientContexts)
|
||||
foreach (var client in UiClients)
|
||||
{
|
||||
if (client.Value.Client != null && client.Value.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
@@ -176,7 +173,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
|
||||
|
||||
UiClientContexts = new Dictionary<string, UiClientContext>();
|
||||
UiClients = new Dictionary<string, UiClientContext>();
|
||||
|
||||
//_joinTokens = new Dictionary<string, JoinToken>();
|
||||
|
||||
@@ -301,8 +298,6 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
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 =>
|
||||
{
|
||||
var token = _secret.Tokens.FirstOrDefault((t) => t.Value.TouchpanelKey.Equals(tp.Key, StringComparison.InvariantCultureIgnoreCase));
|
||||
@@ -324,11 +319,25 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
continue;
|
||||
}
|
||||
|
||||
var appUrl = $"http://{processorIp}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
|
||||
string ip = processorIp;
|
||||
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);
|
||||
|
||||
touchpanel.Messenger.UpdateAppUrl($"http://{processorIp}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}");
|
||||
touchpanel.Messenger.UpdateAppUrl($"http://{ip}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,39 +484,45 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Adding token: {0} for room: {1}", this, token.Key, token.Value.RoomKey);
|
||||
|
||||
if (UiClientContexts == null)
|
||||
if (UiClients == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "UiClients is null", this);
|
||||
UiClientContexts = new Dictionary<string, UiClientContext>();
|
||||
UiClients = new Dictionary<string, UiClientContext>();
|
||||
}
|
||||
|
||||
UiClientContexts.Add(token.Key, new UiClientContext(token.Value));
|
||||
UiClients.Add(token.Key, new UiClientContext(token.Value));
|
||||
}
|
||||
}
|
||||
|
||||
if (UiClientContexts.Count > 0)
|
||||
if (UiClients.Count > 0)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Restored {uiClientCount} UiClients from secrets data", this, UiClientContexts.Count);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Restored {uiClientCount} UiClients from secrets data", this, UiClients.Count);
|
||||
|
||||
foreach (var client in UiClientContexts)
|
||||
foreach (var client in UiClients)
|
||||
{
|
||||
var key = client.Key;
|
||||
var path = _wsPath + key;
|
||||
var roomKey = client.Value.Token.RoomKey;
|
||||
var token = client.Value.Token;
|
||||
|
||||
var bridge = _parent.GetRoomBridge(roomKey);
|
||||
|
||||
if (bridge == null)
|
||||
{
|
||||
this.LogWarning("No bridge found for room key: {0}", this, roomKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
_server.AddWebSocketService(path, () =>
|
||||
{
|
||||
return InitializeUiClient(token, bridge);
|
||||
var c = new UiClient();
|
||||
Debug.LogMessage(LogEventLevel.Debug, "Constructing UiClient with id: {key}", this, key);
|
||||
|
||||
c.Controller = _parent;
|
||||
c.RoomKey = roomKey;
|
||||
UiClients[key].SetClient(c);
|
||||
return c;
|
||||
});
|
||||
|
||||
|
||||
//_server.WebSocketServices.AddService<UiClient>(path, (c) =>
|
||||
//{
|
||||
// Debug.Console(2, this, "Constructing UiClient with id: {0}", key);
|
||||
// c.Controller = _parent;
|
||||
// c.RoomKey = roomKey;
|
||||
// UiClients[key].SetClient(c);
|
||||
//});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,7 +531,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
Debug.LogMessage(LogEventLevel.Warning, "No secret found");
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Debug, "{uiClientCount} UiClients restored from secrets data", this, UiClientContexts.Count);
|
||||
Debug.LogMessage(LogEventLevel.Debug, "{uiClientCount} UiClients restored from secrets data", this, UiClients.Count);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -540,7 +555,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
_secret.Tokens.Clear();
|
||||
|
||||
foreach (var uiClientContext in UiClientContexts)
|
||||
foreach (var uiClientContext in UiClients)
|
||||
{
|
||||
_secret.Tokens.Add(uiClientContext.Key, uiClientContext.Value.Token);
|
||||
}
|
||||
@@ -633,50 +648,24 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
private UiClient InitializeUiClient(JoinToken token, MobileControlBridgeBase bridge)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Constructing UiClient with id: {0}", this, token.Id);
|
||||
|
||||
var c = new UiClient(token.Id)
|
||||
{
|
||||
Controller = _parent,
|
||||
RoomKey = bridge.RoomKey
|
||||
};
|
||||
|
||||
UiClients.Add(c.ClientId, c);
|
||||
|
||||
// reset client ID in token for next use
|
||||
token.Id = null;
|
||||
|
||||
c.Context.WebSocket.OnClose += (sender, e) =>
|
||||
{
|
||||
if (UiClients.ContainsKey(c.ClientId))
|
||||
{
|
||||
UiClients.Remove(c.ClientId);
|
||||
}
|
||||
};
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public (string, string) GenerateClientToken(MobileControlBridgeBase bridge, string touchPanelKey = "")
|
||||
{
|
||||
var key = Guid.NewGuid().ToString();
|
||||
|
||||
var token = new JoinToken { Code = bridge.UserCode, RoomKey = bridge.RoomKey, Uuid = _parent.SystemUuid, TouchpanelKey = touchPanelKey };
|
||||
|
||||
UiClientContexts.Add(key, new UiClientContext(token));
|
||||
UiClients.Add(key, new UiClientContext(token));
|
||||
|
||||
var path = _wsPath + key;
|
||||
|
||||
_server.AddWebSocketService(path, () =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(token.Id))
|
||||
{
|
||||
token.Id = nextClientId++.ToString();
|
||||
}
|
||||
|
||||
return InitializeUiClient(token, bridge);
|
||||
var c = new UiClient();
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Constructing UiClient with id: {0}", this, key);
|
||||
c.Controller = _parent;
|
||||
c.RoomKey = bridge.RoomKey;
|
||||
UiClients[key].SetClient(c);
|
||||
return c;
|
||||
});
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Added new WebSocket UiClient service at path: {path}", this, path);
|
||||
@@ -706,7 +695,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var client in UiClientContexts)
|
||||
foreach (var client in UiClients)
|
||||
{
|
||||
if (client.Value.Client != null && client.Value.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
@@ -724,7 +713,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
UiClientContexts.Clear();
|
||||
UiClients.Clear();
|
||||
|
||||
UpdateSecret();
|
||||
}
|
||||
@@ -743,9 +732,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
var key = s;
|
||||
|
||||
if (UiClientContexts.ContainsKey(key))
|
||||
if (UiClients.ContainsKey(key))
|
||||
{
|
||||
var uiClientContext = UiClientContexts[key];
|
||||
var uiClientContext = UiClients[key];
|
||||
|
||||
if (uiClientContext.Client != null && uiClientContext.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
@@ -755,7 +744,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
var path = _wsPath + key;
|
||||
if (_server.RemoveWebSocketService(path))
|
||||
{
|
||||
UiClientContexts.Remove(key);
|
||||
UiClients.Remove(key);
|
||||
|
||||
UpdateSecret();
|
||||
|
||||
@@ -779,9 +768,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Mobile Control UI Client Info:\r");
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse(string.Format("{0} clients found:\r", UiClientContexts.Count));
|
||||
CrestronConsole.ConsoleCommandResponse(string.Format("{0} clients found:\r", UiClients.Count));
|
||||
|
||||
foreach (var client in UiClientContexts)
|
||||
foreach (var client in UiClients)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(string.Format("RoomKey: {0} Token: {1}\r", client.Value.Token.RoomKey, client.Key));
|
||||
}
|
||||
@@ -791,7 +780,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
if (programEventType == eProgramStatusEventType.Stopping)
|
||||
{
|
||||
foreach (var client in UiClientContexts.Values)
|
||||
foreach (var client in UiClients.Values)
|
||||
{
|
||||
if (client.Client != null && client.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
@@ -930,7 +919,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
this.LogVerbose("Join Room Request with token: {token}", token);
|
||||
|
||||
|
||||
if (UiClientContexts.TryGetValue(token, out UiClientContext clientContext))
|
||||
if (UiClients.TryGetValue(token, out UiClientContext clientContext))
|
||||
{
|
||||
var bridge = _parent.GetRoomBridge(clientContext.Token.RoomKey);
|
||||
|
||||
@@ -939,12 +928,10 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "application/json";
|
||||
|
||||
clientContext.Token.Id = nextClientId++.ToString();
|
||||
|
||||
// Construct the response object
|
||||
JoinResponse jRes = new JoinResponse
|
||||
{
|
||||
ClientId = clientContext.Token.Id,
|
||||
ClientId = token,
|
||||
RoomKey = bridge.RoomKey,
|
||||
SystemUuid = _parent.SystemUuid,
|
||||
RoomUuid = _parent.SystemUuid,
|
||||
@@ -1162,14 +1149,12 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
/// <param name="message"></param>
|
||||
public void SendMessageToAllClients(string message)
|
||||
{
|
||||
foreach (var client in UiClients.Values)
|
||||
foreach (var clientContext in UiClients.Values)
|
||||
{
|
||||
if (!client.Context.WebSocket.IsAlive)
|
||||
if (clientContext.Client != null && clientContext.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
continue;
|
||||
clientContext.Client.Context.WebSocket.Send(message);
|
||||
}
|
||||
|
||||
client.Context.WebSocket.Send(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,25 +1165,129 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
/// <param name="message"></param>
|
||||
public void SendMessageToClient(object clientId, string message)
|
||||
{
|
||||
if (clientId == null || !(clientId is string))
|
||||
if (clientId == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UiClients.TryGetValue((string)clientId, out UiClient client))
|
||||
if (UiClients.TryGetValue((string)clientId, out UiClientContext clientContext))
|
||||
{
|
||||
if (clientContext.Client != null)
|
||||
{
|
||||
var socket = clientContext.Client.Context.WebSocket;
|
||||
|
||||
if (socket.IsAlive)
|
||||
{
|
||||
socket.Send(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogWarning("Unable to find client with ID: {clientId}", clientId);
|
||||
return;
|
||||
}
|
||||
|
||||
var socket = client.Context.WebSocket;
|
||||
|
||||
if (!socket.IsAlive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
socket.Send(message);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class to describe the server version info
|
||||
/// </summary>
|
||||
public class Version
|
||||
{
|
||||
[JsonProperty("serverVersion")]
|
||||
public string ServerVersion { get; set; }
|
||||
|
||||
[JsonProperty("serverIsRunningOnProcessorHardware")]
|
||||
public bool ServerIsRunningOnProcessorHardware { get; private set; }
|
||||
|
||||
public Version()
|
||||
{
|
||||
ServerIsRunningOnProcessorHardware = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an instance of a UiClient and the associated Token
|
||||
/// </summary>
|
||||
public class UiClientContext
|
||||
{
|
||||
public UiClient Client { get; private set; }
|
||||
public JoinToken Token { get; private set; }
|
||||
|
||||
public UiClientContext(JoinToken token)
|
||||
{
|
||||
Token = token;
|
||||
}
|
||||
|
||||
public void SetClient(UiClient client)
|
||||
{
|
||||
Client = client;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the data structure for the grant code and UiClient tokens to be stored in the secrets manager
|
||||
/// </summary>
|
||||
public class ServerTokenSecrets
|
||||
{
|
||||
public string GrantCode { get; set; }
|
||||
|
||||
public Dictionary<string, JoinToken> Tokens { get; set; }
|
||||
|
||||
public ServerTokenSecrets(string grantCode)
|
||||
{
|
||||
GrantCode = grantCode;
|
||||
Tokens = new Dictionary<string, JoinToken>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a join token with the associated properties
|
||||
/// </summary>
|
||||
public class JoinToken
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
public string Uuid { get; set; }
|
||||
|
||||
public string TouchpanelKey { get; set; } = "";
|
||||
|
||||
public string Token { get; set; } = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the structure of the join response
|
||||
/// </summary>
|
||||
public class JoinResponse
|
||||
{
|
||||
[JsonProperty("clientId")]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("systemUUid")]
|
||||
public string SystemUuid { get; set; }
|
||||
|
||||
[JsonProperty("roomUUid")]
|
||||
public string RoomUuid { get; set; }
|
||||
|
||||
[JsonProperty("config")]
|
||||
public object Config { get; set; }
|
||||
|
||||
[JsonProperty("codeExpires")]
|
||||
public DateTime CodeExpires { get; set; }
|
||||
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode { get; set; }
|
||||
|
||||
[JsonProperty("userAppUrl")]
|
||||
public string UserAppUrl { get; set; }
|
||||
|
||||
[JsonProperty("enableDebug")]
|
||||
public bool EnableDebug { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the data structure for the grant code and UiClient tokens to be stored in the secrets manager
|
||||
/// </summary>
|
||||
public class ServerTokenSecrets
|
||||
{
|
||||
public string GrantCode { get; set; }
|
||||
|
||||
public Dictionary<string, JoinToken> Tokens { get; set; }
|
||||
|
||||
public ServerTokenSecrets(string grantCode)
|
||||
{
|
||||
GrantCode = grantCode;
|
||||
Tokens = new Dictionary<string, JoinToken>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
using PepperDash.Essentials.RoomBridges;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using WebSocketSharp;
|
||||
using WebSocketSharp.Server;
|
||||
using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the behaviour to associate with a UiClient for WebSocket communication
|
||||
/// </summary>
|
||||
@@ -22,10 +22,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
public string ClientId
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
private string _clientId;
|
||||
|
||||
private DateTime _connectionTime;
|
||||
|
||||
@@ -44,9 +41,9 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
}
|
||||
}
|
||||
|
||||
public UiClient(string clientId)
|
||||
public UiClient()
|
||||
{
|
||||
ClientId = clientId;
|
||||
|
||||
}
|
||||
|
||||
protected override void OnOpen()
|
||||
@@ -64,7 +61,8 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
return;
|
||||
}
|
||||
|
||||
var clientId = ClientId;
|
||||
var clientId = match.Groups[1].Value;
|
||||
_clientId = clientId;
|
||||
|
||||
if (Controller == null)
|
||||
{
|
||||
@@ -98,7 +96,7 @@ namespace PepperDash.Essentials.WebSocketServer
|
||||
|
||||
private void Bridge_UserCodeChanged(object sender, EventArgs e)
|
||||
{
|
||||
SendUserCodeToClient((MobileControlEssentialsRoomBridge)sender, ClientId);
|
||||
SendUserCodeToClient((MobileControlEssentialsRoomBridge)sender, _clientId);
|
||||
}
|
||||
|
||||
private void SendUserCodeToClient(MobileControlBridgeBase bridge, string clientId)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an instance of a UiClient and the associated Token
|
||||
/// </summary>
|
||||
public class UiClientContext
|
||||
{
|
||||
public UiClient Client { get; private set; }
|
||||
public JoinToken Token { get; private set; }
|
||||
|
||||
public UiClientContext(JoinToken token)
|
||||
{
|
||||
Token = token;
|
||||
}
|
||||
|
||||
public void SetClient(UiClient client)
|
||||
{
|
||||
Client = client;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to describe the server version info
|
||||
/// </summary>
|
||||
public class Version
|
||||
{
|
||||
[JsonProperty("serverVersion")]
|
||||
public string ServerVersion { get; set; }
|
||||
|
||||
[JsonProperty("serverIsRunningOnProcessorHardware")]
|
||||
public bool ServerIsRunningOnProcessorHardware { get; private set; }
|
||||
|
||||
public Version()
|
||||
{
|
||||
ServerIsRunningOnProcessorHardware = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user