Worked on VC directory and favorites. Fixed various bugs.

This commit is contained in:
Neil Dorin
2017-10-11 21:43:14 -06:00
parent 2def648596
commit fb0a91b454
16 changed files with 1895 additions and 1674 deletions

View File

@@ -5,6 +5,7 @@ using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.Devices.Common.Codec namespace PepperDash.Essentials.Devices.Common.Codec
@@ -54,16 +55,16 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{ {
handler(this, new EventArgs()); handler(this, new EventArgs());
if (Debug.Level == 1) //if (Debug.Level == 1)
{ //{
Debug.Console(1, "RecentCalls:\n"); // Debug.Console(1, "RecentCalls:\n");
foreach (CodecCallHistory.CallHistoryEntry entry in RecentCalls) // foreach (CodecCallHistory.CallHistoryEntry entry in RecentCalls)
{ // {
Debug.Console(1, "\nName: {0}\nNumber: {1}\nStartTime: {2}\nType: {3}\n", entry.Name, entry.Number, entry.StartTime.ToString(), entry.OccurenceType); // Debug.Console(1, "\nName: {0}\nNumber: {1}\nStartTime: {2}\nType: {3}\n", entry.Name, entry.Number, entry.StartTime.ToString(), entry.OccurenceType);
} // }
} //}
} }
} }
@@ -94,13 +95,14 @@ namespace PepperDash.Essentials.Devices.Common.Codec
foreach (CiscoCallHistory.Entry entry in entries) foreach (CiscoCallHistory.Entry entry in entries)
{ {
genericEntries.Add(new CallHistoryEntry() genericEntries.Add(new CallHistoryEntry()
{ {
Name = entry.DisplayName.Value, Name = entry.DisplayName.Value,
Number = entry.CallbackNumber.Value, Number = entry.CallbackNumber.Value,
StartTime = entry.LastOccurrenceStartTime.Value, StartTime = entry.LastOccurrenceStartTime.Value,
OccurrenceHistoryId = entry.LastOccurrenceHistoryId.Value, OccurrenceHistoryId = entry.LastOccurrenceHistoryId.Value,
OccurenceType = ConvertToOccurenceTypeEnum(entry.OccurrenceType.Value) OccurenceType = ConvertToOccurenceTypeEnum(entry.OccurrenceType.Value)
}); });
} }

View File

@@ -15,6 +15,8 @@ namespace PepperDash.Essentials.Devices.Common.Codec
CodecDirectory DirectoryRoot { get; } CodecDirectory DirectoryRoot { get; }
CodecPhonebookSyncState PhonebookSyncState { get; }
void SearchDirectory(string searchString); void SearchDirectory(string searchString);
void GetDirectoryFolderContents(string folderId); void GetDirectoryFolderContents(string folderId);
@@ -29,7 +31,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{ {
public List<DirectoryItem> DirectoryResults { get; private set; } public List<DirectoryItem> DirectoryResults { get; private set; }
//public int Offset { get; private set; } public string ResultsFolderId { get; set; }
//public int Limit { get; private set; } //public int Limit { get; private set; }

View File

@@ -132,8 +132,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
&& DateTime.Now <= EndTime.AddMinutes(-5); && DateTime.Now <= EndTime.AddMinutes(-5);
} }
} }
public string ConferenceNumberToDial { get; set; } //public string ConferenceNumberToDial { get; set; }
public string ConferencePassword { get; set; } public string ConferencePassword { get; set; }
public bool IsOneButtonToPushMeeting { get; set; }
public List<Call> Calls { get; private set; }
public Meeting()
{
Calls = new List<Call>();
}
}
public class Call
{
public string Number { get; set; }
public string Protocol { get; set; }
public string CallRate { get; set; }
public string CallType { get; set; }
} }
public class MeetingEventArgs : EventArgs public class MeetingEventArgs : EventArgs

View File

@@ -136,8 +136,8 @@
<Compile Include="Streaming\Roku.cs" /> <Compile Include="Streaming\Roku.cs" />
<Compile Include="VideoCodec\CiscoCodec\BookingsDataClasses.cs" /> <Compile Include="VideoCodec\CiscoCodec\BookingsDataClasses.cs" />
<Compile Include="VideoCodec\CiscoCodec\CallHistoryDataClasses.cs" /> <Compile Include="VideoCodec\CiscoCodec\CallHistoryDataClasses.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCodec.cs" /> <Compile Include="VideoCodec\CiscoCodec\CiscoSparkCodec.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCodecPropertiesConfig.cs" /> <Compile Include="VideoCodec\CiscoCodec\CiscoSparkCodecPropertiesConfig.cs" />
<Compile Include="VideoCodec\MockVC\MockVcPropertiesConfig.cs" /> <Compile Include="VideoCodec\MockVC\MockVcPropertiesConfig.cs" />
<Compile Include="VideoCodec\CiscoCodec\PhonebookDataClasses.cs" /> <Compile Include="VideoCodec\CiscoCodec\PhonebookDataClasses.cs" />
<Compile Include="VideoCodec\CiscoCodec\xConfiguration.cs" /> <Compile Include="VideoCodec\CiscoCodec\xConfiguration.cs" />

View File

@@ -109,11 +109,11 @@ namespace PepperDash.Essentials.Devices.Common
.MockVC(key, name, props); .MockVC(key, name, props);
} }
else if (typeName == "ciscocodec") else if (typeName.StartsWith("ciscospark"))
{ {
var comm = CommFactory.CreateCommForDevice(dc); var comm = CommFactory.CreateCommForDevice(dc);
var props = JsonConvert.DeserializeObject<Codec.CiscoCodecPropertiesConfig>(properties.ToString()); var props = JsonConvert.DeserializeObject<Codec.CiscoSparkCodecPropertiesConfig>(properties.ToString());
return new PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoCodec(key, name, comm, props); return new PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec(key, name, comm, props);
} }
else if (groupName == "settopbox") //(typeName == "irstbbase") else if (groupName == "settopbox") //(typeName == "irstbbase")

View File

@@ -189,8 +189,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public string Value { get; set; } public string Value { get; set; }
} }
public class Calls public class Number
{ {
public string Value { get; set; }
}
public class Protocol
{
public string Value { get; set; }
}
public class CallRate
{
public string Value { get; set; }
}
public class CallType
{
public string Value { get; set; }
}
public class Call
{
public Number Number { get; set; }
public Protocol Protocol { get; set; }
public CallRate CallRate { get; set; }
public CallType CallType { get; set; }
} }
public class ConnectMode public class ConnectMode
@@ -200,8 +224,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public class DialInfo public class DialInfo
{ {
public Calls Calls { get; set; } public List<Call> Calls { get; set; }
public ConnectMode ConnectMode { get; set; } public ConnectMode ConnectMode { get; set; }
public DialInfo()
{
Calls = new List<Call>();
}
} }
public class Booking public class Booking
@@ -231,6 +260,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
Title = new Title(); Title = new Title();
Agenda = new Agenda(); Agenda = new Agenda();
Privacy = new Privacy(); Privacy = new Privacy();
DialInfo = new DialInfo();
} }
} }
@@ -270,13 +300,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
var meeting = new Meeting(); var meeting = new Meeting();
meeting.Id = b.Id.Value; if(b.Id != null)
meeting.Organizer = string.Format("{0}, {1}", b.Organizer.LastName.Value, b.Organizer.FirstName.Value); meeting.Id = b.Id.Value;
meeting.Title = b.Title.Value; if(b.Organizer != null)
meeting.Agenda = b.Agenda.Value; meeting.Organizer = string.Format("{0}, {1}", b.Organizer.LastName.Value, b.Organizer.FirstName.Value);
meeting.StartTime = b.Time.StartTime.Value; if(b.Title != null)
meeting.EndTime = b.Time.EndTime.Value; meeting.Title = b.Title.Value;
meeting.Privacy = CodecCallPrivacy.ConvertToDirectionEnum(b.Privacy.Value); if(b.Agenda != null)
meeting.Agenda = b.Agenda.Value;
if(b.Time != null)
meeting.StartTime = b.Time.StartTime.Value;
meeting.EndTime = b.Time.EndTime.Value;
if(b.Privacy != null)
meeting.Privacy = CodecCallPrivacy.ConvertToDirectionEnum(b.Privacy.Value);
#warning Update this ConnectMode conversion after testing onsite. Expected value is "OBTP", but in PD NYC Test scenarios, "Manual" is being returned for OBTP meetings
if (b.DialInfo.ConnectMode != null)
if (b.DialInfo.ConnectMode.Value.ToLower() == "obtp" || b.DialInfo.ConnectMode.Value.ToLower() == "manual")
meeting.IsOneButtonToPushMeeting = true;
foreach (Call c in b.DialInfo.Calls)
{
meeting.Calls.Add(new PepperDash.Essentials.Devices.Common.Codec.Call()
{
Number = c.Number.Value,
Protocol = c.Protocol.Value,
CallRate = c.CallRate.Value,
CallType = c.CallType.Value
});
}
meetings.Add(meeting); meetings.Add(meeting);
@@ -284,7 +337,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}, Agenda: {3}", meeting.Title, meeting.Id, meeting.Organizer, meeting.Agenda); Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}, Agenda: {3}", meeting.Title, meeting.Id, meeting.Organizer, meeting.Agenda);
Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration); Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration);
Debug.Console(1, " Joinable: {0}", meeting.Joinable); Debug.Console(1, " Joinable: {0}\n", meeting.Joinable);
} }
} }

View File

@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration };
public class CiscoCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory,
IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfview IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfview
{ {
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned; public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
@@ -188,7 +188,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
private CodecSyncState SyncState; private CodecSyncState SyncState;
private CodecPhonebookSyncState PhonebookSyncState; public CodecPhonebookSyncState PhonebookSyncState { get; private set; }
private StringBuilder JsonMessage; private StringBuilder JsonMessage;
@@ -214,7 +214,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public RoutingOutputPort HdmiOut { get; private set; } public RoutingOutputPort HdmiOut { get; private set; }
// Constructor for IBasicCommunication // Constructor for IBasicCommunication
public CiscoCodec(string key, string name, IBasicCommunication comm, CiscoCodecPropertiesConfig props ) public CiscoSparkCodec(string key, string name, IBasicCommunication comm, CiscoSparkCodecPropertiesConfig props )
: base(key, name) : base(key, name)
{ {
StandbyIsOnFeedback = new BoolFeedback(StandbyStateFeedbackFunc); StandbyIsOnFeedback = new BoolFeedback(StandbyStateFeedbackFunc);
@@ -329,6 +329,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
prefix + "/Status/RoomAnalytics" + Delimiter + prefix + "/Status/RoomAnalytics" + Delimiter +
prefix + "/Status/Standby" + Delimiter + prefix + "/Status/Standby" + Delimiter +
prefix + "/Status/Video/Selfview" + Delimiter + prefix + "/Status/Video/Selfview" + Delimiter +
prefix + "/Status/Video/Layout" + Delimiter +
prefix + "/Bookings" + Delimiter + prefix + "/Bookings" + Delimiter +
prefix + "/Event/CallDisconnect" + Delimiter; prefix + "/Event/CallDisconnect" + Delimiter;
@@ -675,9 +676,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
JsonConvert.PopulateObject(response, codecBookings); JsonConvert.PopulateObject(response, codecBookings);
CodecSchedule.Meetings = CiscoCodecBookings.GetGenericMeetingsFromBookingResult(codecBookings.CommandResponse.BookingsListResult.Booking); if(codecBookings.CommandResponse.BookingsListResult.ResultInfo.TotalRows.Value != "0")
CodecSchedule.Meetings = CiscoCodecBookings.GetGenericMeetingsFromBookingResult(codecBookings.CommandResponse.BookingsListResult.Booking);
} }
} }
@@ -795,7 +796,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
/// <param name="folderId"></param> /// <param name="folderId"></param>
public void GetDirectoryFolderContents(string folderId) public void GetDirectoryFolderContents(string folderId)
{ {
SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Contact Limit: {2}", folderId, PhonebookMode, PhonebookResultsLimit)); SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Any Limit: {2}", folderId, PhonebookMode, PhonebookResultsLimit));
} }
void PrintPhonebook(CodecDirectory directory) void PrintPhonebook(CodecDirectory directory)
@@ -808,7 +809,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
if (item is DirectoryFolder) if (item is DirectoryFolder)
{ {
Debug.Console(1, this, "+ {0}", item.Name); Debug.Console(1, this, "[+] {0}", item.Name);
} }
else if (item is DirectoryContact) else if (item is DirectoryContact)
{ {
@@ -818,14 +819,38 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
} }
} }
public override void Dial(string s) /// <summary>
/// Simple dial method
/// </summary>
/// <param name="number"></param>
public override void Dial(string number)
{ {
SendText(string.Format("xCommand Dial Number: \"{0}\"", s)); SendText(string.Format("xCommand Dial Number: \"{0}\"", number));
} }
public void DialBookingId(string s) /// <summary>
/// Dials a specific meeting
/// </summary>
/// <param name="meeting"></param>
public override void Dial(Meeting meeting)
{ {
SendText(string.Format("xCommand Dial BookingId: {0}", s)); foreach (Call c in meeting.Calls)
{
Dial(c.Number, c.Protocol, c.CallRate, c.CallType, meeting.Id);
}
}
/// <summary>
/// Detailed dial method
/// </summary>
/// <param name="number"></param>
/// <param name="protocol"></param>
/// <param name="callRate"></param>
/// <param name="callType"></param>
/// <param name="meetingId"></param>
public void Dial(string number, string protocol, string callRate, string callType, string meetingId)
{
SendText(string.Format("xCommand Dial Number: \"{0}\" Protocol: {1} CallRate: {2} CallType: {3} BookingId: {4}", number, protocol, callRate, callType, meetingId));
} }
public override void EndCall(CodecActiveCallItem activeCall) public override void EndCall(CodecActiveCallItem activeCall)
@@ -1259,98 +1284,4 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
} }
} }
/// <summary>
/// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info
/// </summary>
public class CodecPhonebookSyncState : IKeyed
{
bool _InitialSyncComplete;
public event EventHandler<EventArgs> InitialSyncCompleted;
public string Key { get; private set; }
public bool InitialSyncComplete
{
get { return _InitialSyncComplete; }
private set
{
if (value == true)
{
var handler = InitialSyncCompleted;
if (handler != null)
handler(this, new EventArgs());
}
_InitialSyncComplete = value;
}
}
public bool InitialPhonebookFoldersWasReceived { get; private set; }
public bool NumberOfContactsWasReceived { get; private set; }
public bool PhonebookRootEntriesWasRecieved { get; private set; }
public bool PhonebookHasFolders { get; private set; }
public int NumberOfContacts { get; private set; }
public CodecPhonebookSyncState(string key)
{
Key = key;
CodecDisconnected();
}
public void InitialPhonebookFoldersReceived()
{
InitialPhonebookFoldersWasReceived = true;
CheckSyncStatus();
}
public void PhonebookRootEntriesReceived()
{
PhonebookRootEntriesWasRecieved = true;
CheckSyncStatus();
}
public void SetPhonebookHasFolders(bool value)
{
PhonebookHasFolders = value;
Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders);
}
public void SetNumberOfContacts(int contacts)
{
NumberOfContacts = contacts;
NumberOfContactsWasReceived = true;
Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts);
CheckSyncStatus();
}
public void CodecDisconnected()
{
InitialPhonebookFoldersWasReceived = false;
PhonebookHasFolders = false;
NumberOfContacts = 0;
NumberOfContactsWasReceived = false;
}
void CheckSyncStatus()
{
if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
{
InitialSyncComplete = true;
Debug.Console(1, this, "Initial Phonebook Sync Complete!");
}
else
InitialSyncComplete = false;
}
}
} }

View File

@@ -9,7 +9,7 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec namespace PepperDash.Essentials.Devices.Common.Codec
{ {
public class CiscoCodecPropertiesConfig public class CiscoSparkCodecPropertiesConfig
{ {
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }

View File

@@ -278,6 +278,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// Converts data returned from a cisco codec to the generic Directory format. /// Converts data returned from a cisco codec to the generic Directory format.
/// </summary> /// </summary>
/// <param name="result"></param> /// <param name="result"></param>
/// <param name="resultFolder"></param>
/// <returns></returns> /// <returns></returns>
public static CodecDirectory ConvertCiscoPhonebookToGeneric(PhonebookSearchResult result) public static CodecDirectory ConvertCiscoPhonebookToGeneric(PhonebookSearchResult result)
{ {

View File

@@ -1,401 +1,406 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Core.Routing;
using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
public class MockVC : VideoCodecBase, IRoutingSource, IHasCallHistory, IHasScheduleAwareness, IHasCallFavorites public class MockVC : VideoCodecBase, IRoutingSource, IHasCallHistory, IHasScheduleAwareness, IHasCallFavorites
{ {
public RoutingInputPort CodecOsdIn { get; private set; } public RoutingInputPort CodecOsdIn { get; private set; }
public RoutingInputPort HdmiIn1 { get; private set; } public RoutingInputPort HdmiIn1 { get; private set; }
public RoutingInputPort HdmiIn2 { get; private set; } public RoutingInputPort HdmiIn2 { get; private set; }
public RoutingOutputPort HdmiOut { get; private set; } public RoutingOutputPort HdmiOut { get; private set; }
public CodecCallFavorites CallFavorites { get; private set; } public CodecCallFavorites CallFavorites { get; private set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public MockVC(string key, string name, MockVcPropertiesConfig props) public MockVC(string key, string name, MockVcPropertiesConfig props)
: base(key, name) : base(key, name)
{ {
CodecInfo = new MockCodecInfo(); CodecInfo = new MockCodecInfo();
// Get favoritesw // Get favoritesw
if (props.Favorites != null) if (props.Favorites != null)
{ {
CallFavorites = new CodecCallFavorites(); CallFavorites = new CodecCallFavorites();
CallFavorites.Favorites = props.Favorites; CallFavorites.Favorites = props.Favorites;
} }
// Debug helpers // Debug helpers
IncomingCallFeedback.OutputChange += (o, a) => Debug.Console(1, this, "IncomingCall={0}", _IncomingCall); IncomingCallFeedback.OutputChange += (o, a) => Debug.Console(1, this, "IncomingCall={0}", _IncomingCall);
MuteFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Mute={0}", _IsMuted); MuteFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Mute={0}", _IsMuted);
PrivacyModeIsOnFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Privacy={0}", _PrivacyModeIsOn); PrivacyModeIsOnFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Privacy={0}", _PrivacyModeIsOn);
SharingSourceFeedback.OutputChange += (o, a) => Debug.Console(1, this, "SharingSource={0}", _SharingSource); SharingSourceFeedback.OutputChange += (o, a) => Debug.Console(1, this, "SharingSource={0}", _SharingSource);
VolumeLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Volume={0}", _VolumeLevel); VolumeLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Volume={0}", _VolumeLevel);
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 0, this); CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 0, this);
HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 1, this); HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 1, this);
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 2, this); HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 2, this);
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this); HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
InputPorts.Add(CodecOsdIn); InputPorts.Add(CodecOsdIn);
InputPorts.Add(HdmiIn1); InputPorts.Add(HdmiIn1);
InputPorts.Add(HdmiIn2); InputPorts.Add(HdmiIn2);
OutputPorts.Add(HdmiOut); OutputPorts.Add(HdmiOut);
CallHistory = new CodecCallHistory(); CallHistory = new CodecCallHistory();
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
var call = new CodecCallHistory.CallHistoryEntry(); var call = new CodecCallHistory.CallHistoryEntry();
call.Name = "Call " + i; call.Name = "Call " + i;
call.Number = i + "@call.com"; call.Number = i + "@call.com";
CallHistory.RecentCalls.Add(call); CallHistory.RecentCalls.Add(call);
} }
// eventually fire history event here // eventually fire history event here
SetIsReady(); SetIsReady();
} }
protected override Func<bool> IncomingCallFeedbackFunc protected override Func<bool> IncomingCallFeedbackFunc
{ {
get { return () => _IncomingCall; } get { return () => _IncomingCall; }
} }
bool _IncomingCall; bool _IncomingCall;
protected override Func<bool> MuteFeedbackFunc protected override Func<bool> MuteFeedbackFunc
{ {
get { return () => _IsMuted; } get { return () => _IsMuted; }
} }
bool _IsMuted; bool _IsMuted;
protected override Func<bool> PrivacyModeIsOnFeedbackFunc protected override Func<bool> PrivacyModeIsOnFeedbackFunc
{ {
get { return () => _PrivacyModeIsOn; } get { return () => _PrivacyModeIsOn; }
} }
bool _PrivacyModeIsOn; bool _PrivacyModeIsOn;
protected override Func<string> SharingSourceFeedbackFunc protected override Func<string> SharingSourceFeedbackFunc
{ {
get { return () => _SharingSource; } get { return () => _SharingSource; }
} }
string _SharingSource; string _SharingSource;
protected override Func<int> VolumeLevelFeedbackFunc protected override Func<int> VolumeLevelFeedbackFunc
{ {
get { return () => _VolumeLevel; } get { return () => _VolumeLevel; }
} }
int _VolumeLevel; int _VolumeLevel;
/// <summary> /// <summary>
/// Dials, yo! /// Dials, yo!
/// </summary> /// </summary>
public override void Dial(string s) public override void Dial(string number)
{ {
Debug.Console(1, this, "Dial: {0}", s); Debug.Console(1, this, "Dial: {0}", number);
var call = new CodecActiveCallItem() { Name = s, Number = s, Id = s, Status = eCodecCallStatus.Dialing }; var call = new CodecActiveCallItem() { Name = number, Number = number, Id = number, Status = eCodecCallStatus.Dialing };
ActiveCalls.Add(call); ActiveCalls.Add(call);
OnCallStatusChange(eCodecCallStatus.Unknown, call.Status, call); OnCallStatusChange(eCodecCallStatus.Unknown, call.Status, call);
//ActiveCallCountFeedback.FireUpdate(); //ActiveCallCountFeedback.FireUpdate();
// Simulate 2-second ring, then connecting, then connected // Simulate 2-second ring, then connecting, then connected
new CTimer(o => new CTimer(o =>
{ {
call.Type = eCodecCallType.Video; call.Type = eCodecCallType.Video;
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call); SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call);
new CTimer(oo => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000); new CTimer(oo => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000);
}, 2000); }, 2000);
} }
/// <summary> public override void Dial(Meeting meeting)
/// {
/// </summary> throw new NotImplementedException();
public override void EndCall(CodecActiveCallItem call) }
{
Debug.Console(1, this, "EndCall"); /// <summary>
ActiveCalls.Remove(call); ///
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call); /// </summary>
//ActiveCallCountFeedback.FireUpdate(); public override void EndCall(CodecActiveCallItem call)
} {
Debug.Console(1, this, "EndCall");
/// <summary> ActiveCalls.Remove(call);
/// SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call);
/// </summary> //ActiveCallCountFeedback.FireUpdate();
public override void EndAllCalls() }
{
Debug.Console(1, this, "EndAllCalls"); /// <summary>
for(int i = ActiveCalls.Count - 1; i >= 0; i--) ///
{ /// </summary>
var call = ActiveCalls[i]; public override void EndAllCalls()
ActiveCalls.Remove(call); {
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call); Debug.Console(1, this, "EndAllCalls");
} for(int i = ActiveCalls.Count - 1; i >= 0; i--)
//ActiveCallCountFeedback.FireUpdate(); {
} var call = ActiveCalls[i];
ActiveCalls.Remove(call);
/// <summary> SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call);
/// For a call from the test methods below }
/// </summary> //ActiveCallCountFeedback.FireUpdate();
public override void AcceptCall(CodecActiveCallItem call) }
{
Debug.Console(1, this, "AcceptCall"); /// <summary>
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call); /// For a call from the test methods below
new CTimer(o => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000); /// </summary>
// should already be in active list public override void AcceptCall(CodecActiveCallItem call)
} {
Debug.Console(1, this, "AcceptCall");
/// <summary> SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call);
/// For a call from the test methods below new CTimer(o => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000);
/// </summary> // should already be in active list
public override void RejectCall(CodecActiveCallItem call) }
{
Debug.Console(1, this, "RejectCall"); /// <summary>
ActiveCalls.Remove(call); /// For a call from the test methods below
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call); /// </summary>
//ActiveCallCountFeedback.FireUpdate(); public override void RejectCall(CodecActiveCallItem call)
} {
Debug.Console(1, this, "RejectCall");
/// <summary> ActiveCalls.Remove(call);
/// Makes horrible tones go out on the wire! SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call);
/// </summary> //ActiveCallCountFeedback.FireUpdate();
/// <param name="s"></param> }
public override void SendDtmf(string s)
{ /// <summary>
Debug.Console(1, this, "SendDTMF: {0}", s); /// Makes horrible tones go out on the wire!
} /// </summary>
/// <param name="s"></param>
/// <summary> public override void SendDtmf(string s)
/// {
/// </summary> Debug.Console(1, this, "SendDTMF: {0}", s);
public override void StartSharing() }
{
} /// <summary>
///
/// <summary> /// </summary>
/// public override void StartSharing()
/// </summary> {
public override void StopSharing() }
{
} /// <summary>
///
/// <summary> /// </summary>
/// Called by routing to make it happen public override void StopSharing()
/// </summary> {
/// <param name="selector"></param> }
public override void ExecuteSwitch(object selector)
{ /// <summary>
Debug.Console(1, this, "ExecuteSwitch: {0}", selector); /// Called by routing to make it happen
_SharingSource = selector.ToString(); /// </summary>
} /// <param name="selector"></param>
public override void ExecuteSwitch(object selector)
/// <summary> {
/// Debug.Console(1, this, "ExecuteSwitch: {0}", selector);
/// </summary> _SharingSource = selector.ToString();
public override void MuteOff() }
{
_IsMuted = false; /// <summary>
MuteFeedback.FireUpdate(); ///
} /// </summary>
public override void MuteOff()
/// <summary> {
/// _IsMuted = false;
/// </summary> MuteFeedback.FireUpdate();
public override void MuteOn() }
{
_IsMuted = true; /// <summary>
MuteFeedback.FireUpdate(); ///
} /// </summary>
public override void MuteOn()
/// <summary> {
/// _IsMuted = true;
/// </summary> MuteFeedback.FireUpdate();
public override void MuteToggle() }
{
_IsMuted = !_IsMuted; /// <summary>
MuteFeedback.FireUpdate(); ///
} /// </summary>
public override void MuteToggle()
/// <summary> {
/// _IsMuted = !_IsMuted;
/// </summary> MuteFeedback.FireUpdate();
/// <param name="level"></param> }
public override void SetVolume(ushort level)
{ /// <summary>
_VolumeLevel = level; ///
VolumeLevelFeedback.FireUpdate(); /// </summary>
} /// <param name="level"></param>
public override void SetVolume(ushort level)
/// <summary> {
/// _VolumeLevel = level;
/// </summary> VolumeLevelFeedback.FireUpdate();
/// <param name="pressRelease"></param> }
public override void VolumeDown(bool pressRelease)
{ /// <summary>
} ///
/// </summary>
/// <summary> /// <param name="pressRelease"></param>
/// public override void VolumeDown(bool pressRelease)
/// </summary> {
/// <param name="pressRelease"></param> }
public override void VolumeUp(bool pressRelease)
{ /// <summary>
} ///
/// </summary>
/// <summary> /// <param name="pressRelease"></param>
/// public override void VolumeUp(bool pressRelease)
/// </summary> {
public override void PrivacyModeOn() }
{
Debug.Console(1, this, "PrivacyMuteOn"); /// <summary>
if (_PrivacyModeIsOn) ///
return; /// </summary>
_PrivacyModeIsOn = true; public override void PrivacyModeOn()
PrivacyModeIsOnFeedback.FireUpdate(); {
} Debug.Console(1, this, "PrivacyMuteOn");
if (_PrivacyModeIsOn)
/// <summary> return;
/// _PrivacyModeIsOn = true;
/// </summary> PrivacyModeIsOnFeedback.FireUpdate();
public override void PrivacyModeOff() }
{
Debug.Console(1, this, "PrivacyMuteOff"); /// <summary>
if (!_PrivacyModeIsOn) ///
return; /// </summary>
_PrivacyModeIsOn = false; public override void PrivacyModeOff()
PrivacyModeIsOnFeedback.FireUpdate(); {
} Debug.Console(1, this, "PrivacyMuteOff");
if (!_PrivacyModeIsOn)
/// <summary> return;
/// _PrivacyModeIsOn = false;
/// </summary> PrivacyModeIsOnFeedback.FireUpdate();
public override void PrivacyModeToggle() }
{
_PrivacyModeIsOn = !_PrivacyModeIsOn; /// <summary>
Debug.Console(1, this, "PrivacyMuteToggle: {0}", _PrivacyModeIsOn); ///
PrivacyModeIsOnFeedback.FireUpdate(); /// </summary>
} public override void PrivacyModeToggle()
{
//******************************************************** _PrivacyModeIsOn = !_PrivacyModeIsOn;
// SIMULATION METHODS Debug.Console(1, this, "PrivacyMuteToggle: {0}", _PrivacyModeIsOn);
PrivacyModeIsOnFeedback.FireUpdate();
/// <summary> }
///
/// </summary> //********************************************************
/// <param name="url"></param> // SIMULATION METHODS
public void TestIncomingVideoCall(string url)
{ /// <summary>
Debug.Console(1, this, "TestIncomingVideoCall from {0}", url); ///
var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type= eCodecCallType.Video, Direction = eCodecCallDirection.Incoming }; /// </summary>
ActiveCalls.Add(call); /// <param name="url"></param>
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call); public void TestIncomingVideoCall(string url)
_IncomingCall = true; {
IncomingCallFeedback.FireUpdate(); Debug.Console(1, this, "TestIncomingVideoCall from {0}", url);
} var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type= eCodecCallType.Video, Direction = eCodecCallDirection.Incoming };
ActiveCalls.Add(call);
/// <summary> SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call);
/// _IncomingCall = true;
/// </summary> IncomingCallFeedback.FireUpdate();
/// <param name="url"></param> }
public void TestIncomingAudioCall(string url)
{ /// <summary>
Debug.Console(1, this, "TestIncomingAudioCall from {0}", url); ///
var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type = eCodecCallType.Audio, Direction = eCodecCallDirection.Incoming }; /// </summary>
ActiveCalls.Add(call); /// <param name="url"></param>
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call); public void TestIncomingAudioCall(string url)
_IncomingCall = true; {
IncomingCallFeedback.FireUpdate(); Debug.Console(1, this, "TestIncomingAudioCall from {0}", url);
} var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type = eCodecCallType.Audio, Direction = eCodecCallDirection.Incoming };
ActiveCalls.Add(call);
/// <summary> SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call);
/// _IncomingCall = true;
/// </summary> IncomingCallFeedback.FireUpdate();
public void TestFarEndHangup() }
{
Debug.Console(1, this, "TestFarEndHangup"); /// <summary>
///
} /// </summary>
public void TestFarEndHangup()
#region IHasCallHistory Members {
Debug.Console(1, this, "TestFarEndHangup");
public CodecCallHistory CallHistory { get; private set; }
}
public void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry)
{ #region IHasCallHistory Members
} public CodecCallHistory CallHistory { get; private set; }
#endregion public void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry)
{
#region IHasScheduleAwareness Members
}
public CodecScheduleAwareness CodecSchedule
{ #endregion
get {
// if the last meeting has past, generate a new list #region IHasScheduleAwareness Members
if (_CodecSchedule == null
|| _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now) public CodecScheduleAwareness CodecSchedule
{ {
_CodecSchedule = new CodecScheduleAwareness(); get {
for (int i = 0; i < 5; i++) // if the last meeting has past, generate a new list
{ if (_CodecSchedule == null
var m = new Meeting(); || _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now)
m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i); {
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30); _CodecSchedule = new CodecScheduleAwareness();
m.Title = "Meeting " + i; for (int i = 0; i < 5; i++)
m.ConferenceNumberToDial = i + "meeting@fake.com"; {
_CodecSchedule.Meetings.Add(m); var m = new Meeting();
} m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i);
} m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30);
return _CodecSchedule; m.Title = "Meeting " + i;
} m.Calls[0].Number = i + "meeting@fake.com";
} _CodecSchedule.Meetings.Add(m);
CodecScheduleAwareness _CodecSchedule; }
}
#endregion return _CodecSchedule;
} }
}
/// <summary> CodecScheduleAwareness _CodecSchedule;
/// Implementation for the mock VC
/// </summary> #endregion
public class MockCodecInfo : VideoCodecInfo }
{
/// <summary>
public override bool MultiSiteOptionIsEnabled /// Implementation for the mock VC
{ /// </summary>
get { return true; } public class MockCodecInfo : VideoCodecInfo
} {
public override string IpAddress public override bool MultiSiteOptionIsEnabled
{ {
get { return "xx.xx.xx.xx"; } get { return true; }
} }
public override string PhoneNumber public override string IpAddress
{ {
get { return "333-444-5555"; } get { return "xx.xx.xx.xx"; }
} }
public override string SipUri public override string PhoneNumber
{ {
get { return "mock@someurl.com"; } get { return "333-444-5555"; }
} }
public override bool AutoAnswerEnabled public override string SipUri
{ {
get { return _AutoAnswerEnabled; } get { return "mock@someurl.com"; }
} }
bool _AutoAnswerEnabled;
public override bool AutoAnswerEnabled
public void SetAutoAnswer(bool value) {
{ get { return _AutoAnswerEnabled; }
_AutoAnswerEnabled = value; }
} bool _AutoAnswerEnabled;
}
public void SetAutoAnswer(bool value)
{
_AutoAnswerEnabled = value;
}
}
} }

View File

@@ -65,13 +65,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
InputPorts = new RoutingPortCollection<RoutingInputPort>(); InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>(); OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ActiveCalls = new List<CodecActiveCallItem>(); ActiveCalls = new List<CodecActiveCallItem>();
} }
#region IHasDialer Members #region IHasDialer Members
public abstract void Dial(string s); public abstract void Dial(string number);
public abstract void Dial(Meeting meeting);
public abstract void EndCall(CodecActiveCallItem call); public abstract void EndCall(CodecActiveCallItem call);
public abstract void EndAllCalls(); public abstract void EndAllCalls();
public abstract void AcceptCall(CodecActiveCallItem call); public abstract void AcceptCall(CodecActiveCallItem call);
@@ -198,4 +199,98 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
CallItem = item; CallItem = item;
} }
} }
/// <summary>
/// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info
/// </summary>
public class CodecPhonebookSyncState : IKeyed
{
bool _InitialSyncComplete;
public event EventHandler<EventArgs> InitialSyncCompleted;
public string Key { get; private set; }
public bool InitialSyncComplete
{
get { return _InitialSyncComplete; }
private set
{
if (value == true)
{
var handler = InitialSyncCompleted;
if (handler != null)
handler(this, new EventArgs());
}
_InitialSyncComplete = value;
}
}
public bool InitialPhonebookFoldersWasReceived { get; private set; }
public bool NumberOfContactsWasReceived { get; private set; }
public bool PhonebookRootEntriesWasRecieved { get; private set; }
public bool PhonebookHasFolders { get; private set; }
public int NumberOfContacts { get; private set; }
public CodecPhonebookSyncState(string key)
{
Key = key;
CodecDisconnected();
}
public void InitialPhonebookFoldersReceived()
{
InitialPhonebookFoldersWasReceived = true;
CheckSyncStatus();
}
public void PhonebookRootEntriesReceived()
{
PhonebookRootEntriesWasRecieved = true;
CheckSyncStatus();
}
public void SetPhonebookHasFolders(bool value)
{
PhonebookHasFolders = value;
Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders);
}
public void SetNumberOfContacts(int contacts)
{
NumberOfContacts = contacts;
NumberOfContactsWasReceived = true;
Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts);
CheckSyncStatus();
}
public void CodecDisconnected()
{
InitialPhonebookFoldersWasReceived = false;
PhonebookHasFolders = false;
NumberOfContacts = 0;
NumberOfContactsWasReceived = false;
}
void CheckSyncStatus()
{
if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
{
InitialSyncComplete = true;
Debug.Console(1, this, "Initial Phonebook Sync Complete!");
}
else
InitialSyncComplete = false;
}
}
} }

View File

@@ -1,437 +1,437 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials namespace PepperDash.Essentials
{ {
public class EssentialsPresentationRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange public class EssentialsPresentationRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
{ {
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange; public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSingleSourceChange; public event SourceInfoChangeHandler CurrentSingleSourceChange;
public event SourceInfoChangeHandler CurrentDisplay1SourceChange; public event SourceInfoChangeHandler CurrentDisplay1SourceChange;
public event SourceInfoChangeHandler CurrentDisplay2SourceChange; public event SourceInfoChangeHandler CurrentDisplay2SourceChange;
protected override Func<bool> OnFeedbackFunc { get { protected override Func<bool> OnFeedbackFunc { get {
return () => (CurrentSingleSourceInfo != null return () => (CurrentSingleSourceInfo != null
&& CurrentSingleSourceInfo.Type != eSourceListItemType.Off) && CurrentSingleSourceInfo.Type != eSourceListItemType.Off)
|| (Display1SourceInfo != null || (Display1SourceInfo != null
&& Display1SourceInfo.Type != eSourceListItemType.Off) && Display1SourceInfo.Type != eSourceListItemType.Off)
|| (Display2SourceInfo != null || (Display2SourceInfo != null
&& Display2SourceInfo.Type != eSourceListItemType.Off); } } && Display2SourceInfo.Type != eSourceListItemType.Off); } }
protected override Func<bool> IsWarmingFeedbackFunc { get { return () =>false;; } } protected override Func<bool> IsWarmingFeedbackFunc { get { return () =>false;; } }
protected override Func<bool> IsCoolingFeedbackFunc { get { return () => false; } } protected override Func<bool> IsCoolingFeedbackFunc { get { return () => false; } }
public EssentialsPresentationRoomPropertiesConfig Config { get; private set; } public EssentialsPresentationRoomPropertiesConfig Config { get; private set; }
public Dictionary<uint, IRoutingSinkNoSwitching> Displays { get; private set; } public Dictionary<uint, IRoutingSinkNoSwitching> Displays { get; private set; }
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; } public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
public IBasicVolumeControls DefaultVolumeControls { get; private set; } public IBasicVolumeControls DefaultVolumeControls { get; private set; }
/// <summary> /// <summary>
/// The config name of the source list /// The config name of the source list
/// </summary> /// </summary>
public string SourceListKey { get; set; } public string SourceListKey { get; set; }
/// <summary> /// <summary>
/// If room is off, enables power on to last source. Default true /// If room is off, enables power on to last source. Default true
/// </summary> /// </summary>
public bool EnablePowerOnToLastSource { get; set; } public bool EnablePowerOnToLastSource { get; set; }
string LastSourceKey; string LastSourceKey;
public enum eVideoRoutingMode public enum eVideoRoutingMode
{ {
SelectSourceSelectDisplay, SourceToAllDisplays SelectSourceSelectDisplay, SourceToAllDisplays
} }
public eVideoRoutingMode VideoRoutingMode { get; set; } public eVideoRoutingMode VideoRoutingMode { get; set; }
public enum eAudioRoutingMode public enum eAudioRoutingMode
{ {
AudioFollowsLastVideo, SelectAudioFromDisplay AudioFollowsLastVideo, SelectAudioFromDisplay
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public IBasicVolumeControls CurrentVolumeControls public IBasicVolumeControls CurrentVolumeControls
{ {
get { return _CurrentAudioDevice; } get { return _CurrentAudioDevice; }
set set
{ {
if (value == _CurrentAudioDevice) return; if (value == _CurrentAudioDevice) return;
var oldDev = _CurrentAudioDevice; var oldDev = _CurrentAudioDevice;
// derigister this room from the device, if it can // derigister this room from the device, if it can
if (oldDev is IInUseTracking) if (oldDev is IInUseTracking)
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio"); (oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
var handler = CurrentVolumeDeviceChange; var handler = CurrentVolumeDeviceChange;
if (handler != null) if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange)); CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
_CurrentAudioDevice = value; _CurrentAudioDevice = value;
if (handler != null) if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange)); CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
// register this room with new device, if it can // register this room with new device, if it can
if (_CurrentAudioDevice is IInUseTracking) if (_CurrentAudioDevice is IInUseTracking)
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio"); (_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
} }
} }
IBasicVolumeControls _CurrentAudioDevice; IBasicVolumeControls _CurrentAudioDevice;
/// <summary> /// <summary>
/// The SourceListItem last run - containing names and icons. The complex setter is /// The SourceListItem last run - containing names and icons. The complex setter is
/// to add/remove this room to the source's InUseTracking, if it is capable /// to add/remove this room to the source's InUseTracking, if it is capable
/// </summary> /// </summary>
public SourceListItem CurrentSingleSourceInfo public SourceListItem CurrentSingleSourceInfo
{ {
get { return _CurrentSingleSourceInfo; } get { return _CurrentSingleSourceInfo; }
private set private set
{ {
if (value == _CurrentSingleSourceInfo) return; if (value == _CurrentSingleSourceInfo) return;
var handler = CurrentSingleSourceChange; var handler = CurrentSingleSourceChange;
// remove from in-use tracker, if so equipped // remove from in-use tracker, if so equipped
if(_CurrentSingleSourceInfo != null && _CurrentSingleSourceInfo.SourceDevice is IInUseTracking) if(_CurrentSingleSourceInfo != null && _CurrentSingleSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSingleSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control"); (_CurrentSingleSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
if (handler != null) if (handler != null)
handler(this, _CurrentSingleSourceInfo, ChangeType.WillChange); handler(this, _CurrentSingleSourceInfo, ChangeType.WillChange);
_CurrentSingleSourceInfo = value; _CurrentSingleSourceInfo = value;
// add to in-use tracking // add to in-use tracking
if (_CurrentSingleSourceInfo != null && _CurrentSingleSourceInfo.SourceDevice is IInUseTracking) if (_CurrentSingleSourceInfo != null && _CurrentSingleSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSingleSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control"); (_CurrentSingleSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null) if (handler != null)
handler(this, _CurrentSingleSourceInfo, ChangeType.DidChange); handler(this, _CurrentSingleSourceInfo, ChangeType.DidChange);
} }
} }
SourceListItem _CurrentSingleSourceInfo; SourceListItem _CurrentSingleSourceInfo;
public SourceListItem Display1SourceInfo public SourceListItem Display1SourceInfo
{ {
get { return _Display1SourceInfo; } get { return _Display1SourceInfo; }
set set
{ {
if (value == _Display1SourceInfo) return; if (value == _Display1SourceInfo) return;
var handler = CurrentDisplay1SourceChange; var handler = CurrentDisplay1SourceChange;
if (handler != null) if (handler != null)
handler(this, _Display1SourceInfo, ChangeType.WillChange); handler(this, _Display1SourceInfo, ChangeType.WillChange);
_Display1SourceInfo = value; _Display1SourceInfo = value;
if (handler != null) if (handler != null)
handler(this, _Display1SourceInfo, ChangeType.DidChange); handler(this, _Display1SourceInfo, ChangeType.DidChange);
} }
} }
SourceListItem _Display1SourceInfo; SourceListItem _Display1SourceInfo;
public SourceListItem Display2SourceInfo public SourceListItem Display2SourceInfo
{ {
get { return _Display2SourceInfo; } get { return _Display2SourceInfo; }
set set
{ {
if (value == _Display2SourceInfo) return; if (value == _Display2SourceInfo) return;
var handler = CurrentDisplay2SourceChange; var handler = CurrentDisplay2SourceChange;
if (handler != null) if (handler != null)
handler(this, _Display2SourceInfo, ChangeType.WillChange); handler(this, _Display2SourceInfo, ChangeType.WillChange);
_Display2SourceInfo = value; _Display2SourceInfo = value;
if (handler != null) if (handler != null)
handler(this, _Display2SourceInfo, ChangeType.DidChange); handler(this, _Display2SourceInfo, ChangeType.DidChange);
} }
} }
SourceListItem _Display2SourceInfo; SourceListItem _Display2SourceInfo;
/// <summary> /// <summary>
/// If an audio dialer is available for this room /// If an audio dialer is available for this room
/// </summary>
public bool HasAudioDialer { get { return false; } }
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
public EssentialsPresentationRoom(string key, string name,
Dictionary<uint, IRoutingSinkNoSwitching> displays,
IBasicVolumeWithFeedback defaultVolume, EssentialsPresentationRoomPropertiesConfig config)
: base(key, name)
{
Config = config;
Displays = displays;
DefaultVolumeControls = defaultVolume;
CurrentVolumeControls = defaultVolume;
//DefaultAudioDevice = defaultAudio;
//if (defaultAudio is IBasicVolumeControls)
// DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
//else if (defaultAudio is IHasVolumeDevice)
// DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
SourceListKey = "default";
EnablePowerOnToLastSource = true;
}
/// <summary>
/// Run the same source to all destinations
/// </summary>
/// <param name="sourceItem"></param>
public void RouteSourceToAllDestinations(SourceListItem sourceItem)
{
if (Config.Volumes.Master != null)
{
var audioDev = DeviceManager.GetDeviceForKey(Config.Volumes.Master.DeviceKey);
if (audioDev is IBasicVolumeWithFeedback)
{
}
}
foreach (var display in Displays.Values)
{
if (sourceItem != null)
DoVideoRoute(sourceItem.SourceKey, display.Key);
else
DoVideoRoute("$off", display.Key);
}
Display1SourceInfo = sourceItem;
Display2SourceInfo = sourceItem;
CurrentSingleSourceInfo = sourceItem;
OnFeedback.FireUpdate();
}
public void SourceToDisplay1(SourceListItem sourceItem)
{
DoVideoRoute(sourceItem.SourceKey, Displays[1].Key);
Display1SourceInfo = sourceItem;
OnFeedback.FireUpdate();
}
public void SourceToDisplay2(SourceListItem sourceItem)
{
DoVideoRoute(sourceItem.SourceKey, Displays[2].Key);
Display2SourceInfo = sourceItem;
OnFeedback.FireUpdate();
}
/// <summary>
/// Basic source -> destination routing
/// </summary>
void DoVideoRoute(string sourceKey, string destinationKey)
{
new CTimer(o =>
{
var dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSinkNoSwitching;
if (dest == null)
{
Debug.Console(1, this, "Cannot route. Destination '{0}' not found", destinationKey);
return;
}
// off is special case
if (sourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{
dest.ReleaseRoute();
if (dest is IPower)
(dest as IPower).PowerOff();
return;
}
var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
if (source == null)
{
Debug.Console(1, this, "Cannot route. Source '{0}' not found", sourceKey);
return;
}
dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
}, 0);
}
/// <summary>
///
/// </summary> /// </summary>
protected override void EndShutdown() public bool HasAudioDialer { get { return false; } }
{ /// <summary>
RunRouteAction("roomoff"); ///
} /// </summary>
/// <param name="key"></param>
/// <summary> /// <param name="name"></param>
/// public EssentialsPresentationRoom(string key, string name,
/// </summary> Dictionary<uint, IRoutingSinkNoSwitching> displays,
/// <param name="routeKey"></param> IBasicVolumeWithFeedback defaultVolume, EssentialsPresentationRoomPropertiesConfig config)
public void RunRouteAction(string routeKey) : base(key, name)
{ {
RunRouteAction(routeKey, null); Config = config;
} Displays = displays;
/// <summary> DefaultVolumeControls = defaultVolume;
/// Gets a source from config list SourceListKey and dynamically build and executes the CurrentVolumeControls = defaultVolume;
/// route or commands
/// </summary> //DefaultAudioDevice = defaultAudio;
/// <param name="name"></param> //if (defaultAudio is IBasicVolumeControls)
public void RunRouteAction(string routeKey, Action successCallback) // DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
{ //else if (defaultAudio is IHasVolumeDevice)
// Run this on a separate thread // DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
new CTimer(o =>
{
Debug.Console(1, this, "Run room action '{0}'", routeKey); SourceListKey = "default";
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey); EnablePowerOnToLastSource = true;
if(dict == null) }
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey); /// <summary>
return; /// Run the same source to all destinations
} /// </summary>
/// <param name="sourceItem"></param>
// Try to get the list item by it's string key public void RouteSourceToAllDestinations(SourceListItem sourceItem)
if (!dict.ContainsKey(routeKey)) {
{ if (Config.Volumes.Master != null)
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'", {
routeKey, SourceListKey); var audioDev = DeviceManager.GetDeviceForKey(Config.Volumes.Master.DeviceKey);
return; if (audioDev is IBasicVolumeWithFeedback)
} {
var item = dict[routeKey]; }
//Debug.Console(2, this, "Action {0} has {1} steps", }
// item.SourceKey, item.RouteList.Count);
foreach (var display in Displays.Values)
// Let's run it {
if (routeKey.ToLower() != "roomoff") if (sourceItem != null)
LastSourceKey = routeKey; DoVideoRoute(sourceItem.SourceKey, display.Key);
else
foreach (var route in item.RouteList) DoVideoRoute("$off", display.Key);
{ }
// if there is a $defaultAll on route, run two separate Display1SourceInfo = sourceItem;
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase)) Display2SourceInfo = sourceItem;
{ CurrentSingleSourceInfo = sourceItem;
var tempAudio = new SourceRouteListItem OnFeedback.FireUpdate();
{ }
DestinationKey = "$defaultDisplay",
SourceKey = route.SourceKey, public void SourceToDisplay1(SourceListItem sourceItem)
Type = eRoutingSignalType.Video {
}; DoVideoRoute(sourceItem.SourceKey, Displays[1].Key);
DoRoute(tempAudio); Display1SourceInfo = sourceItem;
OnFeedback.FireUpdate();
var tempVideo = new SourceRouteListItem }
{
DestinationKey = "$defaultAudio", public void SourceToDisplay2(SourceListItem sourceItem)
SourceKey = route.SourceKey, {
Type = eRoutingSignalType.Audio DoVideoRoute(sourceItem.SourceKey, Displays[2].Key);
}; Display2SourceInfo = sourceItem;
DoRoute(tempVideo); OnFeedback.FireUpdate();
continue; }
}
else
DoRoute(route); /// <summary>
} /// Basic source -> destination routing
/// </summary>
// Set volume control on room, using default if non provided void DoVideoRoute(string sourceKey, string destinationKey)
IBasicVolumeControls volDev = null; {
// Handle special cases for volume control new CTimer(o =>
if (string.IsNullOrEmpty(item.VolumeControlKey) {
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase)) var dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSinkNoSwitching;
volDev = DefaultVolumeControls; if (dest == null)
//else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) {
// volDev = DefaultDisplay as IBasicVolumeControls; Debug.Console(1, this, "Cannot route. Destination '{0}' not found", destinationKey);
// Or a specific device, probably rarely used. return;
else }
{ // off is special case
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey); if (sourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
if (dev is IBasicVolumeControls) {
volDev = dev as IBasicVolumeControls; dest.ReleaseRoute();
else if (dev is IHasVolumeDevice) if (dest is IPower)
volDev = (dev as IHasVolumeDevice).VolumeDevice; (dest as IPower).PowerOff();
} return;
CurrentVolumeControls = volDev; }
// store the name and UI info for routes var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
if (item.SourceKey != null) if (source == null)
CurrentSingleSourceInfo = item; {
// And finally, set the "control". This will trigger event Debug.Console(1, this, "Cannot route. Source '{0}' not found", sourceKey);
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device; return;
}
OnFeedback.FireUpdate(); dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
}, 0);
// report back when done }
if (successCallback != null)
successCallback(); /// <summary>
}, 0); // end of CTimer ///
} /// </summary>
protected override void EndShutdown()
/// <summary> {
/// Will power the room on with the last-used source RunRouteAction("roomoff");
/// </summary> }
public void PowerOnToDefaultOrLastSource()
{ /// <summary>
if (!EnablePowerOnToLastSource || LastSourceKey == null) ///
return; /// </summary>
RunRouteAction(LastSourceKey); /// <param name="routeKey"></param>
} public void RunRouteAction(string routeKey)
{
/// <summary> RunRouteAction(routeKey, null);
/// Does what it says }
/// </summary>
public override void SetDefaultLevels() /// <summary>
{ /// Gets a source from config list SourceListKey and dynamically build and executes the
Debug.Console(0, this, "SetDefaultLevels not implemented"); /// route or commands
} /// </summary>
/// <param name="name"></param>
/// <summary> public void RunRouteAction(string routeKey, Action successCallback)
/// {
/// </summary> // Run this on a separate thread
/// <param name="route"></param> new CTimer(o =>
/// <returns></returns> {
bool DoRoute(SourceRouteListItem route) Debug.Console(1, this, "Run room action '{0}'", routeKey);
{ var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
IRoutingSinkNoSwitching dest = null; if(dict == null)
{
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase)) Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
dest = DefaultAudioDevice; return;
//else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) }
// dest = DefaultDisplay;
else // Try to get the list item by it's string key
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching; if (!dict.ContainsKey(routeKey))
{
if (dest == null) Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
{ routeKey, SourceListKey);
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey); return;
return false; }
}
var item = dict[routeKey];
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase)) //Debug.Console(2, this, "Action {0} has {1} steps",
{ // item.SourceKey, item.RouteList.Count);
dest.ReleaseRoute();
if (dest is IPower) // Let's run it
(dest as IPower).PowerOff(); if (routeKey.ToLower() != "roomoff")
} LastSourceKey = routeKey;
else
{ foreach (var route in item.RouteList)
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs; {
if (source == null) // if there is a $defaultAll on route, run two separate
{ if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey); {
return false; var tempAudio = new SourceRouteListItem
} {
dest.ReleaseAndMakeRoute(source, route.Type); DestinationKey = "$defaultDisplay",
} SourceKey = route.SourceKey,
return true; Type = eRoutingSignalType.Video
};
DoRoute(tempAudio);
var tempVideo = new SourceRouteListItem
{
DestinationKey = "$defaultAudio",
SourceKey = route.SourceKey,
Type = eRoutingSignalType.Audio
};
DoRoute(tempVideo);
continue;
}
else
DoRoute(route);
}
// Set volume control on room, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
volDev = DefaultVolumeControls;
//else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
// volDev = DefaultDisplay as IBasicVolumeControls;
// Or a specific device, probably rarely used.
else
{
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
if (dev is IBasicVolumeControls)
volDev = dev as IBasicVolumeControls;
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
CurrentVolumeControls = volDev;
// store the name and UI info for routes
if (item.SourceKey != null)
CurrentSingleSourceInfo = item;
// And finally, set the "control". This will trigger event
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
OnFeedback.FireUpdate();
// report back when done
if (successCallback != null)
successCallback();
}, 0); // end of CTimer
}
/// <summary>
/// Will power the room on with the last-used source
/// </summary>
public void PowerOnToDefaultOrLastSource()
{
if (!EnablePowerOnToLastSource || LastSourceKey == null)
return;
RunRouteAction(LastSourceKey);
}
/// <summary>
/// Does what it says
/// </summary>
public override void SetDefaultLevels()
{
Debug.Console(0, this, "SetDefaultLevels not implemented");
}
/// <summary>
///
/// </summary>
/// <param name="route"></param>
/// <returns></returns>
bool DoRoute(SourceRouteListItem route)
{
IRoutingSinkNoSwitching dest = null;
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
dest = DefaultAudioDevice;
//else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
// dest = DefaultDisplay;
else
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
if (dest == null)
{
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
return false;
}
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{
dest.ReleaseRoute();
if (dest is IPower)
(dest as IPower).PowerOff();
}
else
{
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
if (source == null)
{
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
return false;
}
dest.ReleaseAndMakeRoute(source, route.Type);
}
return true;
} }
public override void RoomVacatedForTimeoutPeriod(object o) public override void RoomVacatedForTimeoutPeriod(object o)
{ {
//Implement this //Implement this
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -29,9 +29,9 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// 1231 - 1261 range of joins for recent list time /// 1231 - 1261 range of joins for recent list time
/// </summary> /// </summary>
public const uint VCRecentListTimeTextStart = 1231; public const uint VCRecentListTimeTextStart = 1231;
// // RANGE IN USE
public const uint VCRecentListTimeTextEnd = 1260; public const uint VCRecentListTimeTextEnd = 1260;
/// <summary> /// <summary>
/// 1291 - the current layout mode /// 1291 - the current layout mode
/// </summary> /// </summary>
@@ -42,7 +42,33 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public const uint VCDirectoryListTextStart = 1301; public const uint VCDirectoryListTextStart = 1301;
// RANGE IN USE // RANGE IN USE
public const uint VCDirectoryListTextEnd = 1400; public const uint VCDirectoryListTextEnd = 1400;
/// <summary>
/// 141112
/// </summary>
public const uint VCFavorites1Text = 1411;
/// <summary>
/// 1412
/// </summary>
public const uint VCFavorites2Text = 1412;
/// <summary>
/// 1413
/// </summary>
public const uint VCFavorites3Text = 1413;
/// <summary>
/// 1414
/// </summary>
public const uint VCFavorites4Text = 1414;
/// <summary>
/// 1415
/// </summary>
public const uint VCFavorites5Text = 1415;
//****************************************************** //******************************************************
// Keyboard // Keyboard

View File

@@ -10,6 +10,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.PageManagers; using PepperDash.Essentials.Core.PageManagers;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials namespace PepperDash.Essentials
@@ -408,7 +409,7 @@ namespace PepperDash.Essentials
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingRibbonJoinPress, () => TriList.SetSigFalseAction(UIBoolJoin.NextMeetingRibbonJoinPress, () =>
{ {
HideNextMeetingPopup(); HideNextMeetingPopup();
RoomOnAndDialMeeting(meeting.ConferenceNumberToDial); RoomOnAndDialMeeting(meeting);
}); });
TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule"); TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule");
TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () => TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () =>
@@ -459,13 +460,15 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Dials a meeting after turning on room (if necessary) /// Dials a meeting after turning on room (if necessary)
/// </summary> /// </summary>
void RoomOnAndDialMeeting(string number) void RoomOnAndDialMeeting(Meeting meeting)
{ {
Action dialAction = () => Action dialAction = () =>
{ {
var d = CurrentRoom.ScheduleSource as VideoCodecBase; var d = CurrentRoom.ScheduleSource as VideoCodecBase;
if (d != null) if (d != null)
d.Dial(number); {
d.Dial(meeting);
}
}; };
if (CurrentRoom.OnFeedback.BoolValue) if (CurrentRoom.OnFeedback.BoolValue)
dialAction(); dialAction();
@@ -980,7 +983,7 @@ namespace PepperDash.Essentials
PopupInterlock.Hide(); PopupInterlock.Hide();
var d = CurrentRoom.ScheduleSource as VideoCodecBase; var d = CurrentRoom.ScheduleSource as VideoCodecBase;
if (d != null) if (d != null)
RoomOnAndDialMeeting(mm.ConferenceNumberToDial); RoomOnAndDialMeeting(mm);
}); });
} }
MeetingsSrl.Count = i; MeetingsSrl.Count = i;

View File

@@ -61,6 +61,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
CodecDirectory CurrentDirectoryResult; CodecDirectory CurrentDirectoryResult;
string LastFolderRequestedParentFolderId;
BoolFeedback DirectoryBackButtonVisibleFeedback;
// These are likely temp until we get a keyboard built // These are likely temp until we get a keyboard built
StringFeedback DialStringFeedback; StringFeedback DialStringFeedback;
StringBuilder DialStringBuilder = new StringBuilder(); StringBuilder DialStringBuilder = new StringBuilder();
@@ -130,6 +134,12 @@ namespace PepperDash.Essentials.UIDrivers.VC
DialStringBackspaceVisibleFeedback DialStringBackspaceVisibleFeedback
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCKeypadBackspaceVisible]); .LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCKeypadBackspaceVisible]);
TriList.SetSigFalseAction(UIBoolJoin.VCDirectoryBackPress, GetDirectoryParentFolderContents);
DirectoryBackButtonVisibleFeedback = new BoolFeedback(() => CurrentDirectoryResult != (codec as IHasDirectory).DirectoryRoot);
DirectoryBackButtonVisibleFeedback
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCDirectoryBackVisible]);
TriList.SetSigFalseAction(UIBoolJoin.VCKeypadTextPress, RevealKeyboard); TriList.SetSigFalseAction(UIBoolJoin.VCKeypadTextPress, RevealKeyboard);
// Address and number // Address and number
@@ -389,9 +399,9 @@ namespace PepperDash.Essentials.UIDrivers.VC
TriList.SetString(timeTextOffset + i, timeText); TriList.SetString(timeTextOffset + i, timeText);
string iconName = null; string iconName = null;
if (c.Direction == eCodecCallDirection.Incoming) if (c.OccurenceType == eCodecOccurrenceType.Received)
iconName = "Left"; iconName = "Left";
else if (c.Direction == eCodecCallDirection.Outgoing) else if (c.OccurenceType == eCodecOccurrenceType.Placed)
iconName = "Right"; iconName = "Right";
else else
iconName = "Help"; iconName = "Help";
@@ -419,7 +429,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
if (i < favs.Count) if (i < favs.Count)
{ {
var fav = favs[(int)i]; var fav = favs[(int)i];
TriList.SetString(1211 + i, fav.Name); TriList.SetString(1411 + i, fav.Name);
TriList.SetBool(1221 + i, true); TriList.SetBool(1221 + i, true);
TriList.SetSigFalseAction(1211 + i, () => TriList.SetSigFalseAction(1211 + i, () =>
{ {
@@ -445,7 +455,14 @@ namespace PepperDash.Essentials.UIDrivers.VC
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList], DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
true, 1300); true, 1300);
codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned); codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
CurrentDirectoryResult = codec.DirectoryRoot;
if (codec.PhonebookSyncState.InitialSyncComplete)
SetCurrentDirectoryToRoot();
else
{
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
}
// If there is something here now, show it otherwise wait for the event // If there is something here now, show it otherwise wait for the event
if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0) if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0)
@@ -456,6 +473,37 @@ namespace PepperDash.Essentials.UIDrivers.VC
} }
} }
/// <summary>
/// Sets the current directory resutls to the DirectorRoot and updates Back Button visibiltiy
/// </summary>
void SetCurrentDirectoryToRoot()
{
LastFolderRequestedParentFolderId = string.Empty;
CurrentDirectoryResult = (Codec as IHasDirectory).DirectoryRoot;
DirectoryBackButtonVisibleFeedback.FireUpdate();
RefreshDirectory();
}
/// <summary>
/// Setup the Directory list when notified that the initial phonebook sync is completed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void PhonebookSyncState_InitialSyncCompleted(object sender, EventArgs e)
{
var codec = Codec as IHasDirectory;
SetCurrentDirectoryToRoot();
if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0)
{
RefreshDirectory();
}
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -464,9 +512,38 @@ namespace PepperDash.Essentials.UIDrivers.VC
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e) void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{ {
CurrentDirectoryResult = e.Directory; CurrentDirectoryResult = e.Directory;
DirectoryBackButtonVisibleFeedback.FireUpdate();
RefreshDirectory(); RefreshDirectory();
} }
/// <summary>
/// Helper method to retrieve directory folder contents and store last requested folder id
/// </summary>
/// <param name="folderId"></param>
void GetDirectoryFolderContents(DirectoryFolder folder)
{
LastFolderRequestedParentFolderId = folder.ParentFolderId;
(Codec as IHasDirectory).GetDirectoryFolderContents(folder.FolderId);
}
/// <summary>
/// Request the parent folder contents or sets back to the root if no parent folder
/// </summary>
void GetDirectoryParentFolderContents()
{
var codec = Codec as IHasDirectory;
if (!string.IsNullOrEmpty(LastFolderRequestedParentFolderId))
codec.GetDirectoryFolderContents(LastFolderRequestedParentFolderId);
else
{
SetCurrentDirectoryToRoot();
}
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -484,9 +561,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
} }
i++; i++;
DirectoryList.SetItemMainText(i, r.Name);
if(r is DirectoryContact) if(r is DirectoryContact)
{ {
DirectoryList.SetItemMainText(i, r.Name);
var dc = r as DirectoryContact; var dc = r as DirectoryContact;
// if more than one contact method, pop up modal to choose // if more than one contact method, pop up modal to choose
// otherwiese dial 0 entry // otherwiese dial 0 entry
@@ -499,15 +578,18 @@ namespace PepperDash.Essentials.UIDrivers.VC
} }
} }
else else // is DirectoryFolder
{ {
DirectoryList.SetItemMainText(i, string.Format("[+] {0}", r.Name));
var df = r as DirectoryFolder;
DirectoryList.SetItemButtonAction(i, b => DirectoryList.SetItemButtonAction(i, b =>
{ {
if (!b) if (!b)
{ {
var id = (r as DirectoryFolder).FolderId; GetDirectoryFolderContents(df);
(Codec as IHasDirectory).GetDirectoryFolderContents(id); // will later call event handler after folder contents retrieved
// will later call event handler
} }
}); });
} }