diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs
index e0f1d1a3..f03c1984 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs
@@ -1,13 +1,20 @@
using System;
using System.Collections.Generic;
+using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
+ ///
+ /// Describes a device that has call participants
+ ///
public interface IHasParticipants
{
CodecParticipants Participants { get; }
}
+ ///
+ /// Describes the ability to mute and unmute a participant's video in a meeting
+ ///
public interface IHasParticipantVideoMute:IHasParticipants
{
void MuteVideoForParticipant(int userId);
@@ -15,13 +22,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
void ToggleVideoForParticipant(int userId);
}
- public interface IHasParticipantAudioMute:IHasParticipantVideoMute
+ ///
+ /// Describes the ability to mute and unmute a participant's audio in a meeting
+ ///
+ public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{
void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId);
}
+ ///
+ /// Describes the ability to pin and unpin a participant in a meeting
+ ///
+ public interface IHasParticipantPinUnpin : IHasParticipants
+ {
+ IntFeedback NumberOfScreensFeedback { get; }
+ int ScreenIndexToPinUserTo { get; }
+
+ void PinParticipant(int userId, int screenIndex);
+ void UnPinParticipant(int userId);
+ void ToggleParticipantPinState(int userId, int screenIndex);
+ }
+
public class CodecParticipants
{
private List _currentParticipants;
@@ -31,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
set
{
_currentParticipants = value;
- var handler = ParticipantsListHasChanged;
-
- if(handler == null) return;
-
- handler(this, new EventArgs());
+ OnParticipantsChanged();
}
}
@@ -45,15 +64,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
_currentParticipants = new List();
}
+
+ public void OnParticipantsChanged()
+ {
+ var handler = ParticipantsListHasChanged;
+
+ if (handler == null) return;
+
+ handler(this, new EventArgs());
+ }
}
+ ///
+ /// Represents a call participant
+ ///
public class Participant
{
+ public int UserId { get; set; }
public bool IsHost { get; set; }
public string Name { get; set; }
public bool CanMuteVideo { get; set; }
public bool CanUnmuteVideo { get; set; }
public bool VideoMuteFb { get; set; }
public bool AudioMuteFb { get; set; }
+ public bool HandIsRaisedFb { get; set; }
+ public bool IsPinnedFb { get; set; }
+ public int ScreenIndexIsPinnedToFb { get; set; }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
index 7b2f7f42..1cdb6bc7 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
@@ -547,16 +547,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
};
+
+ // TODO: #698 Figure out how to decode xsig data and trigger actions based on values from SIMPL
+ // trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, // add method here to decode the xsig info and trigger actions
}
private string UpdateParticipantsXSig(List currentParticipants)
{
const int maxParticipants = 50;
- const int maxDigitals = 5;
+ const int maxDigitals = 7;
const int maxStrings = 1;
+ const int maxAnalogs = 1;
const int offset = maxDigitals + maxStrings;
var digitalIndex = maxStrings * maxParticipants; //15
var stringIndex = 0;
+ var analogIndex = 0;
var meetingIndex = 0;
var tokenArray = new XSigToken[maxParticipants * offset];
@@ -571,29 +576,42 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
+ tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
+ tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 6, participant.IsPinnedFb);
//serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
+ //analogs
+ tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb);
+
digitalIndex += maxDigitals;
meetingIndex += offset;
stringIndex += maxStrings;
+ analogIndex += maxAnalogs;
}
while (meetingIndex < maxParticipants * offset)
{
+ //digitals
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
+ tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false);
+ tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false);
//serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
+ //analogs
+ tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0);
+
digitalIndex += maxDigitals;
meetingIndex += offset;
stringIndex += maxStrings;
+ analogIndex += maxAnalogs;
}
return GetXSigString(tokenArray);
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
index 6720d4fc..c8bfd5bf 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
@@ -480,12 +480,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public string wifiName { get; set; }
}
- public class NumberOfScreens
+ public class NumberOfScreens : NotifiableObject
{
+ private int _numOfScreens;
+
[JsonProperty("NumberOfCECScreens")]
public int NumOfCECScreens { get; set; }
[JsonProperty("NumberOfScreens")]
- public int NumOfScreens { get; set; }
+ public int NumOfScreens
+ {
+ get
+ {
+ return _numOfScreens;
+ }
+ set
+ {
+ if (value != _numOfScreens)
+ {
+ _numOfScreens = value;
+ NotifyPropertyChanged("NumberOfScreens");
+ }
+ }
+ }
}
///
@@ -803,6 +819,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public class PinStatusOfScreenNotification
{
+
+
[JsonProperty("can_be_pinned")]
public bool CanBePinned { get; set; }
[JsonProperty("can_pin_share")]
@@ -1301,8 +1319,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
[JsonProperty("is_raise_hand")]
public bool IsRaiseHand { get; set; }
- [JsonProperty("optimize_vis_validideo_sharing")]
- public string IsValid { get; set; }
+ [JsonProperty("is_valid")]
+ public bool IsValid { get; set; }
[JsonProperty("time_stamp")]
public string TimeStamp { get; set; }
}
@@ -1377,12 +1395,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
p =>
new Participant
{
+ UserId = p.UserId,
Name = p.UserName,
IsHost = p.IsHost,
CanMuteVideo = p.IsVideoCanMuteByHost,
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
- VideoMuteFb = p.VideoStatusIsSending
+ VideoMuteFb = p.VideoStatusIsSending,
+ HandIsRaisedFb = p.HandStatus.IsValid && p.HandStatus.IsRaiseHand,
}).ToList();
}
}
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
index da8f0d67..a0a8158c 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
IRouting,
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
- IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts
+ IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute
{
private const long MeetingRefreshTimer = 60000;
private const uint DefaultMeetingDurationMin = 30;
@@ -125,13 +125,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc);
LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc);
-
LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc);
-
CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc);
-
ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc);
+ NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc);
+
}
public CommunicationGather PortGather { get; private set; }
@@ -574,30 +573,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
case "can_Switch_Wall_View":
case "can_Switch_Share_On_All_Screens":
{
- // #697 TODO: Calls the method to compute the available layouts and set the value of AvailableLayouts enum
ComputeAvailableLayouts();
break;
}
case "is_In_First_Page":
{
- // TODO: #697 Fires appropriate feedback
LayoutViewIsOnFirstPageFeedback.FireUpdate();
break;
}
case "is_In_Last_Page":
{
- // TODO: #697 Fires appropriate feedback
LayoutViewIsOnLastPageFeedback.FireUpdate();
break;
}
//case "video_type":
// {
- // // TODO: #697 It appears as though the actual value we want to watch is Configuration.Call.Layout.Style
+ // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style
// LocalLayoutFeedback.FireUpdate();
// break;
// }
}
};
+
+ Status.NumberOfScreens.PropertyChanged += (o, a) =>
+ {
+ switch (a.PropertyName)
+ {
+ case "NumberOfScreens":
+ {
+ NumberOfScreensFeedback.FireUpdate();
+ break;
+ }
+ }
+ };
}
private void SetUpDirectory()
@@ -1278,6 +1286,38 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
break;
}
+ case "pinstatusofscreennotification":
+ {
+ var status = responseObj.ToObject();
+
+ var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId));
+
+ if (participant != null)
+ {
+ participant.IsPinnedFb = true;
+ participant.ScreenIndexIsPinnedToFb = status.ScreenIndex;
+ }
+ else
+ {
+ participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex));
+
+ if (participant == null)
+ {
+ Debug.Console(2, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex);
+ return;
+ }
+ else
+ {
+ participant.IsPinnedFb = false;
+ participant.ScreenIndexIsPinnedToFb = -1;
+ }
+ }
+
+ // fire the event as we've modified the participants list
+ Participants.OnParticipantsChanged();
+
+ break;
+ }
default:
{
break;
@@ -1682,11 +1722,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
///
public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap)
{
- var codec = this as IHasZoomRoomLayouts;
+ var layoutsCodec = this as IHasZoomRoomLayouts;
- if (codec != null)
+ if (layoutsCodec != null)
{
- codec.AvailableLayoutsChanged += (o, a) =>
+ layoutsCodec.AvailableLayoutsChanged += (o, a) =>
{
trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, a.AvailableLayouts
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery));
@@ -1698,14 +1738,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll));
};
- codec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
- trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => codec.SwapContentWithThumbnail());
- codec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]);
+ layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
+ trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail());
+ layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]);
- codec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]);
- codec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]);
- trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => codec.LayoutTurnNextPage() );
- trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => codec.LayoutTurnPreviousPage());
+ layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]);
+ layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]);
+ trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage());
+ trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage());
trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) =>
@@ -1721,9 +1761,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
});
- codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
+ layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
+ }
-
+ var pinCodec = this as IHasParticipantPinUnpin;
+
+ if (pinCodec != null)
+ {
+ pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]);
+
+ // Set the value of the local property to be used when pinning a participant
+ trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u);
}
}
@@ -1894,6 +1942,114 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
#endregion
+ #region IHasParticipantAudioMute Members
+
+ public void MuteAudioForParticipant(int userId)
+ {
+ SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId));
+ }
+
+ public void UnmuteAudioForParticipant(int userId)
+ {
+ SendText(string.Format("zCommand Call MuteParticipant Mute: off Id: {0}", userId));
+ }
+
+ public void ToggleAudioForParticipant(int userId)
+ {
+ var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
+
+ if (user == null)
+ {
+ Debug.Console(2, this, "Unable to find user with id: {0}", userId);
+ return;
+ }
+
+ if (user.AudioMuteFb)
+ {
+ UnmuteAudioForParticipant(userId);
+ }
+ else
+ {
+ MuteAudioForParticipant(userId);
+ }
+ }
+
+ #endregion
+
+ #region IHasParticipantVideoMute Members
+
+ public void MuteVideoForParticipant(int userId)
+ {
+ SendText(string.Format("zCommand Call MuteParticipantVideo Mute: on Id: {0}", userId));
+ }
+
+ public void UnmuteVideoForParticipant(int userId)
+ {
+ SendText(string.Format("zCommand Call MuteParticipantVideo Mute: off Id: {0}", userId));
+ }
+
+ public void ToggleVideoForParticipant(int userId)
+ {
+ var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
+
+ if (user == null)
+ {
+ Debug.Console(2, this, "Unable to find user with id: {0}", userId);
+ return;
+ }
+
+ if (user.VideoMuteFb)
+ {
+ UnmuteVideoForParticipant(userId);
+ }
+ else
+ {
+ MuteVideoForParticipant(userId);
+ }
+ }
+
+ #endregion
+
+ #region IHasParticipantPinUnpin Members
+
+ private Func NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } }
+
+ public IntFeedback NumberOfScreensFeedback { get; private set; }
+
+ public int ScreenIndexToPinUserTo { get; private set; }
+
+ public void PinParticipant(int userId, int screenIndex)
+ {
+ SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex));
+ }
+
+ public void UnPinParticipant(int userId)
+ {
+ SendText(string.Format("zCommand Call Pin Id: {0} Enable: off", userId));
+ }
+
+ public void ToggleParticipantPinState(int userId, int screenIndex)
+ {
+ var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
+
+ if(user == null)
+ {
+ Debug.Console(2, this, "Unable to find user with id: {0}", userId);
+ return;
+ }
+
+ if (user.IsPinnedFb)
+ {
+ UnPinParticipant(userId);
+ }
+ else
+ {
+ PinParticipant(userId, screenIndex);
+ }
+ }
+
+ #endregion
+
#region Implementation of IHasCameraOff
public BoolFeedback CameraIsOffFeedback { get; private set; }
@@ -2052,7 +2208,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
private void ComputeAvailableLayouts()
{
zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None;
- //TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts
+ // TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts
+ // Will need to test and confirm that this logic evaluates correctly
if (Status.Layout.can_Switch_Wall_View)
{
availableLayouts |= zConfiguration.eLayoutStyle.Gallery;
@@ -2140,6 +2297,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
#endregion
+
}
///
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs
index 49b22ae4..f4d11f14 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs
@@ -128,6 +128,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
JoinType = eJoinType.Digital
});
+ [JoinName("ScreenIndexToPinUserTo")]
+ public JoinDataComplete ScreenIndexToPinUserTo =
+ new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = "Specifies the screen index a participant should be pinned to",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Analog
+ });
+
+ [JoinName("NumberOfScreens")]
+ public JoinDataComplete NumberOfScreens =
+ new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = "Reports the number of screens connected",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Analog
+ });
+
public ZoomRoomJoinMap(uint joinStart)
: base(joinStart, typeof(ZoomRoomJoinMap))
{