diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/eMeetingPrivacy.cs b/Essentials Devices Common/Essentials Devices Common/Codec/eMeetingPrivacy.cs
new file mode 100644
index 00000000..2381d569
--- /dev/null
+++ b/Essentials Devices Common/Essentials Devices Common/Codec/eMeetingPrivacy.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Essentials.Devices.Common.Codec
+{
+ public enum eMeetingPrivacy
+ {
+ Unknown = 0,
+ Public,
+ Private
+ }
+
+ public class CodecCallPrivacy
+ {
+ ///
+ /// Takes the Cisco privacy type and converts to the matching enum
+ ///
+ ///
+ ///
+ public static eMeetingPrivacy ConvertToDirectionEnum(string s)
+ {
+ switch (s.ToLower())
+ {
+ case "public":
+ {
+ return eMeetingPrivacy.Public;
+ }
+ case "private":
+ {
+ return eMeetingPrivacy.Private;
+ }
+ default:
+ return eMeetingPrivacy.Unknown;
+ }
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs b/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs
new file mode 100644
index 00000000..7edbec1c
--- /dev/null
+++ b/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Essentials.Devices.Common.Codec
+{
+ public interface IHasScheduleAwareness
+ {
+ CodecScheduleAwareness CodecSchedule { get; }
+ }
+
+ public class CodecScheduleAwareness
+ {
+ public List Meetings { get; set; }
+
+ public CodecScheduleAwareness()
+ {
+ Meetings = new List();
+ }
+ }
+
+ ///
+ /// Generic class to represent a meeting (Cisco or Polycom OBTP or Fusion)
+ ///
+ public class Meeting
+ {
+ public string Id { get; set; }
+ public string Organizer { get; set; }
+ public string Title { get; set; }
+ public string Agenda { get; set; }
+ public DateTime StartTime { get; set; }
+ public DateTime EndTime { get; set; }
+ public TimeSpan Duration
+ {
+ get
+ {
+ return EndTime - StartTime;
+ }
+ }
+ public eMeetingPrivacy Privacy { get; set; }
+ public bool Joinable
+ {
+ get
+ {
+ var timeToMeetingStart = StartTime - DateTime.Now;
+
+ var timetoMeetingEnd = DateTime.Now - EndTime;
+
+ // Meeting is joinable from 5 minutes before start until 5 minutes before end
+ if (timeToMeetingStart.Minutes <= 5 && timetoMeetingEnd.Minutes >= 5)
+ return true;
+ else
+ return false;
+ }
+ }
+ public string ConferenceNumberToDial { get; set; }
+ public string ConferencePassword { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
index c6efdea9..348bbe0d 100644
--- a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
+++ b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
@@ -106,12 +106,14 @@
+
+
diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs
index 429119b6..19c54028 100644
--- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs
+++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs
@@ -4,6 +4,9 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
+using PepperDash.Core;
+using PepperDash.Essentials.Devices.Common.Codec;
+
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class CiscoCodecBookings
@@ -69,6 +72,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public LastName LastName { get; set; }
public Email Email { get; set; }
public Id2 Id { get; set; }
+
+ public Organizer()
+ {
+ FirstName = new FirstName();
+ LastName = new LastName();
+ Email = new Email();
+ }
}
public class StartTime
@@ -97,6 +107,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public StartTimeBuffer StartTimeBuffer { get; set; }
public EndTime EndTime { get; set; }
public EndTimeBuffer EndTimeBuffer { get; set; }
+
+ public Time()
+ {
+ StartTime = new StartTime();
+ EndTime = new EndTime();
+ }
}
public class MaximumMeetingExtension
@@ -206,6 +222,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public Role Role { get; set; }
public Recording Recording { get; set; }
public DialInfo DialInfo { get; set; }
+
+ public Booking()
+ {
+ Time = new Time();
+ Id = new Id();
+ Organizer = new Organizer();
+ Title = new Title();
+ Agenda = new Agenda();
+ Privacy = new Privacy();
+ }
}
public class BookingsListResult
@@ -225,5 +251,46 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public CommandResponse CommandResponse { get; set; }
}
+
+ ///
+ /// Extracts the necessary meeting values from the Cisco bookings response ans converts them to the generic class
+ ///
+ ///
+ ///
+ public static List GetGenericMeetingsFromBookingResult(List bookings)
+ {
+ var meetings = new List();
+
+ if (Debug.Level > 0)
+ {
+ Debug.Console(1, "Meetings List:\n");
+ }
+
+ foreach(Booking b in bookings)
+ {
+ var meeting = new Meeting();
+
+ meeting.Id = b.Id.Value;
+ meeting.Organizer = string.Format("{0}, {1}", b.Organizer.LastName.Value, b.Organizer.FirstName.Value);
+ meeting.Title = b.Title.Value;
+ meeting.Agenda = b.Agenda.Value;
+ meeting.StartTime = b.Time.StartTime.Value;
+ meeting.EndTime = b.Time.EndTime.Value;
+ meeting.Privacy = CodecCallPrivacy.ConvertToDirectionEnum(b.Privacy.Value);
+
+ if(Debug.Level > 0)
+ {
+ 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, " Joinable: {0}", meeting.Joinable);
+ }
+ }
+
+ meetings.OrderBy(m => m.StartTime);
+
+
+
+ return meetings;
+ }
}
}
\ No newline at end of file
diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs
index 926a30d2..c770bad4 100644
--- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs
+++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs
@@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration };
- public class CiscoCodec : VideoCodecBase, IHasCallHistory, iHasCallFavorites, iHasDirectory
+ public class CiscoCodec : VideoCodecBase, IHasCallHistory, iHasCallFavorites, iHasDirectory, IHasScheduleAwareness
{
public event EventHandler UpcomingMeetingWarning;
@@ -56,6 +56,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public CodecDirectory DirectoryRoot { get; private set; }
+ public CodecScheduleAwareness CodecSchedule { get; private set; }
+
///
/// Gets and returns the scaled volume of the codec
///
@@ -88,10 +90,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
protected override Func SharingSourceFeedbackFunc
{
-#warning figure out how to return the key of the shared source somehow
+#warning verify that source feedback to room works from codec
get
{
- return () => "todo";
+ return () => PresentationSourceKey;
}
}
@@ -160,12 +162,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
int PresentationSource;
+ string PresentationSourceKey;
+
string PhonebookMode = "Local"; // Default to Local
int PhonebookResultsLimit = 255; // Could be set later by config.
CTimer LoginMessageReceived;
+ public RoutingInputPort CodecOsdIn { get; private set; }
+ public RoutingInputPort HdmiIn1 { get; private set; }
+ public RoutingInputPort HdmiIn2 { get; private set; }
+ public RoutingOutputPort HdmiOut { get; private set; }
+
// Constructor for IBasicCommunication
public CiscoCodec(string key, string name, IBasicCommunication comm, CiscoCodecPropertiesConfig props )
: base(key, name)
@@ -217,6 +226,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CallFavorites.Favorites = props.Favorites;
DirectoryRoot = new CodecDirectory();
+
+ CodecSchedule = new CodecScheduleAwareness();
//Set Feedback Actions
CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate;
@@ -235,8 +246,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public override bool CustomActivate()
{
CrestronConsole.AddNewConsoleCommand(SendText, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCiscoCommDebug", "0 for Off, 1 for on", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCodecCommDebug", "0 for Off, 1 for on", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(GetBookings, "GetCodecBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
//CommDebuggingIsOn = true;
Communication.Connect();
@@ -248,8 +260,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CommunicationMonitor.Start();
- InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this));
- InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource2), this));
+ CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this);
+ HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this);
+ HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource2), this);
+
+ HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
+
+ InputPorts.Add(CodecOsdIn);
+ InputPorts.Add(HdmiIn1);
+ InputPorts.Add(HdmiIn2);
+ OutputPorts.Add(HdmiOut);
+
string prefix = "xFeedback register ";
@@ -281,10 +302,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
GetCallHistory();
- // Get bookings for the day
- //SendText("xCommand Bookings List Days: 1 DayOffset: 0");
-
GetPhonebook(null);
+
+ GetBookings(null);
}
public void SetCommDebug(string s)
@@ -609,7 +629,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
JsonConvert.PopulateObject(response, codecBookings);
- // Do something with this data....
+ CodecSchedule.Meetings = CiscoCodecBookings.GetGenericMeetingsFromBookingResult(codecBookings.CommandResponse.BookingsListResult.Booking);
}
}
@@ -649,6 +669,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public override void ExecuteSwitch(object selector)
{
(selector as Action)();
+ PresentationSourceKey = selector.ToString();
}
protected override Func IncomingCallFeedbackFunc { get { return () => false; } }
@@ -677,6 +698,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
SendText("xCommand CallHistory Recents Limit: 20 Order: OccurrenceTime");
}
+ ///
+ /// Gets the bookings for today
+ ///
+ ///
+ public void GetBookings(string command)
+ {
+ SendText("xCommand Bookings List Days: 1 DayOffset: 0");
+ }
+
///
/// Triggers a refresh of the codec phonebook
///