Skip to content

Commit 91aa0ef

Browse files
ndorinCopilot
andcommitted
feat: Add new messengers for various device interfaces and remove VideoCodecBaseMessenger
- Implemented IHasMeetingInfoMessenger to handle meeting information updates. - Created IHasReadyMessenger for devices indicating readiness status. - Added IHasStandbyModeMessenger to manage standby mode actions. - Introduced IPrivacyMessenger for privacy mode control. - Developed IVideoCodecInfoMessenger to provide codec information. - Removed the obsolete VideoCodecBaseMessenger class. - Updated MessengerFactoryRegistry to register new messengers for IHasReady, IHasMeetingInfo, IHasStartMeeting, IHasStandbyMode, IPrivacy, and IVideoCodecInfo interfaces. Co-authored-by: Copilot <copilot@github.com>
1 parent b41c30c commit 91aa0ef

22 files changed

Lines changed: 1197 additions & 567 deletions
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.Generic;
2+
3+
namespace PepperDash.Essentials.Devices.Common.Codec;
4+
5+
/// <summary>
6+
/// Defines call control functionality for a codec, extending the base dialer interface
7+
/// with active call list access and meeting dialing.
8+
/// </summary>
9+
public interface ICodecCallControls : IHasDialer
10+
{
11+
/// <summary>
12+
/// Gets the list of currently active, dialing, or incoming calls
13+
/// </summary>
14+
List<CodecActiveCallItem> ActiveCalls { get; }
15+
16+
/// <summary>
17+
/// Dials the specified meeting
18+
/// </summary>
19+
/// <param name="meeting">The meeting to dial</param>
20+
void Dial(Meeting meeting);
21+
}

src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,7 @@ public interface IHasDialer
5353
/// Gets a value indicating whether the device is currently in a call
5454
/// </summary>
5555
bool IsInCall { get; }
56+
57+
5658
}
5759

src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
55
/// <summary>
66
/// Implements a common set of data about a codec
77
/// </summary>
8-
public interface iVideoCodecInfo
8+
public interface IVideoCodecInfo
99
{
1010
/// <summary>
1111
/// Gets the codec information

src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Linq;
44
using Crestron.SimplSharp.CrestronIO;
55
using Crestron.SimplSharpPro.DeviceSupport;
6-
using Crestron.SimplSharp;
76
using PepperDash.Core;
87
using PepperDash.Core.Intersystem;
98
using PepperDash.Core.Intersystem.Tokens;
@@ -29,7 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec;
2928
/// Also contains the logic to link commonly implemented interfaces to the API bridge.
3029
/// </summary>
3130
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
32-
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode
31+
IUsageTracking, ICodecCallControls, IHasContentSharing, ICodecAudio, IVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode, IHasReady
3332
{
3433
private const int XSigEncoding = 28591;
3534

@@ -338,7 +337,7 @@ public virtual void SendDtmf(string s, CodecActiveCallItem call) { }
338337
/// <summary>
339338
/// Fired when the Codec is ready to be used
340339
/// </summary>
341-
public event EventHandler<EventArgs> IsReadyChange;
340+
public event EventHandler<IsReadyEventArgs> IsReadyEvent;
342341

343342
/// <summary>
344343
/// Dials the specified meeting
@@ -405,7 +404,7 @@ protected void SetIsReady()
405404
try
406405
{
407406
IsReady = true;
408-
IsReadyChange?.Invoke(this, new EventArgs());
407+
IsReadyEvent?.Invoke(this, new IsReadyEventArgs(IsReady));
409408
}
410409
catch (Exception e)
411410
{
@@ -498,7 +497,7 @@ protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, V
498497
LinkVideoCodecInfoToApi(trilist, joinMap);
499498

500499
// Register for this event to link any functions that require the codec to be ready first
501-
codec.IsReadyChange += (o, a) =>
500+
codec.IsReadyEvent += (o, a) =>
502501
{
503502
if (codec is IHasCodecCameras)
504503
{
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Newtonsoft.Json;
6+
using Newtonsoft.Json.Linq;
7+
using PepperDash.Core;
8+
using PepperDash.Core.Logging;
9+
using PepperDash.Essentials.Core;
10+
using PepperDash.Essentials.Devices.Common.Codec;
11+
12+
namespace PepperDash.Essentials.AppServer.Messengers
13+
{
14+
/// <summary>
15+
/// Provides a messaging bridge for devices implementing <see cref="ICodecCallControls"/>
16+
/// </summary>
17+
public class ICallControlsMessenger : MessengerBase
18+
{
19+
private readonly ICodecCallControls _callControls;
20+
21+
/// Initializes a new instance of the <see cref="ICallControlsMessenger"/> class.
22+
public ICallControlsMessenger(string key, string messagePath, EssentialsDevice device)
23+
: base(key, messagePath, device)
24+
{
25+
_callControls = device as ICodecCallControls ?? throw new ArgumentNullException(nameof(device));
26+
_callControls.CallStatusChange += CallControls_CallStatusChange;
27+
}
28+
29+
/// <inheritdoc />
30+
protected override void RegisterActions()
31+
{
32+
base.RegisterActions();
33+
34+
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
35+
36+
AddAction("/callControlsStatus", (id, content) => SendFullStatus(id));
37+
38+
AddAction("/dialMeeting", (id, content) =>
39+
_callControls.Dial(content.ToObject<Meeting>()));
40+
41+
AddAction("/endCallById", (id, content) =>
42+
{
43+
var s = content.ToObject<MobileControlSimpleContent<string>>();
44+
var call = GetCallWithId(s.Value);
45+
if (call != null)
46+
_callControls.EndCall(call);
47+
});
48+
49+
AddAction("/rejectById", (id, content) =>
50+
{
51+
var s = content.ToObject<MobileControlSimpleContent<string>>();
52+
var call = GetCallWithId(s.Value);
53+
if (call != null)
54+
_callControls.RejectCall(call);
55+
});
56+
57+
AddAction("/acceptById", (id, content) =>
58+
{
59+
var s = content.ToObject<MobileControlSimpleContent<string>>();
60+
var call = GetCallWithId(s.Value);
61+
if (call != null)
62+
_callControls.AcceptCall(call);
63+
});
64+
}
65+
66+
private void CallControls_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
67+
{
68+
try
69+
{
70+
PostStatusMessage(BuildState());
71+
}
72+
catch (Exception ex)
73+
{
74+
this.LogError(ex, "Error posting call controls status");
75+
}
76+
}
77+
78+
private void SendFullStatus(string id = null)
79+
{
80+
try
81+
{
82+
Task.Run(() => PostStatusMessage(BuildState(), id));
83+
}
84+
catch (Exception ex)
85+
{
86+
this.LogError(ex, "Error sending call controls full status");
87+
}
88+
}
89+
90+
private ICallControlsStateMessage BuildState()
91+
{
92+
return new ICallControlsStateMessage
93+
{
94+
Calls = _callControls.ActiveCalls,
95+
};
96+
}
97+
98+
private CodecActiveCallItem GetCallWithId(string id)
99+
{
100+
return _callControls.ActiveCalls?.FirstOrDefault(c => c.Id == id);
101+
}
102+
}
103+
104+
/// <summary>
105+
/// State message for <see cref="ICodecCallControls"/>
106+
/// </summary>
107+
public class ICallControlsStateMessage : DeviceStateMessageBase
108+
{
109+
/// <summary>
110+
/// Gets or sets the list of active calls. Null if unknown or not applicable.
111+
/// </summary>
112+
[JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
113+
public List<CodecActiveCallItem> Calls { get; set; }
114+
115+
}
116+
}

src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallHistoryMessenger.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private void PostCallHistory()
6565
{
6666
PostStatusMessage(new IHasCallHistoryStateMessage
6767
{
68-
RecentCalls = recents
68+
RecentCalls = recents,
6969
});
7070
}
7171
}
@@ -76,9 +76,22 @@ private void PostCallHistory()
7676
}
7777
}
7878

79+
/// <summary>
80+
/// State message for <see cref="IHasCallHistory"/>
81+
///
82+
/// </summary>
7983
public class IHasCallHistoryStateMessage : DeviceStateMessageBase
8084
{
85+
/// <summary>
86+
/// Gets or sets the list of recent calls. Null if unknown or not applicable.
87+
/// </summary>
8188
[JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)]
8289
public List<CodecCallHistory.CallHistoryEntry> RecentCalls { get; set; }
90+
91+
/// <summary>
92+
/// Gets or sets a value indicating whether the device has call history functionality. Null if unknown or not applicable.
93+
/// </summary>
94+
[JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)]
95+
public bool? HasRecents { get; set; } = true; // Since this messenger should only be used for devices with call history, default to true unless specified otherwise.
8396
}
8497
}

src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlsMessenger.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ private void SendFullStatus(string clientId)
8181

8282
foreach (var cam in CameraController.Cameras)
8383
{
84-
cameraList.Add(new KeyName{
84+
cameraList.Add(new KeyName
85+
{
8586
Key = cam.Key,
8687
Name = cam.Name
8788
});
@@ -96,10 +97,27 @@ private void SendFullStatus(string clientId)
9697
};
9798
}
9899

100+
string mode = "";
101+
102+
if (CameraController is IHasCameraAutoMode speakerTrackCodec)
103+
{
104+
mode = speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue
105+
? eCameraControlMode.Auto.ToString().ToLower()
106+
: eCameraControlMode.Manual.ToString().ToLower();
107+
}
108+
109+
if (CameraController is IHasCameraOff cameraOffCodec)
110+
{
111+
if (cameraOffCodec.CameraIsOffFeedback.BoolValue)
112+
mode = eCameraControlMode.Off.ToString().ToLower();
113+
}
114+
99115
var state = new IHasCamerasWithControlsStateMessage
100116
{
101117
CameraList = cameraList,
102-
SelectedCamera = selectedCamera
118+
SelectedCamera = selectedCamera,
119+
CameraMode = mode,
120+
HasCameraAutoMode = CameraController is IHasCameraAutoMode,
103121
};
104122

105123
PostStatusMessage(state, clientId);
@@ -122,6 +140,18 @@ public class IHasCamerasWithControlsStateMessage : DeviceStateMessageBase
122140
/// </summary>
123141
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
124142
public IKeyName SelectedCamera { get; set; }
143+
144+
/// <summary>
145+
/// Indicates whether the device has any cameras. Null if unknown or not applicable.
146+
/// </summary>
147+
[JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
148+
public bool HasCameras { get; set; } = true; // Since this messenger should only be used for devices with cameras, default to true unless specified otherwise.
149+
150+
[JsonProperty("hasCameraAutoMode", NullValueHandling = NullValueHandling.Ignore)]
151+
public bool? HasCameraAutoMode { get; set; }
152+
153+
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
154+
public string CameraMode { get; set; }
125155
}
126156

127157
class KeyName : IKeyName

0 commit comments

Comments
 (0)