feat: all fullStatus messages are now client-specific

This commit is contained in:
Andrew Welker
2025-07-10 12:44:56 -05:00
parent 505067f38f
commit af82ba2351
29 changed files with 457 additions and 205 deletions

View File

@@ -38,7 +38,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject()); AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject(id));
AddAction("/dial", (id, content) => AddAction("/dial", (id, content) =>
{ {
var msg = content.ToObject<MobileControlSimpleContent<string>>(); var msg = content.ToObject<MobileControlSimpleContent<string>>();
@@ -101,7 +101,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// Helper method to build call status for vtc /// Helper method to build call status for vtc
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private void SendAtcFullMessageObject() private void SendAtcFullMessageObject(string id = null)
{ {
var info = Codec.CodecInfo; var info = Codec.CodecInfo;
@@ -113,7 +113,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
phoneNumber = info.PhoneNumber phoneNumber = info.PhoneNumber
} }
}) }), clientId: id
); );
} }
} }

View File

@@ -57,7 +57,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject()); AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject(id));
if (Camera is IHasCameraPtzControl ptzCamera) if (Camera is IHasCameraPtzControl ptzCamera)
@@ -174,7 +174,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Helper method to update the full status of the camera /// Helper method to update the full status of the camera
/// </summary> /// </summary>
private void SendCameraFullMessageObject() private void SendCameraFullMessageObject(string id = null)
{ {
var presetList = new List<CameraPreset>(); var presetList = new List<CameraPreset>();
@@ -189,7 +189,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
cameraMode = GetCameraMode(), cameraMode = GetCameraMode(),
hasPresets = Camera is IHasCameraPresets, hasPresets = Camera is IHasCameraPresets,
presets = presetList presets = presetList
}) }), clientId: id
); );
} }

View File

@@ -1,4 +1,5 @@
using System.Timers; using System.Timers;
using Independentsoft.Exchange;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
@@ -70,7 +71,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
{ {
DeviceInfo = _deviceInfoProvider.DeviceInfo DeviceInfo = _deviceInfoProvider.DeviceInfo
})); }, id));
AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo()); AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
} }

View File

@@ -29,12 +29,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
_presetsDevice = presetsDevice; _presetsDevice = presetsDevice;
} }
private void SendPresets() private void SendPresets(string id = null)
{ {
PostStatusMessage(new PresetStateMessage PostStatusMessage(new PresetStateMessage
{ {
Favorites = _presetsDevice.TvPresets.PresetsList Favorites = _presetsDevice.TvPresets.PresetsList
}); }, id);
} }
private void RecallPreset(ISetTopBoxNumericKeypad device, string channel) private void RecallPreset(ISetTopBoxNumericKeypad device, string channel)
@@ -62,7 +62,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
this.LogInformation("getting full status for client {id}", id); this.LogInformation("getting full status for client {id}", id);
try try
{ {
SendPresets(); SendPresets(id);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -27,7 +27,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
_localDevice = device; _localDevice = device;
} }
private void SendStatus() private void SendStatus(string id = null)
{ {
try try
{ {
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
messageObj.Volume.Units = volumeAdvanced.Units; messageObj.Volume.Units = volumeAdvanced.Units;
} }
PostStatusMessage(messageObj); PostStatusMessage(messageObj, id);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -64,7 +64,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/fullStatus", (id, content) => SendStatus()); AddAction("/fullStatus", (id, content) => SendStatus(id));
AddAction("/level", (id, content) => AddAction("/level", (id, content) =>
{ {

View File

@@ -22,14 +22,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var state = new DeviceStateMessageBase(); var state = new DeviceStateMessageBase();
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }
} }

View File

@@ -42,7 +42,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline, IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
Status = _communicationMonitor.CommunicationMonitor.Status Status = _communicationMonitor.CommunicationMonitor.Status
} }
}); }, id);
}); });
_communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) => _communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) =>

View File

@@ -40,7 +40,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
Presets = device.Presets Presets = device.Presets
}; };
PostStatusMessage(message); PostStatusMessage(message, id);
}); });
AddAction("/recallPreset", (id, content) => AddAction("/recallPreset", (id, content) =>

View File

@@ -1,17 +1,17 @@
using Newtonsoft.Json; using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary> /// <summary>
/// Provides messaging functionality for managing room combination scenarios and partition states in an <see /// 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 /// cref="IEssentialsRoomCombiner"/> instance. Enables external systems to interact with the room combiner via
/// predefined actions and status updates. /// predefined actions and status updates.
/// </summary> /// </summary>
/// <remarks>This class facilitates communication with an <see cref="IEssentialsRoomCombiner"/> by /// <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 /// 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; private readonly IEssentialsRoomCombiner _roomCombiner;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IEssentialsRoomCombinerMessenger"/> class, which facilitates /// Initializes a new instance of the <see cref="IEssentialsRoomCombinerMessenger"/> class, which facilitates
/// messaging for an <see cref="IEssentialsRoomCombiner"/> instance. /// messaging for an <see cref="IEssentialsRoomCombiner"/> instance.
/// </summary> /// </summary>
/// <remarks>This class is designed to enable communication and interaction with an <see /// <remarks>This class is designed to enable communication and interaction with an <see
/// cref="IEssentialsRoomCombiner"/> through the specified messaging path. Ensure that the <paramref /// cref="IEssentialsRoomCombiner"/> through the specified messaging path. Ensure that the <paramref
/// name="roomCombiner"/> parameter is not null when creating an instance.</remarks> /// name="roomCombiner"/> parameter is not null when creating an instance.</remarks>
/// <param name="key">The unique key identifying this messenger instance.</param> /// <param name="key">The unique key identifying this messenger instance.</param>
/// <param name="messagePath">The path used for messaging operations.</param> /// <param name="messagePath">The path used for messaging operations.</param>
/// <param name="roomCombiner">The <see cref="IEssentialsRoomCombiner"/> instance associated with this messenger.</param> /// <param name="roomCombiner">The <see cref="IEssentialsRoomCombiner"/> instance associated with this messenger.</param>
public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner) public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner)
: base(key, messagePath, roomCombiner as IKeyName) : base(key, messagePath, roomCombiner as IKeyName)
@@ -37,8 +37,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
_roomCombiner = roomCombiner; _roomCombiner = roomCombiner;
} }
/// <summary> /// <summary>
/// Registers actions and event handlers for managing room combination scenarios and partition states. /// Registers actions and event handlers for managing room combination scenarios and partition states.
/// </summary> /// </summary>
/// <remarks>This method sets up various actions that can be triggered via specific endpoints, /// <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 /// 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> /// partition states.</remarks>
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/setAutoMode", (id, content) => AddAction("/setAutoMode", (id, content) =>
{ {
@@ -120,7 +120,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
try try
{ {
@@ -141,7 +141,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
Partitions = _roomCombiner.Partitions Partitions = _roomCombiner.Partitions
}; };
PostStatusMessage(message); PostStatusMessage(message, id);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -159,47 +159,47 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
/// <summary> /// <summary>
/// Represents the state message for a room combiner system, providing information about the current configuration, /// Represents the state message for a room combiner system, providing information about the current configuration,
/// operational mode, and associated rooms, partitions, and scenarios. /// operational mode, and associated rooms, partitions, and scenarios.
/// </summary> /// </summary>
/// <remarks>This class is used to encapsulate the state of a room combiner system, including its current /// <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 /// 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> /// typically serialized and transmitted to communicate the state of the system.</remarks>
public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase
{ {
/// <summary> /// <summary>
/// Gets or sets a value indicating whether automatic mode is disabled. /// Gets or sets a value indicating whether automatic mode is disabled.
/// </summary> /// </summary>
[JsonProperty("disableAutoMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("disableAutoMode", NullValueHandling = NullValueHandling.Ignore)]
public bool DisableAutoMode { get; set; } public bool DisableAutoMode { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether the system is operating in automatic mode. /// Gets or sets a value indicating whether the system is operating in automatic mode.
/// </summary> /// </summary>
[JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)]
public bool IsInAutoMode { get; set; } public bool IsInAutoMode { get; set; }
/// <summary> /// <summary>
/// Gets or sets the current room combination scenario. /// Gets or sets the current room combination scenario.
/// </summary> /// </summary>
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
public IRoomCombinationScenario CurrentScenario { get; set; } public IRoomCombinationScenario CurrentScenario { get; set; }
/// <summary> /// <summary>
/// Gets or sets the collection of rooms associated with the entity. /// Gets or sets the collection of rooms associated with the entity.
/// </summary> /// </summary>
[JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)]
public List<IKeyName> Rooms { get; set; } public List<IKeyName> Rooms { get; set; }
/// <summary> /// <summary>
/// Gets or sets the collection of room combination scenarios. /// Gets or sets the collection of room combination scenarios.
/// </summary> /// </summary>
[JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)]
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; set; } public List<IRoomCombinationScenario> RoomCombinationScenarios { get; set; }
/// <summary> /// <summary>
/// Gets or sets the collection of partition controllers. /// Gets or sets the collection of partition controllers.
/// </summary> /// </summary>
[JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)]
public List<IPartitionController> Partitions { get; set; } public List<IPartitionController> Partitions { get; set; }

View File

@@ -36,7 +36,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentSource = sourceDevice.CurrentSourceInfo CurrentSource = sourceDevice.CurrentSourceInfo
}; };
PostStatusMessage(message); PostStatusMessage(message, id);
}); });
sourceDevice.CurrentSourceChange += (sender, e) => sourceDevice.CurrentSourceChange += (sender, e) =>

View File

@@ -34,7 +34,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/fullStatus", (id, context) => AddAction("/fullStatus", (id, context) =>
{ {
SendFullStatus(); SendFullStatus(id);
}); });
itemDevice.Inputs.ItemsUpdated += (sender, args) => itemDevice.Inputs.ItemsUpdated += (sender, args) =>
@@ -64,7 +64,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
try try
{ {
@@ -79,7 +79,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
}; };
PostStatusMessage(stateObject); PostStatusMessage(stateObject, id);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@@ -28,14 +28,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Sends the full power control status to connected clients. /// Sends the full power control status to connected clients.
/// </summary> /// </summary>
public void SendFullStatus() public void SendFullStatus(string id = null)
{ {
var messageObj = new PowerControlWithFeedbackStateMessage var messageObj = new PowerControlWithFeedbackStateMessage
{ {
PowerState = _powerControl.PowerIsOnFeedback.BoolValue PowerState = _powerControl.PowerIsOnFeedback.BoolValue
}; };
PostStatusMessage(messageObj); PostStatusMessage(messageObj, id);
} }
/// <summary> /// <summary>
@@ -46,7 +46,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
_powerControl.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; ; _powerControl.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; ;
} }

View File

@@ -34,7 +34,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <inheritdoc /> /// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject()); AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject(id));
} }
private void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e) private void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e)
@@ -58,13 +58,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Helper method to send the full schedule data /// Helper method to send the full schedule data
/// </summary> /// </summary>
private void SendFullScheduleObject() private void SendFullScheduleObject(string id = null)
{ {
PostStatusMessage(new FullScheduleMessage PostStatusMessage(new FullScheduleMessage
{ {
Meetings = ScheduleSource.CodecSchedule.Meetings, Meetings = ScheduleSource.CodecSchedule.Meetings,
MeetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes MeetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes
}); }, id);
} }
} }

View File

@@ -1,7 +1,7 @@
using Newtonsoft.Json; using System;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -19,19 +19,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
device.HumidityFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus()); device.HumidityFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var state = new IHumiditySensorStateMessage var state = new IHumiditySensorStateMessage
{ {
Humidity = string.Format("{0}%", device.HumidityFeedback.UShortValue) Humidity = string.Format("{0}%", device.HumidityFeedback.UShortValue)
}; };
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }

View File

@@ -37,7 +37,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 }) Levels = levelControlsDevice.LevelControlPoints.ToDictionary(kv => kv.Key, kv => new Volume { Level = kv.Value.VolumeLevelFeedback.IntValue, Muted = kv.Value.MuteFeedback.BoolValue })
}; };
PostStatusMessage(message); PostStatusMessage(message, id);
}); });
foreach (var levelControl in levelControlsDevice.LevelControlPoints) foreach (var levelControl in levelControlsDevice.LevelControlPoints)

View File

@@ -45,7 +45,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}; };
PostStatusMessage(message); PostStatusMessage(message, id);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@@ -1,9 +1,9 @@
using Newtonsoft.Json; using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/raise", (id, content) => AddAction("/raise", (id, content) =>
{ {
@@ -50,7 +50,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(JToken.FromObject(state)); PostStatusMessage(JToken.FromObject(state));
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var state = new ScreenLiftStateMessage var state = new ScreenLiftStateMessage
{ {
@@ -59,7 +59,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
DisplayDeviceKey = device.DisplayDeviceKey DisplayDeviceKey = device.DisplayDeviceKey
}; };
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }

View File

@@ -1,12 +1,15 @@
using Newtonsoft.Json; using System;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary>
/// Messenger for routing actions
/// </summary>
public class RunRouteActionMessenger : MessengerBase public class RunRouteActionMessenger : MessengerBase
{ {
/// <summary> /// <summary>
@@ -14,6 +17,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
public IRunRouteAction RoutingDevice { get; private set; } 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) public RunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath)
: base(key, messagePath, routingDevice as IKeyName) : base(key, messagePath, routingDevice as IKeyName)
{ {
@@ -31,9 +41,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
SendRoutingFullMessageObject(); SendRoutingFullMessageObject();
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject()); AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject(id));
AddAction("/source", (id, content) => AddAction("/source", (id, content) =>
{ {
@@ -59,7 +70,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// <summary> /// <summary>
/// Helper method to update full status of the routing device /// Helper method to update full status of the routing device
/// </summary> /// </summary>
private void SendRoutingFullMessageObject() private void SendRoutingFullMessageObject(string id = null)
{ {
if (RoutingDevice is IRoutingSink sinkDevice) if (RoutingDevice is IRoutingSink sinkDevice)
{ {
@@ -71,13 +82,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(new RoutingStateMessage PostStatusMessage(new RoutingStateMessage
{ {
SelectedSourceKey = sourceKey SelectedSourceKey = sourceKey
}); }, id);
} }
} }
} }
/// <summary>
/// Message class for routing state
/// </summary>
public class RoutingStateMessage : DeviceStateMessageBase public class RoutingStateMessage : DeviceStateMessageBase
{ {
/// <summary>
/// Gets or sets the selected source key
/// </summary>
[JsonProperty("selectedSourceKey")] [JsonProperty("selectedSourceKey")]
public string SelectedSourceKey { get; set; } public string SelectedSourceKey { get; set; }
} }

View File

@@ -37,7 +37,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/fullStatus", (id, context) => AddAction("/fullStatus", (id, context) =>
{ {
SendFullStatus(); SendFullStatus(id);
}); });
itemDevice.ItemsUpdated += (sender, args) => itemDevice.ItemsUpdated += (sender, args) =>
@@ -67,7 +67,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
try try
{ {
@@ -79,7 +79,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentItem = itemDevice.CurrentItem CurrentItem = itemDevice.CurrentItem
}; };
PostStatusMessage(stateObject); PostStatusMessage(stateObject, id);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@@ -5,16 +5,26 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary>
/// Messenger for the shutdown prompt timer
/// </summary>
public class IShutdownPromptTimerMessenger : MessengerBase public class IShutdownPromptTimerMessenger : MessengerBase
{ {
private readonly IShutdownPromptTimer _room; 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) public IShutdownPromptTimerMessenger(string key, string messagePath, IShutdownPromptTimer room)
: base(key, messagePath, room as IKeyName) : base(key, messagePath, room as IKeyName)
{ {
_room = room; _room = room;
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/status", (id, content) => AddAction("/status", (id, content) =>
@@ -65,7 +75,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
}; };
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var status = new IShutdownPromptTimerStateMessage var status = new IShutdownPromptTimerStateMessage
{ {
@@ -74,7 +84,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
PercentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue PercentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
}; };
PostStatusMessage(status); PostStatusMessage(status, id);
} }
} }

View File

@@ -1,26 +1,39 @@
using Newtonsoft.Json; using System;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.CrestronIO; using PepperDash.Essentials.Core.CrestronIO;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary>
/// Messenger for ISwitchedOutput devices
/// </summary>
public class ISwitchedOutputMessenger : MessengerBase public class ISwitchedOutputMessenger : MessengerBase
{ {
private readonly ISwitchedOutput device; 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) public ISwitchedOutputMessenger(string key, ISwitchedOutput device, string messagePath)
: base(key, messagePath, device as IKeyName) : base(key, messagePath, device as IKeyName)
{ {
this.device = device; this.device = device;
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/on", (id, content) => AddAction("/on", (id, content) =>
{ {
@@ -39,19 +52,29 @@ namespace PepperDash.Essentials.AppServer.Messengers
device.OutputIsOnFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus()); device.OutputIsOnFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var state = new ISwitchedOutputStateMessage var state = new ISwitchedOutputStateMessage
{ {
IsOn = device.OutputIsOnFeedback.BoolValue IsOn = device.OutputIsOnFeedback.BoolValue
}; };
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }
/// <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 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")] [JsonProperty("isOn")]
public bool IsOn { get; set; } public bool IsOn { get; set; }
} }

View File

@@ -29,7 +29,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/status", (id, content) => AddAction("/status", (id, content) =>
{ {
SendFullStatus(); SendFullStatus(id);
}); });
AddAction("/validateTechPassword", (id, content) => AddAction("/validateTechPassword", (id, content) =>
@@ -62,14 +62,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
}; };
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var status = new ITechPasswordStateMessage var status = new ITechPasswordStateMessage
{ {
TechPasswordLength = _room.TechPasswordLength TechPasswordLength = _room.TechPasswordLength
}; };
PostStatusMessage(status); PostStatusMessage(status, id);
} }
} }

View File

@@ -1,25 +1,37 @@
using Newtonsoft.Json; using System;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using System;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary>
/// Messenger for temperature sensor devices
/// </summary>
public class ITemperatureSensorMessenger : MessengerBase public class ITemperatureSensorMessenger : MessengerBase
{ {
private readonly ITemperatureSensor device; 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) public ITemperatureSensorMessenger(string key, ITemperatureSensor device, string messagePath)
: base(key, messagePath, device as IKeyName) : base(key, messagePath, device as IKeyName)
{ {
this.device = device; this.device = device;
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/setTemperatureUnitsToCelcius", (id, content) => AddAction("/setTemperatureUnitsToCelcius", (id, content) =>
{ {
@@ -35,7 +47,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
device.TemperatureInCFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus()); device.TemperatureInCFeedback.OutputChange += new EventHandler<Core.FeedbackEventArgs>((o, a) => SendFullStatus());
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
// format the temperature to a string with one decimal place // format the temperature to a string with one decimal place
var tempString = string.Format("{0}.{1}", device.TemperatureFeedback.UShortValue / 10, device.TemperatureFeedback.UShortValue % 10); var tempString = string.Format("{0}.{1}", device.TemperatureFeedback.UShortValue / 10, device.TemperatureFeedback.UShortValue % 10);
@@ -46,15 +58,27 @@ namespace PepperDash.Essentials.AppServer.Messengers
TemperatureInCelsius = device.TemperatureInCFeedback.BoolValue TemperatureInCelsius = device.TemperatureInCFeedback.BoolValue
}; };
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }
/// <summary>
/// State message for temperature sensor devices
/// </summary>
public class ITemperatureSensorStateMessage : DeviceStateMessageBase 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")] [JsonProperty("temperature")]
public string Temperature { get; set; } 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")] [JsonProperty("temperatureInCelsius")]
public bool TemperatureInCelsius { get; set; } public bool TemperatureInCelsius { get; set; }
} }

View File

@@ -1,15 +1,25 @@
using Newtonsoft.Json; using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Lighting; using PepperDash.Essentials.Core.Lighting;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
/// <summary>
/// Messenger for lighting scenes devices
/// </summary>
public class ILightingScenesMessenger : MessengerBase public class ILightingScenesMessenger : MessengerBase
{ {
private ILightingScenes lightingScenesDevice; 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) public ILightingScenesMessenger(string key, ILightingScenes device, string messagePath)
: base(key, messagePath, device as IKeyName) : base(key, messagePath, device as IKeyName)
{ {
@@ -28,11 +38,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(state); PostStatusMessage(state);
} }
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/selectScene", (id, content) => AddAction("/selectScene", (id, content) =>
{ {
@@ -40,14 +51,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
lightingScenesDevice.SelectScene(s); lightingScenesDevice.SelectScene(s);
}); });
if(!(lightingScenesDevice is ILightingScenesDynamic lightingScenesDynamic)) if (!(lightingScenesDevice is ILightingScenesDynamic lightingScenesDynamic))
return; return;
lightingScenesDynamic.LightingScenesUpdated += (s, e) => SendFullStatus(); lightingScenesDynamic.LightingScenesUpdated += (s, e) => SendFullStatus();
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var state = new LightingBaseStateMessage var state = new LightingBaseStateMessage
{ {
@@ -55,7 +66,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentLightingScene = lightingScenesDevice.CurrentLightingScene CurrentLightingScene = lightingScenesDevice.CurrentLightingScene
}; };
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }

View File

@@ -1,18 +1,30 @@
using Newtonsoft.Json; using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Logging; using PepperDash.Core.Logging;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers 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 public class RoomEventScheduleMessenger : MessengerBase
{ {
private readonly IRoomEventSchedule _room; 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) public RoomEventScheduleMessenger(string key, string messagePath, IRoomEventSchedule room)
: base(key, messagePath, room as IKeyName) : base(key, messagePath, room as IKeyName)
{ {
@@ -21,6 +33,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
#region Overrides of MessengerBase #region Overrides of MessengerBase
/// <inheritdoc />
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/saveScheduledEvents", (id, content) => SaveScheduledEvents(content.ToObject<List<ScheduledEventConfig>>())); AddAction("/saveScheduledEvents", (id, content) => SaveScheduledEvents(content.ToObject<List<ScheduledEventConfig>>()));
@@ -28,7 +41,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
var events = _room.GetScheduledEvents(); var events = _room.GetScheduledEvents();
SendFullStatus(events); SendFullStatus(events, id);
}); });
_room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents); _room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
@@ -52,11 +65,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
catch (Exception ex) catch (Exception ex)
{ {
this.LogException(ex,"Exception saving event"); this.LogException(ex, "Exception saving event");
} }
} }
private void SendFullStatus(List<ScheduledEventConfig> events) private void SendFullStatus(List<ScheduledEventConfig> events, string id = null)
{ {
var message = new RoomEventScheduleStateMessage var message = new RoomEventScheduleStateMessage
@@ -64,12 +77,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
ScheduleEvents = events, ScheduleEvents = events,
}; };
PostStatusMessage(message); PostStatusMessage(message, id);
} }
} }
/// <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 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")] [JsonProperty("scheduleEvents")]
public List<ScheduledEventConfig> ScheduleEvents { get; set; } public List<ScheduledEventConfig> ScheduleEvents { get; set; }
} }

View File

@@ -33,7 +33,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/shadeUp", (id, content) => AddAction("/shadeUp", (id, content) =>
{ {
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
private void SendFullStatus() private void SendFullStatus(string id = null)
{ {
var state = new ShadeBaseStateMessage(); var state = new ShadeBaseStateMessage();
@@ -96,7 +96,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue; state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue;
} }
PostStatusMessage(state); PostStatusMessage(state, id);
} }
} }

View File

@@ -64,17 +64,17 @@ namespace PepperDash.Essentials.AppServer.Messengers
SendSystemMonitorStatusMessage(); SendSystemMonitorStatusMessage();
} }
private void SendFullStatusMessage() private void SendFullStatusMessage(string id = null)
{ {
SendSystemMonitorStatusMessage(); SendSystemMonitorStatusMessage(id);
foreach (var p in systemMonitor.ProgramStatusFeedbackCollection) foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
{ {
PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo)); PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo), id);
} }
} }
private void SendSystemMonitorStatusMessage() private void SendSystemMonitorStatusMessage(string id = null)
{ {
// This takes a while, launch a new thread // This takes a while, launch a new thread
@@ -87,7 +87,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
SnmpVersion = systemMonitor.SnmpVersionFeedback.StringValue, SnmpVersion = systemMonitor.SnmpVersionFeedback.StringValue,
BacnetVersion = systemMonitor.BaCnetAppVersionFeedback.StringValue, BacnetVersion = systemMonitor.BaCnetAppVersionFeedback.StringValue,
ControllerVersion = systemMonitor.ControllerVersionFeedback.StringValue ControllerVersion = systemMonitor.ControllerVersionFeedback.StringValue
}) }), id
)); ));
} }
@@ -97,7 +97,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
/// </summary> /// </summary>
protected override void RegisterActions() protected override void RegisterActions()
{ {
AddAction("/fullStatus", (id, content) => SendFullStatusMessage()); AddAction("/fullStatus", (id, content) => SendFullStatusMessage(id));
} }
} }

View File

@@ -5,10 +5,27 @@ using PepperDash.Essentials.Devices.Common.Displays;
namespace PepperDash.Essentials.AppServer.Messengers 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 public class TwoWayDisplayBaseMessenger : MessengerBase
{ {
private readonly TwoWayDisplayBase _display; 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) public TwoWayDisplayBaseMessenger(string key, string messagePath, TwoWayDisplayBase display)
: base(key, messagePath, display) : base(key, messagePath, display)
{ {
@@ -17,7 +34,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
#region Overrides of MessengerBase #region Overrides of MessengerBase
public void SendFullStatus()
private void SendFullStatus(string id = null)
{ {
var messageObj = new TwoWayDisplayBaseStateMessage var messageObj = new TwoWayDisplayBaseStateMessage
{ {
@@ -25,16 +43,20 @@ namespace PepperDash.Essentials.AppServer.Messengers
CurrentInput = _display.CurrentInputFeedback.StringValue CurrentInput = _display.CurrentInputFeedback.StringValue
}; };
PostStatusMessage(messageObj); PostStatusMessage(messageObj, id);
} }
/// <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() protected override void RegisterActions()
{ {
base.RegisterActions(); base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
//_display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
_display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange; _display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange;
_display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange; _display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange;
_display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange; _display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange;
@@ -49,16 +71,6 @@ 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) private void IsWarmingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{ {
PostStatusMessage(JToken.FromObject(new PostStatusMessage(JToken.FromObject(new

View File

@@ -1,4 +1,8 @@
using Crestron.SimplSharp; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Crestron.SimplSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
@@ -9,9 +13,6 @@ using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers namespace PepperDash.Essentials.AppServer.Messengers
{ {
@@ -21,18 +22,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
public class VideoCodecBaseMessenger : MessengerBase public class VideoCodecBaseMessenger : MessengerBase
{ {
/// <summary> /// <summary>
/// /// The video codec device being managed by this messenger.
/// </summary> /// </summary>
protected VideoCodecBase Codec { get; private set; } protected VideoCodecBase Codec { get; private set; }
/// <summary> /// <summary>
/// /// Initializes a new instance of the <see cref="VideoCodecBaseMessenger"/> class.
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key">The unique identifier for the messenger.</param>
/// <param name="codec"></param> /// <param name="codec">The video codec device to be managed.</param>
/// <param name="messagePath"></param> /// <param name="messagePath">The message path for communication.</param>
/// <exception cref="ArgumentNullException">Thrown when codec is null</exception>
public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath) public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
: base(key, messagePath, codec) : base(key, messagePath, codec)
{ {
@@ -70,11 +71,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostEventMessage(eventMsg); PostEventMessage(eventMsg);
} }
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e) private void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
{ {
try try
@@ -98,10 +94,10 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
/// <summary> /// <summary>
/// /// Handles the event when a directory result is returned from the codec.
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender">The source of the event.</param>
/// <param name="e"></param> /// <param name="e">The directory event arguments.</param>
protected virtual void DirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e) protected virtual void DirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{ {
if (Codec is IHasDirectory) if (Codec is IHasDirectory)
@@ -109,8 +105,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
/// <summary> /// <summary>
/// Posts the current directory /// Sends the current directory structure to the mobile control interface.
/// </summary> /// </summary>
/// <param name="directory">The directory structure to send.</param>
protected void SendDirectory(CodecDirectory directory) protected void SendDirectory(CodecDirectory directory)
{ {
try try
@@ -134,11 +131,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Codec_IsReadyChange(object sender, EventArgs e) private void Codec_IsReadyChange(object sender, EventArgs e)
{ {
try try
@@ -151,16 +143,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
PostStatusMessage(state); PostStatusMessage(state);
SendFullStatus(); SendFullStatus();
} catch (Exception ex) }
catch (Exception ex)
{ {
this.LogError(ex, "Error sending codec ready status"); this.LogError(ex, "Error sending codec ready status");
} }
} }
/// <summary> /// <inheritdoc />
/// Called from base's RegisterWithAppServer method
/// </summary>
/// <param name="appServerController"></param>
protected override void RegisterActions() protected override void RegisterActions()
{ {
try try
@@ -169,7 +159,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
AddAction("/isReady", (id, content) => SendIsReady()); AddAction("/isReady", (id, content) => SendIsReady());
AddAction("/fullStatus", (id, content) => SendFullStatus()); AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/dial", (id, content) => AddAction("/dial", (id, content) =>
{ {
@@ -369,7 +359,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
}; };
PostStatusMessage(state); PostStatusMessage(state);
} catch (Exception ex) }
catch (Exception ex)
{ {
this.LogError(ex, "Error posting sharing source"); this.LogError(ex, "Error posting sharing source");
} }
@@ -385,7 +376,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
}; };
PostStatusMessage(state); PostStatusMessage(state);
} catch (Exception ex) }
catch (Exception ex)
{ {
this.LogError(ex, "Error posting sharing content"); this.LogError(ex, "Error posting sharing content");
} }
@@ -435,15 +427,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
MapCameraActions(); MapCameraActions();
PostSelectedCamera(); PostSelectedCamera();
} catch(Exception ex) }
catch (Exception ex)
{ {
this.LogError(ex, "Exception handling camera selected event"); 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() private void MapCameraActions()
{ {
if (Codec is IHasCameras cameraCodec && cameraCodec.SelectedCamera != null) if (Codec is IHasCameras cameraCodec && cameraCodec.SelectedCamera != null)
@@ -599,7 +589,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{ {
try try
{ {
var codec = (Codec as IHasCallHistory); var codec = Codec as IHasCallHistory;
if (codec != null) if (codec != null)
{ {
@@ -621,20 +611,11 @@ 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) private CodecActiveCallItem GetCallWithId(string id)
{ {
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id); return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
} }
/// <summary>
///
/// </summary>
/// <param name="id"></param>
private void GetDirectory(string id) private void GetDirectory(string id)
{ {
if (!(Codec is IHasDirectory dirCodec)) if (!(Codec is IHasDirectory dirCodec))
@@ -644,10 +625,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
dirCodec.GetDirectoryFolderContents(id); dirCodec.GetDirectoryFolderContents(id);
} }
/// <summary> private void GetDirectoryRoot(string id = null)
///
/// </summary>
private void GetDirectoryRoot()
{ {
try try
{ {
@@ -675,9 +653,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
/// <summary>
/// Requests the parent folder contents
/// </summary>
private void GetPreviousDirectory() private void GetPreviousDirectory()
{ {
if (!(Codec is IHasDirectory dirCodec)) if (!(Codec is IHasDirectory dirCodec))
@@ -688,17 +663,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
dirCodec.GetDirectoryParentFolderContents(); dirCodec.GetDirectoryParentFolderContents();
} }
/// <summary>
/// Handler for codec changes
/// </summary>
private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e) private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{ {
SendFullStatus(); SendFullStatus();
} }
/// <summary>
///
/// </summary>
private void SendIsReady() private void SendIsReady()
{ {
try try
@@ -719,9 +688,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
/// <summary> /// <summary>
/// Helper method to build call status for vtc /// Gets the current status of the video codec.
/// </summary> /// </summary>
/// <returns></returns> /// <returns> The current status of the video codec.</returns>
protected VideoCodecBaseStateMessage GetStatus() protected VideoCodecBaseStateMessage GetStatus()
{ {
try try
@@ -780,14 +749,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
protected virtual void SendFullStatus() /// <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)
{ {
if (!Codec.IsReady) if (!Codec.IsReady)
{ {
return; return;
} }
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(GetStatus())); Task.Run(() => PostStatusMessage(GetStatus(), id));
} }
private void PostReceivingContent(bool receivingContent) private void PostReceivingContent(bool receivingContent)
@@ -800,7 +773,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
}; };
PostStatusMessage(state); PostStatusMessage(state);
} catch(Exception ex) }
catch (Exception ex)
{ {
this.LogError(ex, "Error posting receiving content"); this.LogError(ex, "Error posting receiving content");
} }
@@ -824,9 +798,6 @@ namespace PepperDash.Essentials.AppServer.Messengers
} }
} }
/// <summary>
///
/// </summary>
private void PostCameraMode() private void PostCameraMode()
{ {
try try
@@ -928,164 +899,324 @@ namespace PepperDash.Essentials.AppServer.Messengers
public class VideoCodecBaseStateMessage : DeviceStateMessageBase public class VideoCodecBaseStateMessage : DeviceStateMessageBase
{ {
/// <summary>
/// The list of active calls on the codec.
/// </summary>
[JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
public List<CodecActiveCallItem> Calls { get; set; } public List<CodecActiveCallItem> Calls { get; set; }
/// <summary>
/// The current mode of the camera.
/// </summary>
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
public string CameraMode { get; set; } public string CameraMode { get; set; }
/// <summary>
/// Indicates whether the camera self-view is enabled.
/// </summary>
[JsonProperty("cameraSelfView", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraSelfView", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraSelfViewIsOn { get; set; } public bool? CameraSelfViewIsOn { get; set; }
/// <summary>
/// Gets the current status of the cameras.
/// </summary>
[JsonProperty("cameras", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameras", NullValueHandling = NullValueHandling.Ignore)]
public CameraStatus Cameras { get; set; } public CameraStatus Cameras { get; set; }
/// <summary>
/// Indicates whether the camera supports auto mode.
/// </summary>
[JsonProperty("cameraSupportsAutoMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraSupportsAutoMode", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraSupportsAutoMode { get; set; } public bool? CameraSupportsAutoMode { get; set; }
/// <summary>
/// Indicates whether the camera supports off mode.
/// </summary>
[JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraSupportsOffMode { get; set; } public bool? CameraSupportsOffMode { get; set; }
/// <summary>
/// The current dial string for the codec.
/// </summary>
[JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)]
public string CurrentDialString { get; set; } public string CurrentDialString { get; set; }
/// <summary>
/// Gets the current directory for the codec.
/// </summary>
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
public CodecDirectory CurrentDirectory { get; set; } public CodecDirectory CurrentDirectory { get; set; }
/// <summary>
/// Gets the selected folder name in the directory.
/// </summary>
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
public string DirectorySelectedFolderName { get; set; } public string DirectorySelectedFolderName { get; set; }
/// <summary>
/// Indicates whether the codec has active camera streams.
/// </summary>
[JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasCameras { get; set; } public bool? HasCameras { get; set; }
/// <summary>
/// Indicates whether the codec has a directory.
/// </summary>
[JsonProperty("hasDirectory", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasDirectory", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasDirectory { get; set; } public bool? HasDirectory { get; set; }
/// <summary>
/// Indicates whether the codec supports directory search functionality.
/// </summary>
[JsonProperty("hasDirectorySearch", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasDirectorySearch", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasDirectorySearch { get; set; } public bool? HasDirectorySearch { get; set; }
/// <summary>
/// Indicates whether the codec has presets.
/// </summary>
[JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasPresets { get; set; } public bool? HasPresets { get; set; }
/// <summary>
/// Indicates whether the codec has recent calls.
/// </summary>
[JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasRecents { get; set; } public bool? HasRecents { get; set; }
/// <summary>
/// Indicates whether the initial phonebook sync is complete.
/// </summary>
[JsonProperty("initialPhonebookSyncComplete", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("initialPhonebookSyncComplete", NullValueHandling = NullValueHandling.Ignore)]
public bool? InitialPhonebookSyncComplete { get; set; } public bool? InitialPhonebookSyncComplete { get; set; }
/// <summary>
/// Gets the information about the video codec.
/// </summary>
[JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
public VideoCodecInfo Info { get; set; } public VideoCodecInfo Info { get; set; }
/// <summary>
/// Indicates whether the codec is currently in a call.
/// </summary>
[JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsInCall { get; set; } public bool? IsInCall { get; set; }
/// <summary>
/// Indicates whether the codec is ready.
/// </summary>
[JsonProperty("isReady", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isReady", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsReady { get; set; } public bool? IsReady { get; set; }
/// <summary>
/// Indicates whether the codec is a Zoom Room.
/// </summary>
[JsonProperty("isZoomRoom", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsZoomRoom { get; set; } public bool? IsZoomRoom { get; set; }
/// <summary>
/// Gets the meeting information for the codec, if available.
/// </summary>
[JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
public MeetingInfo MeetingInfo { get; set; } public MeetingInfo MeetingInfo { get; set; }
/// <summary>
/// Gets the list of presets for the codec.
/// </summary>
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
public List<CodecRoomPreset> Presets { get; set; } public List<CodecRoomPreset> Presets { get; set; }
/// <summary>
/// Indicates whether the privacy mode is currently enabled.
/// </summary>
[JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)]
public bool? PrivacyModeIsOn { get; set; } public bool? PrivacyModeIsOn { get; set; }
/// <summary>
/// Indicates whether the codec is currently receiving content.
/// </summary>
[JsonProperty("receivingContent", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("receivingContent", NullValueHandling = NullValueHandling.Ignore)]
public bool? ReceivingContent { get; set; } public bool? ReceivingContent { get; set; }
/// <summary>
/// Gets the list of recent calls for the codec, if available.
/// </summary>
[JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)]
public List<CodecCallHistory.CallHistoryEntry> RecentCalls { get; set; } public List<CodecCallHistory.CallHistoryEntry> RecentCalls { get; set; }
/// <summary>
/// Indicates whether the codec is currently sharing content.
/// </summary>
[JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)]
public bool? SharingContentIsOn { get; set; } public bool? SharingContentIsOn { get; set; }
/// <summary>
/// Gets the source of the shared content, if available.
/// </summary>
[JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
public string SharingSource { get; set; } public string SharingSource { get; set; }
/// <summary>
/// Indicates whether the cameras should be shown when not in a call.
/// </summary>
[JsonProperty("showCamerasWhenNotInCall", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("showCamerasWhenNotInCall", NullValueHandling = NullValueHandling.Ignore)]
public bool? ShowCamerasWhenNotInCall { get; set; } public bool? ShowCamerasWhenNotInCall { get; set; }
/// <summary>
/// Indicates whether the self-view is shown by default.
/// </summary>
[JsonProperty("showSelfViewByDefault", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("showSelfViewByDefault", NullValueHandling = NullValueHandling.Ignore)]
public bool? ShowSelfViewByDefault { get; set; } public bool? ShowSelfViewByDefault { get; set; }
/// <summary>
/// Indicates whether the codec is currently in standby mode.
/// </summary>
[JsonProperty("standbyIsOn", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("standbyIsOn", NullValueHandling = NullValueHandling.Ignore)]
public bool? StandbyIsOn { get; set; } public bool? StandbyIsOn { get; set; }
/// <summary>
/// Indicates whether the codec supports ad-hoc meetings.
/// </summary>
[JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)]
public bool? SupportsAdHocMeeting { get; set; } public bool? SupportsAdHocMeeting { get; set; }
} }
/// <summary>
/// Represents the status of the camera.
/// </summary>
public class CameraStatus public class CameraStatus
{ {
/// <summary>
/// Indicates whether the camera manual control is supported.
/// </summary>
[JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraManualIsSupported { get; set; } public bool? CameraManualIsSupported { get; set; }
/// <summary>
/// Indicates whether the camera auto control is supported.
/// </summary>
[JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraAutoIsSupported { get; set; } public bool? CameraAutoIsSupported { get; set; }
/// <summary>
/// Indicates whether the camera off control is supported.
/// </summary>
[JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraOffIsSupported { get; set; } public bool? CameraOffIsSupported { get; set; }
/// <summary>
/// Indicates the current mode of the camera.
/// </summary>
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
public string CameraMode { get; set; } public string CameraMode { get; set; }
/// <summary>
/// Represents the list of cameras available.
/// </summary>
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
public List<CameraBase> Cameras { get; set; } public List<CameraBase> Cameras { get; set; }
/// <summary>
/// Represents the currently selected camera.
/// </summary>
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)] [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 public class Camera
{ {
/// <summary>
/// The unique identifier for the camera.
/// </summary>
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
public string Key { get; set; } public string Key { get; set; }
/// <summary>
/// The name of the camera.
/// </summary>
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// Indicates whether the camera is a far-end camera.
/// </summary>
[JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsFarEnd { get; set; } public bool? IsFarEnd { get; set; }
/// <summary>
/// Represents the capabilities of the camera.
/// </summary>
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
public CameraCapabilities Capabilities { get; set; } public CameraCapabilities Capabilities { get; set; }
} }
/// <summary>
/// Represents the capabilities of the camera.
/// </summary>
public class CameraCapabilities public class CameraCapabilities
{ {
/// <summary>
/// Indicates whether the camera can pan.
/// </summary>
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
public bool? CanPan { get; set; } public bool? CanPan { get; set; }
/// <summary>
/// Indicates whether the camera can tilt.
/// </summary>
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
public bool? CanTilt { get; set; } public bool? CanTilt { get; set; }
/// <summary>
/// Indicates whether the camera can zoom.
/// </summary>
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
public bool? CanZoom { get; set; } public bool? CanZoom { get; set; }
/// <summary>
/// Indicates whether the camera can focus.
/// </summary>
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
public bool? CanFocus { get; set; } public bool? CanFocus { get; set; }
} }
/// <summary>
/// Represents a video codec event message.
/// </summary>
public class VideoCodecBaseEventMessage : DeviceEventMessageBase public class VideoCodecBaseEventMessage : DeviceEventMessageBase
{ {
} }
/// <summary>
/// Represents a password prompt event message.
/// </summary>
public class PasswordPromptEventMessage : VideoCodecBaseEventMessage public class PasswordPromptEventMessage : VideoCodecBaseEventMessage
{ {
/// <summary>
/// The message to display in the password prompt.
/// </summary>
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
public string Message { get; set; } public string Message { get; set; }
/// <summary>
/// Indicates whether the last password attempt was incorrect.
/// </summary>
[JsonProperty("lastAttemptWasIncorrect", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("lastAttemptWasIncorrect", NullValueHandling = NullValueHandling.Ignore)]
public bool LastAttemptWasIncorrect { get; set; } public bool LastAttemptWasIncorrect { get; set; }
/// <summary>
/// Indicates whether the login attempt failed.
/// </summary>
[JsonProperty("loginAttemptFailed", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("loginAttemptFailed", NullValueHandling = NullValueHandling.Ignore)]
public bool LoginAttemptFailed { get; set; } public bool LoginAttemptFailed { get; set; }
/// <summary>
/// Indicates whether the login attempt was cancelled.
/// </summary>
[JsonProperty("loginAttemptCancelled", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("loginAttemptCancelled", NullValueHandling = NullValueHandling.Ignore)]
public bool LoginAttemptCancelled { get; set; } public bool LoginAttemptCancelled { get; set; }
} }