Call favorites start on mock; Fixed OBTP dialogs to match NYU

This commit is contained in:
Heath Volmer
2017-10-05 12:10:51 -06:00
parent c7cfcbe69e
commit 54f23eeb9f
12 changed files with 233 additions and 152 deletions

View File

@@ -1,122 +1,122 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// A bridge class to cover the basic features of GenericBase hardware
/// </summary>
public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
{
public virtual GenericBase Hardware { get; protected set; }
public BoolFeedback IsOnline { get; private set; }
public BoolFeedback IsRegistered { get; private set; }
public StringFeedback IpConnectionsText { get; private set; }
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
: base(key, name)
{
Hardware = hardware;
IsOnline = new BoolFeedback(CommonBoolCue.IsOnlineFeedback, () => Hardware.IsOnline);
IsRegistered = new BoolFeedback(new Cue("IsRegistered", 0, eCueType.Bool), () => Hardware.Registered);
IpConnectionsText = new StringFeedback(CommonStringCue.IpConnectionsText, () =>
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
}
/// <summary>
/// Make sure that overriding classes call this!
/// Registers the Crestron device, connects up to the base events, starts communication monitor
/// </summary>
public override bool CustomActivate()
{
new CTimer(o =>
{
Debug.Console(1, this, "Activating");
var response = Hardware.RegisterWithLogging(Key);
if (response == eDeviceRegistrationUnRegistrationResponse.Success)
{
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
}
}, 0);
return true;
}
/// <summary>
/// This disconnects events and unregisters the base hardware device.
/// </summary>
/// <returns></returns>
public override bool Deactivate()
{
CommunicationMonitor.Stop();
Hardware.OnlineStatusChange -= Hardware_OnlineStatusChange;
return Hardware.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
}
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
IsOnline,
IsRegistered,
IpConnectionsText
};
}
}
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
IsOnline.FireUpdate();
}
#region IStatusMonitor Members
public StatusMonitorBase CommunicationMonitor { get; private set; }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// A bridge class to cover the basic features of GenericBase hardware
/// </summary>
public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
{
public virtual GenericBase Hardware { get; protected set; }
public BoolFeedback IsOnline { get; private set; }
public BoolFeedback IsRegistered { get; private set; }
public StringFeedback IpConnectionsText { get; private set; }
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
: base(key, name)
{
Hardware = hardware;
IsOnline = new BoolFeedback(CommonBoolCue.IsOnlineFeedback, () => Hardware.IsOnline);
IsRegistered = new BoolFeedback(new Cue("IsRegistered", 0, eCueType.Bool), () => Hardware.Registered);
IpConnectionsText = new StringFeedback(CommonStringCue.IpConnectionsText, () =>
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
}
/// <summary>
/// Make sure that overriding classes call this!
/// Registers the Crestron device, connects up to the base events, starts communication monitor
/// </summary>
public override bool CustomActivate()
{
new CTimer(o =>
{
Debug.Console(1, this, "Activating");
var response = Hardware.RegisterWithLogging(Key);
if (response == eDeviceRegistrationUnRegistrationResponse.Success)
{
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
}
}, 0);
return true;
}
/// <summary>
/// This disconnects events and unregisters the base hardware device.
/// </summary>
/// <returns></returns>
public override bool Deactivate()
{
CommunicationMonitor.Stop();
Hardware.OnlineStatusChange -= Hardware_OnlineStatusChange;
return Hardware.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
}
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
IsOnline,
IsRegistered,
IpConnectionsText
};
}
}
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
IsOnline.FireUpdate();
}
#region IStatusMonitor Members
public StatusMonitorBase CommunicationMonitor { get; private set; }
#endregion
#region IUsageTracking Members
public UsageTracking UsageTracker { get; set; }
#endregion
}
//***********************************************************************************
public class CrestronGenericBaseDeviceEventIds
{
public const uint IsOnline = 1;
public const uint IpConnectionsText =2;
}
/// <summary>
/// Adds logging to Register() failure
/// </summary>
public static class GenericBaseExtensions
{
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
{
var result = device.Register();
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
}
return result;
}
}
#endregion
}
//***********************************************************************************
public class CrestronGenericBaseDeviceEventIds
{
public const uint IsOnline = 1;
public const uint IpConnectionsText =2;
}
/// <summary>
/// Adds logging to Register() failure
/// </summary>
public static class GenericBaseExtensions
{
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
{
var result = device.Register();
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
}
return result;
}
}
}

View File

@@ -108,6 +108,7 @@ namespace PepperDash.Essentials.Core
WarningTimer.Reset(WarningTime, WarningTime);
if(ErrorTimer != null)
ErrorTimer.Reset(ErrorTime, ErrorTime);
}
}
}

View File

@@ -142,6 +142,7 @@
<Compile Include="VideoCodec\CiscoCodec\BookingsDataClasses.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCodec.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCodecPropertiesConfig.cs" />
<Compile Include="VideoCodec\MockVC\MockVcPropertiesConfig.cs" />
<Compile Include="VideoCodec\CiscoCodec\PhonebookDataClasses.cs" />
<Compile Include="VideoCodec\CiscoCodec\xConfiguration.cs" />
<Compile Include="VideoCodec\CiscoCodec\xEvent.cs" />

View File

@@ -103,8 +103,10 @@ namespace PepperDash.Essentials.Devices.Common
else if (typeName == "mockvc")
{
return new PepperDash.Essentials.Devices.Common.VideoCodec
.MockVC(key, name);
var props = JsonConvert.DeserializeObject
<PepperDash.Essentials.Devices.Common.VideoCodec.MockVcPropertiesConfig>(properties.ToString());
return new PepperDash.Essentials.Devices.Common.VideoCodec
.MockVC(key, name, props);
}
else if (typeName == "ciscocodec")

View File

@@ -11,21 +11,30 @@ using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class MockVC : VideoCodecBase, IRoutingSource, IHasCallHistory, IHasScheduleAwareness
public class MockVC : VideoCodecBase, IRoutingSource, IHasCallHistory, IHasScheduleAwareness, IHasCallFavorites
{
public RoutingInputPort CodecOsdIn { get; private set; }
public RoutingInputPort HdmiIn1 { get; private set; }
public RoutingInputPort HdmiIn2 { get; private set; }
public RoutingOutputPort HdmiOut { get; private set; }
public CodecCallFavorites CallFavorites { get; private set; }
/// <summary>
///
/// </summary>
public MockVC(string key, string name)
public MockVC(string key, string name, MockVcPropertiesConfig props)
: base(key, name)
{
CodecInfo = new MockCodecInfo();
// Get favoritesw
if (props.Favorites != null)
{
CallFavorites = new CodecCallFavorites();
CallFavorites.Favorites = props.Favorites;
}
// Debug helpers
IncomingCallFeedback.OutputChange += (o, a) => Debug.Console(1, this, "IncomingCall={0}", _IncomingCall);
MuteFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Mute={0}", _IsMuted);
@@ -329,19 +338,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public CodecScheduleAwareness CodecSchedule
{
get {
var sch = new CodecScheduleAwareness();
for(int i = 0; i < 5; i++)
// if the last meeting has past, generate a new list
if (_CodecSchedule == null
|| _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now)
{
var m = new Meeting();
m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i);
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30);
m.Title = "Meeting " + i;
m.ConferenceNumberToDial = i + "meeting@fake.com";
sch.Meetings.Add(m);
_CodecSchedule = new CodecScheduleAwareness();
for (int i = 0; i < 5; i++)
{
var m = new Meeting();
m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i);
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30);
m.Title = "Meeting " + i;
m.ConferenceNumberToDial = i + "meeting@fake.com";
_CodecSchedule.Meetings.Add(m);
}
}
return sch;
return _CodecSchedule;
}
}
CodecScheduleAwareness _CodecSchedule;
#endregion
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class MockVcPropertiesConfig
{
public List<CodecActiveCallItem> Favorites { get; set; }
}
}

View File

@@ -324,6 +324,10 @@ namespace PepperDash.Essentials
/// </summary>
public const uint Volume6MutePressAndFB = 3863;
/// <summary>
/// 3869 - when the system is off and the gear is pressed
/// </summary>
public const uint VolumesPagePowerOffVisible = 3869;
/// <summary>
/// 3870
/// </summary>

View File

@@ -174,5 +174,13 @@ namespace PepperDash.Essentials
/// 3970
/// </summary>
public const uint NextMeetingRibbonButtonLabel = 3970;
/// <summary>
/// 3971
/// </summary>
public const uint NextMeetingSecondaryButtonLabel = 3971;
/// <summary>
/// 3972
/// </summary>
public const uint NextMeetingFollowingMeetingText = 3972;
}
}

View File

@@ -62,6 +62,9 @@ namespace PepperDash.Essentials
BoolInputSig ShareButtonSig;
BoolInputSig EndMeetingButtonSig;
public HeaderListButton HeaderCallButton { get; private set; }
public HeaderListButton HeaderGearButton { get; private set; }
/// <summary>
/// The parent driver for this
/// </summary>
@@ -345,7 +348,7 @@ namespace PepperDash.Essentials
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
if (NextMeetingTimer != null)
NextMeetingTimer.Stop();
HideNextMeetingRibbon();
HideNextMeetingPopup();
base.Hide();
}
@@ -390,9 +393,11 @@ namespace PepperDash.Essentials
#warning HLV-Add some sort of every-minute "cron" thing to run these.
NextMeetingTimer = new CTimer(o =>
{
if (CurrentRoom.OnFeedback.BoolValue)
return;
// Every 60 seconds, check meetings list for the closest, joinable meeting
var meeting = ss.CodecSchedule.Meetings
.Aggregate((m1, m2) => m1.StartTime < m2.StartTime ? m1 : m2);
var meetings = ss.CodecSchedule.Meetings;
var meeting = meetings.Aggregate((m1, m2) => m1.StartTime < m2.StartTime ? m1 : m2);
if (meeting != null && meeting.Joinable)
{
TriList.SetString(UIStringJoin.NextMeetingRibbonStartText, meeting.StartTime.ToShortTimeString());
@@ -402,10 +407,22 @@ namespace PepperDash.Essentials
TriList.SetString(UIStringJoin.NextMeetingRibbonButtonLabel, "Join");
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingRibbonJoinPress, () =>
{
HideNextMeetingRibbon();
HideNextMeetingPopup();
RoomOnAndDialMeeting(meeting.ConferenceNumberToDial);
});
ShowNextMeetingRibbon();
TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule");
TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () =>
{
HideNextMeetingPopup();
CalendarPress();
});
if (meetings.Count > 1)
{
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText,
meetings[1].StartTime.ToShortTimeString());
}
ShowNextMeetingPopup();
}
}, null, 0, 60000);
}
@@ -414,16 +431,16 @@ namespace PepperDash.Essentials
/// <summary>
///
/// </summary>
void ShowNextMeetingRibbon()
void ShowNextMeetingPopup()
{
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingRibbonClosePress, HideNextMeetingRibbon);
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingRibbonClosePress, HideNextMeetingPopup);
TriList.SetBool(UIBoolJoin.NextMeetingRibbonVisible, true);
}
/// <summary>
///
/// </summary>
void HideNextMeetingRibbon()
void HideNextMeetingPopup()
{
TriList.SetBool(UIBoolJoin.NextMeetingRibbonVisible, false);
}
@@ -860,11 +877,17 @@ namespace PepperDash.Essentials
var roomConf = CurrentRoom.Config;
//
var setupButton = new HeaderListButton(HeaderButtonsList, 5);
setupButton.SetIcon(HeaderListButton.Gear);
setupButton.OutputSig.SetSigHeldAction(2000,
HeaderGearButton = new HeaderListButton(HeaderButtonsList, 5);
HeaderGearButton.SetIcon(HeaderListButton.Gear);
HeaderGearButton.OutputSig.SetSigHeldAction(2000,
ShowTech,
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPageVisible));
() =>
{
if (CurrentRoom.OnFeedback.BoolValue)
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPageVisible);
else
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPagePowerOffVisible);
});
TriList.SetSigFalseAction(UIBoolJoin.TechExitButton, () =>
PopupInterlock.HideAndClear());
@@ -920,10 +943,11 @@ namespace PepperDash.Essentials
}
// Call button
var callBut = new HeaderListButton(HeaderButtonsList, nextIndex);
callBut.SetIcon(HeaderListButton.OnHook);
callBut.OutputSig.SetSigFalseAction(() =>
HeaderCallButton = new HeaderListButton(HeaderButtonsList, nextIndex);
HeaderCallButton.SetIcon(HeaderListButton.OnHook);
HeaderCallButton.OutputSig.SetSigFalseAction(() =>
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible));
nextIndex--;
// blank any that remain
@@ -1217,5 +1241,7 @@ namespace PepperDash.Essentials
JoinedSigInterlock PopupInterlock { get; }
void ShowNotificationRibbon(string message, int timeout);
void HideNotificationRibbon();
HeaderListButton HeaderGearButton { get; }
HeaderListButton HeaderCallButton { get; }
}
}

View File

@@ -207,12 +207,15 @@ namespace PepperDash.Essentials.UIDrivers.VC
UIBoolJoin.VCStagingActivePopoverVisible : UIBoolJoin.VCStagingInactivePopoverVisible);
// Set mode of header button
if (!Codec.IsInCall)
TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 0);
else if(Codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
else
TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
if (!Codec.IsInCall)
Parent.HeaderCallButton.SetIcon(HeaderListButton.OnHook);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 0);
else if (Codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
Parent.HeaderCallButton.SetIcon(HeaderListButton.Camera);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
else
Parent.HeaderCallButton.SetIcon(HeaderListButton.Phone);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
// Update list of calls
UpdateCallsHeaderList(call);
@@ -228,7 +231,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
ushort i = 1;
foreach (var c in activeList)
{
var item = new SubpageReferenceListItem(1, ActiveCallsSRL);
//var item = new SubpageReferenceListItem(1, ActiveCallsSRL);
ActiveCallsSRL.StringInputSig(i, 1).StringValue = c.Name;
ActiveCallsSRL.StringInputSig(i, 2).StringValue = c.Number;
ActiveCallsSRL.StringInputSig(i, 3).StringValue = c.Status.ToString();
@@ -308,7 +311,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
else
Codec.EndAllCalls();
});
TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, Codec.EndAllCalls);
TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, () =>
{
Parent.PopupInterlock.HideAndClear();
Codec.EndAllCalls();
});
}
/// <summary>
@@ -380,7 +387,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
var codec = Codec as IHasDirectory;
if (codec != null)
{
codec.CallHistory.RecentCallsListHasChanged += (o, a) => RefreshRecentCallsList();
//codec.CallHistory.RecentCallsListHasChanged += (o, a) => RefreshRecentCallsList();
// EVENT??????????????? Pointed at refresh
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
true, 1300);