mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
Merge c7cc98bff7 into a91af6bd75
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -176,6 +176,7 @@
|
|||||||
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
||||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
||||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
||||||
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomJoinMap.cs" />
|
||||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
|
||||||
<None Include="Properties\ControlSystem.cfg" />
|
<None Include="Properties\ControlSystem.cfg" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -19,4 +19,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
void LocalLayoutToggleSingleProminent();
|
void LocalLayoutToggleSingleProminent();
|
||||||
void MinMaxLayoutToggle();
|
void MinMaxLayoutToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the requirements for Zoom Room layout control
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasZoomRoomLayouts : IHasCodecLayouts
|
||||||
|
{
|
||||||
|
event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
|
||||||
|
|
||||||
|
BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
|
||||||
|
BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
|
||||||
|
BoolFeedback CanSwapContentWithThumbnailFeedback { get; }
|
||||||
|
BoolFeedback ContentSwappedWithThumbnailFeedback { get; }
|
||||||
|
|
||||||
|
ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; }
|
||||||
|
ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; }
|
||||||
|
|
||||||
|
void GetAvailableLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout
|
||||||
|
void SetLayout(ZoomRoom.zConfiguration.eLayoutStyle layoutStyle);
|
||||||
|
void SwapContentWithThumbnail();
|
||||||
|
|
||||||
|
void LayoutTurnNextPage();
|
||||||
|
void LayoutTurnPreviousPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LayoutInfoChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a device that has call participants
|
||||||
|
/// </summary>
|
||||||
public interface IHasParticipants
|
public interface IHasParticipants
|
||||||
{
|
{
|
||||||
CodecParticipants Participants { get; }
|
CodecParticipants Participants { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the ability to mute and unmute a participant's video in a meeting
|
||||||
|
/// </summary>
|
||||||
public interface IHasParticipantVideoMute:IHasParticipants
|
public interface IHasParticipantVideoMute:IHasParticipants
|
||||||
{
|
{
|
||||||
void MuteVideoForParticipant(int userId);
|
void MuteVideoForParticipant(int userId);
|
||||||
@@ -15,13 +22,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
|||||||
void ToggleVideoForParticipant(int userId);
|
void ToggleVideoForParticipant(int userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IHasParticipantAudioMute:IHasParticipantVideoMute
|
/// <summary>
|
||||||
|
/// Describes the ability to mute and unmute a participant's audio in a meeting
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
|
||||||
{
|
{
|
||||||
void MuteAudioForParticipant(int userId);
|
void MuteAudioForParticipant(int userId);
|
||||||
void UnmuteAudioForParticipant(int userId);
|
void UnmuteAudioForParticipant(int userId);
|
||||||
void ToggleAudioForParticipant(int userId);
|
void ToggleAudioForParticipant(int userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the ability to pin and unpin a participant in a meeting
|
||||||
|
/// </summary>
|
||||||
|
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
|
public class CodecParticipants
|
||||||
{
|
{
|
||||||
private List<Participant> _currentParticipants;
|
private List<Participant> _currentParticipants;
|
||||||
@@ -31,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_currentParticipants = value;
|
_currentParticipants = value;
|
||||||
var handler = ParticipantsListHasChanged;
|
OnParticipantsChanged();
|
||||||
|
|
||||||
if(handler == null) return;
|
|
||||||
|
|
||||||
handler(this, new EventArgs());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,15 +64,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
|||||||
{
|
{
|
||||||
_currentParticipants = new List<Participant>();
|
_currentParticipants = new List<Participant>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnParticipantsChanged()
|
||||||
|
{
|
||||||
|
var handler = ParticipantsListHasChanged;
|
||||||
|
|
||||||
|
if (handler == null) return;
|
||||||
|
|
||||||
|
handler(this, new EventArgs());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a call participant
|
||||||
|
/// </summary>
|
||||||
public class Participant
|
public class Participant
|
||||||
{
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
public bool IsHost { get; set; }
|
public bool IsHost { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool CanMuteVideo { get; set; }
|
public bool CanMuteVideo { get; set; }
|
||||||
public bool CanUnmuteVideo { get; set; }
|
public bool CanUnmuteVideo { get; set; }
|
||||||
public bool VideoMuteFb { get; set; }
|
public bool VideoMuteFb { get; set; }
|
||||||
public bool AudioMuteFb { get; set; }
|
public bool AudioMuteFb { get; set; }
|
||||||
|
public bool HandIsRaisedFb { get; set; }
|
||||||
|
public bool IsPinnedFb { get; set; }
|
||||||
|
public int ScreenIndexIsPinnedToFb { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
|
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
|
||||||
{
|
{
|
||||||
private const int XSigEncoding = 28591;
|
private const int XSigEncoding = 28591;
|
||||||
|
protected const int MaxParticipants = 50;
|
||||||
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
|
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
|
||||||
protected VideoCodecBase(DeviceConfig config)
|
protected VideoCodecBase(DeviceConfig config)
|
||||||
: base(config)
|
: base(config)
|
||||||
@@ -271,6 +272,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
|
|
||||||
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use this method when using a plain VideoCodecControllerJoinMap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="codec"></param>
|
||||||
|
/// <param name="trilist"></param>
|
||||||
|
/// <param name="joinStart"></param>
|
||||||
|
/// <param name="joinMapKey"></param>
|
||||||
|
/// <param name="bridge"></param>
|
||||||
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
|
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||||
EiscApiAdvanced bridge)
|
EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
@@ -288,10 +297,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
bridge.AddJoinMap(Key, joinMap);
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkVideoCodecToApi(codec, trilist, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="codec"></param>
|
||||||
|
/// <param name="trilist"></param>
|
||||||
|
/// <param name="joinMap"></param>
|
||||||
|
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
|
{
|
||||||
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
|
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LinkVideoCodecDtmfToApi(trilist, joinMap);
|
LinkVideoCodecDtmfToApi(trilist, joinMap);
|
||||||
|
|
||||||
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
||||||
@@ -524,6 +542,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants);
|
||||||
|
|
||||||
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
|
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
|
||||||
|
|
||||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||||
@@ -532,14 +552,59 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the actions for each participant in the list
|
||||||
|
/// </summary>
|
||||||
|
private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List<Participant> currentParticipants)
|
||||||
|
{
|
||||||
|
uint index = 0; // track the index of the participant in the
|
||||||
|
|
||||||
|
foreach (var participant in currentParticipants)
|
||||||
|
{
|
||||||
|
var p = participant;
|
||||||
|
if (index > MaxParticipants) break;
|
||||||
|
|
||||||
|
var audioMuteCodec = this as IHasParticipantAudioMute;
|
||||||
|
if (audioMuteCodec != null)
|
||||||
|
{
|
||||||
|
trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index,
|
||||||
|
() => audioMuteCodec.ToggleAudioForParticipant(p.UserId));
|
||||||
|
|
||||||
|
trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index,
|
||||||
|
() => audioMuteCodec.ToggleVideoForParticipant(p.UserId));
|
||||||
|
}
|
||||||
|
|
||||||
|
var pinCodec = this as IHasParticipantPinUnpin;
|
||||||
|
if (pinCodec != null)
|
||||||
|
{
|
||||||
|
trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index,
|
||||||
|
() => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo));
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear out any previously set actions
|
||||||
|
while (index < MaxParticipants)
|
||||||
|
{
|
||||||
|
trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index);
|
||||||
|
trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index);
|
||||||
|
trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
||||||
{
|
{
|
||||||
const int maxParticipants = 50;
|
const int maxParticipants = MaxParticipants;
|
||||||
const int maxDigitals = 5;
|
const int maxDigitals = 7;
|
||||||
const int maxStrings = 1;
|
const int maxStrings = 1;
|
||||||
const int offset = maxDigitals + maxStrings;
|
const int maxAnalogs = 1;
|
||||||
var digitalIndex = maxStrings * maxParticipants; //15
|
const int offset = maxDigitals + maxStrings + maxAnalogs; // 9
|
||||||
|
var digitalIndex = (maxStrings + maxAnalogs) * maxParticipants; // 100
|
||||||
var stringIndex = 0;
|
var stringIndex = 0;
|
||||||
|
var analogIndex = stringIndex + maxParticipants;
|
||||||
var meetingIndex = 0;
|
var meetingIndex = 0;
|
||||||
|
|
||||||
var tokenArray = new XSigToken[maxParticipants * offset];
|
var tokenArray = new XSigToken[maxParticipants * offset];
|
||||||
@@ -554,29 +619,42 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
|
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
|
||||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
|
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
|
||||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
|
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
|
||||||
|
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
|
||||||
|
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb);
|
||||||
|
|
||||||
//serials
|
//serials
|
||||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
|
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
|
||||||
|
|
||||||
|
//analogs
|
||||||
|
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb);
|
||||||
|
|
||||||
digitalIndex += maxDigitals;
|
digitalIndex += maxDigitals;
|
||||||
meetingIndex += offset;
|
meetingIndex += offset;
|
||||||
stringIndex += maxStrings;
|
stringIndex += maxStrings;
|
||||||
|
analogIndex += maxAnalogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (meetingIndex < maxParticipants * offset)
|
while (meetingIndex < maxParticipants * offset)
|
||||||
{
|
{
|
||||||
|
//digitals
|
||||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
||||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
||||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
|
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
|
||||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
|
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
|
||||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, 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
|
//serials
|
||||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
||||||
|
|
||||||
|
//analogs
|
||||||
|
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0);
|
||||||
|
|
||||||
digitalIndex += maxDigitals;
|
digitalIndex += maxDigitals;
|
||||||
meetingIndex += offset;
|
meetingIndex += offset;
|
||||||
stringIndex += maxStrings;
|
stringIndex += maxStrings;
|
||||||
|
analogIndex += maxAnalogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetXSigString(tokenArray);
|
return GetXSigString(tokenArray);
|
||||||
@@ -595,7 +673,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
|
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
private List<Meeting> _currentMeetings = new List<Meeting>();
|
private List<Meeting> _currentMeetings = new List<Meeting>();
|
||||||
|
|
||||||
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
@@ -607,7 +684,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
codec.CodecSchedule.MeetingWarningMinutes = i;
|
codec.CodecSchedule.MeetingWarningMinutes = i;
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
|
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
var mtg = 1;
|
var mtg = 1;
|
||||||
@@ -617,7 +693,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
if (_currentMeetings[index] != null)
|
if (_currentMeetings[index] != null)
|
||||||
Dial(_currentMeetings[index]);
|
Dial(_currentMeetings[index]);
|
||||||
});
|
});
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
|
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
var mtg = 2;
|
var mtg = 2;
|
||||||
@@ -627,7 +703,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
if (_currentMeetings[index] != null)
|
if (_currentMeetings[index] != null)
|
||||||
Dial(_currentMeetings[index]);
|
Dial(_currentMeetings[index]);
|
||||||
});
|
});
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
|
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
var mtg = 3;
|
var mtg = 3;
|
||||||
@@ -652,14 +728,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
{
|
{
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = DateTime.Now;
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
// - changed var currentMeetings >> field _currentMeetings
|
|
||||||
//_currentMeetings.Clear();
|
|
||||||
_currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
|
_currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
// - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi
|
|
||||||
|
|
||||||
var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
|
var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
|
||||||
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
|
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
|
||||||
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
|
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
{
|
{
|
||||||
foreach (Contact c in zoomContacts)
|
foreach (Contact c in zoomContacts)
|
||||||
{
|
{
|
||||||
var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid};
|
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
|
||||||
|
|
||||||
if (folders.Count > 0)
|
if (folders.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -480,12 +480,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
public string wifiName { get; set; }
|
public string wifiName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NumberOfScreens
|
public class NumberOfScreens : NotifiableObject
|
||||||
{
|
{
|
||||||
|
private int _numOfScreens;
|
||||||
|
|
||||||
[JsonProperty("NumberOfCECScreens")]
|
[JsonProperty("NumberOfCECScreens")]
|
||||||
public int NumOfCECScreens { get; set; }
|
public int NumOfCECScreens { get; set; }
|
||||||
[JsonProperty("NumberOfScreens")]
|
[JsonProperty("NumberOfScreens")]
|
||||||
public int NumOfScreens { get; set; }
|
public int NumOfScreens
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _numOfScreens;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _numOfScreens)
|
||||||
|
{
|
||||||
|
_numOfScreens = value;
|
||||||
|
NotifyPropertyChanged("NumberOfScreens");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -551,18 +567,136 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Layout
|
public class Layout : NotifiableObject
|
||||||
{
|
{
|
||||||
|
// backer variables
|
||||||
|
private bool _can_Switch_Speaker_View;
|
||||||
|
private bool _can_Switch_Wall_View;
|
||||||
|
private bool _can_Switch_Share_On_All_Screens;
|
||||||
|
private bool _is_In_First_Page;
|
||||||
|
private bool _is_In_Last_Page;
|
||||||
|
private string _video_type;
|
||||||
|
|
||||||
|
|
||||||
public bool can_Adjust_Floating_Video { get; set; }
|
public bool can_Adjust_Floating_Video { get; set; }
|
||||||
public bool can_Switch_Floating_Share_Content { get; set; }
|
public bool can_Switch_Floating_Share_Content { get; set; }
|
||||||
public bool can_Switch_Share_On_All_Screens { get; set; }
|
|
||||||
public bool can_Switch_Speaker_View { get; set; }
|
/// <summary>
|
||||||
public bool can_Switch_Wall_View { get; set; }
|
/// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors.
|
||||||
public bool is_In_First_Page { get; set; }
|
/// </summary>
|
||||||
public bool is_In_Last_Page { get; set; }
|
[JsonProperty("can_Switch_Share_On_All_Screens")]
|
||||||
|
public bool can_Switch_Share_On_All_Screens
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _can_Switch_Share_On_All_Screens;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _can_Switch_Share_On_All_Screens)
|
||||||
|
{
|
||||||
|
_can_Switch_Share_On_All_Screens = value;
|
||||||
|
NotifyPropertyChanged("can_Switch_Share_On_All_Screens");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("can_Switch_Speaker_View")]
|
||||||
|
public bool can_Switch_Speaker_View
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _can_Switch_Speaker_View;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _can_Switch_Speaker_View)
|
||||||
|
{
|
||||||
|
_can_Switch_Speaker_View = value;
|
||||||
|
NotifyPropertyChanged("can_Switch_Speaker_View");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [on/off] On if it is possible to invoke zConfiguration Call Layout Style: Gallery, to switch to the Gallery mode, showing video participants in tiled windows: The Zoom Room shows up to a 5x5 array of tiled windows per page.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("can_Switch_Wall_View")]
|
||||||
|
public bool can_Switch_Wall_View
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _can_Switch_Wall_View;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _can_Switch_Wall_View)
|
||||||
|
{
|
||||||
|
_can_Switch_Wall_View = value;
|
||||||
|
NotifyPropertyChanged("can_Switch_Wall_View");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("is_In_First_Page")]
|
||||||
|
public bool is_In_First_Page
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _is_In_First_Page;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _is_In_First_Page)
|
||||||
|
{
|
||||||
|
_is_In_First_Page = value;
|
||||||
|
NotifyPropertyChanged("is_In_First_Page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("is_In_Last_Page")]
|
||||||
|
public bool is_In_Last_Page
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _is_In_Last_Page;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _is_In_Last_Page)
|
||||||
|
{
|
||||||
|
_is_In_Last_Page = value;
|
||||||
|
NotifyPropertyChanged("is_In_Last_Page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool is_supported { get; set; }
|
public bool is_supported { get; set; }
|
||||||
public int video_Count_In_Current_Page { get; set; }
|
public int video_Count_In_Current_Page { get; set; }
|
||||||
public string video_type { get; set; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// [Gallery | Strip] Indicates which mode applies: Strip or Gallery.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("video_type")]
|
||||||
|
public string video_type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _video_type;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _video_type)
|
||||||
|
{
|
||||||
|
_video_type = value;
|
||||||
|
NotifyPropertyChanged("video_type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CallRecordInfo
|
public class CallRecordInfo
|
||||||
@@ -685,6 +819,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public class PinStatusOfScreenNotification
|
public class PinStatusOfScreenNotification
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
[JsonProperty("can_be_pinned")]
|
[JsonProperty("can_be_pinned")]
|
||||||
public bool CanBePinned { get; set; }
|
public bool CanBePinned { get; set; }
|
||||||
[JsonProperty("can_pin_share")]
|
[JsonProperty("can_pin_share")]
|
||||||
@@ -703,7 +839,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
public string WhyCannotPinShare { get; set; }
|
public string WhyCannotPinShare { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PhoneCallStatus:NotifiableObject
|
public class PhoneCallStatus : NotifiableObject
|
||||||
{
|
{
|
||||||
private bool _isIncomingCall;
|
private bool _isIncomingCall;
|
||||||
private string _peerDisplayName;
|
private string _peerDisplayName;
|
||||||
@@ -712,15 +848,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
private bool _offHook;
|
private bool _offHook;
|
||||||
|
|
||||||
public string CallId { get; set; }
|
public string CallId { get; set; }
|
||||||
public bool IsIncomingCall {
|
public bool IsIncomingCall
|
||||||
|
{
|
||||||
get { return _isIncomingCall; }
|
get { return _isIncomingCall; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(value == _isIncomingCall) return;
|
if (value == _isIncomingCall) return;
|
||||||
|
|
||||||
_isIncomingCall = value;
|
_isIncomingCall = value;
|
||||||
NotifyPropertyChanged("IsIncomingCall");
|
NotifyPropertyChanged("IsIncomingCall");
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string PeerDisplayName
|
public string PeerDisplayName
|
||||||
{
|
{
|
||||||
@@ -826,7 +964,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(value != _mute)
|
if (value != _mute)
|
||||||
{
|
{
|
||||||
_mute = value;
|
_mute = value;
|
||||||
NotifyPropertyChanged("Mute");
|
NotifyPropertyChanged("Mute");
|
||||||
@@ -835,12 +973,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
public enum eLayoutStyle
|
public enum eLayoutStyle
|
||||||
{
|
{
|
||||||
Gallery,
|
None = 0,
|
||||||
Speaker,
|
Gallery = 1,
|
||||||
Strip,
|
Speaker = 2,
|
||||||
ShareAll
|
Strip = 4,
|
||||||
|
ShareAll = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum eLayoutSize
|
public enum eLayoutSize
|
||||||
@@ -865,20 +1005,64 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
DownLeft
|
DownLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Layout:NotifiableObject
|
public class Layout : NotifiableObject
|
||||||
{
|
{
|
||||||
public bool ShareThumb { get; set; }
|
private bool _shareThumb;
|
||||||
public eLayoutStyle Style { get; set; }
|
private eLayoutStyle _style;
|
||||||
public eLayoutSize Size { get; set; }
|
private eLayoutSize _size;
|
||||||
|
|
||||||
private eLayoutPosition _position;
|
private eLayoutPosition _position;
|
||||||
public eLayoutPosition Position {
|
|
||||||
|
public bool ShareThumb
|
||||||
|
{
|
||||||
|
get { return _shareThumb; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _shareThumb)
|
||||||
|
{
|
||||||
|
_shareThumb = value;
|
||||||
|
NotifyPropertyChanged("ShareThumb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public eLayoutStyle Style
|
||||||
|
{
|
||||||
|
get { return _style; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _style)
|
||||||
|
{
|
||||||
|
_style = value;
|
||||||
|
NotifyPropertyChanged("Style");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public eLayoutSize Size
|
||||||
|
{
|
||||||
|
get { return _size; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _size)
|
||||||
|
{
|
||||||
|
_size = value;
|
||||||
|
NotifyPropertyChanged("Size");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public eLayoutPosition Position
|
||||||
|
{
|
||||||
get { return _position; }
|
get { return _position; }
|
||||||
set
|
set
|
||||||
|
{
|
||||||
|
if (value != _position)
|
||||||
{
|
{
|
||||||
_position = value;
|
_position = value;
|
||||||
NotifyPropertyChanged("Position");
|
NotifyPropertyChanged("Position");
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Lock
|
public class Lock
|
||||||
@@ -998,7 +1182,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
private string _selectedId;
|
private string _selectedId;
|
||||||
|
|
||||||
[JsonProperty("selectedId")]
|
[JsonProperty("selectedId")]
|
||||||
public string SelectedId {
|
public string SelectedId
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _selectedId;
|
return _selectedId;
|
||||||
@@ -1020,6 +1205,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
{
|
{
|
||||||
public string appVersion { get; set; }
|
public string appVersion { get; set; }
|
||||||
public string deviceSystem { get; set; }
|
public string deviceSystem { get; set; }
|
||||||
|
|
||||||
|
// This doesn't belong here, but there's a bug in the object structure of Zoom Room 5.6.3 that puts it here
|
||||||
|
public zConfiguration.Call Call { get; set; }
|
||||||
|
|
||||||
|
public Client()
|
||||||
|
{
|
||||||
|
Call = new zConfiguration.Call();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1135,14 +1328,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public class HandStatus
|
public class HandStatus
|
||||||
{
|
{
|
||||||
[JsonProperty("is_raise_hand")]
|
// example return of the "hand_status" object
|
||||||
|
// !!!! Note the properties contain ': ' within the property name !!!
|
||||||
|
//"hand_status": {
|
||||||
|
// "is_raise_hand: ": false,
|
||||||
|
// "is_valid: ": "on",
|
||||||
|
// "time_stamp: ": "11825083"
|
||||||
|
//},
|
||||||
|
[JsonProperty("is_raise_hand: ")]
|
||||||
public bool IsRaiseHand { get; set; }
|
public bool IsRaiseHand { get; set; }
|
||||||
[JsonProperty("optimize_vis_validideo_sharing")]
|
[JsonProperty("is_valid: ")]
|
||||||
public string IsValid { get; set; }
|
public string IsValid { get; set; }
|
||||||
[JsonProperty("time_stamp")]
|
[JsonProperty("time_stamp: ")]
|
||||||
public string TimeStamp { get; set; }
|
public string TimeStamp { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Retuns a boolean value if the participant hand state is raised and is valid (both need to be true)
|
||||||
|
/// </summary>
|
||||||
|
public bool HandIsRaisedAndValid
|
||||||
|
{
|
||||||
|
get { return IsValid != null && IsValid == "on" && IsRaiseHand; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ListParticipant
|
public class ListParticipant
|
||||||
{
|
{
|
||||||
[JsonProperty("audio_status state")]
|
[JsonProperty("audio_status state")]
|
||||||
@@ -1205,22 +1411,87 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
HandStatus = new HandStatus();
|
HandStatus = new HandStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts ZoomRoom pariticpant list response to an Essentials participant list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="participants"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static List<Participant> GetGenericParticipantListFromParticipantsResult(
|
public static List<Participant> GetGenericParticipantListFromParticipantsResult(
|
||||||
List<ListParticipant> participants)
|
List<ListParticipant> participants)
|
||||||
{
|
{
|
||||||
return
|
//return participants.Select(p => new Participant
|
||||||
participants.Select(
|
// {
|
||||||
p =>
|
// UserId = p.UserId,
|
||||||
new Participant
|
// Name = p.UserName,
|
||||||
|
// IsHost = p.IsHost,
|
||||||
|
// CanMuteVideo = p.IsVideoCanMuteByHost,
|
||||||
|
// CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
||||||
|
// AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
||||||
|
// VideoMuteFb = p.VideoStatusIsSending,
|
||||||
|
// HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid,
|
||||||
|
// }).ToList();
|
||||||
|
|
||||||
|
var sortedParticipants = SortParticipantListByHandStatus(participants);
|
||||||
|
return sortedParticipants.Select(p => new Participant
|
||||||
{
|
{
|
||||||
|
UserId = p.UserId,
|
||||||
Name = p.UserName,
|
Name = p.UserName,
|
||||||
IsHost = p.IsHost,
|
IsHost = p.IsHost,
|
||||||
CanMuteVideo = p.IsVideoCanMuteByHost,
|
CanMuteVideo = p.IsVideoCanMuteByHost,
|
||||||
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
||||||
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
||||||
VideoMuteFb = p.VideoStatusIsSending
|
VideoMuteFb = p.VideoStatusIsSending,
|
||||||
|
HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will sort by hand-raise status and then alphabetically
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="participants">Zoom Room response list of participants</param>
|
||||||
|
/// <returns>List</returns>
|
||||||
|
public static List<ListParticipant> SortParticipantListByHandStatus(List<ListParticipant> participants)
|
||||||
|
{
|
||||||
|
if (participants == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "SortParticiapntListByHandStatu(participants == null)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug testing
|
||||||
|
foreach (ListParticipant participant in participants)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "{0} | IsValid: {1} | IsRaiseHand: {2} | HandIsRaisedAndValid: {3}",
|
||||||
|
participant.UserName, participant.HandStatus.IsValid, participant.HandStatus.IsRaiseHand.ToString(), participant.HandStatus.HandIsRaisedAndValid.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ListParticipant> handRaisedParticipantsList = participants.Where(p => p.HandStatus.HandIsRaisedAndValid).ToList();
|
||||||
|
|
||||||
|
if (handRaisedParticipantsList != null)
|
||||||
|
{
|
||||||
|
IOrderedEnumerable<ListParticipant> orderByDescending = handRaisedParticipantsList.OrderByDescending(p => p.HandStatus.TimeStamp);
|
||||||
|
|
||||||
|
foreach (var participant in handRaisedParticipantsList)
|
||||||
|
Debug.Console(1, "handRaisedParticipantList: {0} | {1}", participant.UserName, participant.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ListParticipant> allOtherParticipantsList = participants.Where(p => !p.HandStatus.HandIsRaisedAndValid).ToList();
|
||||||
|
|
||||||
|
if (allOtherParticipantsList != null)
|
||||||
|
{
|
||||||
|
allOtherParticipantsList.OrderBy(p => p.UserName);
|
||||||
|
|
||||||
|
foreach (var participant in allOtherParticipantsList)
|
||||||
|
Debug.Console(1, "allOtherParticipantsList: {0} | {1}", participant.UserName, participant.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge the lists
|
||||||
|
List<ListParticipant> sortedList = handRaisedParticipantsList.Union(allOtherParticipantsList).ToList();
|
||||||
|
|
||||||
|
// return the sorted list
|
||||||
|
return sortedList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CallinCountryList
|
public class CallinCountryList
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
using Crestron.SimplSharpPro.CrestronThread;
|
using Crestron.SimplSharpPro.CrestronThread;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Intersystem.Tokens;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
@@ -23,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
||||||
IRouting,
|
IRouting,
|
||||||
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
|
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
|
||||||
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing
|
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute
|
||||||
{
|
{
|
||||||
private const long MeetingRefreshTimer = 60000;
|
private const long MeetingRefreshTimer = 60000;
|
||||||
private const uint DefaultMeetingDurationMin = 30;
|
private const uint DefaultMeetingDurationMin = 30;
|
||||||
@@ -53,7 +55,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
_receiveQueue = new CrestronQueue<string>(1024);
|
_receiveQueue = new CrestronQueue<string>(1024);
|
||||||
|
|
||||||
// The thread responsible for dequeuing and processing the messages
|
// The thread responsible for dequeuing and processing the messages
|
||||||
_receiveThread = new Thread(o => ProcessQueue(), null) {Priority = Thread.eThreadPriority.MediumPriority};
|
_receiveThread = new Thread(o => ProcessQueue(), null) { Priority = Thread.eThreadPriority.MediumPriority };
|
||||||
|
|
||||||
Communication = comm;
|
Communication = comm;
|
||||||
|
|
||||||
@@ -82,7 +84,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync");
|
PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync");
|
||||||
|
|
||||||
PortGather = new CommunicationGather(Communication, "\x0A") {IncludeDelimiter = true};
|
PortGather = new CommunicationGather(Communication, "\x0A") { IncludeDelimiter = true };
|
||||||
PortGather.LineReceived += Port_LineReceived;
|
PortGather.LineReceived += Port_LineReceived;
|
||||||
|
|
||||||
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd,
|
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd,
|
||||||
@@ -121,6 +123,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
||||||
CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
|
CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
|
||||||
CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
|
CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
|
||||||
|
|
||||||
|
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; }
|
public CommunicationGather PortGather { get; private set; }
|
||||||
@@ -216,11 +228,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Func<string> LocalLayoutFeedbackFunc
|
|
||||||
{
|
|
||||||
get { return () => ""; }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Func<bool> LocalLayoutIsProminentFeedbackFunc
|
protected Func<bool> LocalLayoutIsProminentFeedbackFunc
|
||||||
{
|
{
|
||||||
get { return () => false; }
|
get { return () => false; }
|
||||||
@@ -343,7 +350,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public void GetDirectoryFolderContents(string folderId)
|
public void GetDirectoryFolderContents(string folderId)
|
||||||
{
|
{
|
||||||
var directoryResults = new CodecDirectory {ResultsFolderId = folderId};
|
var directoryResults = new CodecDirectory { ResultsFolderId = folderId };
|
||||||
|
|
||||||
directoryResults.AddContactsToDirectory(
|
directoryResults.AddContactsToDirectory(
|
||||||
DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId)));
|
DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId)));
|
||||||
@@ -484,11 +491,55 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
Configuration.Call.Layout.PropertyChanged += (o, a) =>
|
Configuration.Call.Layout.PropertyChanged += (o, a) =>
|
||||||
{
|
{
|
||||||
if (a.PropertyName != "Position") return;
|
switch (a.PropertyName)
|
||||||
|
{
|
||||||
|
case "Position":
|
||||||
|
{
|
||||||
ComputeSelfviewPipStatus();
|
ComputeSelfviewPipStatus();
|
||||||
|
|
||||||
SelfviewPipPositionFeedback.FireUpdate();
|
SelfviewPipPositionFeedback.FireUpdate();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ShareThumb":
|
||||||
|
{
|
||||||
|
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Style":
|
||||||
|
{
|
||||||
|
LocalLayoutFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3
|
||||||
|
Configuration.Client.Call.Layout.PropertyChanged += (o,a) =>
|
||||||
|
{
|
||||||
|
switch (a.PropertyName)
|
||||||
|
{
|
||||||
|
case "Position":
|
||||||
|
{
|
||||||
|
ComputeSelfviewPipStatus();
|
||||||
|
|
||||||
|
SelfviewPipPositionFeedback.FireUpdate();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ShareThumb":
|
||||||
|
{
|
||||||
|
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Style":
|
||||||
|
{
|
||||||
|
LocalLayoutFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
||||||
@@ -542,6 +593,48 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Status.Layout.PropertyChanged += (o, a) =>
|
||||||
|
{
|
||||||
|
switch (a.PropertyName)
|
||||||
|
{
|
||||||
|
case "can_Switch_Speaker_View":
|
||||||
|
case "can_Switch_Wall_View":
|
||||||
|
case "can_Switch_Share_On_All_Screens":
|
||||||
|
{
|
||||||
|
ComputeAvailableLayouts();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "is_In_First_Page":
|
||||||
|
{
|
||||||
|
LayoutViewIsOnFirstPageFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "is_In_Last_Page":
|
||||||
|
{
|
||||||
|
LayoutViewIsOnLastPageFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//case "video_type":
|
||||||
|
// {
|
||||||
|
// 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()
|
private void SetUpDirectory()
|
||||||
@@ -777,7 +870,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
_jsonCurlyBraceCounter--;
|
_jsonCurlyBraceCounter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter);
|
//Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter);
|
||||||
|
|
||||||
if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter)
|
if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter)
|
||||||
// Check for the beginning of a new JSON message
|
// Check for the beginning of a new JSON message
|
||||||
@@ -889,7 +982,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
var eType =
|
var eType =
|
||||||
(eZoomRoomResponseType)
|
(eZoomRoomResponseType)
|
||||||
Enum.Parse(typeof (eZoomRoomResponseType), message["type"].Value<string>(), true);
|
Enum.Parse(typeof(eZoomRoomResponseType), message["type"].Value<string>(), true);
|
||||||
|
|
||||||
var topKey = message["topKey"].Value<string>();
|
var topKey = message["topKey"].Value<string>();
|
||||||
|
|
||||||
@@ -1220,6 +1313,38 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
case "phonecallstatus":
|
case "phonecallstatus":
|
||||||
{
|
{
|
||||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
|
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "pinstatusofscreennotification":
|
||||||
|
{
|
||||||
|
var status = responseObj.ToObject<zEvent.PinStatusOfScreenNotification>();
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1392,7 +1517,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
|
if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Creating new Status.Call object");
|
Debug.Console(1, this, "Creating new Status.Call object");
|
||||||
Status.Call = new zStatus.Call {Status = callStatus};
|
Status.Call = new zStatus.Call { Status = callStatus };
|
||||||
|
|
||||||
SetUpCallFeedbackActions();
|
SetUpCallFeedbackActions();
|
||||||
}
|
}
|
||||||
@@ -1414,7 +1539,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newCall = new CodecActiveCallItem {Status = newStatus};
|
var newCall = new CodecActiveCallItem { Status = newStatus };
|
||||||
|
|
||||||
ActiveCalls.Add(newCall);
|
ActiveCalls.Add(newCall);
|
||||||
|
|
||||||
@@ -1524,7 +1649,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public override void MuteOff()
|
public override void MuteOff()
|
||||||
{
|
{
|
||||||
SetVolume((ushort) _previousVolumeLevel);
|
SetVolume((ushort)_previousVolumeLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void MuteOn()
|
public override void MuteOn()
|
||||||
@@ -1600,7 +1725,87 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge);
|
var joinMap = new ZoomRoomJoinMap(joinStart);
|
||||||
|
|
||||||
|
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (customJoins != null)
|
||||||
|
{
|
||||||
|
joinMap.SetCustomJoinData(customJoins);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bridge != null)
|
||||||
|
{
|
||||||
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkVideoCodecToApi(this, trilist, joinMap);
|
||||||
|
|
||||||
|
LinkZoomRoomToApi(trilist, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Links all the specific Zoom functionality to the API bridge
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trilist"></param>
|
||||||
|
/// <param name="joinMap"></param>
|
||||||
|
public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap)
|
||||||
|
{
|
||||||
|
var layoutsCodec = this as IHasZoomRoomLayouts;
|
||||||
|
if (layoutsCodec != null)
|
||||||
|
{
|
||||||
|
layoutsCodec.AvailableLayoutsChanged += (o, a) =>
|
||||||
|
{
|
||||||
|
trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery));
|
||||||
|
trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker));
|
||||||
|
trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip));
|
||||||
|
trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll));
|
||||||
|
|
||||||
|
// pass the names used to set the layout through the bridge
|
||||||
|
trilist.SetString(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery.ToString());
|
||||||
|
trilist.SetString(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker.ToString());
|
||||||
|
trilist.SetString(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip.ToString());
|
||||||
|
trilist.SetString(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll.ToString());
|
||||||
|
};
|
||||||
|
|
||||||
|
layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
|
||||||
|
trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail());
|
||||||
|
layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]);
|
||||||
|
|
||||||
|
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.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts());
|
||||||
|
|
||||||
|
trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true);
|
||||||
|
SetLayout(style);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExecuteSwitch(object selector)
|
public override void ExecuteSwitch(object selector)
|
||||||
@@ -1656,7 +1861,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public override void Dial(Meeting meeting)
|
public override void Dial(Meeting meeting)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this,"Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title);
|
Debug.Console(1, this, "Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title);
|
||||||
SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id));
|
SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1770,6 +1975,114 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
#endregion
|
#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<int> 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
|
#region Implementation of IHasCameraOff
|
||||||
|
|
||||||
public BoolFeedback CameraIsOffFeedback { get; private set; }
|
public BoolFeedback CameraIsOffFeedback { get; private set; }
|
||||||
@@ -1875,7 +2188,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
#region Implementation of IHasPhoneDialing
|
#region Implementation of IHasPhoneDialing
|
||||||
|
|
||||||
private Func<bool> PhoneOffHookFeedbackFunc {get {return () => Status.PhoneCall.OffHook; }}
|
private Func<bool> PhoneOffHookFeedbackFunc { get { return () => Status.PhoneCall.OffHook; } }
|
||||||
private Func<string> CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
|
private Func<string> CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
|
||||||
private Func<string> CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } }
|
private Func<string> CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } }
|
||||||
|
|
||||||
@@ -1899,6 +2212,137 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region IHasZoomRoomLayouts Members
|
||||||
|
|
||||||
|
public event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
|
||||||
|
|
||||||
|
private Func<bool> LayoutViewIsOnFirstPageFeedbackFunc { get { return () => Status.Layout.is_In_First_Page; } }
|
||||||
|
private Func<bool> LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } }
|
||||||
|
private Func<bool> CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } }
|
||||||
|
private Func<bool> ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } }
|
||||||
|
|
||||||
|
public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback LayoutViewIsOnLastPageFeedback { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback CanSwapContentWithThumbnailFeedback { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback ContentSwappedWithThumbnailFeedback { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
public zConfiguration.eLayoutStyle LastSelectedLayout { get; private set; }
|
||||||
|
|
||||||
|
public zConfiguration.eLayoutStyle AvailableLayouts { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads individual properties to determine if which layouts are avalailable
|
||||||
|
/// </summary>
|
||||||
|
private void ComputeAvailableLayouts()
|
||||||
|
{
|
||||||
|
zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None;
|
||||||
|
// TODO: #697 [X] 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status.Layout.can_Switch_Speaker_View)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.Speaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status.Layout.can_Switch_Share_On_All_Screens)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.ShareAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is no property that directly reports if strip mode is valid, but API stipulates
|
||||||
|
// that strip mode is available if the number of screens is 1
|
||||||
|
if (Status.NumberOfScreens.NumOfScreens == 1)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.Strip;
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = AvailableLayoutsChanged;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts });
|
||||||
|
}
|
||||||
|
|
||||||
|
AvailableLayouts = availableLayouts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetAvailableLayouts()
|
||||||
|
{
|
||||||
|
SendText("zStatus Call Layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLayout(zConfiguration.eLayoutStyle layoutStyle)
|
||||||
|
{
|
||||||
|
LastSelectedLayout = layoutStyle;
|
||||||
|
SendText(String.Format("zConfiguration Call Layout Style: {0}", layoutStyle.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SwapContentWithThumbnail()
|
||||||
|
{
|
||||||
|
if (CanSwapContentWithThumbnailFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state
|
||||||
|
// TODO: #697 [*] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback
|
||||||
|
// to toggle the state
|
||||||
|
SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LayoutTurnNextPage()
|
||||||
|
{
|
||||||
|
SendText("zCommand Call Layout TurnPage Forward: On");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LayoutTurnPreviousPage()
|
||||||
|
{
|
||||||
|
SendText("zCommand Call Layout TurnPage Forward: Off");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IHasCodecLayouts Members
|
||||||
|
|
||||||
|
private Func<string> LocalLayoutFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None)
|
||||||
|
return Configuration.Call.Layout.Style.ToString();
|
||||||
|
else
|
||||||
|
return Configuration.Client.Call.Layout.Style.ToString();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringFeedback LocalLayoutFeedback { get; private set; }
|
||||||
|
|
||||||
|
public void LocalLayoutToggle()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LocalLayoutToggleSingleProminent()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MinMaxLayoutToggle()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -2115,7 +2559,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
{
|
{
|
||||||
public ZoomRoomFactory()
|
public ZoomRoomFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string> {"zoomroom"};
|
TypeNames = new List<string> { "zoomroom" };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
using System;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Bridges.JoinMaps;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||||
|
{
|
||||||
|
public class ZoomRoomJoinMap : VideoCodecControllerJoinMap
|
||||||
|
{
|
||||||
|
// TODO: #697 [X] Set join numbers
|
||||||
|
|
||||||
|
#region Digital
|
||||||
|
|
||||||
|
[JoinName("CanSwapContentWithThumbnail")]
|
||||||
|
public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 206,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "FB Indicates if content can be swapped with thumbnail",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("SwapContentWithThumbnail")]
|
||||||
|
public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 206,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Pulse to swap content with thumbnail. FB reports current state",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("GetAvailableLayouts")]
|
||||||
|
public JoinDataComplete GetAvailableLayouts = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 215,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.",
|
||||||
|
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutIsOnFirstPage")]
|
||||||
|
public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 216,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Indicates if layout is on first page",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutIsOnLastPage")]
|
||||||
|
public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 217,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Indicates if layout is on first page",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutTurnToNextPage")]
|
||||||
|
public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 216,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Turns layout view to next page",
|
||||||
|
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutTurnToPreviousPage")]
|
||||||
|
public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 217,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Turns layout view to previous page",
|
||||||
|
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||||
|
JoinType = eJoinType.Digital
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutGalleryIsAvailable")]
|
||||||
|
public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 221,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "FB Indicates if layout 'Gallery' is available",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.DigitalSerial
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutSpeakerIsAvailable")]
|
||||||
|
public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 222,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "FB Indicates if layout 'Speaker' is available",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.DigitalSerial
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutStripIsAvailable")]
|
||||||
|
public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 223,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "FB Indicates if layout 'Strip' is available",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.DigitalSerial
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("LayoutShareAllIsAvailable")]
|
||||||
|
public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 224,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "FB Indicates if layout 'ShareAll' is available",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.DigitalSerial
|
||||||
|
});
|
||||||
|
|
||||||
|
//[JoinName("ParticipantAudioMuteToggleStart")]
|
||||||
|
//public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
|
||||||
|
// new JoinData
|
||||||
|
// {
|
||||||
|
// JoinNumber = 500,
|
||||||
|
// JoinSpan = 100
|
||||||
|
// },
|
||||||
|
// new JoinMetadata
|
||||||
|
// {
|
||||||
|
// Description = "Toggles the participant's audio mute status",
|
||||||
|
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
// JoinType = eJoinType.Digital
|
||||||
|
// });
|
||||||
|
|
||||||
|
//[JoinName("ParticipantVideoMuteToggleStart")]
|
||||||
|
//public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
|
||||||
|
// new JoinData
|
||||||
|
// {
|
||||||
|
// JoinNumber = 800,
|
||||||
|
// JoinSpan = 100
|
||||||
|
// },
|
||||||
|
// new JoinMetadata
|
||||||
|
// {
|
||||||
|
// Description = "Toggles the participant's video mute status",
|
||||||
|
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
// JoinType = eJoinType.Digital
|
||||||
|
// });
|
||||||
|
|
||||||
|
//[JoinName("ParticipantPinToggleStart")]
|
||||||
|
//public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
|
||||||
|
// new JoinData
|
||||||
|
// {
|
||||||
|
// JoinNumber = 1100,
|
||||||
|
// JoinSpan = 100
|
||||||
|
// },
|
||||||
|
// new JoinMetadata
|
||||||
|
// {
|
||||||
|
// Description = "Toggles the participant's pin status",
|
||||||
|
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
// JoinType = eJoinType.Digital
|
||||||
|
// });
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Analog
|
||||||
|
|
||||||
|
[JoinName("NumberOfScreens")]
|
||||||
|
public JoinDataComplete NumberOfScreens = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 11,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Reports the number of screens connected",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||||
|
JoinType = eJoinType.Analog
|
||||||
|
});
|
||||||
|
|
||||||
|
[JoinName("ScreenIndexToPinUserTo")]
|
||||||
|
public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 11,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Specifies the screen index a participant should be pinned to",
|
||||||
|
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||||
|
JoinType = eJoinType.Analog
|
||||||
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
|
||||||
|
[JoinName("GetSetCurrentLayout")]
|
||||||
|
public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete(
|
||||||
|
new JoinData
|
||||||
|
{
|
||||||
|
JoinNumber = 215,
|
||||||
|
JoinSpan = 1
|
||||||
|
},
|
||||||
|
new JoinMetadata
|
||||||
|
{
|
||||||
|
Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts",
|
||||||
|
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||||
|
JoinType = eJoinType.Serial
|
||||||
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public ZoomRoomJoinMap(uint joinStart)
|
||||||
|
: base(joinStart, typeof(ZoomRoomJoinMap))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZoomRoomJoinMap(uint joinStart, Type type)
|
||||||
|
: base(joinStart, type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user