mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-31 05:14:51 +00:00
Compare commits
53 Commits
1.9.2-alph
...
1.9.3-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ac1d77c2a | ||
|
|
2dd0c53a08 | ||
|
|
fab1219146 | ||
|
|
60d0f50cd2 | ||
|
|
d193de79da | ||
|
|
87ab43c745 | ||
|
|
2a37e44d7d | ||
|
|
efa801137c | ||
|
|
4b4f1f3c3d | ||
|
|
6e7bf061cf | ||
|
|
c26d7d73f8 | ||
|
|
7f6160eb44 | ||
|
|
854a0691d3 | ||
|
|
61c638452b | ||
|
|
072411e4f6 | ||
|
|
7dc9afa119 | ||
|
|
b5004d5b1d | ||
|
|
6f0bfedac1 | ||
|
|
71881addab | ||
|
|
cea1d2fcdd | ||
|
|
22aea3089d | ||
|
|
3aab807631 | ||
|
|
9ec090397f | ||
|
|
86916c4357 | ||
|
|
40151c5f8f | ||
|
|
4210df693a | ||
|
|
56bb872d2b | ||
|
|
43256acfcd | ||
|
|
1696ef3ac1 | ||
|
|
864e0675ea | ||
|
|
19cbe480a6 | ||
|
|
49c1c61a88 | ||
|
|
c306e2c1a1 | ||
|
|
0cd3c1bdc5 | ||
|
|
d64cbc639a | ||
|
|
82af1366df | ||
|
|
56492a00cd | ||
|
|
8404e7d5a4 | ||
|
|
e4135a958c | ||
|
|
f4ac4e6319 | ||
|
|
b026174cd2 | ||
|
|
66ff6b2e07 | ||
|
|
e7bbfbd40a | ||
|
|
eec86fde48 | ||
|
|
7b57ce439e | ||
|
|
28bac18667 | ||
|
|
ea254ef983 | ||
|
|
76e4d4a82d | ||
|
|
4bd777f6b9 | ||
|
|
f607394ee7 | ||
|
|
5d120391a5 | ||
|
|
db5aa319ec | ||
|
|
4cc40227fd |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,6 +7,9 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Was this bug identified in a specific build version?**
|
||||
Please note the build version where this bug was identified
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
CreateMobileControlBridge(room as EssentialsRoomBase);
|
||||
}
|
||||
else if (room is IEssentialsHuddleVtc1Room)
|
||||
{
|
||||
@@ -494,7 +494,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
CreateMobileControlBridge(room as EssentialsRoomBase);
|
||||
}
|
||||
else if (room is EssentialsTechRoom)
|
||||
{
|
||||
@@ -506,7 +506,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
CreateMobileControlBridge(room as EssentialsRoomBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -527,7 +527,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
}
|
||||
|
||||
private static void CreateMobileControlBridge(IEssentialsRoom room)
|
||||
private static void CreateMobileControlBridge(EssentialsRoomBase room)
|
||||
{
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
|
||||
@@ -454,7 +454,8 @@ namespace PepperDash.Essentials
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
throw new NotImplementedException();
|
||||
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +472,11 @@ namespace PepperDash.Essentials
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -79,6 +79,16 @@ namespace PepperDash.Essentials
|
||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||
else if (type == "tsw1060")
|
||||
Panel = new Tsw1060(id, Global.ControlSystem);
|
||||
else if (type == "tsw570")
|
||||
Panel = new Tsw570(id, Global.ControlSystem);
|
||||
else if (type == "tsw770")
|
||||
Panel = new Tsw770(id, Global.ControlSystem);
|
||||
else if (type == "ts770")
|
||||
Panel = new Ts770(id, Global.ControlSystem);
|
||||
else if (type == "tsw1070")
|
||||
Panel = new Tsw1070(id, Global.ControlSystem);
|
||||
else if (type == "ts1070")
|
||||
Panel = new Ts1070(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
@@ -203,7 +213,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
public EssentialsTouchpanelControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" };
|
||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// 1202
|
||||
/// </summary>
|
||||
public const uint VCStagingInactivePopoverVisible = 1202;
|
||||
public const uint VCStagingInactivePopoverWithRecentsVisible = 1202;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -121,6 +121,11 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCRecentsVisible = 1206;
|
||||
|
||||
/// <summary>
|
||||
/// 1202
|
||||
/// </summary>
|
||||
public const uint VCStagingInactivePopoverWithoutRecentsVisible = 1207;
|
||||
|
||||
/// <summary>
|
||||
/// 1208
|
||||
/// </summary>
|
||||
@@ -243,6 +248,10 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCCameraSelectBarWithoutModeVisible = 1261;
|
||||
|
||||
/// <summary>
|
||||
/// 1262
|
||||
/// </summary>
|
||||
public const uint VCCameraAutoModeIsOnFb = 1262;
|
||||
|
||||
/// <summary>
|
||||
/// 1271
|
||||
@@ -743,10 +752,10 @@ namespace PepperDash.Essentials
|
||||
/// 15044 Close button for source modal overlay
|
||||
/// </summary>
|
||||
public const uint SourceBackgroundOverlayClosePress = 15044;
|
||||
/// <summary>
|
||||
/// 15045 - Visibility for the bar containing call navigation button list
|
||||
/// </summary>
|
||||
public const uint CallStagingBarVisible = 15045;
|
||||
///// <summary>
|
||||
///// 15045 - Visibility for the bar containing call navigation button list
|
||||
///// </summary>
|
||||
//public const uint CallStagingBarVisible = 15045;
|
||||
/// <summary>
|
||||
/// 15046
|
||||
/// </summary>
|
||||
|
||||
@@ -207,6 +207,7 @@ namespace PepperDash.Essentials
|
||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
||||
|
||||
// Set the call status text
|
||||
Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count);
|
||||
if (codec.ActiveCalls.Count > 0)
|
||||
{
|
||||
if (codec.ActiveCalls.Count == 1)
|
||||
|
||||
@@ -1,326 +1,326 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
using PepperDash.Essentials.Devices.Displays;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers
|
||||
{
|
||||
public class EssentialsHuddleTechPageDriver : PanelDriverBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SmartObjectDynamicList MenuList;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SubpageReferenceList StatusList;
|
||||
/// <summary>
|
||||
/// The list of display controls
|
||||
/// </summary>
|
||||
SubpageReferenceList DisplayList;
|
||||
/// <summary>
|
||||
/// References lines in the list against device instances
|
||||
/// </summary>
|
||||
Dictionary<ICommunicationMonitor, uint> StatusListDeviceIndexes;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
JoinedSigInterlock PagesInterlock;
|
||||
|
||||
/// <summary>
|
||||
/// 1
|
||||
/// </summary>
|
||||
public const uint JoinText = 1;
|
||||
|
||||
CTimer PinAuthorizedTimer;
|
||||
|
||||
EssentialsRoomTechConfig Config;
|
||||
|
||||
StringBuilder PinEntryBuilder = new StringBuilder(4);
|
||||
|
||||
bool IsAuthorized;
|
||||
|
||||
SmartObjectNumeric PinKeypad;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="trilist"></param>
|
||||
/// <param name="parent"></param>
|
||||
public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config)
|
||||
: base(trilist)
|
||||
{
|
||||
Config = config;
|
||||
|
||||
PagesInterlock = new JoinedSigInterlock(trilist);
|
||||
PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible);
|
||||
|
||||
trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide);
|
||||
|
||||
MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList],
|
||||
true, 3100);
|
||||
|
||||
MenuList.SetFeedback(1, true); // initial fb
|
||||
ushort count = 0;
|
||||
|
||||
MenuList.SetItemMainText(1, "System Status");
|
||||
MenuList.SetItemButtonAction(1, b => {
|
||||
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible);
|
||||
MenuList.SetFeedback(1, true);
|
||||
});
|
||||
|
||||
MenuList.SetItemMainText(2, "Display Controls");
|
||||
MenuList.SetItemButtonAction(2, b => {
|
||||
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible);
|
||||
MenuList.SetFeedback(2, true);
|
||||
});
|
||||
|
||||
count = 2;
|
||||
|
||||
// Don't show panel setup on iPad or xpanel
|
||||
if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button)
|
||||
{
|
||||
count++;
|
||||
MenuList.SetItemMainText(count, "Panel Setup");
|
||||
MenuList.SetItemButtonAction(count, b =>
|
||||
{
|
||||
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible);
|
||||
MenuList.SetFeedback(count, true);
|
||||
});
|
||||
}
|
||||
|
||||
MenuList.Count = count;
|
||||
BuildStatusList();
|
||||
BuildDisplayList();
|
||||
SetupPinModal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Show()
|
||||
{
|
||||
// divert to PIN if we need auth
|
||||
if (IsAuthorized)
|
||||
{
|
||||
// Cancel the auth timer so we don't deauth after coming back in
|
||||
if (PinAuthorizedTimer != null)
|
||||
PinAuthorizedTimer.Stop();
|
||||
|
||||
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true);
|
||||
PagesInterlock.Show();
|
||||
base.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Hide()
|
||||
{
|
||||
// Leave it authorized for 60 seconds.
|
||||
if (IsAuthorized)
|
||||
PinAuthorizedTimer = new CTimer(o => {
|
||||
IsAuthorized = false;
|
||||
PinAuthorizedTimer = null;
|
||||
}, 60000);
|
||||
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false);
|
||||
PagesInterlock.Hide();
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wire up the keypad and buttons
|
||||
/// </summary>
|
||||
void SetupPinModal()
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog);
|
||||
PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true);
|
||||
PinKeypad.Digit0.UserObject = new Action<bool>(b => { if (b)DialPinDigit('0'); });
|
||||
PinKeypad.Digit1.UserObject = new Action<bool>(b => { if (b)DialPinDigit('1'); });
|
||||
PinKeypad.Digit2.UserObject = new Action<bool>(b => { if (b)DialPinDigit('2'); });
|
||||
PinKeypad.Digit3.UserObject = new Action<bool>(b => { if (b)DialPinDigit('3'); });
|
||||
PinKeypad.Digit4.UserObject = new Action<bool>(b => { if (b)DialPinDigit('4'); });
|
||||
PinKeypad.Digit5.UserObject = new Action<bool>(b => { if (b)DialPinDigit('5'); });
|
||||
PinKeypad.Digit6.UserObject = new Action<bool>(b => { if (b)DialPinDigit('6'); });
|
||||
PinKeypad.Digit7.UserObject = new Action<bool>(b => { if (b)DialPinDigit('7'); });
|
||||
PinKeypad.Digit8.UserObject = new Action<bool>(b => { if (b)DialPinDigit('8'); });
|
||||
PinKeypad.Digit9.UserObject = new Action<bool>(b => { if (b)DialPinDigit('9'); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
void DialPinDigit(char d)
|
||||
{
|
||||
PinEntryBuilder.Append(d);
|
||||
var len = PinEntryBuilder.Length;
|
||||
SetPinDotsFeedback(len);
|
||||
|
||||
// check it!
|
||||
if (len == 4)
|
||||
{
|
||||
if (Config.Password == PinEntryBuilder.ToString())
|
||||
{
|
||||
IsAuthorized = true;
|
||||
SetPinDotsFeedback(0);
|
||||
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false);
|
||||
Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPinDotsFeedback(0);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true);
|
||||
new CTimer(o =>
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false);
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
PinEntryBuilder.Remove(0, len); // clear it either way
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the dots as pin is entered
|
||||
/// </summary>
|
||||
/// <param name="len"></param>
|
||||
void SetPinDotsFeedback(int len)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does what it says
|
||||
/// </summary>
|
||||
void CancelPinDialog()
|
||||
{
|
||||
PinEntryBuilder.Remove(0, PinEntryBuilder.Length);
|
||||
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void BuildStatusList()
|
||||
{
|
||||
StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3);
|
||||
StatusListDeviceIndexes = new Dictionary<ICommunicationMonitor, uint>();
|
||||
uint i = 0;
|
||||
foreach (var d in DeviceManager.AllDevices)
|
||||
{
|
||||
// make sure it is both ICommunicationMonitor and a Device
|
||||
var sd = d as ICommunicationMonitor;
|
||||
if (sd == null)
|
||||
continue;
|
||||
var dd = sd as Device;
|
||||
if(dd == null)
|
||||
continue;
|
||||
i++;
|
||||
StatusList.StringInputSig(i, 1).StringValue = dd.Name;
|
||||
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status;
|
||||
StatusListDeviceIndexes.Add(sd, i);
|
||||
sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ;
|
||||
}
|
||||
StatusList.Count = (ushort)i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the list of display controls
|
||||
/// </summary>
|
||||
void BuildDisplayList()
|
||||
{
|
||||
DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3);
|
||||
|
||||
var devKeys = ConfigReader.ConfigObject.Devices.Where(d =>
|
||||
d.Group.Equals("display", StringComparison.OrdinalIgnoreCase)
|
||||
|| d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(dd => dd.Key);
|
||||
var disps = DeviceManager.AllDevices.Where(d =>
|
||||
devKeys.Contains(d.Key));
|
||||
ushort i = 0;
|
||||
foreach (var disp in disps)
|
||||
{
|
||||
var display = disp as DisplayBase;
|
||||
if (display != null)
|
||||
{
|
||||
i++;
|
||||
DisplayList.StringInputSig(i, 1).StringValue = display.Name;
|
||||
DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn);
|
||||
DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff);
|
||||
if (display is TwoWayDisplayBase)
|
||||
{
|
||||
var powerOnSig = DisplayList.BoolInputSig(i, 1);
|
||||
(display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig);
|
||||
|
||||
var powerOffSig = DisplayList.BoolInputSig(1, 2);
|
||||
(display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig);
|
||||
}
|
||||
DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() =>
|
||||
{ if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); });
|
||||
DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() =>
|
||||
{ if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); });
|
||||
DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() =>
|
||||
{ if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); });
|
||||
//DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() =>
|
||||
//{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); });
|
||||
DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() =>
|
||||
{ if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); });
|
||||
|
||||
|
||||
// Figure out some way to provide current input feedback
|
||||
if (display is TwoWayDisplayBase)
|
||||
{
|
||||
(display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
DisplayList.Count = i;
|
||||
}
|
||||
|
||||
|
||||
void CurrentInputFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
|
||||
{
|
||||
var c = sender as ICommunicationMonitor;
|
||||
if (StatusListDeviceIndexes.ContainsKey(c))
|
||||
{
|
||||
var i = StatusListDeviceIndexes[c];
|
||||
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
using PepperDash.Essentials.Devices.Displays;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers
|
||||
{
|
||||
public class EssentialsHuddleTechPageDriver : PanelDriverBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SmartObjectDynamicList MenuList;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SubpageReferenceList StatusList;
|
||||
/// <summary>
|
||||
/// The list of display controls
|
||||
/// </summary>
|
||||
SubpageReferenceList DisplayList;
|
||||
/// <summary>
|
||||
/// References lines in the list against device instances
|
||||
/// </summary>
|
||||
Dictionary<ICommunicationMonitor, uint> StatusListDeviceIndexes;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
JoinedSigInterlock PagesInterlock;
|
||||
|
||||
/// <summary>
|
||||
/// 1
|
||||
/// </summary>
|
||||
public const uint JoinText = 1;
|
||||
|
||||
CTimer PinAuthorizedTimer;
|
||||
|
||||
EssentialsRoomTechConfig Config;
|
||||
|
||||
StringBuilder PinEntryBuilder = new StringBuilder(4);
|
||||
|
||||
bool IsAuthorized;
|
||||
|
||||
SmartObjectNumeric PinKeypad;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="trilist"></param>
|
||||
/// <param name="parent"></param>
|
||||
public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config)
|
||||
: base(trilist)
|
||||
{
|
||||
Config = config;
|
||||
|
||||
PagesInterlock = new JoinedSigInterlock(trilist);
|
||||
PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible);
|
||||
|
||||
trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide);
|
||||
|
||||
MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList],
|
||||
true, 3100);
|
||||
|
||||
MenuList.SetFeedback(1, true); // initial fb
|
||||
ushort count = 0;
|
||||
|
||||
MenuList.SetItemMainText(1, "System Status");
|
||||
MenuList.SetItemButtonAction(1, b => {
|
||||
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible);
|
||||
MenuList.SetFeedback(1, true);
|
||||
});
|
||||
|
||||
MenuList.SetItemMainText(2, "Display Controls");
|
||||
MenuList.SetItemButtonAction(2, b => {
|
||||
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible);
|
||||
MenuList.SetFeedback(2, true);
|
||||
});
|
||||
|
||||
count = 2;
|
||||
|
||||
// Don't show panel setup on iPad or xpanel
|
||||
if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button)
|
||||
{
|
||||
count++;
|
||||
MenuList.SetItemMainText(count, "Panel Setup");
|
||||
MenuList.SetItemButtonAction(count, b =>
|
||||
{
|
||||
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible);
|
||||
MenuList.SetFeedback(count, true);
|
||||
});
|
||||
}
|
||||
|
||||
MenuList.Count = count;
|
||||
BuildStatusList();
|
||||
BuildDisplayList();
|
||||
SetupPinModal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Show()
|
||||
{
|
||||
// divert to PIN if we need auth
|
||||
if (IsAuthorized)
|
||||
{
|
||||
// Cancel the auth timer so we don't deauth after coming back in
|
||||
if (PinAuthorizedTimer != null)
|
||||
PinAuthorizedTimer.Stop();
|
||||
|
||||
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true);
|
||||
PagesInterlock.Show();
|
||||
base.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Hide()
|
||||
{
|
||||
// Leave it authorized for 60 seconds.
|
||||
if (IsAuthorized)
|
||||
PinAuthorizedTimer = new CTimer(o => {
|
||||
IsAuthorized = false;
|
||||
PinAuthorizedTimer = null;
|
||||
}, 60000);
|
||||
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false);
|
||||
PagesInterlock.Hide();
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wire up the keypad and buttons
|
||||
/// </summary>
|
||||
void SetupPinModal()
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog);
|
||||
PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true);
|
||||
PinKeypad.Digit0.UserObject = new Action<bool>(b => { if (b)DialPinDigit('0'); });
|
||||
PinKeypad.Digit1.UserObject = new Action<bool>(b => { if (b)DialPinDigit('1'); });
|
||||
PinKeypad.Digit2.UserObject = new Action<bool>(b => { if (b)DialPinDigit('2'); });
|
||||
PinKeypad.Digit3.UserObject = new Action<bool>(b => { if (b)DialPinDigit('3'); });
|
||||
PinKeypad.Digit4.UserObject = new Action<bool>(b => { if (b)DialPinDigit('4'); });
|
||||
PinKeypad.Digit5.UserObject = new Action<bool>(b => { if (b)DialPinDigit('5'); });
|
||||
PinKeypad.Digit6.UserObject = new Action<bool>(b => { if (b)DialPinDigit('6'); });
|
||||
PinKeypad.Digit7.UserObject = new Action<bool>(b => { if (b)DialPinDigit('7'); });
|
||||
PinKeypad.Digit8.UserObject = new Action<bool>(b => { if (b)DialPinDigit('8'); });
|
||||
PinKeypad.Digit9.UserObject = new Action<bool>(b => { if (b)DialPinDigit('9'); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
void DialPinDigit(char d)
|
||||
{
|
||||
PinEntryBuilder.Append(d);
|
||||
var len = PinEntryBuilder.Length;
|
||||
SetPinDotsFeedback(len);
|
||||
|
||||
// check it!
|
||||
if (len == 4)
|
||||
{
|
||||
if (Config.Password == PinEntryBuilder.ToString())
|
||||
{
|
||||
IsAuthorized = true;
|
||||
SetPinDotsFeedback(0);
|
||||
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false);
|
||||
Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPinDotsFeedback(0);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true);
|
||||
new CTimer(o =>
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false);
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
PinEntryBuilder.Remove(0, len); // clear it either way
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the dots as pin is entered
|
||||
/// </summary>
|
||||
/// <param name="len"></param>
|
||||
void SetPinDotsFeedback(int len)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3);
|
||||
TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does what it says
|
||||
/// </summary>
|
||||
void CancelPinDialog()
|
||||
{
|
||||
PinEntryBuilder.Remove(0, PinEntryBuilder.Length);
|
||||
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void BuildStatusList()
|
||||
{
|
||||
StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3);
|
||||
StatusListDeviceIndexes = new Dictionary<ICommunicationMonitor, uint>();
|
||||
uint i = 0;
|
||||
foreach (var d in DeviceManager.AllDevices)
|
||||
{
|
||||
// make sure it is both ICommunicationMonitor and a Device
|
||||
var sd = d as ICommunicationMonitor;
|
||||
if (sd == null)
|
||||
continue;
|
||||
var dd = sd as Device;
|
||||
if(dd == null)
|
||||
continue;
|
||||
i++;
|
||||
StatusList.StringInputSig(i, 1).StringValue = dd.Name;
|
||||
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status;
|
||||
StatusListDeviceIndexes.Add(sd, i);
|
||||
sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ;
|
||||
}
|
||||
StatusList.Count = (ushort)i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the list of display controls
|
||||
/// </summary>
|
||||
void BuildDisplayList()
|
||||
{
|
||||
DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3);
|
||||
|
||||
var devKeys = ConfigReader.ConfigObject.Devices.Where(d =>
|
||||
d.Group.Equals("display", StringComparison.OrdinalIgnoreCase)
|
||||
|| d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(dd => dd.Key);
|
||||
var disps = DeviceManager.AllDevices.Where(d =>
|
||||
devKeys.Contains(d.Key));
|
||||
ushort i = 0;
|
||||
foreach (var disp in disps)
|
||||
{
|
||||
var display = disp as DisplayBase;
|
||||
if (display != null)
|
||||
{
|
||||
i++;
|
||||
DisplayList.StringInputSig(i, 1).StringValue = display.Name;
|
||||
DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn);
|
||||
DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff);
|
||||
if (display is TwoWayDisplayBase)
|
||||
{
|
||||
var powerOnSig = DisplayList.BoolInputSig(i, 1);
|
||||
(display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig);
|
||||
|
||||
var powerOffSig = DisplayList.BoolInputSig(1, 2);
|
||||
(display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig);
|
||||
}
|
||||
DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() =>
|
||||
{ if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); });
|
||||
DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() =>
|
||||
{ if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); });
|
||||
DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() =>
|
||||
{ if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); });
|
||||
//DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() =>
|
||||
//{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); });
|
||||
DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() =>
|
||||
{ if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); });
|
||||
|
||||
|
||||
// Figure out some way to provide current input feedback
|
||||
if (display is TwoWayDisplayBase)
|
||||
{
|
||||
(display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
DisplayList.Count = i;
|
||||
}
|
||||
|
||||
|
||||
void CurrentInputFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
|
||||
{
|
||||
var c = sender as ICommunicationMonitor;
|
||||
if (c != null && StatusListDeviceIndexes.ContainsKey(c))
|
||||
{
|
||||
var i = StatusListDeviceIndexes[c];
|
||||
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,10 +173,28 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; }
|
||||
|
||||
|
||||
private UiDisplayMode _currentMode;
|
||||
|
||||
/// <summary>
|
||||
/// The mode showing. Presentation or call.
|
||||
/// </summary>
|
||||
UiDisplayMode CurrentMode = UiDisplayMode.Start;
|
||||
UiDisplayMode CurrentMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentMode;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _currentMode)
|
||||
{
|
||||
_currentMode = value;
|
||||
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CTimer NextMeetingTimer;
|
||||
|
||||
@@ -207,6 +225,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5);
|
||||
|
||||
CurrentMode = UiDisplayMode.Start;
|
||||
|
||||
// buttons are added in SetCurrentRoom
|
||||
//HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]);
|
||||
@@ -607,11 +626,21 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void SetActivityFooterFeedbacks()
|
||||
{
|
||||
CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
|
||||
if (CurrentRoom != null)
|
||||
{
|
||||
var startMode = CurrentMode == UiDisplayMode.Start;
|
||||
var presentationMode = CurrentMode == UiDisplayMode.Presentation;
|
||||
var callMode = CurrentMode == UiDisplayMode.Call;
|
||||
|
||||
TriList.SetBool(StartPageVisibleJoin, startMode ? true : false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false);
|
||||
|
||||
CallButtonSig.BoolValue = callMode
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
ShareButtonSig.BoolValue = presentationMode
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -623,14 +652,13 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
HideLogo();
|
||||
HideNextMeetingPopup();
|
||||
TriList.SetBool(StartPageVisibleJoin, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
//TriList.SetBool(StartPageVisibleJoin, false);
|
||||
//TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
//TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
if (CurrentSourcePageManager != null)
|
||||
CurrentSourcePageManager.Hide();
|
||||
PowerOnFromCall();
|
||||
CurrentMode = UiDisplayMode.Call;
|
||||
SetActivityFooterFeedbacks();
|
||||
VCDriver.Show();
|
||||
}
|
||||
|
||||
@@ -643,9 +671,6 @@ namespace PepperDash.Essentials
|
||||
if (VCDriver.IsVisible)
|
||||
VCDriver.Hide();
|
||||
HideNextMeetingPopup();
|
||||
TriList.SetBool(StartPageVisibleJoin, false);
|
||||
TriList.SetBool(UIBoolJoin.CallStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true);
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
@@ -665,7 +690,6 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
SetupSourceList();
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -707,6 +731,8 @@ namespace PepperDash.Essentials
|
||||
if (CurrentRoom.CurrentSourceInfo == null)
|
||||
return;
|
||||
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
|
||||
if (CurrentRoom.CurrentSourceInfo.SourceDevice == null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
@@ -1035,7 +1061,7 @@ namespace PepperDash.Essentials
|
||||
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
||||
CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey);
|
||||
CurrentRoom.RunRouteAction("codecOsd");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,9 +1244,8 @@ namespace PepperDash.Essentials
|
||||
VCDriver.Hide();
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
ShowLogo();
|
||||
SetActivityFooterFeedbacks();
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
// Clear this so that the pesky meeting warning can resurface every minute when off
|
||||
LastMeetingDismissedId = null;
|
||||
}
|
||||
|
||||
@@ -142,7 +142,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible);
|
||||
|
||||
StagingBarsInterlock = new JoinedSigInterlock(triList);
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible);
|
||||
if(Codec is IHasCallHistory)
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible);
|
||||
else
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible);
|
||||
|
||||
StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList);
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
||||
@@ -351,10 +354,15 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0);
|
||||
|
||||
uint stageJoin;
|
||||
if (Codec.IsInCall)
|
||||
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
|
||||
else
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverVisible;
|
||||
if (Codec.IsInCall)
|
||||
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
|
||||
else
|
||||
{
|
||||
if (Codec is IHasCallHistory)
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible;
|
||||
else
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible;
|
||||
}
|
||||
if (IsVisible)
|
||||
StagingBarsInterlock.ShowInterlocked(stageJoin);
|
||||
else
|
||||
@@ -513,13 +521,18 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var supportsCameraOffMode = Codec.SupportsCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
if (codecAutoCameras != null)
|
||||
var supportsAutoCameraMode = Codec.SupportsCameraAutoMode;
|
||||
|
||||
if (codecAutoCameras != null && supportsAutoCameraMode)
|
||||
{
|
||||
CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn());
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true;
|
||||
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]);
|
||||
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCCameraAutoModeIsOnFb]);
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 1 Pressed"].SetSigFalseAction(
|
||||
//() => codecAutoCameras.CameraAutoModeOn());
|
||||
|
||||
@@ -554,7 +567,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction(
|
||||
// () => ShowCameraManualMode());
|
||||
|
||||
if (codecOffCameras != null)
|
||||
if (codecOffCameras != null && supportsCameraOffMode)
|
||||
{
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true;
|
||||
codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]);
|
||||
@@ -769,12 +782,14 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
if (camerasCodec != null && camerasCodec.SelectedCamera != null)
|
||||
{
|
||||
|
||||
Debug.Console(2, "Attempting to map camera actions to selected camera: '{0}'", camerasCodec.SelectedCamera.Key);
|
||||
var dpad = CameraPtzPad;
|
||||
|
||||
var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl;
|
||||
if (camera != null)
|
||||
{
|
||||
|
||||
Debug.Console(2, "Selected camera is IHasCameraPtzControl");
|
||||
if (camerasCodec.SelectedCamera.CanTilt)
|
||||
{
|
||||
dpad.SigUp.SetBoolSigAction((b) =>
|
||||
@@ -839,25 +854,46 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Selected Camera is not IHasCameraPtzControl. No controls to map");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Codec does not have cameras of selected camera is null");
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if codec is in manual camera control mode and shows feedback
|
||||
void ShowCameraManualMode()
|
||||
{
|
||||
Debug.Console(2, "ShowCameraManualMode");
|
||||
|
||||
var inManualMode = true;
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
var supportsAutoCameras = codecAutoCameras != null && Codec.SupportsCameraAutoMode;
|
||||
|
||||
if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
inManualMode = false;
|
||||
|
||||
var codecCameraMute = Codec as IHasCameraMute;
|
||||
|
||||
if (codecCameraMute != null)
|
||||
{
|
||||
codecCameraMute.CameraMuteOff();
|
||||
inManualMode = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Clear auto mode
|
||||
if (codecAutoCameras != null )
|
||||
if (supportsAutoCameras)
|
||||
{
|
||||
if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue)
|
||||
{
|
||||
@@ -1044,10 +1080,12 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
{
|
||||
var codec = Codec as IHasDirectory;
|
||||
|
||||
SetCurrentDirectoryToRoot();
|
||||
if (codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
|
||||
{
|
||||
SetCurrentDirectoryToRoot();
|
||||
|
||||
RefreshDirectory();
|
||||
|
||||
RefreshDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1125,10 +1163,23 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
});
|
||||
|
||||
}
|
||||
else if (dc.ContactMethods.Count == 1)
|
||||
{
|
||||
var invitableContact = dc as IInvitableContact;
|
||||
|
||||
if (invitableContact != null)
|
||||
{
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(invitableContact); });
|
||||
}
|
||||
else
|
||||
{
|
||||
// If only one contact method, just dial that method
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If only one contact method, just dial that method
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
|
||||
Debug.Console(1, "Unable to dial contact. No availble ContactMethod(s) specified");
|
||||
}
|
||||
}
|
||||
else // is DirectoryFolder
|
||||
@@ -1201,7 +1252,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
var lc = Codec as IHasCodecLayouts;
|
||||
if (lc != null)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
|
||||
|
||||
lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]);
|
||||
lc.LocalLayoutFeedback.OutputChange += (o,a) =>
|
||||
{
|
||||
@@ -1214,14 +1265,24 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
var cisco = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec;
|
||||
if (cisco != null)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
|
||||
// Cisco has min/max buttons that need special sauce
|
||||
cisco.SharingContentIsOnFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
|
||||
//cisco.PresentationViewMaximizedFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCMinMaxPress, cisco.MinMaxLayoutToggle);
|
||||
}
|
||||
|
||||
var zoomRoom = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom;
|
||||
if (zoomRoom != null)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.VCLayoutToggleEnable].BoolValue = true;
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
/// </summary>
|
||||
public interface IMobileControl : IKeyed
|
||||
{
|
||||
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
|
||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
|
||||
|
||||
void LinkSystemMonitorToAppServer();
|
||||
}
|
||||
|
||||
@@ -19,13 +19,34 @@ namespace PepperDash.Essentials.Core
|
||||
protected EssentialsDevice(string key)
|
||||
: base(key)
|
||||
{
|
||||
|
||||
SubscribeToActivateComplete();
|
||||
}
|
||||
|
||||
protected EssentialsDevice(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
SubscribeToActivateComplete();
|
||||
}
|
||||
|
||||
private void SubscribeToActivateComplete()
|
||||
{
|
||||
DeviceManager.AllDevicesActivated += DeviceManagerOnAllDevicesActivated;
|
||||
}
|
||||
|
||||
private void DeviceManagerOnAllDevicesActivated(object sender, EventArgs eventArgs)
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Exception initializing device: {0}", ex.Message);
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,90 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using PepperDash.Essentials.Core.Touchpanels;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class DeviceFactoryWrapper
|
||||
{
|
||||
public CType CType { get; set; }
|
||||
public string Description { get; set; }
|
||||
public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; }
|
||||
|
||||
public DeviceFactoryWrapper()
|
||||
{
|
||||
CType = null;
|
||||
Description = "Not Available";
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceFactory
|
||||
{
|
||||
public DeviceFactory()
|
||||
{
|
||||
var assy = Assembly.GetExecutingAssembly();
|
||||
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
|
||||
|
||||
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
|
||||
|
||||
if (types != null)
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||
factory.LoadTypeFactories();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of factory methods, keyed by config types, added by plugins.
|
||||
/// These methods are looked up and called by GetDevice in this class.
|
||||
/// </summary>
|
||||
static Dictionary<string, DeviceFactoryWrapper> FactoryMethods =
|
||||
new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a plugin factory method
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
|
||||
}
|
||||
|
||||
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
|
||||
if(FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
|
||||
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using PepperDash.Essentials.Core.Touchpanels;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class DeviceFactoryWrapper
|
||||
{
|
||||
public CType CType { get; set; }
|
||||
public string Description { get; set; }
|
||||
public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; }
|
||||
|
||||
public DeviceFactoryWrapper()
|
||||
{
|
||||
CType = null;
|
||||
Description = "Not Available";
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceFactory
|
||||
{
|
||||
public DeviceFactory()
|
||||
{
|
||||
var assy = Assembly.GetExecutingAssembly();
|
||||
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
|
||||
|
||||
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
|
||||
|
||||
if (types != null)
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||
factory.LoadTypeFactories();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of factory methods, keyed by config types, added by plugins.
|
||||
/// These methods are looked up and called by GetDevice in this class.
|
||||
/// </summary>
|
||||
static Dictionary<string, DeviceFactoryWrapper> FactoryMethods =
|
||||
new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a plugin factory method
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
|
||||
}
|
||||
|
||||
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
|
||||
if(FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
|
||||
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
||||
}
|
||||
|
||||
private static void CheckForSecrets(IEnumerable<JProperty> obj)
|
||||
@@ -156,44 +156,53 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
|
||||
|
||||
Debug.Console(2, "{0}", ex.StackTrace);
|
||||
|
||||
if (ex.InnerException == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Inner exception while creating device {0}: {1}", dc.Key,
|
||||
ex.InnerException.Message);
|
||||
Debug.Console(2, "{0}", ex.InnerException.StackTrace);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public static void GetDeviceFactoryTypes(string filter)
|
||||
{
|
||||
Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>();
|
||||
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
{
|
||||
types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
types = FactoryMethods;
|
||||
}
|
||||
|
||||
Debug.Console(0, "Device Types:");
|
||||
|
||||
foreach (var type in types.OrderBy(t => t.Key))
|
||||
{
|
||||
var description = type.Value.Description;
|
||||
var cType = "Not Specified by Plugin";
|
||||
|
||||
if(type.Value.CType != null)
|
||||
{
|
||||
cType = type.Value.CType.FullName;
|
||||
}
|
||||
|
||||
Debug.Console(0,
|
||||
@"Type: '{0}'
|
||||
CType: '{1}'
|
||||
Description: {2}", type.Key, cType, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public static void GetDeviceFactoryTypes(string filter)
|
||||
{
|
||||
Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>();
|
||||
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
{
|
||||
types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
types = FactoryMethods;
|
||||
}
|
||||
|
||||
Debug.Console(0, "Device Types:");
|
||||
|
||||
foreach (var type in types.OrderBy(t => t.Key))
|
||||
{
|
||||
var description = type.Value.Description;
|
||||
var cType = "Not Specified by Plugin";
|
||||
|
||||
if(type.Value.CType != null)
|
||||
{
|
||||
cType = type.Value.CType.FullName;
|
||||
}
|
||||
|
||||
Debug.Console(0,
|
||||
@"Type: '{0}'
|
||||
CType: '{1}'
|
||||
Description: {2}", type.Key, cType, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,11 +88,6 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
else
|
||||
Debug.Console(0, this, "Unable to add Red LED device");
|
||||
|
||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
};
|
||||
|
||||
AddPostActivationAction(() => {
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||
@@ -103,6 +98,15 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetPrivacyDevice(IPrivacy privacyDevice)
|
||||
{
|
||||
PrivacyDevice = privacyDevice;
|
||||
|
||||
@@ -16,7 +16,8 @@ using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.DM.Config;
|
||||
|
||||
namespace PepperDash.Essentials.DM {
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
|
||||
///
|
||||
@@ -75,8 +76,10 @@ namespace PepperDash.Essentials.DM {
|
||||
/// Factory method to create a new chassis controller from config data. Limited to 8x8 right now
|
||||
/// </summary>
|
||||
public static DmBladeChassisController GetDmChassisController(string key, string name,
|
||||
string type, DMChassisPropertiesConfig properties) {
|
||||
try {
|
||||
string type, DMChassisPropertiesConfig properties)
|
||||
{
|
||||
try
|
||||
{
|
||||
type = type.ToLower();
|
||||
uint ipid = properties.Control.IpIdInt;
|
||||
|
||||
@@ -85,7 +88,8 @@ namespace PepperDash.Essentials.DM {
|
||||
else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); }
|
||||
|
||||
|
||||
if (chassis == null) {
|
||||
if (chassis == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -93,11 +97,13 @@ namespace PepperDash.Essentials.DM {
|
||||
// add the cards and port names
|
||||
foreach (var kvp in properties.InputSlots)
|
||||
controller.AddInputBlade(kvp.Value, kvp.Key);
|
||||
foreach (var kvp in properties.OutputSlots) {
|
||||
foreach (var kvp in properties.OutputSlots)
|
||||
{
|
||||
controller.AddOutputBlade(kvp.Value, kvp.Key);
|
||||
}
|
||||
|
||||
foreach (var kvp in properties.VolumeControls) {
|
||||
foreach (var kvp in properties.VolumeControls)
|
||||
{
|
||||
// get the card
|
||||
// check it for an audio-compatible type
|
||||
// make a something-something that will make it work
|
||||
@@ -123,7 +129,8 @@ namespace PepperDash.Essentials.DM {
|
||||
controller.PropertiesConfig = properties;
|
||||
return controller;
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.Console(0, "Error creating DM chassis:\r{0}", e);
|
||||
}
|
||||
return null;
|
||||
@@ -137,7 +144,8 @@ namespace PepperDash.Essentials.DM {
|
||||
/// <param name="name"></param>
|
||||
/// <param name="chassis"></param>
|
||||
public DmBladeChassisController(string key, string name, BladeSwitch chassis)
|
||||
: base(key, name, chassis) {
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
Chassis = chassis;
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
@@ -161,68 +169,87 @@ namespace PepperDash.Essentials.DM {
|
||||
InputCardHdcpCapabilityFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||
InputCardHdcpCapabilityTypes = new Dictionary<uint, eHdcpCapabilityType>();
|
||||
|
||||
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) {
|
||||
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
|
||||
{
|
||||
var tempX = x;
|
||||
|
||||
if (Chassis.Outputs[tempX] != null) {
|
||||
VideoOutputFeedbacks[tempX] = new IntFeedback(() => {
|
||||
if (Chassis.Outputs[tempX] != null)
|
||||
{
|
||||
VideoOutputFeedbacks[tempX] = new IntFeedback(() =>
|
||||
{
|
||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; }
|
||||
else { return 0; };
|
||||
});
|
||||
|
||||
OutputNameFeedbacks[tempX] = new StringFeedback(() => {
|
||||
if (Chassis.Outputs[tempX].NameFeedback != null) {
|
||||
OutputNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||
{
|
||||
if (Chassis.Outputs[tempX].NameFeedback != null)
|
||||
{
|
||||
return Chassis.Outputs[tempX].NameFeedback.StringValue;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => {
|
||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null) {
|
||||
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||
{
|
||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null)
|
||||
{
|
||||
return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
|
||||
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
|
||||
{
|
||||
//if (Chassis.Outputs[tempX].Endpoint != null)
|
||||
// return Chassis.Outputs[tempX].Endpoint.IsOnline;
|
||||
//else
|
||||
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
|
||||
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
|
||||
});
|
||||
}
|
||||
|
||||
if (Chassis.Inputs[tempX] != null) {
|
||||
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => {
|
||||
if (Chassis.Inputs[tempX] != null)
|
||||
{
|
||||
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() =>
|
||||
{
|
||||
if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; }
|
||||
else { return 0; };
|
||||
});
|
||||
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => {
|
||||
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() =>
|
||||
{
|
||||
if (Chassis.Inputs[tempX].VideoDetectedFeedback != null)
|
||||
return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
InputNameFeedbacks[tempX] = new StringFeedback(() => {
|
||||
if (Chassis.Inputs[tempX].NameFeedback != null) {
|
||||
InputNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||
{
|
||||
if (Chassis.Inputs[tempX].NameFeedback != null)
|
||||
{
|
||||
return Chassis.Inputs[tempX].NameFeedback.StringValue;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
|
||||
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
|
||||
{
|
||||
return Chassis.Inputs[tempX].EndpointOnlineFeedback;
|
||||
});
|
||||
|
||||
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => {
|
||||
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() =>
|
||||
{
|
||||
var inputCard = Chassis.Inputs[tempX];
|
||||
|
||||
if (inputCard.Card is DmHdmi4kInputBladeCard) {
|
||||
if (inputCard.Card is DmHdmi4kInputBladeCard)
|
||||
{
|
||||
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue)
|
||||
@@ -231,7 +258,8 @@ namespace PepperDash.Essentials.DM {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inputCard.Card is DmC4kInputBladeCard) {
|
||||
if (inputCard.Card is DmC4kInputBladeCard)
|
||||
{
|
||||
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff))
|
||||
@@ -252,45 +280,56 @@ namespace PepperDash.Essentials.DM {
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="number"></param>
|
||||
public void AddInputBlade(string type, uint number) {
|
||||
public void AddInputBlade(string type, uint number)
|
||||
{
|
||||
Debug.Console(2, this, "Adding input blade '{0}', slot {1}", type, number);
|
||||
|
||||
type = type.ToLower();
|
||||
|
||||
if (type == "dmb4kihd") {
|
||||
if (type == "dmb4kihd")
|
||||
{
|
||||
var inputBlade = new Dmb4kIHd(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
|
||||
var cecPort = card as ICec;
|
||||
AddHdmiInBladePorts(item.Number, cecPort);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4kihddnt") {
|
||||
else if (type == "dmb4kihddnt")
|
||||
{
|
||||
var inputBlade = new Dmb4kIHd(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
|
||||
var cecPort = card as ICec;
|
||||
AddHdmiInBladePorts(item.Number, cecPort);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4kic") {
|
||||
else if (type == "dmb4kic")
|
||||
{
|
||||
var inputBlade = new Dmb4kIC(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
AddDmInBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmbis") {
|
||||
else if (type == "dmbis")
|
||||
{
|
||||
var inputBlade = new DmbIS(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
AddDmInMmFiberPorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmbis2") {
|
||||
else if (type == "dmbis2")
|
||||
{
|
||||
var inputBlade = new DmbIS2(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
AddDmInSmFiberPorts(item.Number);
|
||||
}
|
||||
}
|
||||
@@ -304,22 +343,26 @@ namespace PepperDash.Essentials.DM {
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AddHdmiInBladePorts(uint number, ICec cecPort) {
|
||||
void AddHdmiInBladePorts(uint number, ICec cecPort)
|
||||
{
|
||||
AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort);
|
||||
}
|
||||
|
||||
void AddDmInBladePorts(uint number) {
|
||||
void AddDmInBladePorts(uint number)
|
||||
{
|
||||
AddInputPortWithDebug(number, "dmCIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat);
|
||||
}
|
||||
|
||||
void AddDmInMmFiberPorts(uint number) {
|
||||
void AddDmInMmFiberPorts(uint number)
|
||||
{
|
||||
AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
|
||||
}
|
||||
|
||||
void AddDmInSmFiberPorts(uint number) {
|
||||
void AddDmInSmFiberPorts(uint number)
|
||||
{
|
||||
AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
|
||||
}
|
||||
|
||||
@@ -328,64 +371,81 @@ namespace PepperDash.Essentials.DM {
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="number"></param>
|
||||
public void AddOutputBlade(string type, uint number) {
|
||||
public void AddOutputBlade(string type, uint number)
|
||||
{
|
||||
type = type.ToLower();
|
||||
|
||||
Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number);
|
||||
if (type == "dmb4kohd") {
|
||||
if (type == "dmb4kohd")
|
||||
{
|
||||
var outputBlade = new Dmb4KOHD(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddHdmiOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4kohddnt") {
|
||||
else if (type == "dmb4kohddnt")
|
||||
{
|
||||
var outputBlade = new Dmb4KOHD(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddHdmiOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4koc") {
|
||||
else if (type == "dmb4koc")
|
||||
{
|
||||
var outputBlade = new Dmb4KOC(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmb4koc") {
|
||||
else if (type == "dmb4koc")
|
||||
{
|
||||
var outputBlade = new Dmb4KOC(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmbos") {
|
||||
else if (type == "dmbos")
|
||||
{
|
||||
var outputBlade = new DmbOS(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutMmFiberBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmbos2") {
|
||||
else if (type == "dmbos2")
|
||||
{
|
||||
var outputBlade = new DmbOS2(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutSmFiberBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddHdmiOutBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
|
||||
void AddHdmiOutBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "hdmiOut", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
|
||||
void AddDmOutBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "dmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutMmFiberBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
|
||||
void AddDmOutMmFiberBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "dmMmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutSmFiberBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
|
||||
void AddDmOutSmFiberBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "dmSmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
|
||||
@@ -417,23 +477,44 @@ namespace PepperDash.Essentials.DM {
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds OutputPort
|
||||
/// </summary>
|
||||
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
|
||||
|
||||
/*void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
|
||||
var portKey = string.Format("{0}--{1}", cardName, portName);
|
||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||
{
|
||||
FeedbackMatchObject = Chassis.Outputs[(uint)selector]
|
||||
});
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Adds OutputPort
|
||||
/// </summary>
|
||||
void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
|
||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||
{
|
||||
FeedbackMatchObject = Chassis.Outputs[cardNum]
|
||||
};
|
||||
OutputPorts.Add(outputPort);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, "Exception : {0}", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void AddVolumeControl(uint number, Audio.Output audio) {
|
||||
void AddVolumeControl(uint number, Audio.Output audio)
|
||||
{
|
||||
VolumeControls.Add(number, new DmCardAudioOutputController(audio));
|
||||
}
|
||||
|
||||
@@ -443,35 +524,43 @@ namespace PepperDash.Essentials.DM {
|
||||
//}
|
||||
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args) {
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
|
||||
switch (args.EventId) {
|
||||
case DMInputEventIds.EndpointOnlineEventId: {
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMInputEventIds.EndpointOnlineEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.OnlineFeedbackEventId: {
|
||||
case DMInputEventIds.OnlineFeedbackEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.VideoDetectedEventId: {
|
||||
case DMInputEventIds.VideoDetectedEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
|
||||
VideoInputSyncFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.InputNameEventId: {
|
||||
case DMInputEventIds.InputNameEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
|
||||
InputNameFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.HdcpCapabilityFeedbackEventId: {
|
||||
case DMInputEventIds.HdcpCapabilityFeedbackEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number);
|
||||
InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
{
|
||||
Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
@@ -487,74 +576,74 @@ namespace PepperDash.Essentials.DM {
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMOutputEventIds.VolumeEventId:
|
||||
{
|
||||
if (VolumeControls.ContainsKey(output))
|
||||
{
|
||||
VolumeControls[args.Number].VolumeEventFromChassis();
|
||||
if (VolumeControls.ContainsKey(output))
|
||||
{
|
||||
VolumeControls[args.Number].VolumeEventFromChassis();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.EndpointOnlineEventId:
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
if (Chassis.Outputs[output].Endpoint != null)
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
|
||||
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
if (Chassis.Outputs[output].Endpoint != null)
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
|
||||
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
|
||||
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.OnlineFeedbackEventId:
|
||||
{
|
||||
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
{
|
||||
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.VideoOutEventId:
|
||||
{
|
||||
|
||||
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
|
||||
|
||||
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
|
||||
inputNumber, output);
|
||||
|
||||
if (VideoOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
|
||||
|
||||
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
|
||||
|
||||
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
|
||||
inputNumber, output);
|
||||
|
||||
if (VideoOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]);
|
||||
|
||||
|
||||
VideoOutputFeedbacks[output].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(output,
|
||||
inputNumber,
|
||||
localOutputPort,
|
||||
localInputPort,
|
||||
eRoutingSignalType.AudioVideo));
|
||||
VideoOutputFeedbacks[output].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(output,
|
||||
inputNumber,
|
||||
localOutputPort,
|
||||
localInputPort,
|
||||
eRoutingSignalType.AudioVideo));
|
||||
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[output].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[output].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.OutputNameEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
|
||||
OutputNameFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
{
|
||||
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
|
||||
OutputNameFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
|
||||
args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
{
|
||||
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
|
||||
args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -564,7 +653,8 @@ namespace PepperDash.Essentials.DM {
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pnt"></param>
|
||||
void StartOffTimer(PortNumberType pnt) {
|
||||
void StartOffTimer(PortNumberType pnt)
|
||||
{
|
||||
if (RouteOffTimers.ContainsKey(pnt))
|
||||
return;
|
||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime);
|
||||
@@ -572,8 +662,10 @@ namespace PepperDash.Essentials.DM {
|
||||
|
||||
|
||||
// Send out sigs when coming online
|
||||
void IsOnline_OutputChange(object sender, EventArgs e) {
|
||||
if (IsOnline.BoolValue) {
|
||||
void IsOnline_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (IsOnline.BoolValue)
|
||||
{
|
||||
Chassis.EnableUSBBreakaway.BoolValue = true;
|
||||
|
||||
if (InputNames != null)
|
||||
@@ -587,12 +679,13 @@ namespace PepperDash.Essentials.DM {
|
||||
|
||||
#region IRouting Members
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) {
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType);
|
||||
|
||||
var input = inputSelector as DMInput; // Cast can sometimes fail
|
||||
var output = outputSelector as DMOutput;
|
||||
|
||||
|
||||
|
||||
if (output == null)
|
||||
{
|
||||
@@ -605,11 +698,14 @@ namespace PepperDash.Essentials.DM {
|
||||
// Check to see if there's an off timer waiting on this and if so, cancel
|
||||
var key = new PortNumberType(output, sigType);
|
||||
|
||||
if (input == null) {
|
||||
if (input == null)
|
||||
{
|
||||
StartOffTimer(key);
|
||||
}
|
||||
else {
|
||||
if (RouteOffTimers.ContainsKey(key)) {
|
||||
else
|
||||
{
|
||||
if (RouteOffTimers.ContainsKey(key))
|
||||
{
|
||||
Debug.Console(2, this, "{0} cancelling route off due to new source", output);
|
||||
RouteOffTimers[key].Stop();
|
||||
RouteOffTimers.Remove(key);
|
||||
@@ -671,7 +767,7 @@ namespace PepperDash.Essentials.DM {
|
||||
var ioSlotJoin = ioSlot - 1;
|
||||
|
||||
// Control
|
||||
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video));
|
||||
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort)ioSlot, eRoutingSignalType.Video));
|
||||
|
||||
if (TxDictionary.ContainsKey(ioSlot))
|
||||
{
|
||||
|
||||
@@ -216,21 +216,11 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
var presetsCamera = cameraDevice as IHasCameraPresets;
|
||||
presetsCamera.PresetsListHasChanged += new EventHandler<EventArgs>((o, a) =>
|
||||
{
|
||||
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
|
||||
{
|
||||
int tempNum = i - 1;
|
||||
|
||||
string label = "";
|
||||
|
||||
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
|
||||
|
||||
if (preset != null)
|
||||
label = preset.Description;
|
||||
|
||||
trilist.SetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||
}
|
||||
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
|
||||
});
|
||||
|
||||
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
|
||||
|
||||
for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++)
|
||||
{
|
||||
int tempNum = i;
|
||||
@@ -246,10 +236,35 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
presetsCamera.PresetStore(tempNum, label);
|
||||
});
|
||||
}
|
||||
trilist.OnlineStatusChange += (sender, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine)
|
||||
{ return; }
|
||||
|
||||
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
private void SendCameraPresetNamesToApi(IHasCameraPresets presetsCamera, CameraControllerJoinMap joinMap, BasicTriList trilist)
|
||||
{
|
||||
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
|
||||
{
|
||||
int tempNum = i - 1;
|
||||
|
||||
string label = "";
|
||||
|
||||
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
|
||||
|
||||
if (preset != null)
|
||||
label = preset.Description;
|
||||
|
||||
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CameraPreset : PresetBase
|
||||
{
|
||||
public CameraPreset(int id, string description, bool isDefined, bool isDefinable)
|
||||
|
||||
@@ -525,6 +525,15 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
|
||||
public event EventHandler<EventArgs> PresetsListHasChanged;
|
||||
|
||||
protected void OnPresetsListHasChanged()
|
||||
{
|
||||
var handler = PresetsListHasChanged;
|
||||
if (handler == null)
|
||||
return;
|
||||
|
||||
handler.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public List<CameraPreset> Presets { get; private set; }
|
||||
|
||||
public void PresetSelect(int preset)
|
||||
@@ -537,6 +546,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
SavePreset(preset);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasCameraFocusControl Members
|
||||
|
||||
@@ -69,6 +69,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
[JsonProperty("directoryResults")]
|
||||
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
|
||||
|
||||
public List<DirectoryItem> Contacts
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryContact>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<DirectoryItem> Folders
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryFolder>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to store the ID of the current folder for CurrentDirectoryResults
|
||||
/// </summary>
|
||||
@@ -104,6 +120,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
SortDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the CurrentDirectoryResults by the predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
public void FilterContacts(Func<DirectoryItem, bool> predicate)
|
||||
{
|
||||
CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically
|
||||
/// </summary>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
||||
public interface IInputVga1 { void InputVga1(); }
|
||||
|
||||
}
|
||||
@@ -314,7 +314,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
FarEndIsSharingContentFeedback = new BoolFeedback(FarEndIsSharingContentFeedbackFunc);
|
||||
CameraIsOffFeedback = new BoolFeedback(() => CodecStatus.Status.Video.Input.MainVideoMute.BoolValue);
|
||||
CameraIsMutedFeedback = CameraIsOffFeedback;
|
||||
|
||||
SupportsCameraOff = true;
|
||||
|
||||
PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized");
|
||||
|
||||
@@ -417,6 +417,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate;
|
||||
CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate;
|
||||
CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate;
|
||||
CodecStatus.Status.Cameras.SpeakerTrack.Availability.ValueChangedAction = () => { SupportsCameraAutoMode = CodecStatus.Status.Cameras.SpeakerTrack.Availability.BoolValue; };
|
||||
CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate;
|
||||
CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus;
|
||||
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;
|
||||
@@ -550,6 +551,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
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);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
var socket = Communication as ISocketStatus;
|
||||
if (socket != null)
|
||||
{
|
||||
@@ -558,9 +566,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
|
||||
Communication.Connect();
|
||||
|
||||
CommunicationMonitor.Start();
|
||||
CommunicationMonitor.Start();
|
||||
|
||||
string prefix = "xFeedback register ";
|
||||
const string prefix = "xFeedback register ";
|
||||
|
||||
CliFeedbackRegistrationExpression =
|
||||
prefix + "/Configuration" + Delimiter +
|
||||
@@ -575,14 +583,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
prefix + "/Status/Video/Layout" + Delimiter +
|
||||
prefix + "/Status/Video/Input/MainVideoMute" + Delimiter +
|
||||
prefix + "/Bookings" + Delimiter +
|
||||
prefix + "/Event/CallDisconnect" + Delimiter +
|
||||
prefix + "/Event/CallDisconnect" + Delimiter +
|
||||
prefix + "/Event/Bookings" + Delimiter +
|
||||
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
|
||||
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
||||
|
||||
return base.CustomActivate();
|
||||
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc.
|
||||
/// </summary>
|
||||
|
||||
@@ -277,9 +277,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
public SoftwareID SoftwareID { get; set; }
|
||||
}
|
||||
|
||||
public class Availability
|
||||
public class Availability : ValueProperty
|
||||
{
|
||||
public string Value { get; set; }
|
||||
string _Value;
|
||||
public bool BoolValue { get; private set; }
|
||||
|
||||
public string Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
// If the incoming value is "Available" it sets the BoolValue true, otherwise sets it false
|
||||
_Value = value;
|
||||
BoolValue = value == "Available";
|
||||
OnValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Status2 : ValueProperty
|
||||
|
||||
@@ -65,8 +65,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
public bool ShowSelfViewByDefault { get; protected set; }
|
||||
|
||||
protected bool SupportsCameraOff;
|
||||
protected bool SupportsCameraAutoMode;
|
||||
public bool SupportsCameraOff { get; protected set; }
|
||||
public bool SupportsCameraAutoMode { get; protected set; }
|
||||
|
||||
public bool IsReady { get; protected set; }
|
||||
|
||||
|
||||
@@ -276,6 +276,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
if (zoomRooms.Count > 0)
|
||||
{
|
||||
// If so, setup a rooms and contacts folder and add them.
|
||||
|
||||
directory.ResultsFolderId = "root";
|
||||
|
||||
roomFolder.Name = "Rooms";
|
||||
roomFolder.ParentFolderId = "root";
|
||||
roomFolder.FolderId = "rooms";
|
||||
@@ -292,22 +295,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
try
|
||||
{
|
||||
if (zoomContacts.Count == 0) return directory;
|
||||
if (zoomContacts.Count == 0)
|
||||
{
|
||||
return directory;
|
||||
}
|
||||
|
||||
foreach (Contact c in zoomContacts)
|
||||
{
|
||||
foreach (Contact c in zoomContacts)
|
||||
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
|
||||
|
||||
contact.ContactMethods.Add(new ContactMethod() { Number = c.Jid, Device = eContactMethodDevice.Video, CallType = eContactMethodCallType.Video, ContactMethodId = c.Jid });
|
||||
|
||||
if (folders.Count > 0)
|
||||
{
|
||||
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
|
||||
|
||||
if (folders.Count > 0)
|
||||
{
|
||||
contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
|
||||
}
|
||||
|
||||
contacts.Add(contact);
|
||||
contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
|
||||
}
|
||||
|
||||
directory.AddContactsToDirectory(contacts);
|
||||
contacts.Add(contact);
|
||||
}
|
||||
|
||||
directory.AddContactsToDirectory(contacts);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1161,11 +1168,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _hideConfSelfVideo)
|
||||
{
|
||||
//if (value != _hideConfSelfVideo)
|
||||
//{
|
||||
_hideConfSelfVideo = value;
|
||||
NotifyPropertyChanged("HideConfSelfVideo");
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Core.Queues;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||
@@ -30,10 +31,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
private const long MeetingRefreshTimer = 60000;
|
||||
private const uint DefaultMeetingDurationMin = 30;
|
||||
private const string Delimiter = "\x0D\x0A";
|
||||
private readonly CrestronQueue<string> _receiveQueue;
|
||||
|
||||
private readonly GenericQueue _receiveQueue;
|
||||
//private readonly CrestronQueue<string> _receiveQueue;
|
||||
|
||||
|
||||
private readonly Thread _receiveThread;
|
||||
//private readonly Thread _receiveThread;
|
||||
|
||||
private readonly ZoomRoomSyncState _syncState;
|
||||
public bool CommDebuggingIsOn;
|
||||
@@ -51,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
_props = JsonConvert.DeserializeObject<ZoomRoomPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
// The queue that will collect the repsonses in the order they are received
|
||||
_receiveQueue = new CrestronQueue<string>(1024);
|
||||
|
||||
// The thread responsible for dequeuing and processing the messages
|
||||
_receiveThread = new Thread(o => ProcessQueue(), null) { Priority = Thread.eThreadPriority.MediumPriority };
|
||||
_receiveQueue = new GenericQueue(Key + "-rxQueue", Thread.eThreadPriority.MediumPriority, 512);
|
||||
|
||||
Communication = comm;
|
||||
|
||||
@@ -95,6 +94,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
Output2 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut,
|
||||
eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DisplayPort, null, this);
|
||||
|
||||
SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc);
|
||||
|
||||
CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc);
|
||||
@@ -120,7 +123,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
Participants = new CodecParticipants();
|
||||
|
||||
SupportsCameraOff = _props.SupportsCameraOff;
|
||||
SupportsCameraOff = true; // Always allow turning off the camera for zoom calls?
|
||||
SupportsCameraAutoMode = _props.SupportsCameraAutoMode;
|
||||
|
||||
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
||||
@@ -154,7 +157,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0);
|
||||
return () =>
|
||||
{
|
||||
var scaledVol = CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0);
|
||||
|
||||
if (Configuration.Audio.Output.Volume != 0)
|
||||
{
|
||||
Debug.Console(2, this, "Storing previous volume level as: {0}, scaled: {1}", Configuration.Audio.Output.Volume, scaledVol);
|
||||
_previousVolumeLevel = scaledVol; // Store the previous level for recall
|
||||
}
|
||||
|
||||
return scaledVol;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,6 +266,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public RoutingInputPort CodecOsdIn { get; private set; }
|
||||
public RoutingOutputPort Output1 { get; private set; }
|
||||
public RoutingOutputPort Output2 { get; private set; }
|
||||
|
||||
#region ICommunicationMonitor Members
|
||||
|
||||
@@ -277,7 +292,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
var handler = CameraSelected;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new CameraSelectedEventArgs(SelectedCamera));
|
||||
handler(this, new CameraSelectedEventArgs(_selectedCamera));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,6 +329,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public BoolFeedback SelfviewIsOnFeedback { get; private set; }
|
||||
|
||||
public void GetSelfViewMode()
|
||||
{
|
||||
SendText("zConfiguration Video hide_conf_self_video");
|
||||
}
|
||||
|
||||
public void SelfViewModeOn()
|
||||
{
|
||||
SendText("zConfiguration Video hide_conf_self_video: off");
|
||||
@@ -346,6 +366,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public CodecDirectory CurrentDirectoryResult
|
||||
{
|
||||
get { return _currentDirectoryResult; }
|
||||
private set
|
||||
{
|
||||
_currentDirectoryResult = value;
|
||||
|
||||
Debug.Console(2, this, "CurrentDirectoryResult Updated. ResultsFolderId: {0}", _currentDirectoryResult.ResultsFolderId);
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
|
||||
|
||||
OnDirectoryResultReturned(_currentDirectoryResult);
|
||||
}
|
||||
}
|
||||
|
||||
public CodecPhonebookSyncState PhonebookSyncState { get; private set; }
|
||||
@@ -359,9 +389,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
c => c.Name.IndexOf(searchString, 0, StringComparison.OrdinalIgnoreCase) > -1));
|
||||
|
||||
DirectoryBrowseHistoryStack.Clear();
|
||||
_currentDirectoryResult = directoryResults;
|
||||
CurrentDirectoryResult = directoryResults;
|
||||
|
||||
OnDirectoryResultReturned(directoryResults);
|
||||
}
|
||||
|
||||
public void GetDirectoryFolderContents(string folderId)
|
||||
@@ -373,19 +402,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
DirectoryBrowseHistoryStack.Push(_currentDirectoryResult);
|
||||
|
||||
_currentDirectoryResult = directoryResults;
|
||||
CurrentDirectoryResult = directoryResults;
|
||||
|
||||
OnDirectoryResultReturned(directoryResults);
|
||||
}
|
||||
|
||||
public void SetCurrentDirectoryToRoot()
|
||||
{
|
||||
DirectoryBrowseHistoryStack.Clear();
|
||||
|
||||
_currentDirectoryResult = DirectoryRoot;
|
||||
|
||||
OnDirectoryResultReturned(DirectoryRoot);
|
||||
}
|
||||
CurrentDirectoryResult = DirectoryRoot;
|
||||
}
|
||||
|
||||
public void GetDirectoryParentFolderContents()
|
||||
{
|
||||
@@ -396,10 +422,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
var currentDirectory = DirectoryBrowseHistoryStack.Pop();
|
||||
|
||||
_currentDirectoryResult = currentDirectory;
|
||||
|
||||
OnDirectoryResultReturned(currentDirectory);
|
||||
}
|
||||
CurrentDirectoryResult = currentDirectory;
|
||||
}
|
||||
|
||||
public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; }
|
||||
|
||||
@@ -665,14 +689,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
private void SetUpDirectory()
|
||||
{
|
||||
DirectoryRoot = new CodecDirectory();
|
||||
DirectoryRoot = new CodecDirectory() { ResultsFolderId = "root" };
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult.ResultsFolderId != "root");
|
||||
|
||||
CurrentDirectoryResult = DirectoryRoot;
|
||||
|
||||
DirectoryBrowseHistory = new List<CodecDirectory>();
|
||||
DirectoryBrowseHistoryStack = new Stack<CodecDirectory>();
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => _currentDirectoryResult != DirectoryRoot);
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
|
||||
}
|
||||
|
||||
private void SetUpRouting()
|
||||
@@ -683,6 +708,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
// Set up output ports
|
||||
OutputPorts.Add(Output1);
|
||||
OutputPorts.Add(Output2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -717,7 +743,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
|
||||
"Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
var socket = Communication as ISocketStatus;
|
||||
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
var socket = Communication as ISocketStatus;
|
||||
if (socket != null)
|
||||
{
|
||||
socket.ConnectionChange += socket_ConnectionChange;
|
||||
@@ -728,11 +763,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Communication.Connect();
|
||||
|
||||
CommunicationMonitor.Start();
|
||||
}
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void SetCommDebug(string s)
|
||||
public void SetCommDebug(string s)
|
||||
{
|
||||
if (s == "1")
|
||||
{
|
||||
@@ -779,37 +814,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
//if (CommDebuggingIsOn)
|
||||
// Debug.Console(1, this, "Gathered: '{0}'", args.Text);
|
||||
|
||||
_receiveQueue.Enqueue(args.Text);
|
||||
|
||||
// If the receive thread has for some reason stopped, this will restart it
|
||||
if (_receiveThread.ThreadState != Thread.eThreadStates.ThreadRunning)
|
||||
{
|
||||
_receiveThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Runs in it's own thread to dequeue messages in the order they were received to be processed
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private object ProcessQueue()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var message = _receiveQueue.Dequeue();
|
||||
|
||||
ProcessMessage(message);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error Processing Queue: {0}", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
_receiveQueue.Enqueue(new ProcessStringMessage(args.Text, ProcessMessage));
|
||||
}
|
||||
|
||||
|
||||
@@ -970,10 +975,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
SendText("echo off");
|
||||
Thread.Sleep(100);
|
||||
// set feedback exclusions
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list");
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list");
|
||||
Thread.Sleep(100);
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list");
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list");
|
||||
Thread.Sleep(100);
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist");
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (!_props.DisablePhonebookAutoDownload)
|
||||
{
|
||||
@@ -1064,24 +1071,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
case "phonebooklistresult":
|
||||
{
|
||||
// This result will always be the complete contents of the directory and never
|
||||
// A subset of the results via a search
|
||||
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook);
|
||||
|
||||
var directoryResults =
|
||||
zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts);
|
||||
|
||||
if (!PhonebookSyncState.InitialSyncComplete)
|
||||
{
|
||||
PhonebookSyncState.InitialPhonebookFoldersReceived();
|
||||
PhonebookSyncState.PhonebookRootEntriesReceived();
|
||||
PhonebookSyncState.SetPhonebookHasFolders(false);
|
||||
PhonebookSyncState.SetPhonebookHasFolders(true);
|
||||
PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count);
|
||||
}
|
||||
|
||||
var directoryResults =
|
||||
zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts);
|
||||
if (directoryResults.ResultsFolderId != "root")
|
||||
{
|
||||
directoryResults.ResultsFolderId = "root";
|
||||
}
|
||||
|
||||
DirectoryRoot = directoryResults;
|
||||
DirectoryRoot = directoryResults;
|
||||
|
||||
_currentDirectoryResult = DirectoryRoot;
|
||||
|
||||
OnDirectoryResultReturned(directoryResults);
|
||||
CurrentDirectoryResult = directoryResults;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1237,7 +1250,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
Direction = eCodecCallDirection.Incoming,
|
||||
Status = eCodecCallStatus.Ringing,
|
||||
Type = eCodecCallType.Unknown,
|
||||
Type = eCodecCallType.Video,
|
||||
Name = incomingCall.callerName,
|
||||
Id = incomingCall.callerJID
|
||||
};
|
||||
@@ -1565,6 +1578,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Debug.Console(1, this, "Creating new Status.Call object");
|
||||
Status.Call = new zStatus.Call { Status = callStatus };
|
||||
|
||||
OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected });
|
||||
|
||||
SetUpCallFeedbackActions();
|
||||
}
|
||||
|
||||
@@ -1585,7 +1600,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
|
||||
var newCall = new CodecActiveCallItem { Status = newStatus };
|
||||
var newCall = new CodecActiveCallItem
|
||||
{
|
||||
Name = Status.Call.Info.meeting_list_item.meetingName,
|
||||
Number = Status.Call.Info.meeting_id,
|
||||
Id = Status.Call.Info.meeting_id,
|
||||
Status = newStatus,
|
||||
Type = eCodecCallType.Video,
|
||||
};
|
||||
|
||||
ActiveCalls.Add(newCall);
|
||||
|
||||
@@ -1594,6 +1616,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
OnCallStatusChange(newCall);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1641,7 +1665,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
//clear participants list after call cleanup
|
||||
if (ActiveCalls.Count == 0)
|
||||
{
|
||||
Participants.CurrentParticipants = new List<Participant>();
|
||||
var emptyList = new List<Participant>();
|
||||
Participants.CurrentParticipants = emptyList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1695,12 +1720,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public override void MuteOff()
|
||||
{
|
||||
Debug.Console(2, this, "Unmuting to previous level: {0}", _previousVolumeLevel);
|
||||
SetVolume((ushort)_previousVolumeLevel);
|
||||
}
|
||||
|
||||
public override void MuteOn()
|
||||
{
|
||||
_previousVolumeLevel = Configuration.Audio.Output.Volume; // Store the previous level for recall
|
||||
|
||||
SetVolume(0);
|
||||
}
|
||||
@@ -1999,18 +2024,43 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
/// <param name="result"></param>
|
||||
private void OnDirectoryResultReturned(CodecDirectory result)
|
||||
{
|
||||
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
|
||||
try
|
||||
{
|
||||
Debug.Console(2, this, "OnDirectoryResultReturned");
|
||||
|
||||
// This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology
|
||||
var handler = DirectoryResultReturned;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new DirectoryEventArgs
|
||||
{
|
||||
Directory = result,
|
||||
DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue
|
||||
});
|
||||
}
|
||||
var directoryResult = new CodecDirectory();
|
||||
|
||||
// If result is Root, create a copy and filter out contacts whose parent folder is not root
|
||||
if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
|
||||
{
|
||||
Debug.Console(2, this, "Filtering DirectoryRoot to remove contacts for display");
|
||||
|
||||
directoryResult.ResultsFolderId = result.ResultsFolderId;
|
||||
directoryResult.AddFoldersToDirectory(result.Folders);
|
||||
directoryResult.AddContactsToDirectory(result.Contacts.Where((c) => c.ParentFolderId == result.ResultsFolderId).ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
directoryResult = result;
|
||||
}
|
||||
|
||||
Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0}", !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue);
|
||||
|
||||
// This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology
|
||||
var handler = DirectoryResultReturned;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new DirectoryEventArgs
|
||||
{
|
||||
Directory = directoryResult,
|
||||
DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Error: {0}", e);
|
||||
}
|
||||
|
||||
//PrintDirectory(result);
|
||||
}
|
||||
@@ -2026,6 +2076,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
foreach (var cam in Status.Cameras)
|
||||
{
|
||||
// Known Issue:
|
||||
// Crestron UC engine systems seem to report an item in the cameras list that represnts the USB bridge device.
|
||||
// If we know the name and it's reliably consistent, we could ignore it here...
|
||||
|
||||
if (cam.Name.IndexOf("HD-CONV-USB") > -1)
|
||||
{
|
||||
// Skip this as it's the Crestron USB box, not a real camera
|
||||
continue;
|
||||
}
|
||||
|
||||
var camera = new ZoomRoomCamera(cam.id, cam.Name, this);
|
||||
|
||||
Cameras.Add(camera);
|
||||
@@ -2457,9 +2517,51 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public void LocalLayoutToggle()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var currentLayout = LocalLayoutFeedback.StringValue;
|
||||
|
||||
var eCurrentLayout = (int)Enum.Parse(typeof(zConfiguration.eLayoutStyle), currentLayout, true);
|
||||
|
||||
var nextLayout = GetNextLayout(eCurrentLayout);
|
||||
|
||||
if (nextLayout != zConfiguration.eLayoutStyle.None)
|
||||
{
|
||||
SetLayout(nextLayout);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the next available layout
|
||||
/// </summary>
|
||||
/// <param name="currentLayout"></param>
|
||||
/// <returns></returns>
|
||||
private zConfiguration.eLayoutStyle GetNextLayout(int currentLayout)
|
||||
{
|
||||
if (AvailableLayouts == zConfiguration.eLayoutStyle.None)
|
||||
{
|
||||
return zConfiguration.eLayoutStyle.None;
|
||||
}
|
||||
|
||||
zConfiguration.eLayoutStyle nextLayout;
|
||||
|
||||
if (((zConfiguration.eLayoutStyle)currentLayout & zConfiguration.eLayoutStyle.ShareAll) == zConfiguration.eLayoutStyle.ShareAll)
|
||||
{
|
||||
nextLayout = zConfiguration.eLayoutStyle.Gallery;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLayout = (zConfiguration.eLayoutStyle)(currentLayout << 1);
|
||||
}
|
||||
|
||||
if ((AvailableLayouts & nextLayout) == nextLayout)
|
||||
{
|
||||
return nextLayout;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetNextLayout((int)nextLayout);
|
||||
}
|
||||
}
|
||||
|
||||
public void LocalLayoutToggleSingleProminent()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
: base(key, name)
|
||||
{
|
||||
ParentCodec = codec;
|
||||
|
||||
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<packages>
|
||||
<package id="PepperDashCore" version="1.0.47" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
|
||||
<package id="PepperDashCore" version="1.0.48" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
|
||||
</packages>
|
||||
Reference in New Issue
Block a user