mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-08 17:24:47 +00:00
Compare commits
28 Commits
1.9.5-hotf
...
1.9.3-hotf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7af8f0d087 | ||
|
|
82af1366df | ||
|
|
56492a00cd | ||
|
|
28bac18667 | ||
|
|
ea254ef983 | ||
|
|
76e4d4a82d | ||
|
|
4bd777f6b9 | ||
|
|
f607394ee7 | ||
|
|
085a64c87b | ||
|
|
290e887903 | ||
|
|
de7a74eaff | ||
|
|
88e5c49663 | ||
|
|
1415999d86 | ||
|
|
5f6b650dba | ||
|
|
94c0e92f6b | ||
|
|
a5046df671 | ||
|
|
5a4f7b6a28 | ||
|
|
dfaaa3f6bc | ||
|
|
377cccf912 | ||
|
|
9795637d75 | ||
|
|
6f6ca50c37 | ||
|
|
7b7ec53355 | ||
|
|
e3920132bf | ||
|
|
c2e5bd290a | ||
|
|
7fd52814a0 | ||
|
|
06a3dda2e4 | ||
|
|
d97ca6d5a4 | ||
|
|
4c50d6980f |
@@ -450,14 +450,13 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
}
|
||||
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
|
||||
{
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
|
||||
if (room != null)
|
||||
{
|
||||
// default IPID
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
// default to no join map key
|
||||
string fusionJoinMapKey = string.Empty;
|
||||
|
||||
@@ -478,7 +477,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
|
||||
@@ -490,7 +489,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
@@ -502,7 +501,7 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
@@ -515,31 +514,26 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
}
|
||||
|
||||
fusionIpId += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
|
||||
|
||||
}
|
||||
|
||||
private static void CreateMobileControlBridge(object room)
|
||||
private static void CreateMobileControlBridge(IEssentialsRoom room)
|
||||
{
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
var mobileControl3 = mobileControl as IMobileControl3;
|
||||
|
||||
if (mobileControl3 != null)
|
||||
{
|
||||
mobileControl3.CreateMobileControlRoomBridge(room as IEssentialsRoom, mobileControl);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobileControl.CreateMobileControlRoomBridge(room as EssentialsRoomBase, mobileControl);
|
||||
}
|
||||
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
|
||||
@@ -149,7 +149,8 @@
|
||||
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
||||
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
|
||||
<Compile Include="Room\Types\IEssentialsHuddleSpaceRoom.cs" />
|
||||
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleSpaceRoom.cs" />
|
||||
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleVtc1Room.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||
|
||||
@@ -454,8 +454,7 @@ namespace PepperDash.Essentials
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,11 +471,7 @@ namespace PepperDash.Essentials
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay
|
||||
{
|
||||
bool ExcludeFromGlobalFunctions { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
IBasicVolumeControls CurrentVolumeControls { get; }
|
||||
|
||||
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
}
|
||||
|
||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||
{
|
||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
IHasScheduleAwareness ScheduleSource { get; }
|
||||
|
||||
BoolFeedback InCallFeedback { get; }
|
||||
|
||||
BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||
|
||||
string DefaultCodecRouteString { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay
|
||||
{
|
||||
bool ExcludeFromGlobalFunctions { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
IBasicVolumeControls CurrentVolumeControls { get; }
|
||||
|
||||
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||
{
|
||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
IHasScheduleAwareness ScheduleSource { get; }
|
||||
|
||||
new BoolFeedback InCallFeedback { get; }
|
||||
|
||||
new BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||
|
||||
string DefaultCodecRouteString { get; }
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// 1202
|
||||
/// </summary>
|
||||
public const uint VCStagingInactivePopoverWithRecentsVisible = 1202;
|
||||
public const uint VCStagingInactivePopoverVisible = 1202;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -121,11 +121,6 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCRecentsVisible = 1206;
|
||||
|
||||
/// <summary>
|
||||
/// 1202
|
||||
/// </summary>
|
||||
public const uint VCStagingInactivePopoverWithoutRecentsVisible = 1207;
|
||||
|
||||
/// <summary>
|
||||
/// 1208
|
||||
/// </summary>
|
||||
@@ -248,10 +243,6 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCCameraSelectBarWithoutModeVisible = 1261;
|
||||
|
||||
/// <summary>
|
||||
/// 1262
|
||||
/// </summary>
|
||||
public const uint VCCameraAutoModeIsOnFb = 1262;
|
||||
|
||||
/// <summary>
|
||||
/// 1271
|
||||
@@ -752,10 +743,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>
|
||||
|
||||
@@ -316,7 +316,7 @@ namespace PepperDash.Essentials.UIDrivers
|
||||
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
|
||||
{
|
||||
var c = sender as ICommunicationMonitor;
|
||||
if (c != null && StatusListDeviceIndexes.ContainsKey(c))
|
||||
if (StatusListDeviceIndexes.ContainsKey(c))
|
||||
{
|
||||
var i = StatusListDeviceIndexes[c];
|
||||
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;
|
||||
|
||||
@@ -173,28 +173,10 @@ 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
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentMode;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _currentMode)
|
||||
{
|
||||
_currentMode = value;
|
||||
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
}
|
||||
}
|
||||
UiDisplayMode CurrentMode = UiDisplayMode.Start;
|
||||
|
||||
CTimer NextMeetingTimer;
|
||||
|
||||
@@ -225,7 +207,6 @@ 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]);
|
||||
@@ -626,21 +607,11 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void SetActivityFooterFeedbacks()
|
||||
{
|
||||
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;
|
||||
}
|
||||
CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -652,13 +623,14 @@ 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();
|
||||
}
|
||||
|
||||
@@ -671,6 +643,9 @@ 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)
|
||||
{
|
||||
@@ -690,6 +665,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
SetupSourceList();
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -731,8 +707,6 @@ namespace PepperDash.Essentials
|
||||
if (CurrentRoom.CurrentSourceInfo == null)
|
||||
return;
|
||||
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
|
||||
if (CurrentRoom.CurrentSourceInfo.SourceDevice == null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
@@ -1244,8 +1218,9 @@ namespace PepperDash.Essentials
|
||||
VCDriver.Hide();
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
ShowLogo();
|
||||
//TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
SetActivityFooterFeedbacks();
|
||||
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,10 +142,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible);
|
||||
|
||||
StagingBarsInterlock = new JoinedSigInterlock(triList);
|
||||
if(Codec is IHasCallHistory)
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible);
|
||||
else
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible);
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible);
|
||||
|
||||
StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList);
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
||||
@@ -354,15 +351,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0);
|
||||
|
||||
uint stageJoin;
|
||||
if (Codec.IsInCall)
|
||||
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
|
||||
else
|
||||
{
|
||||
if (Codec is IHasCallHistory)
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible;
|
||||
else
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible;
|
||||
}
|
||||
if (Codec.IsInCall)
|
||||
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
|
||||
else
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverVisible;
|
||||
if (IsVisible)
|
||||
StagingBarsInterlock.ShowInterlocked(stageJoin);
|
||||
else
|
||||
@@ -521,18 +513,13 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var supportsCameraOffMode = Codec.SupportsCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
var supportsAutoCameraMode = Codec.SupportsCameraAutoMode;
|
||||
|
||||
if (codecAutoCameras != null && supportsAutoCameraMode)
|
||||
if (codecAutoCameras != null)
|
||||
{
|
||||
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());
|
||||
|
||||
@@ -567,7 +554,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction(
|
||||
// () => ShowCameraManualMode());
|
||||
|
||||
if (codecOffCameras != null && supportsCameraOffMode)
|
||||
if (codecOffCameras != null)
|
||||
{
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true;
|
||||
codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]);
|
||||
@@ -782,14 +769,12 @@ 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) =>
|
||||
@@ -854,46 +839,25 @@ 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 (supportsAutoCameras)
|
||||
if (codecAutoCameras != null )
|
||||
{
|
||||
if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue)
|
||||
{
|
||||
@@ -1041,21 +1005,22 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
void SetupDirectoryList()
|
||||
{
|
||||
var codec = Codec as IHasDirectory;
|
||||
if (codec == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (codec != null)
|
||||
{
|
||||
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
||||
true, 1300);
|
||||
codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
|
||||
|
||||
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
||||
true, 1300);
|
||||
codec.DirectoryResultReturned += dir_DirectoryResultReturned;
|
||||
if (codec.PhonebookSyncState.InitialSyncComplete)
|
||||
SetCurrentDirectoryToRoot();
|
||||
else
|
||||
{
|
||||
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
|
||||
}
|
||||
|
||||
if (codec.PhonebookSyncState.InitialSyncComplete)
|
||||
SetCurrentDirectoryToRoot();
|
||||
else
|
||||
{
|
||||
codec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
|
||||
}
|
||||
RefreshDirectory();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1063,15 +1028,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
void SetCurrentDirectoryToRoot()
|
||||
{
|
||||
var hasDirectory = Codec as IHasDirectory;
|
||||
(Codec as IHasDirectory).SetCurrentDirectoryToRoot();
|
||||
|
||||
if (hasDirectory == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hasDirectory.SetCurrentDirectoryToRoot();
|
||||
SearchKeypadClear();
|
||||
|
||||
RefreshDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1083,17 +1044,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
{
|
||||
var codec = Codec as IHasDirectory;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetCurrentDirectoryToRoot();
|
||||
|
||||
RefreshDirectory();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1103,7 +1057,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// <param name="e"></param>
|
||||
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
||||
{
|
||||
RefreshDirectory(e.Directory);
|
||||
|
||||
RefreshDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1132,27 +1087,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void RefreshDirectory()
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dir"></param>
|
||||
void RefreshDirectory()
|
||||
{
|
||||
var codec = Codec as IHasDirectory;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshDirectory(codec.CurrentDirectoryResult);
|
||||
}
|
||||
|
||||
void RefreshDirectory(CodecDirectory directory)
|
||||
{
|
||||
if (directory.CurrentDirectoryResults.Count > 0)
|
||||
if ((Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults.Count > 0)
|
||||
{
|
||||
ushort i = 0;
|
||||
foreach (var r in directory.CurrentDirectoryResults)
|
||||
foreach (var r in (Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults)
|
||||
{
|
||||
if (i == DirectoryList.MaxCount)
|
||||
{
|
||||
@@ -1172,33 +1116,19 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
// If more than one contact method, show contact method modal dialog
|
||||
DirectoryList.SetItemButtonAction(i, b =>
|
||||
{
|
||||
if (b)
|
||||
if (!b)
|
||||
{
|
||||
return;
|
||||
// Refresh the contact methods list
|
||||
RefreshContactMethodsModalList(dc);
|
||||
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
}
|
||||
// Refresh the contact methods list
|
||||
RefreshContactMethodsModalList(dc);
|
||||
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
});
|
||||
|
||||
}
|
||||
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
|
||||
{
|
||||
Debug.Console(1, "Unable to dial contact. No availble ContactMethod(s) specified");
|
||||
// If only one contact method, just dial that method
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
|
||||
}
|
||||
}
|
||||
else // is DirectoryFolder
|
||||
@@ -1225,7 +1155,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
DirectoryList.SetItemMainText(1, "No Results Found");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RefreshContactMethodsModalList(DirectoryContact contact)
|
||||
{
|
||||
@@ -1270,7 +1201,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) =>
|
||||
{
|
||||
@@ -1283,24 +1214,14 @@ 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,19 +8,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
/// </summary>
|
||||
public interface IMobileControl : IKeyed
|
||||
{
|
||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
|
||||
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
|
||||
|
||||
void LinkSystemMonitorToAppServer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a MobileSystemController that accepts IEssentialsRoom
|
||||
/// </summary>
|
||||
public interface IMobileControl3 : IMobileControl
|
||||
{
|
||||
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a MobileControl Room Bridge
|
||||
/// </summary>
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace PepperDash.Essentials.Core
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
Debug.Console(0,"****PreActivation starting...****");
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
@@ -69,9 +70,12 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} PreActivation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "****PreActivation complete****");
|
||||
Debug.Console(0, "****Activation starting...****");
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
@@ -83,10 +87,14 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} Activation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "****Activation complete****");
|
||||
Debug.Console(0, "****PostActivation starting...****");
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
@@ -97,10 +105,13 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} PostActivation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "****PostActivation complete****");
|
||||
|
||||
OnAllDevicesActivated();
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -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,53 +156,44 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,11 @@ namespace PepperDash.Essentials.Core
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
public void SetValueFunc(Func<bool> newFunc)
|
||||
{
|
||||
ValueFunc = newFunc;
|
||||
}
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||
|
||||
@@ -51,6 +51,12 @@ namespace PepperDash.Essentials.Core
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
public void SetValueFunc(Func<int> newFunc)
|
||||
{
|
||||
ValueFunc = newFunc;
|
||||
}
|
||||
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||
|
||||
@@ -52,7 +52,10 @@ namespace PepperDash.Essentials.Core
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
|
||||
public void SetValueFunc(Func<string> newFunc)
|
||||
{
|
||||
ValueFunc = newFunc;
|
||||
}
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
|
||||
@@ -119,9 +119,21 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
var slot = Global.ControlSystem.ProgramNumber;
|
||||
|
||||
var guidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
var oldGuidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
|
||||
if (File.Exists(oldGuidFilePath))
|
||||
{
|
||||
Debug.Console(0, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
|
||||
|
||||
File.Copy(oldGuidFilePath, guidFilePath);
|
||||
|
||||
File.Delete(oldGuidFilePath);
|
||||
}
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
|
||||
// Check if file exists
|
||||
if (!_guidFileExists)
|
||||
@@ -149,19 +161,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
});
|
||||
AddPostActivationAction(() => PostActivate(guidFilePath));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -169,6 +169,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
}
|
||||
|
||||
private void PostActivate(string guidFilePath)
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
}
|
||||
|
||||
protected string RoomGuid
|
||||
{
|
||||
get { return _guiDs.RoomGuid; }
|
||||
@@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an abstract controller device for a partition dividing rooms that are combinable
|
||||
///
|
||||
/// In Auto mode, it can use a partition sensor to automatically determine whether the partition is present.
|
||||
///
|
||||
/// In Manual mode it accepts user input to tell it whether the partition is present.
|
||||
/// </summary>
|
||||
public class EssentialsPartitionController : IPartitionController
|
||||
{
|
||||
private IPartitionStateProvider _partitionSensor;
|
||||
|
||||
private bool isInAutoMode;
|
||||
|
||||
private bool partitionPresent;
|
||||
|
||||
public EssentialsPartitionController(string key, string name, IPartitionStateProvider sensor, bool defaultToManualMode, List<string> adjacentRoomKeys)
|
||||
{
|
||||
Key = key;
|
||||
|
||||
Name = name;
|
||||
|
||||
AdjacentRoomKeys = adjacentRoomKeys;
|
||||
|
||||
if (sensor != null)
|
||||
{
|
||||
_partitionSensor = sensor;
|
||||
|
||||
if (!defaultToManualMode)
|
||||
{
|
||||
SetAutoMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetManualMode();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetManualMode();
|
||||
}
|
||||
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
if (isInAutoMode)
|
||||
{
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
#region IPartitionController Members
|
||||
|
||||
public List<string> AdjacentRoomKeys { get; private set; }
|
||||
|
||||
public void SetAutoMode()
|
||||
{
|
||||
isInAutoMode = true;
|
||||
if (PartitionPresentFeedback != null)
|
||||
{
|
||||
PartitionPresentFeedback.SetValueFunc(() => _partitionSensor.PartitionPresentFeedback.BoolValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionPresentFeedback.BoolValue);
|
||||
}
|
||||
|
||||
if (_partitionSensor != null)
|
||||
{
|
||||
_partitionSensor.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetManualMode()
|
||||
{
|
||||
isInAutoMode = false;
|
||||
if (PartitionPresentFeedback != null)
|
||||
{
|
||||
PartitionPresentFeedback.SetValueFunc(() => partitionPresent);
|
||||
}
|
||||
else
|
||||
{
|
||||
PartitionPresentFeedback = new BoolFeedback(() => partitionPresent);
|
||||
}
|
||||
|
||||
if (_partitionSensor != null)
|
||||
{
|
||||
_partitionSensor.PartitionPresentFeedback.OutputChange -= PartitionPresentFeedback_OutputChange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetPartitionStatePresent()
|
||||
{
|
||||
if (!isInAutoMode)
|
||||
{
|
||||
partitionPresent = true;
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPartitionStateNotPresent()
|
||||
{
|
||||
if (!isInAutoMode)
|
||||
{
|
||||
partitionPresent = false;
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggglePartitionState()
|
||||
{
|
||||
if (!isInAutoMode)
|
||||
{
|
||||
partitionPresent = !partitionPresent;
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartitionStateProvider Members
|
||||
|
||||
public BoolFeedback PartitionPresentFeedback { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IKeyName Members
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IKeyed Members
|
||||
|
||||
public string Key { get; private set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -13,13 +13,13 @@ using PepperDash.Essentials.Core.Config;
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Description("Wrapper class for GLS Cresnet Partition Sensor")]
|
||||
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice
|
||||
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice, IPartitionStateProvider
|
||||
{
|
||||
private GlsPartCn _partitionSensor;
|
||||
|
||||
public StringFeedback NameFeedback { get; private set; }
|
||||
public BoolFeedback EnableFeedback { get; private set; }
|
||||
public BoolFeedback PartitionSensedFeedback { get; private set; }
|
||||
public BoolFeedback PartitionPresentFeedback { get; private set; }
|
||||
public BoolFeedback PartitionNotSensedFeedback { get; private set; }
|
||||
public IntFeedback SensitivityFeedback { get; private set; }
|
||||
|
||||
@@ -39,10 +39,10 @@ namespace PepperDash.Essentials.Core
|
||||
RegisterCrestronGenericBase(_partitionSensor);
|
||||
|
||||
NameFeedback = new StringFeedback(() => Name);
|
||||
EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue);
|
||||
PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||
PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||
SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue);
|
||||
EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue);
|
||||
PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||
PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||
SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue);
|
||||
|
||||
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
|
||||
});
|
||||
@@ -61,7 +61,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
case (GlsPartCn.PartitionSensedFeedbackEventId):
|
||||
{
|
||||
PartitionSensedFeedback.FireUpdate();
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case (GlsPartCn.PartitionNotSensedFeedbackEventId):
|
||||
@@ -93,6 +93,9 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestEnableFeedback = state;
|
||||
|
||||
EnableFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
|
||||
return;
|
||||
}
|
||||
@@ -105,6 +108,10 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestPartitionSensedFeedback = state;
|
||||
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
PartitionNotSensedFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
|
||||
return;
|
||||
}
|
||||
@@ -117,6 +124,8 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestSensitivityFeedback = value;
|
||||
|
||||
SensitivityFeedback.FireUpdate();
|
||||
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
|
||||
return;
|
||||
}
|
||||
@@ -186,7 +195,7 @@ namespace PepperDash.Essentials.Core
|
||||
// link output to simpl
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]);
|
||||
PartitionSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
|
||||
PartitionPresentFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
|
||||
PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]);
|
||||
SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]);
|
||||
|
||||
@@ -216,7 +225,7 @@ namespace PepperDash.Essentials.Core
|
||||
IsOnline.FireUpdate();
|
||||
NameFeedback.FireUpdate();
|
||||
EnableFeedback.FireUpdate();
|
||||
PartitionSensedFeedback.FireUpdate();
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
PartitionNotSensedFeedback.FireUpdate();
|
||||
SensitivityFeedback.FireUpdate();
|
||||
}
|
||||
@@ -257,7 +266,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
|
||||
Debug.Console(1, "Factory Attempting to create new GlsPartitionSensorController Device");
|
||||
|
||||
return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the functionality of a device that senses and provides partition state
|
||||
/// </summary>
|
||||
public interface IPartitionStateProvider : IKeyName
|
||||
{
|
||||
BoolFeedback PartitionPresentFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the functionality of a device that can provide partition state either manually via user input or optionally via a sensor state
|
||||
/// </summary>
|
||||
public interface IPartitionController : IPartitionStateProvider
|
||||
{
|
||||
List<string> AdjacentRoomKeys { get; }
|
||||
|
||||
void SetPartitionStatePresent();
|
||||
|
||||
void SetPartitionStateNotPresent();
|
||||
|
||||
void ToggglePartitionState();
|
||||
|
||||
void SetManualMode();
|
||||
|
||||
void SetAutoMode();
|
||||
}
|
||||
}
|
||||
@@ -234,6 +234,8 @@
|
||||
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
|
||||
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
|
||||
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
|
||||
<Compile Include="PartitionSensor\EssentialsPartitionController.cs" />
|
||||
<Compile Include="PartitionSensor\IPartitionStateProvider.cs" />
|
||||
<Compile Include="Occupancy\OccupancyAggregatorConfig.cs" />
|
||||
<Compile Include="Queues\ComsMessage.cs" />
|
||||
<Compile Include="Queues\ProcessStringMessage.cs" />
|
||||
@@ -289,6 +291,10 @@
|
||||
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
|
||||
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
|
||||
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
|
||||
<Compile Include="Room\Combining\EssentialsRoomCombiner.cs" />
|
||||
<Compile Include="Room\Combining\EssentialsRoomCombinerPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Combining\IEssentialsRoomCombiner.cs" />
|
||||
<Compile Include="Room\Combining\RoomCombinationScenario.cs" />
|
||||
<Compile Include="Room\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
|
||||
<Compile Include="Room\IEssentialsRoom.cs" />
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner
|
||||
{
|
||||
private EssentialsRoomCombinerPropertiesConfig _propertiesConfig;
|
||||
|
||||
private IRoomCombinationScenario _currentScenario;
|
||||
|
||||
private List<IEssentialsRoom> _rooms;
|
||||
|
||||
private bool isInAutoMode;
|
||||
|
||||
private CTimer _scenarioChangeDebounceTimer;
|
||||
|
||||
private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s
|
||||
|
||||
public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props)
|
||||
: base(key)
|
||||
{
|
||||
_propertiesConfig = props;
|
||||
|
||||
Partitions = new List<IPartitionController>();
|
||||
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
|
||||
|
||||
if (_propertiesConfig.ScenarioChangeDebounceTimeSeconds > 0)
|
||||
{
|
||||
_scenarioChangeDebounceTimeSeconds = _propertiesConfig.ScenarioChangeDebounceTimeSeconds;
|
||||
}
|
||||
|
||||
IsInAutoModeFeedback = new BoolFeedback(() => isInAutoMode);
|
||||
|
||||
// default to auto mode
|
||||
isInAutoMode = true;
|
||||
|
||||
if (_propertiesConfig.defaultToManualMode)
|
||||
{
|
||||
isInAutoMode = false;
|
||||
}
|
||||
|
||||
IsInAutoModeFeedback.FireUpdate();
|
||||
|
||||
CreateScenarios();
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
SetupPartitionStateProviders();
|
||||
|
||||
SetRooms();
|
||||
});
|
||||
}
|
||||
|
||||
void CreateScenarios()
|
||||
{
|
||||
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
|
||||
|
||||
foreach (var scenarioConfig in _propertiesConfig.Scenarios)
|
||||
{
|
||||
var scenario = new RoomCombinationScenario(scenarioConfig);
|
||||
RoomCombinationScenarios.Add(scenario);
|
||||
}
|
||||
}
|
||||
|
||||
void SetRooms()
|
||||
{
|
||||
_rooms = new List<IEssentialsRoom>();
|
||||
|
||||
foreach (var roomKey in _propertiesConfig.RoomKeys)
|
||||
{
|
||||
var room = DeviceManager.GetDeviceForKey(roomKey) as IEssentialsRoom;
|
||||
if (room != null)
|
||||
{
|
||||
_rooms.Add(room);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetupPartitionStateProviders()
|
||||
{
|
||||
foreach (var pConfig in _propertiesConfig.Partitions)
|
||||
{
|
||||
var sensor = DeviceManager.GetDeviceForKey(pConfig.DeviceKey) as IPartitionStateProvider;
|
||||
|
||||
var partition = new EssentialsPartitionController(pConfig.Key, pConfig.Name, sensor, _propertiesConfig.defaultToManualMode, pConfig.AdjacentRoomKeys);
|
||||
|
||||
partition.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange;
|
||||
|
||||
Partitions.Add(partition);
|
||||
}
|
||||
}
|
||||
|
||||
void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
StartDebounceTimer();
|
||||
}
|
||||
|
||||
void StartDebounceTimer()
|
||||
{
|
||||
var time = _scenarioChangeDebounceTimeSeconds * 1000;
|
||||
|
||||
if (_scenarioChangeDebounceTimer == null)
|
||||
{
|
||||
_scenarioChangeDebounceTimer = new CTimer((o) => DetermineRoomCombinationScenario(), time);
|
||||
}
|
||||
else
|
||||
{
|
||||
_scenarioChangeDebounceTimer.Reset(time);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the current room combination scenario based on the state of the partition sensors
|
||||
/// </summary>
|
||||
void DetermineRoomCombinationScenario()
|
||||
{
|
||||
if (_scenarioChangeDebounceTimer != null)
|
||||
{
|
||||
_scenarioChangeDebounceTimer.Dispose();
|
||||
_scenarioChangeDebounceTimer = null;
|
||||
}
|
||||
|
||||
var currentScenario = RoomCombinationScenarios.FirstOrDefault((s) =>
|
||||
{
|
||||
// iterate the partition states
|
||||
foreach (var partitionState in s.PartitionStates)
|
||||
{
|
||||
// get the partition by key
|
||||
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey));
|
||||
|
||||
if (partition != null && partitionState.PartitionPresent != partition.PartitionPresentFeedback.BoolValue)
|
||||
{
|
||||
// the partition can't be found or the state doesn't match
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if it hasn't returned false by now we have the matching scenario
|
||||
return true;
|
||||
});
|
||||
|
||||
if (currentScenario != null)
|
||||
{
|
||||
CurrentScenario = currentScenario;
|
||||
}
|
||||
}
|
||||
|
||||
#region IEssentialsRoomCombiner Members
|
||||
|
||||
public event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||
|
||||
public IRoomCombinationScenario CurrentScenario
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentScenario;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _currentScenario)
|
||||
{
|
||||
_currentScenario = value;
|
||||
Debug.Console(1, this, "Current Scenario: {0}", _currentScenario.Name);
|
||||
var handler = RoomCombinationScenarioChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BoolFeedback IsInAutoModeFeedback { get; private set; }
|
||||
|
||||
public void SetAutoMode()
|
||||
{
|
||||
isInAutoMode = true;
|
||||
IsInAutoModeFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public void SetManualMode()
|
||||
{
|
||||
isInAutoMode = false;
|
||||
IsInAutoModeFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public void ToggleMode()
|
||||
{
|
||||
isInAutoMode = !isInAutoMode;
|
||||
IsInAutoModeFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; private set; }
|
||||
|
||||
public List<IPartitionController> Partitions { get; private set; }
|
||||
|
||||
public void TogglePartitionState(string partitionKey)
|
||||
{
|
||||
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey)) as IPartitionController;
|
||||
|
||||
if (partition != null)
|
||||
{
|
||||
partition.ToggglePartitionState();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRoomCombinationScenario(string scenarioKey)
|
||||
{
|
||||
if (isInAutoMode)
|
||||
{
|
||||
Debug.Console(0, this, "Cannot set room combination scenario when in auto mode. Set to auto mode first.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the scenario
|
||||
var scenario = RoomCombinationScenarios.FirstOrDefault((s) => s.Key.Equals(scenarioKey));
|
||||
|
||||
// Set the parition states from the scenario manually
|
||||
if (scenario != null)
|
||||
{
|
||||
foreach (var partitionState in scenario.PartitionStates)
|
||||
{
|
||||
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey));
|
||||
|
||||
if (partition != null)
|
||||
{
|
||||
if (partitionState.PartitionPresent)
|
||||
{
|
||||
partition.SetPartitionStatePresent();
|
||||
}
|
||||
else
|
||||
{
|
||||
partition.SetPartitionStateNotPresent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory<EssentialsRoomCombiner>
|
||||
{
|
||||
public EssentialsRoomCombinerFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "essentialsroomcombiner" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new EssentialsRoomCombiner Device");
|
||||
|
||||
var props = dc.Properties.ToObject<EssentialsRoomCombinerPropertiesConfig>();
|
||||
|
||||
return new EssentialsRoomCombiner(dc.Key, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Config properties for an EssentialsRoomCombiner device
|
||||
/// </summary>
|
||||
public class EssentialsRoomCombinerPropertiesConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The list of partitions that device the rooms
|
||||
/// </summary>
|
||||
[JsonProperty("partitions")]
|
||||
public List<PartitionConfig> Partitions {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// The list of combinations scenarios for the rooms
|
||||
/// </summary>
|
||||
[JsonProperty("scenarios")]
|
||||
public List<RoomCombinationScenarioConfig> Scenarios { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of rooms keys that can be combined
|
||||
/// </summary>
|
||||
[JsonProperty("roomMap")]
|
||||
public List<string> RoomKeys {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to default to manual mode
|
||||
/// </summary>
|
||||
[JsonProperty("defaultToManualMode")]
|
||||
public bool defaultToManualMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The key of the scenario to default to at system startup if in manual mode
|
||||
/// </summary>
|
||||
[JsonProperty("defaultScenarioKey")]
|
||||
public string defaultScenarioKey { get; set; }
|
||||
|
||||
[JsonProperty("scenarioChangeDebounceTimeSeconds")]
|
||||
public int ScenarioChangeDebounceTimeSeconds { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config properties for a partition that separates rooms
|
||||
/// </summary>
|
||||
public class PartitionConfig : IKeyName
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key of the device that implements IPartitionStateProvider to provide the state of the partition
|
||||
/// </summary>
|
||||
[JsonProperty("deviceKey")]
|
||||
public string DeviceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Keys of the rooms that this partion would be located between
|
||||
/// </summary>
|
||||
[JsonProperty("adjacentRoomKeys")]
|
||||
public List<string> AdjacentRoomKeys { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config propeties for a room combination scenario
|
||||
/// </summary>
|
||||
public class RoomCombinationScenarioConfig : IKeyName
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("partitionStates")]
|
||||
public List<PartitionState> PartitionStates { get; set; }
|
||||
|
||||
[JsonProperty("uiMap")]
|
||||
public Dictionary<string, string> UiMap { get; set; }
|
||||
|
||||
[JsonProperty("activationActions")]
|
||||
public List<DeviceActionWrapper> ActivationActions { get; set; }
|
||||
|
||||
[JsonProperty("deactivationActions")]
|
||||
public List<DeviceActionWrapper> DeactivationActions { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config properties to represent the state of a partition sensor in a RoomCombinationScenario
|
||||
/// </summary>
|
||||
public class PartitionState
|
||||
{
|
||||
[JsonProperty("partitionKey")]
|
||||
public string PartitionKey { get; set; }
|
||||
|
||||
[JsonProperty("partitionSensedState")]
|
||||
public bool PartitionPresent { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the functionality for an EssentailsRoomCombiner device
|
||||
/// </summary>
|
||||
public interface IEssentialsRoomCombiner : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the room combination scenario has changed
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||
|
||||
/// <summary>
|
||||
/// The current room combination scenario
|
||||
/// </summary>
|
||||
IRoomCombinationScenario CurrentScenario { get; }
|
||||
|
||||
/// <summary>
|
||||
/// When true, indicates the current mode is auto mode
|
||||
/// </summary>
|
||||
BoolFeedback IsInAutoModeFeedback {get;}
|
||||
|
||||
/// <summary>
|
||||
/// Sets auto mode
|
||||
/// </summary>
|
||||
void SetAutoMode();
|
||||
|
||||
/// <summary>
|
||||
/// Sets manual mode
|
||||
/// </summary>
|
||||
void SetManualMode();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the current mode between auto and manual
|
||||
/// </summary>
|
||||
void ToggleMode();
|
||||
|
||||
/// <summary>
|
||||
/// The available room combinatino scenarios
|
||||
/// </summary>
|
||||
List<IRoomCombinationScenario> RoomCombinationScenarios { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The partition
|
||||
/// </summary>
|
||||
List<IPartitionController> Partitions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the state of a manual partition sensor
|
||||
/// </summary>
|
||||
/// <param name="partitionKey"></param>
|
||||
void TogglePartitionState(string partitionKey);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the room combination scenario (if in manual mode)
|
||||
/// </summary>
|
||||
/// <param name="scenarioKey"></param>
|
||||
void SetRoomCombinationScenario(string scenarioKey);
|
||||
}
|
||||
|
||||
public interface IRoomCombinationScenario : IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// When true, indicates that this room combination scenario is active
|
||||
/// </summary>
|
||||
BoolFeedback IsActiveFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Activates this room combination scenario
|
||||
/// </summary>
|
||||
void Activate();
|
||||
|
||||
/// <summary>
|
||||
/// The state of the partitions that would activate this scenario
|
||||
/// </summary>
|
||||
List<PartitionState> PartitionStates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The mapping of UIs by key to rooms by key
|
||||
/// </summary>
|
||||
Dictionary<string, string> UiMap { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a room combination scenario
|
||||
/// </summary>
|
||||
public class RoomCombinationScenario: IRoomCombinationScenario
|
||||
{
|
||||
private RoomCombinationScenarioConfig _config;
|
||||
|
||||
public string Key { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public List<PartitionState> PartitionStates { get; private set; }
|
||||
|
||||
public Dictionary<string, string> UiMap { get; set; }
|
||||
|
||||
private bool _isActive;
|
||||
|
||||
public BoolFeedback IsActiveFeedback { get; private set; }
|
||||
|
||||
List<DeviceActionWrapper> activationActions;
|
||||
|
||||
List<DeviceActionWrapper> deactivationActions;
|
||||
|
||||
public RoomCombinationScenario(RoomCombinationScenarioConfig config)
|
||||
{
|
||||
Key = config.Key;
|
||||
|
||||
Name = config.Name;
|
||||
|
||||
PartitionStates = config.PartitionStates;
|
||||
|
||||
UiMap = config.UiMap;
|
||||
|
||||
activationActions = config.ActivationActions;
|
||||
|
||||
deactivationActions = config.DeactivationActions;
|
||||
|
||||
_config = config;
|
||||
|
||||
IsActiveFeedback = new BoolFeedback(() => _isActive);
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (activationActions != null)
|
||||
{
|
||||
foreach (var action in activationActions)
|
||||
{
|
||||
DeviceJsonApi.DoDeviceAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
_isActive = true;
|
||||
IsActiveFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
if (deactivationActions != null)
|
||||
{
|
||||
foreach (var action in deactivationActions)
|
||||
{
|
||||
DeviceJsonApi.DoDeviceAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
_isActive = false;
|
||||
IsActiveFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
@@ -15,421 +16,446 @@ using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.DM.Chassis
|
||||
{
|
||||
[Description("Wrapper class for all HdMdNxM4E switchers")]
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
|
||||
{
|
||||
private HdMdNxM _Chassis;
|
||||
private HdMd4x14kE _Chassis4x1;
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
public Dictionary<uint, string> InputNames { get; set; }
|
||||
public Dictionary<uint, string> OutputNames { get; set; }
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
|
||||
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputRouteNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> InputHdcpEnableFeedback { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> DeviceNameFeedback { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> AutoRouteFeedback { get; private set; }
|
||||
|
||||
#region Constructor
|
||||
|
||||
public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis,
|
||||
HdMdNxM4kEBridgeablePropertiesConfig props)
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
_Chassis = chassis;
|
||||
var _props = props;
|
||||
|
||||
InputNames = props.Inputs;
|
||||
OutputNames = props.Outputs;
|
||||
|
||||
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
|
||||
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
|
||||
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
InputHdcpEnableFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
DeviceNameFeedback = new FeedbackCollection<StringFeedback>();
|
||||
AutoRouteFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
DeviceNameFeedback.Add(new StringFeedback(this.Name, () => this.Name));
|
||||
|
||||
if (_Chassis.NumberOfInputs == 1)
|
||||
{
|
||||
_Chassis4x1 = _Chassis as HdMd4x14kE;
|
||||
AutoRouteFeedback.Add(new BoolFeedback(this.Name + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue));
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var inputName = InputNames[index];
|
||||
_Chassis.Inputs[index].Name.StringValue = inputName;
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiInputs[index]
|
||||
});
|
||||
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
|
||||
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue));
|
||||
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var outputName = OutputNames[index];
|
||||
_Chassis.Outputs[i].Name.StringValue = outputName;
|
||||
|
||||
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
|
||||
});
|
||||
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
|
||||
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue));
|
||||
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
|
||||
}
|
||||
|
||||
_Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange);
|
||||
_Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange);
|
||||
|
||||
AddPostActivationAction(AddFeedbackCollections);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
public void EnableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
|
||||
public void DisableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
|
||||
public void EnableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
|
||||
if (_Chassis4x1 == null) return;
|
||||
|
||||
_Chassis4x1.AutoModeOn();
|
||||
}
|
||||
|
||||
public void DisableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
|
||||
if (_Chassis4x1 == null) return;
|
||||
|
||||
_Chassis4x1.AutoModeOff();
|
||||
}
|
||||
|
||||
#region PostActivate
|
||||
|
||||
public void AddFeedbackCollections()
|
||||
{
|
||||
AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback);
|
||||
AddCollectionsToList(VideoOutputRouteFeedbacks);
|
||||
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FeedbackCollection Methods
|
||||
|
||||
//Add arrays of collections
|
||||
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add Collections
|
||||
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
//Add Individual Feedbacks
|
||||
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
|
||||
{
|
||||
if (newFb == null) return;
|
||||
|
||||
if (!Feedbacks.Contains(newFb))
|
||||
{
|
||||
Feedbacks.Add(newFb);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRouting Members
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
// Try to make switch only when necessary. The unit appears to toggle when already selected.
|
||||
var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut;
|
||||
if (current != _Chassis.HdmiInputs[(uint)inputSelector])
|
||||
_Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, signalType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
|
||||
|
||||
if (_Chassis4x1 != null)
|
||||
{
|
||||
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
|
||||
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
|
||||
AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
//Digital
|
||||
VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]);
|
||||
trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i));
|
||||
trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i));
|
||||
|
||||
//Serial
|
||||
InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
//Analog
|
||||
VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]);
|
||||
trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo));
|
||||
|
||||
//Serial
|
||||
OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]);
|
||||
OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]);
|
||||
}
|
||||
|
||||
_Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange);
|
||||
|
||||
trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
{
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
_Chassis.Inputs[i].Name.StringValue = InputNames[i];
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
|
||||
|
||||
for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++)
|
||||
{
|
||||
var index = i;
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]);
|
||||
|
||||
|
||||
VideoOutputRouteFeedbacks[i].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMInputEventIds.VideoDetectedEventId) return;
|
||||
foreach (var item in VideoInputSyncFeedbacks)
|
||||
{
|
||||
item.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory
|
||||
|
||||
public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory<HdMdNxM4kEBridgeableController>
|
||||
{
|
||||
public HdMdNxM4kEControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<HdMdNxM4kEBridgeablePropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
var type = dc.Type.ToLower();
|
||||
var control = props.Control;
|
||||
var ipid = control.IpIdInt;
|
||||
var address = control.TcpSshProperties.Address;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ("hdmd4x14ke-bridgeable"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd4x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd6x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
[Description("Wrapper class for all HdMdNxM4E switchers")]
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
|
||||
{
|
||||
private HdMdNxM _Chassis;
|
||||
private HdMd4x14kE _Chassis4x1;
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
public Dictionary<uint, string> InputNames { get; set; }
|
||||
public Dictionary<uint, string> OutputNames { get; set; }
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
|
||||
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputRouteNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> InputHdcpEnableFeedback { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> DeviceNameFeedback { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> AutoRouteFeedback { get; private set; }
|
||||
|
||||
#region Constructor
|
||||
|
||||
public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis,
|
||||
HdMdNxM4kEBridgeablePropertiesConfig props)
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
_Chassis = chassis;
|
||||
|
||||
if (props == null)
|
||||
{
|
||||
Debug.Console(1, this, "HdMdNx4keBridgeableController properties are null, failed to build the device");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (props.Inputs != null)
|
||||
{
|
||||
foreach (var kvp in props.Inputs)
|
||||
{
|
||||
Debug.Console(0, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
InputNames = props.Inputs;
|
||||
}
|
||||
if (props.Outputs != null)
|
||||
{
|
||||
foreach (var kvp in props.Outputs)
|
||||
{
|
||||
Debug.Console(0, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
OutputNames = props.Outputs;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// OutputNames.Add(1, "Output");
|
||||
//}
|
||||
|
||||
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
|
||||
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
|
||||
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
InputHdcpEnableFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
DeviceNameFeedback = new FeedbackCollection<StringFeedback>();
|
||||
AutoRouteFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
var deviceName = string.IsNullOrEmpty(this.Name) ? name : this.Name;
|
||||
DeviceNameFeedback.Add(new StringFeedback(deviceName, () => deviceName));
|
||||
|
||||
if (_Chassis.NumberOfInputs == 1)
|
||||
{
|
||||
_Chassis4x1 = _Chassis as HdMd4x14kE;
|
||||
AutoRouteFeedback.Add(new BoolFeedback(deviceName + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue));
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var inputName = InputNames[index];
|
||||
_Chassis.Inputs[index].Name.StringValue = inputName;
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiInputs[index]
|
||||
});
|
||||
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
|
||||
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue));
|
||||
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var outputName = OutputNames[index];
|
||||
_Chassis.Outputs[i].Name.StringValue = outputName;
|
||||
|
||||
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
|
||||
});
|
||||
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
|
||||
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue));
|
||||
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
|
||||
}
|
||||
|
||||
_Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange);
|
||||
_Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange);
|
||||
|
||||
AddPostActivationAction(AddFeedbackCollections);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
public void EnableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
|
||||
public void DisableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
|
||||
public void EnableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
|
||||
if (_Chassis4x1 == null) return;
|
||||
|
||||
_Chassis4x1.AutoModeOn();
|
||||
}
|
||||
|
||||
public void DisableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
|
||||
if (_Chassis4x1 == null) return;
|
||||
|
||||
_Chassis4x1.AutoModeOff();
|
||||
}
|
||||
|
||||
#region PostActivate
|
||||
|
||||
public void AddFeedbackCollections()
|
||||
{
|
||||
AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback);
|
||||
AddCollectionsToList(VideoOutputRouteFeedbacks);
|
||||
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FeedbackCollection Methods
|
||||
|
||||
//Add arrays of collections
|
||||
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add Collections
|
||||
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
//Add Individual Feedbacks
|
||||
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
|
||||
{
|
||||
if (newFb == null) return;
|
||||
|
||||
if (!Feedbacks.Contains(newFb))
|
||||
{
|
||||
Feedbacks.Add(newFb);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRouting Members
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
// Try to make switch only when necessary. The unit appears to toggle when already selected.
|
||||
var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut;
|
||||
if (current != _Chassis.HdmiInputs[(uint)inputSelector])
|
||||
_Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, signalType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
|
||||
|
||||
if (_Chassis4x1 != null)
|
||||
{
|
||||
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
|
||||
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
|
||||
AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
//Digital
|
||||
VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]);
|
||||
trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i));
|
||||
trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i));
|
||||
|
||||
//Serial
|
||||
InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
//Analog
|
||||
VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]);
|
||||
trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo));
|
||||
|
||||
//Serial
|
||||
OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]);
|
||||
OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]);
|
||||
}
|
||||
|
||||
_Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange);
|
||||
|
||||
trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
{
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
_Chassis.Inputs[i].Name.StringValue = InputNames[i];
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
|
||||
|
||||
for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++)
|
||||
{
|
||||
var index = i;
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]);
|
||||
|
||||
|
||||
VideoOutputRouteFeedbacks[i].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMInputEventIds.VideoDetectedEventId) return;
|
||||
foreach (var item in VideoInputSyncFeedbacks)
|
||||
{
|
||||
item.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory
|
||||
|
||||
public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory<HdMdNxM4kEBridgeableController>
|
||||
{
|
||||
public HdMdNxM4kEControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<HdMdNxM4kEBridgeablePropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
var type = dc.Type.ToLower();
|
||||
var control = props.Control;
|
||||
var ipid = control.IpIdInt;
|
||||
var address = control.TcpSshProperties.Address;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ("hdmd4x14ke-bridgeable"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd4x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd6x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Newtonsoft.Json;
|
||||
@@ -43,14 +44,19 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this));
|
||||
|
||||
|
||||
// physical settings
|
||||
if (props != null && props.Inputs != null)
|
||||
{
|
||||
var inputRegex = new Regex(@"(?<InputNum>\d)", RegexOptions.IgnoreCase);
|
||||
foreach (var kvp in props.Inputs)
|
||||
{
|
||||
// strip "hdmiIn"
|
||||
var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
|
||||
// get numnbers from key and convert to int
|
||||
//var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
|
||||
var inputMatch = inputRegex.Match(kvp.Key);
|
||||
if (inputMatch == null) continue;
|
||||
|
||||
var inputNum = Convert.ToUInt32(inputMatch.Groups["InputNum"].Value);
|
||||
|
||||
var port = chassis.HdmiInputs[inputNum].HdmiInputPort;
|
||||
// set hdcp disables
|
||||
|
||||
@@ -69,22 +69,6 @@ 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>
|
||||
@@ -120,15 +104,6 @@ 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,7 +417,6 @@ 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;
|
||||
@@ -551,6 +550,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)
|
||||
{
|
||||
@@ -559,9 +565,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 +
|
||||
@@ -576,14 +582,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,25 +277,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
public SoftwareID SoftwareID { get; set; }
|
||||
}
|
||||
|
||||
public class Availability : ValueProperty
|
||||
public class Availability
|
||||
{
|
||||
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 string Value { get; set; }
|
||||
}
|
||||
|
||||
public class Status2 : ValueProperty
|
||||
|
||||
@@ -1,108 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a device that has call participants
|
||||
/// </summary>
|
||||
public interface IHasParticipants
|
||||
{
|
||||
CodecParticipants Participants { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Describes a device that has call participants
|
||||
/// </summary>
|
||||
public interface IHasParticipants
|
||||
{
|
||||
CodecParticipants Participants { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute a participant's video in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantVideoMute : IHasParticipants
|
||||
{
|
||||
void MuteVideoForParticipant(int userId);
|
||||
void UnmuteVideoForParticipant(int userId);
|
||||
void ToggleVideoForParticipant(int userId);
|
||||
}
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute a participant's video in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantVideoMute:IHasParticipants
|
||||
{
|
||||
void MuteVideoForParticipant(int userId);
|
||||
void UnmuteVideoForParticipant(int userId);
|
||||
void ToggleVideoForParticipant(int userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute a participant's audio in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
|
||||
{
|
||||
void MuteAudioForParticipant(int userId);
|
||||
void UnmuteAudioForParticipant(int userId);
|
||||
void ToggleAudioForParticipant(int userId);
|
||||
}
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute a participant's audio in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
|
||||
{
|
||||
void MuteAudioForParticipant(int userId);
|
||||
void UnmuteAudioForParticipant(int userId);
|
||||
void ToggleAudioForParticipant(int userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the ability to pin and unpin a participant in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantPinUnpin : IHasParticipants
|
||||
{
|
||||
IntFeedback NumberOfScreensFeedback { get; }
|
||||
int ScreenIndexToPinUserTo { get; }
|
||||
/// <summary>
|
||||
/// Describes the ability to pin and unpin a participant in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantPinUnpin : IHasParticipants
|
||||
{
|
||||
IntFeedback NumberOfScreensFeedback { get; }
|
||||
int ScreenIndexToPinUserTo { get; }
|
||||
|
||||
void PinParticipant(int userId, int screenIndex);
|
||||
void UnPinParticipant(int userId);
|
||||
void ToggleParticipantPinState(int userId, int screenIndex);
|
||||
}
|
||||
void PinParticipant(int userId, int screenIndex);
|
||||
void UnPinParticipant(int userId);
|
||||
void ToggleParticipantPinState(int userId, int screenIndex);
|
||||
}
|
||||
|
||||
public class CodecParticipants
|
||||
{
|
||||
private List<Participant> _currentParticipants;
|
||||
public class CodecParticipants
|
||||
{
|
||||
private List<Participant> _currentParticipants;
|
||||
|
||||
public List<Participant> CurrentParticipants {
|
||||
get { return _currentParticipants; }
|
||||
set
|
||||
{
|
||||
_currentParticipants = value;
|
||||
OnParticipantsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Participant> CurrentParticipants
|
||||
{
|
||||
get { return _currentParticipants; }
|
||||
set
|
||||
{
|
||||
_currentParticipants = value;
|
||||
foreach (var participant in _currentParticipants)
|
||||
{
|
||||
Debug.Console(1, "[CurrentParticipants] participant UserId: {0} Name: {1} IsHost: {2}", participant.UserId, participant.Name, participant.IsHost);
|
||||
}
|
||||
OnParticipantsChanged();
|
||||
}
|
||||
}
|
||||
public event EventHandler<EventArgs> ParticipantsListHasChanged;
|
||||
|
||||
public event EventHandler<EventArgs> ParticipantsListHasChanged;
|
||||
public CodecParticipants()
|
||||
{
|
||||
_currentParticipants = new List<Participant>();
|
||||
}
|
||||
|
||||
public CodecParticipants()
|
||||
{
|
||||
_currentParticipants = new List<Participant>();
|
||||
}
|
||||
public void OnParticipantsChanged()
|
||||
{
|
||||
var handler = ParticipantsListHasChanged;
|
||||
|
||||
public void OnParticipantsChanged()
|
||||
{
|
||||
var handler = ParticipantsListHasChanged;
|
||||
if (handler == null) return;
|
||||
|
||||
Debug.Console(1, "[OnParticipantsChanged] Event Fired - handler is {0}", handler == null ? "null" : "not null");
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
if (handler == null) return;
|
||||
/// <summary>
|
||||
/// Represents a call participant
|
||||
/// </summary>
|
||||
public class Participant
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public bool IsHost { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool CanMuteVideo { get; set; }
|
||||
public bool CanUnmuteVideo { get; set; }
|
||||
public bool VideoMuteFb { get; set; }
|
||||
public bool AudioMuteFb { get; set; }
|
||||
public bool HandIsRaisedFb { get; set; }
|
||||
public bool IsPinnedFb { get; set; }
|
||||
public int ScreenIndexIsPinnedToFb { get; set; }
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a call participant
|
||||
/// </summary>
|
||||
public class Participant
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public bool IsHost { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool CanMuteVideo { get; set; }
|
||||
public bool CanUnmuteVideo { get; set; }
|
||||
public bool VideoMuteFb { get; set; }
|
||||
public bool AudioMuteFb { get; set; }
|
||||
public bool HandIsRaisedFb { get; set; }
|
||||
public bool IsPinnedFb { get; set; }
|
||||
public int ScreenIndexIsPinnedToFb { get; set; }
|
||||
|
||||
public Participant()
|
||||
{
|
||||
// Initialize to -1 (no screen)
|
||||
ScreenIndexIsPinnedToFb = -1;
|
||||
}
|
||||
}
|
||||
public Participant()
|
||||
{
|
||||
// Initialize to -1 (no screen)
|
||||
ScreenIndexIsPinnedToFb = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,8 +65,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
public bool ShowSelfViewByDefault { get; protected set; }
|
||||
|
||||
public bool SupportsCameraOff { get; protected set; }
|
||||
public bool SupportsCameraAutoMode { get; protected set; }
|
||||
protected bool SupportsCameraOff;
|
||||
protected bool SupportsCameraAutoMode;
|
||||
|
||||
public bool IsReady { get; protected set; }
|
||||
|
||||
|
||||
@@ -276,9 +276,6 @@ 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";
|
||||
@@ -295,26 +292,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
try
|
||||
{
|
||||
if (zoomContacts.Count == 0)
|
||||
{
|
||||
return directory;
|
||||
}
|
||||
|
||||
foreach (Contact c in zoomContacts)
|
||||
if (zoomContacts.Count == 0) return directory;
|
||||
{
|
||||
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)
|
||||
foreach (Contact c in zoomContacts)
|
||||
{
|
||||
contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
|
||||
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
|
||||
|
||||
if (folders.Count > 0)
|
||||
{
|
||||
contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
|
||||
}
|
||||
|
||||
contacts.Add(contact);
|
||||
}
|
||||
|
||||
contacts.Add(contact);
|
||||
directory.AddContactsToDirectory(contacts);
|
||||
}
|
||||
|
||||
directory.AddContactsToDirectory(contacts);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1168,11 +1161,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
set
|
||||
{
|
||||
//if (value != _hideConfSelfVideo)
|
||||
//{
|
||||
if (value != _hideConfSelfVideo)
|
||||
{
|
||||
_hideConfSelfVideo = value;
|
||||
NotifyPropertyChanged("HideConfSelfVideo");
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
@@ -16,7 +15,6 @@ 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;
|
||||
@@ -32,12 +30,10 @@ 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 GenericQueue _receiveQueue;
|
||||
//private readonly CrestronQueue<string> _receiveQueue;
|
||||
private readonly CrestronQueue<string> _receiveQueue;
|
||||
|
||||
|
||||
//private readonly Thread _receiveThread;
|
||||
private readonly Thread _receiveThread;
|
||||
|
||||
private readonly ZoomRoomSyncState _syncState;
|
||||
public bool CommDebuggingIsOn;
|
||||
@@ -55,7 +51,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
_props = JsonConvert.DeserializeObject<ZoomRoomPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
_receiveQueue = new GenericQueue(Key + "-rxQueue", Thread.eThreadPriority.MediumPriority, 512);
|
||||
// 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 };
|
||||
|
||||
Communication = comm;
|
||||
|
||||
@@ -95,10 +95,6 @@ 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);
|
||||
@@ -115,7 +111,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
// TODO: #714 [ ] SelfviewPipSizeFeedback
|
||||
SelfviewPipSizeFeedback = new StringFeedback(SelfviewPipSizeFeedbackFunc);
|
||||
|
||||
|
||||
SetUpFeedbackActions();
|
||||
|
||||
Cameras = new List<CameraBase>();
|
||||
@@ -124,7 +120,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
Participants = new CodecParticipants();
|
||||
|
||||
SupportsCameraOff = true; // Always allow turning off the camera for zoom calls?
|
||||
SupportsCameraOff = _props.SupportsCameraOff;
|
||||
SupportsCameraAutoMode = _props.SupportsCameraAutoMode;
|
||||
|
||||
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
||||
@@ -158,18 +154,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
get
|
||||
{
|
||||
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;
|
||||
};
|
||||
return () => CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +252,6 @@ 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
|
||||
|
||||
@@ -293,7 +277,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
var handler = CameraSelected;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new CameraSelectedEventArgs(_selectedCamera));
|
||||
handler(this, new CameraSelectedEventArgs(SelectedCamera));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,11 +314,6 @@ 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");
|
||||
@@ -367,16 +346,6 @@ 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; }
|
||||
@@ -390,8 +359,9 @@ 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)
|
||||
@@ -403,15 +373,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
DirectoryBrowseHistoryStack.Push(_currentDirectoryResult);
|
||||
|
||||
CurrentDirectoryResult = directoryResults;
|
||||
_currentDirectoryResult = directoryResults;
|
||||
|
||||
OnDirectoryResultReturned(directoryResults);
|
||||
}
|
||||
|
||||
public void SetCurrentDirectoryToRoot()
|
||||
{
|
||||
DirectoryBrowseHistoryStack.Clear();
|
||||
|
||||
CurrentDirectoryResult = DirectoryRoot;
|
||||
_currentDirectoryResult = DirectoryRoot;
|
||||
|
||||
OnDirectoryResultReturned(DirectoryRoot);
|
||||
}
|
||||
|
||||
public void GetDirectoryParentFolderContents()
|
||||
@@ -423,7 +396,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
var currentDirectory = DirectoryBrowseHistoryStack.Pop();
|
||||
|
||||
CurrentDirectoryResult = currentDirectory;
|
||||
_currentDirectoryResult = currentDirectory;
|
||||
|
||||
OnDirectoryResultReturned(currentDirectory);
|
||||
}
|
||||
|
||||
public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; }
|
||||
@@ -553,44 +528,44 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
case "Size":
|
||||
{
|
||||
// TODO: #714 [ ] SetupFeedbackActions >> Size
|
||||
ComputeSelfviewPipSizeStatus();
|
||||
{
|
||||
// TODO: #714 [ ] SetupFeedbackActions >> Size
|
||||
ComputeSelfviewPipSizeStatus();
|
||||
|
||||
SelfviewPipSizeFeedback.FireUpdate();
|
||||
SelfviewPipSizeFeedback.FireUpdate();
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3
|
||||
Configuration.Client.Call.Layout.PropertyChanged += (o, a) =>
|
||||
{
|
||||
switch (a.PropertyName)
|
||||
{
|
||||
case "Position":
|
||||
{
|
||||
ComputeSelfviewPipPositionStatus();
|
||||
// This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3
|
||||
Configuration.Client.Call.Layout.PropertyChanged += (o,a) =>
|
||||
{
|
||||
switch (a.PropertyName)
|
||||
{
|
||||
case "Position":
|
||||
{
|
||||
ComputeSelfviewPipPositionStatus();
|
||||
|
||||
SelfviewPipPositionFeedback.FireUpdate();
|
||||
SelfviewPipPositionFeedback.FireUpdate();
|
||||
|
||||
break;
|
||||
}
|
||||
case "ShareThumb":
|
||||
{
|
||||
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case "Style":
|
||||
{
|
||||
LocalLayoutFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ShareThumb":
|
||||
{
|
||||
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case "Style":
|
||||
{
|
||||
LocalLayoutFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
||||
{
|
||||
@@ -690,15 +665,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
private void SetUpDirectory()
|
||||
{
|
||||
DirectoryRoot = new CodecDirectory() { ResultsFolderId = "root" };
|
||||
DirectoryRoot = new CodecDirectory();
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult.ResultsFolderId != "root");
|
||||
|
||||
CurrentDirectoryResult = DirectoryRoot;
|
||||
_currentDirectoryResult = DirectoryRoot;
|
||||
|
||||
DirectoryBrowseHistory = new List<CodecDirectory>();
|
||||
DirectoryBrowseHistoryStack = new Stack<CodecDirectory>();
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => _currentDirectoryResult != DirectoryRoot);
|
||||
|
||||
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
|
||||
}
|
||||
|
||||
private void SetUpRouting()
|
||||
@@ -709,7 +685,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
// Set up output ports
|
||||
OutputPorts.Add(Output1);
|
||||
OutputPorts.Add(Output2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -744,7 +719,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;
|
||||
@@ -755,21 +739,21 @@ 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")
|
||||
{
|
||||
CommDebuggingIsOn = true;
|
||||
Debug.Console(1, this, "Comm Debug Enabled.");
|
||||
Debug.Console(0, this, "Comm Debug Enabled.");
|
||||
}
|
||||
else
|
||||
{
|
||||
CommDebuggingIsOn = false;
|
||||
Debug.Console(1, this, "Comm Debug Disabled.");
|
||||
Debug.Console(0, this, "Comm Debug Disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,7 +790,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
//if (CommDebuggingIsOn)
|
||||
// Debug.Console(1, this, "Gathered: '{0}'", args.Text);
|
||||
|
||||
_receiveQueue.Enqueue(new ProcessStringMessage(args.Text, ProcessMessage));
|
||||
_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -877,7 +891,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
// Counts the curly braces
|
||||
if (message.Contains("client_loop: send disconnect: Broken pipe"))
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Error,
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Zoom Room Controller or App connected. Essentials will NOT control the Zoom Room until it is disconnected.");
|
||||
|
||||
return;
|
||||
@@ -971,8 +985,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Thread.Sleep(100);
|
||||
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);
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist");
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (!_props.DisablePhonebookAutoDownload)
|
||||
{
|
||||
@@ -1063,30 +1077,24 @@ 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(true);
|
||||
PhonebookSyncState.SetPhonebookHasFolders(false);
|
||||
PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count);
|
||||
}
|
||||
|
||||
if (directoryResults.ResultsFolderId != "root")
|
||||
{
|
||||
directoryResults.ResultsFolderId = "root";
|
||||
}
|
||||
var directoryResults =
|
||||
zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts);
|
||||
|
||||
DirectoryRoot = directoryResults;
|
||||
|
||||
CurrentDirectoryResult = directoryResults;
|
||||
_currentDirectoryResult = DirectoryRoot;
|
||||
|
||||
OnDirectoryResultReturned(directoryResults);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1111,10 +1119,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
if (participant != null)
|
||||
{
|
||||
Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} **********************************", participant.Event);
|
||||
Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} - UserId: {1} Name: {2} IsHost: {3}",
|
||||
participant.Event, participant.UserId, participant.UserName, participant.IsHost);
|
||||
|
||||
switch (participant.Event)
|
||||
{
|
||||
case "ZRCUserChangedEventUserInfoUpdated":
|
||||
@@ -1140,30 +1144,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
break;
|
||||
case "ZRCUserChangedEventJoinedMeeting":
|
||||
{
|
||||
var existingParticipant =
|
||||
Status.Call.Participants.FirstOrDefault(p => p.UserId.Equals(participant.UserId));
|
||||
|
||||
if (existingParticipant != null)
|
||||
{
|
||||
Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...updating matching UserId participant with UserId: {1} UserName: {2}",
|
||||
participant.Event, participant.UserId, participant.UserName);
|
||||
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), existingParticipant);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...adding participant with UserId: {1} UserName: {2}",
|
||||
participant.Event, participant.UserId, participant.UserName);
|
||||
|
||||
Status.Call.Participants.Add(participant);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
Status.Call.Participants.Add(participant);
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ***********************************", participant.Event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1174,6 +1157,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Status.Call.Participants);
|
||||
|
||||
Participants.CurrentParticipants = participants;
|
||||
|
||||
PrintCurrentCallParticipants();
|
||||
|
||||
break;
|
||||
@@ -1266,7 +1250,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
Direction = eCodecCallDirection.Incoming,
|
||||
Status = eCodecCallStatus.Ringing,
|
||||
Type = eCodecCallType.Video,
|
||||
Type = eCodecCallType.Unknown,
|
||||
Name = incomingCall.callerName,
|
||||
Id = incomingCall.callerJID
|
||||
};
|
||||
@@ -1307,9 +1291,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
var disconnectEvent =
|
||||
JsonConvert.DeserializeObject<zEvent.CallDisconnect>(responseObj.ToString());
|
||||
|
||||
Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************");
|
||||
Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - disconnectEvent.Successful: {0}", disconnectEvent.Successful);
|
||||
|
||||
if (disconnectEvent.Successful)
|
||||
{
|
||||
if (ActiveCalls.Count > 0)
|
||||
@@ -1318,16 +1299,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
if (activeCall != null)
|
||||
{
|
||||
Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - ActiveCalls.Count: {0} activeCall.Id: {1}, activeCall.Number: {2} activeCall.Name: {3}, activeCall.IsActive: {4}", ActiveCalls.Count, activeCall.Id, activeCall.Number, activeCall.Name, activeCall.IsActiveCall);
|
||||
activeCall.Status = eCodecCallStatus.Disconnected;
|
||||
|
||||
OnCallStatusChange(activeCall);
|
||||
}
|
||||
}
|
||||
var emptyList = new List<Participant>();
|
||||
Participants.CurrentParticipants = emptyList;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************");
|
||||
|
||||
UpdateCallStatus();
|
||||
break;
|
||||
}
|
||||
@@ -1378,24 +1358,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
var status = responseObj.ToObject<zEvent.PinStatusOfScreenNotification>();
|
||||
|
||||
Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex);
|
||||
Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex);
|
||||
|
||||
Participant alreadyPinnedParticipant = null;
|
||||
Participant alreadyPinnedParticipant = null;
|
||||
|
||||
// Check for a participant already pinned to the same screen index.
|
||||
if (status.PinnedUserId > 0)
|
||||
{
|
||||
alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex));
|
||||
// Check for a participant already pinned to the same screen index.
|
||||
if (status.PinnedUserId > 0)
|
||||
{
|
||||
alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex));
|
||||
|
||||
// Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb.
|
||||
if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId)
|
||||
{
|
||||
Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.",
|
||||
alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb);
|
||||
alreadyPinnedParticipant.IsPinnedFb = false;
|
||||
alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1;
|
||||
}
|
||||
}
|
||||
// Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb.
|
||||
if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId)
|
||||
{
|
||||
Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.",
|
||||
alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb);
|
||||
alreadyPinnedParticipant.IsPinnedFb = false;
|
||||
alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1;
|
||||
}
|
||||
}
|
||||
|
||||
var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId));
|
||||
|
||||
@@ -1415,7 +1395,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
else if (participant != null)
|
||||
{
|
||||
Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex);
|
||||
Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex);
|
||||
participant.IsPinnedFb = false;
|
||||
participant.ScreenIndexIsPinnedToFb = -1;
|
||||
}
|
||||
@@ -1460,12 +1440,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.Call);
|
||||
|
||||
Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Info.meeting_id: {0} Status.Call.Info.meeting_list_item.meetingName: {1}", Status.Call.Info.meeting_id, Status.Call.Info.meeting_list_item.meetingName);
|
||||
foreach (var participant in Status.Call.Participants)
|
||||
{
|
||||
Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Participants participant.UserId: {0} participant.UserName: {1}", participant.UserId, participant.UserName);
|
||||
}
|
||||
|
||||
UpdateCallStatus();
|
||||
|
||||
break;
|
||||
@@ -1561,26 +1535,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the current call participants list
|
||||
/// </summary>
|
||||
public void GetCurrentCallParticipants()
|
||||
{
|
||||
SendText("zCommand Call ListParticipants");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints the current call particiapnts list
|
||||
/// </summary>
|
||||
public void PrintCurrentCallParticipants()
|
||||
{
|
||||
if (Debug.Level <= 0) return;
|
||||
if (Debug.Level <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "*************************** Call Participants **************************");
|
||||
foreach (var participant in Participants.CurrentParticipants)
|
||||
{
|
||||
Debug.Console(1, this, "UserId: {3} Name: {0} Audio: {1} IsHost: {2}",
|
||||
participant.Name, participant.AudioMuteFb, participant.IsHost, participant.UserId);
|
||||
Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name,
|
||||
participant.AudioMuteFb, participant.IsHost);
|
||||
}
|
||||
Debug.Console(1, this, "************************************************************************");
|
||||
}
|
||||
@@ -1600,19 +1566,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
private void UpdateCallStatus()
|
||||
{
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Status.ToString() : "no call");
|
||||
Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call");
|
||||
|
||||
if (Status.Call != null)
|
||||
{
|
||||
var callStatus = Status.Call.Status;
|
||||
|
||||
// If not crrently in a meeting, intialize the call object
|
||||
// If not currently in a meeting, intialize the call object
|
||||
if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
|
||||
{
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Creating new Status.Call object");
|
||||
Debug.Console(1, this, "Creating new Status.Call object");
|
||||
Status.Call = new zStatus.Call { Status = callStatus };
|
||||
|
||||
OnCallStatusChange(new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected });
|
||||
OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected });
|
||||
|
||||
SetUpCallFeedbackActions();
|
||||
}
|
||||
@@ -1634,30 +1600,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Status.Call.Info.meeting_id))
|
||||
{
|
||||
var newCall = new CodecActiveCallItem
|
||||
{
|
||||
Name = Status.Call.Info.meeting_list_item.meetingName,
|
||||
Number = Status.Call.Info.meeting_list_item.meetingNumber,
|
||||
Id = Status.Call.Info.meeting_id,
|
||||
Status = newStatus,
|
||||
Type = eCodecCallType.Video,
|
||||
};
|
||||
var newCall = new CodecActiveCallItem
|
||||
{
|
||||
Name = Status.Call.Info.meeting_list_item.meetingName,
|
||||
Id = Status.Call.Info.meeting_id,
|
||||
Status = newStatus
|
||||
};
|
||||
|
||||
ActiveCalls.Add(newCall);
|
||||
ActiveCalls.Add(newCall);
|
||||
|
||||
Debug.Console(1, this, "[UpdateCallStatus] IF w/ meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count);
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call");
|
||||
|
||||
OnCallStatusChange(newCall);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "[UpdateCallStatus] IF w/o meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count);
|
||||
}
|
||||
OnCallStatusChange(newCall);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1673,14 +1631,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "[UpdateCallStatus] ELSE ActiveCalls.Count == {1} - Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count);
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call");
|
||||
|
||||
OnCallStatusChange(existingCall);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Active Calls ------------------------------");
|
||||
Debug.Console(1, this, "*************************** Active Calls ********************************");
|
||||
|
||||
// Clean up any disconnected calls left in the list
|
||||
for (int i = 0; i < ActiveCalls.Count; i++)
|
||||
@@ -1688,26 +1646,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
var call = ActiveCalls[i];
|
||||
|
||||
Debug.Console(1, this,
|
||||
@"ID: {1}
|
||||
Number: {5}
|
||||
Name: {0}
|
||||
@"Name: {0}
|
||||
ID: {1}
|
||||
IsActive: {2}
|
||||
Status: {3}
|
||||
Direction: {4}
|
||||
IsActiveCall: {6}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction, call.Number, call.IsActiveCall);
|
||||
Direction: {4}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction);
|
||||
|
||||
if (!call.IsActiveCall)
|
||||
{
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Removing Inactive call.Id: {1} call.Name: {0}", call.Name, call.Id);
|
||||
Debug.Console(1, this, "***** Removing Inactive Call: {0} *****", call.Name);
|
||||
ActiveCalls.Remove(call);
|
||||
}
|
||||
}
|
||||
Debug.Console(1, this, "[UpdateCallStatus] Active Calls ------------------------------");
|
||||
Debug.Console(1, this, "**************************************************************************");
|
||||
|
||||
//clear participants list after call cleanup
|
||||
var emptyList = new List<Participant>();
|
||||
Participants.CurrentParticipants = emptyList;
|
||||
if (ActiveCalls.Count > 0) GetCurrentCallParticipants();
|
||||
if (ActiveCalls.Count == 0)
|
||||
{
|
||||
var emptyList = new List<Participant>();
|
||||
Participants.CurrentParticipants = emptyList;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCallStatusChange(CodecActiveCallItem item)
|
||||
@@ -1715,7 +1673,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
base.OnCallStatusChange(item);
|
||||
|
||||
Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}",
|
||||
Status.Call != null ? Status.Call.Status.ToString() : "no call");
|
||||
Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call");
|
||||
|
||||
if (_props.AutoDefaultLayouts)
|
||||
{
|
||||
@@ -1760,12 +1718,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);
|
||||
}
|
||||
@@ -1852,7 +1810,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
LinkVideoCodecToApi(this, trilist, joinMap);
|
||||
|
||||
LinkZoomRoomToApi(trilist, joinMap);
|
||||
LinkZoomRoomToApi(trilist, joinMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1882,7 +1840,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
trilist.SetString(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip.ToString());
|
||||
trilist.SetString(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll.ToString());
|
||||
};
|
||||
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail());
|
||||
|
||||
layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
|
||||
@@ -1907,7 +1865,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
});
|
||||
|
||||
layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
|
||||
layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
|
||||
}
|
||||
|
||||
var pinCodec = this as IHasParticipantPinUnpin;
|
||||
@@ -1928,7 +1886,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
try
|
||||
{
|
||||
var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true);
|
||||
var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true);
|
||||
var cmd = SelfviewPipSizes.FirstOrDefault(c => c.Command.Equals(size.ToString()));
|
||||
SelfviewPipSizeSet(cmd);
|
||||
}
|
||||
@@ -1946,7 +1904,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
ComputeAvailableLayouts();
|
||||
layoutsCodec.LocalLayoutFeedback.FireUpdate();
|
||||
layoutsCodec.LocalLayoutFeedback.FireUpdate();
|
||||
layoutsCodec.CanSwapContentWithThumbnailFeedback.FireUpdate();
|
||||
layoutsCodec.ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||
layoutsCodec.LayoutViewIsOnFirstPageFeedback.FireUpdate();
|
||||
@@ -1954,7 +1912,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
pinCodec.NumberOfScreensFeedback.FireUpdate();
|
||||
layoutSizeCodec.SelfviewPipSizeFeedback.FireUpdate();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteSwitch(object selector)
|
||||
{
|
||||
@@ -2064,42 +2022,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
/// <param name="result"></param>
|
||||
private void OnDirectoryResultReturned(CodecDirectory result)
|
||||
{
|
||||
try
|
||||
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
|
||||
|
||||
// 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)
|
||||
{
|
||||
Debug.Console(2, this, "OnDirectoryResultReturned");
|
||||
|
||||
var directoryResult = new CodecDirectory();
|
||||
|
||||
// If result is Root, create a copy and filter out contacts whose parent folder is not root
|
||||
if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
|
||||
handler(this, new DirectoryEventArgs
|
||||
{
|
||||
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);
|
||||
Directory = result,
|
||||
DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue
|
||||
});
|
||||
}
|
||||
|
||||
//PrintDirectory(result);
|
||||
@@ -2116,16 +2049,6 @@ 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);
|
||||
@@ -2492,7 +2415,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
availableLayouts |= zConfiguration.eLayoutStyle.Strip;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "availablelayouts: {0}", availableLayouts);
|
||||
Debug.Console(1, this, "availablelayouts: {0}", availableLayouts);
|
||||
|
||||
var handler = AvailableLayoutsChanged;
|
||||
if (handler != null)
|
||||
@@ -2539,67 +2462,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
#region IHasCodecLayouts Members
|
||||
|
||||
private Func<string> LocalLayoutFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None)
|
||||
return Configuration.Call.Layout.Style.ToString();
|
||||
else
|
||||
return Configuration.Client.Call.Layout.Style.ToString();
|
||||
};
|
||||
}
|
||||
}
|
||||
private Func<string> LocalLayoutFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None)
|
||||
return Configuration.Call.Layout.Style.ToString();
|
||||
else
|
||||
return Configuration.Client.Call.Layout.Style.ToString();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public StringFeedback LocalLayoutFeedback { get; private set; }
|
||||
|
||||
public void LocalLayoutToggle()
|
||||
{
|
||||
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);
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void LocalLayoutToggleSingleProminent()
|
||||
@@ -2610,7 +2491,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public void MinMaxLayoutToggle()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -63,8 +63,6 @@ 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