Compare commits

..

72 Commits

Author SHA1 Message Date
Neil Dorin
8bf4b0d568 fix(essentails): Increase phonebook list limit to 10000 2021-08-19 12:49:11 -06:00
Neil Dorin
621205e65c fix(essentials): Hides password prompt on successful call connection 2021-08-19 12:04:11 -06:00
Neil Dorin
62fcf3856f fix(essentials): Minor update to clear out previous password text when displaying password prompt 2021-08-19 09:37:21 -06:00
Neil Dorin
dad986414c feat(essentials): Updated EssentialsVideoCodecUIDriver to display password prompt when joining password protected meeting 2021-08-18 17:55:04 -06:00
Neil Dorin
f298b5cc41 feat(essentials): Implements IPasswordPrompt on ZoomRoom 2021-08-18 14:45:16 -06:00
Neil Dorin
f8129fe7ae feat(essentials): #800 adds public access modifier on properties 2021-08-18 13:35:48 -06:00
Neil Dorin
dbdaedcca3 feat(essentials): #800 Adds IPasswordPrompt 2021-08-18 13:25:26 -06:00
Neil Dorin
893950d8c4 Merge pull request #798 from PepperDash/hotfix/room-method-updates 2021-08-18 08:30:53 -06:00
Andrew Welker
b780351bf0 Merge branch 'main' into hotfix/room-method-updates 2021-08-18 07:38:11 -06:00
Andrew Welker
6a1671aae1 ci: Remove PR trigger 2021-08-17 22:25:18 -06:00
Andrew Welker
9a1a23c88a fix: Instantiate Availability class when 2021-08-17 22:23:41 -06:00
Andrew Welker
2e4bb7466c Merge pull request #794 from PepperDash/hotfix/sg-ui-issue
fix(essentials): #792 refactors logic to show/hide SelectASourceVisible subpage
2021-08-17 21:48:50 -06:00
Neil Dorin
36a41ac477 fix(essentials): #792 refactors logic to show/hide SelectASourceVisible subpage 2021-08-17 18:00:41 -06:00
Andrew Welker
92f4d37cd6 refactor: Clean up Room Interfaces to help with ambiguities 2021-08-17 16:54:02 -06:00
Andrew Welker
b9479bab70 refactor: Rename Initialize to InitializeRoom 2021-08-17 16:54:01 -06:00
Andrew Welker
fd94a94ee9 Merge pull request #789 from PepperDash/hotfix/zoomroom-duplicate-participant-in-list
Hotfix/zoomroom duplicate participant in list
2021-08-17 16:26:18 -06:00
Jason DeVito
3fa2954ca0 style: Updated formatting for ZoomRoom.cs and IHasParticipants.cs 2021-08-17 16:46:24 -05:00
Jason DeVito
c4f6afa412 Fixed debug references used for call status that were printing Status.Call.Sharing.State. Added GetCurrentCallParticipants method to referesh participant list. Updated UpdateCallStatus to resolve issue with duplicate participants when admitted from the waiting room. 2021-08-17 15:56:57 -05:00
Jason DeVito
6bdda5451b Updated UpdateCallStatus method to fix call status references previously looking at Status.Call.Sharing.State. Added else statement to 'if(ActiveCalls.Count == 0)' used to cleanup after calls that refreshs the participant list. Added GetCurrentCallParticipant method used to poll the participant list. 2021-08-17 15:14:02 -05:00
Andrew Welker
3ee8c07ecd Merge pull request #786 from PepperDash/hotfix/IMobileControl3
feat(essentials): Adds IMobileControl3 interface to maintain backwards compatibility
2021-08-16 15:06:00 -06:00
Neil Dorin
01b713e6e1 feat(essentials): Adds IMobileControl3 interface to maintain backwards compatibility 2021-08-16 14:27:28 -06:00
Neil Dorin
ffd0fbc57b Merge pull request #783 from PepperDash/hotfix/UI-codec-directory-fixes
refactor: Add RefreshDirectory overload
2021-08-16 11:47:52 -06:00
Andrew Welker
23e8280904 refactor: Add RefreshDirectory overload
This allows the directory to be refreshed by the event that updates the directory correctly
2021-08-16 09:42:11 -06:00
Andrew Welker
6708be0d15 Merge pull request #779 from PepperDash/hotfix/zoomroom-fixes
Hotfix/zoomroom fixes
2021-08-16 08:22:19 -06:00
Jason DeVito
d193de79da Added GetSelfViewMode method to ZoomRoom.cs, upated Removed if statement in HideConfSelfVideo property that was blocking feedback updates and setting of the property from boot. Tested with Zoom Rooms system on site and verified working. Closes #781. 2021-08-16 08:26:27 -05:00
Neil Dorin
87ab43c745 fix(essentials): Updates to resolve oddities with ZoomRoom directory browsing and dialing 2021-08-13 13:45:46 -06:00
Neil Dorin
2a37e44d7d fix(essentials): fixes inverted activity call button state 2021-08-12 15:33:17 -06:00
Neil Dorin
efa801137c fix(Essentials): moves code inside null check for CurrentRoom 2021-08-12 14:53:41 -06:00
Neil Dorin
4b4f1f3c3d fix(essentials): Updates to staging subpage join logic 2021-08-12 14:48:19 -06:00
Neil Dorin
6e7bf061cf fix(essentials): Add null check for CurrentRoom 2021-08-12 13:51:48 -06:00
Neil Dorin
7f6160eb44 fix(essentials): Updates to better set feedback for current mode 2021-08-12 12:24:23 -06:00
Andrew Welker
b5004d5b1d Merge pull request #774 from PepperDash/hotfix/zoom-camera-fixes
Hotfix/zoom camera fixes
2021-08-11 11:46:42 -06:00
Neil Dorin
cea1d2fcdd Updates to mute toggle for ZoomRoom 2021-08-09 16:20:55 -06:00
Neil Dorin
22aea3089d #773 Adds some debug and sets the Capabilities value on ZoomRoomCamera
Also updates RunRouteAction in EssentialsHuddleVtc1Room to still call down in to main RunRouteAction method if called with a sourceListKey
2021-08-09 14:41:31 -06:00
Andrew Welker
43256acfcd Merge pull request #771 from PepperDash/hotfix/zoomroom-updates
Hotfix/zoomroom updates
2021-08-02 17:36:28 -06:00
Neil Dorin
1696ef3ac1 Adds LocalLayoutToggle() implementation and minor updates to UI Driver 2021-08-02 16:58:32 -06:00
Neil Dorin
19cbe480a6 reverts IMobileControl back to using EssentialsRoomBase instead of IEssentialsRoom for now 2021-07-29 16:39:34 -06:00
Neil Dorin
49c1c61a88 updates ZoomRoom to use GenericQueue 2021-07-29 14:51:16 -06:00
Neil Dorin
0cd3c1bdc5 fix(ZoomRoom): #767 #768 Adds Output2 on ZoomRoom and updates to UI for VTC
Updates EssentialsVideoCodecUiDriver and codec classes to better deal with dynamic use of IHasCallHistory and
2021-07-29 13:01:02 -06:00
Andrew Welker
d64cbc639a Merge pull request #762 from PepperDash/release/1.9.2
Release/1.9.2
2021-07-28 18:47:34 -06:00
Andrew Welker
8404e7d5a4 Merge branch 'main' into release/1.9.2 2021-07-28 17:07:01 -06:00
Andrew Welker
e4135a958c Merge pull request #764 from PepperDash/hotfix/add-tsw7xx-types-to-factory
Hotfix/add tsw7xx types to factory
2021-07-28 17:06:45 -06:00
Andrew Welker
b026174cd2 Merge branch 'main' into release/1.9.2 2021-07-28 15:47:46 -06:00
Neil Dorin
10f5516a5a Merge pull request #749 from PepperDash/feature/occ-aggregator
Update Occupancy Aggregator to be real device
2021-07-19 15:43:58 -06:00
Andrew Welker
45e6dff26d fix: update access level for config constructor 2021-07-19 15:10:03 -06:00
Andrew Welker
10129b8178 feat: Add post activation action for aggregator 2021-07-19 15:09:37 -06:00
Andrew Welker
9128e108f7 feat: Add clear method to BoolOutputLogical
and do a bit of refactoring
2021-07-19 15:09:03 -06:00
Andrew Welker
760ec8be92 feat: Add occupancy aggregator factory and config 2021-07-19 14:08:57 -06:00
Andrew Welker
bbcdd3e179 Merge pull request #747 from PepperDash/feature/C2N-IO-add
Add C2NIoController to csproj
2021-07-19 14:06:33 -06:00
Andrew Welker
7a649f4ea8 Merge branch 'development' into feature/C2N-IO-add 2021-07-19 13:48:43 -06:00
Andrew Welker
6946946c12 chore: Add c2nIoController to csproj 2021-07-19 13:47:17 -06:00
Neil Dorin
dca73e1508 Merge pull request #745 from PepperDash/feature/C2N-IO-add
Add C2N-IO
2021-07-19 11:55:15 -06:00
Andrew Welker
990090e1de feat: Add support for C2N-IO 2021-07-19 10:29:30 -06:00
Andrew Welker
3b843104d8 Merge pull request #738 from PepperDash/feature/room-combining
Feature/room combining
2021-07-13 22:14:42 -06:00
Neil Dorin
a37814ab3c #736 adds IEssentialsHuddleVtc1Room and refactors to use interface rather than EssentialsHudleVtc1Room 2021-07-12 21:49:54 -06:00
Neil Dorin
2181410927 #736 Adds IEssentialsRoom and IEssentialsHuddleSpaceRoom interfaces
Refactors all references to EssentialsRoomBase and EssentialsHuddleSpaceRoom to use the new interfaces instead
2021-07-12 17:22:36 -06:00
Andrew Welker
d4191ceb75 Merge pull request #735 from PepperDash/hotfix/zip-release-upload
Hotfix/zip release upload
2021-07-08 12:04:57 -06:00
Andrew Welker
5f6d15c6c0 Merge branch 'development' into hotfix/zip-release-upload 2021-07-08 11:41:40 -06:00
Andrew Welker
c7180db2b7 Merge pull request #730 from PepperDash/feature/update-ihasscheduleawareness
Feature/update ihasscheduleawareness
2021-07-03 00:39:29 -06:00
Neil Dorin
d95ee27979 #728 corrects casing of folder name in Global.FilePathPrefix at startup 2021-07-02 15:01:51 -06:00
Neil Dorin
e964172200 #729 Updates to get CheckSchedule method working as designed 2021-07-02 15:01:17 -06:00
Neil Dorin
840934502b Working on getting meeting change events to trigger properly 2021-06-29 17:35:22 -06:00
Neil Dorin
a76f4c15dc Updates to IHasScheduleAwareness 2021-06-29 09:47:56 -06:00
Neil Dorin
b19e2e38ad Merge pull request #727 from PepperDash/hotfix/add-eisc-server-client-options-to-eiscapiadvanced-factory
Hotfix/add eisc server client options to eiscapiadvanced factory
2021-06-24 16:53:14 -06:00
Neil Dorin
9a7fe553f9 Merge branch 'development' into hotfix/add-eisc-server-client-options-to-eiscapiadvanced-factory 2021-06-24 16:35:29 -06:00
Andrew Welker
895b76a0cd Merge pull request #723 from PepperDash/hotfix/zoom-room-views
Hotfix/zoom room views
2021-06-24 13:28:48 -06:00
Andrew Welker
0cc2328276 Merge branch 'development' into hotfix/zoom-room-views 2021-06-17 10:03:42 -06:00
Neil Dorin
54769ce270 Merge pull request #722 from PepperDash/hotfix/plugin-loading
Hotfix/plugin loading
2021-06-16 17:20:57 -06:00
Andrew Welker
6b85323949 Merge branch 'development' into hotfix/plugin-loading 2021-06-16 15:17:52 -06:00
Neil Dorin
4e81859695 Merge pull request #719 from PepperDash/bugfix/setdevicestreamdebug-fix
Bugfix/setdevicestreamdebug fix
2021-06-08 13:45:08 -06:00
Andrew Welker
1ebacf3f0f Fix formatting issue 2021-06-08 12:12:59 -06:00
Andrew Welker
7de0251188 add ConvertType method to convert type
This method should allow for using a string value in place of an enum as a parameter. Integers will still fail.
2021-06-08 11:44:09 -06:00
56 changed files with 2790 additions and 1637 deletions

View File

@@ -8,12 +8,9 @@ on:
- bugfix/* - bugfix/*
- release/* - release/*
- development - development
pull_request:
branches:
- development
env: env:
# solution path doesn't need slashes unless there it is multiple folders deep # solution path doesn't need slashes unless it is multiple folders deep
# solution name does not include extension. .sln is assumed # solution name does not include extension. .sln is assumed
SOLUTION_PATH: PepperDashEssentials SOLUTION_PATH: PepperDashEssentials
SOLUTION_FILE: PepperDashEssentials SOLUTION_FILE: PepperDashEssentials

View File

@@ -131,29 +131,46 @@ namespace PepperDash.Essentials
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
{ {
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString()); string userFolder;
string nvramFolder;
bool is4series = false;
if (eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4)) // Handle 4-series
{
is4series = true;
// Set path to user/
userFolder = "user";
nvramFolder = "nvram";
}
else
{
userFolder = "User";
nvramFolder = "Nvram";
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, is4series ? "4-series" : "3-series");
// Check if User/ProgramX exists // Check if User/ProgramX exists
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User" if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + userFolder
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
{ {
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber); Debug.Console(0, @"{0}/program{1} directory found", userFolder, InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "User" filePathPrefix = directoryPrefix + dirSeparator + userFolder
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
} }
// Check if Nvram/Programx exists // Check if Nvram/Programx exists
else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram" else if (Directory.Exists(directoryPrefix + dirSeparator + nvramFolder
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
{ {
Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber); Debug.Console(0, @"{0}/program{1} directory found", nvramFolder, InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "Nvram" filePathPrefix = directoryPrefix + dirSeparator + nvramFolder
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
} }
// If neither exists, set path to User/ProgramX // If neither exists, set path to User/ProgramX
else else
{ {
Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber); Debug.Console(0, @"No previous directory found. Using {0}/program{1}", userFolder, InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "User" filePathPrefix = directoryPrefix + dirSeparator + userFolder
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
} }
} }
@@ -435,7 +452,7 @@ namespace PepperDash.Essentials
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{ {
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase; var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
if (room != null) if (room != null)
{ {
// default IPID // default IPID
@@ -457,7 +474,7 @@ namespace PepperDash.Essentials
} }
} }
if (room is EssentialsHuddleSpaceRoom) if (room is IEssentialsHuddleSpaceRoom)
{ {
DeviceManager.AddDevice(room); DeviceManager.AddDevice(room);
@@ -469,12 +486,12 @@ namespace PepperDash.Essentials
CreateMobileControlBridge(room); CreateMobileControlBridge(room);
} }
else if (room is EssentialsHuddleVtc1Room) else if (room is IEssentialsHuddleVtc1Room)
{ {
DeviceManager.AddDevice(room); 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");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
@@ -507,13 +524,22 @@ namespace PepperDash.Essentials
} }
private static void CreateMobileControlBridge(EssentialsRoomBase room) private static void CreateMobileControlBridge(object room)
{ {
var mobileControl = GetMobileControlDevice(); var mobileControl = GetMobileControlDevice();
if (mobileControl == null) return; if (mobileControl == null) return;
mobileControl.CreateMobileControlRoomBridge(room, mobileControl); var mobileControl3 = mobileControl as IMobileControl3;
if (mobileControl3 != null)
{
mobileControl3.CreateMobileControlRoomBridge(room as IEssentialsRoom, mobileControl);
}
else
{
mobileControl.CreateMobileControlRoomBridge(room as EssentialsRoomBase, mobileControl);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added..."); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
} }

View File

@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Fusion
{ {
BooleanSigData CodecIsInCall; BooleanSigData CodecIsInCall;
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey) public EssentialsHuddleVtc1FusionController(IEssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
: base(room, ipId, joinMapKey) : base(room, ipId, joinMapKey)
{ {
@@ -37,7 +37,7 @@ namespace PepperDash.Essentials.Fusion
{ {
try try
{ {
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
if (codec == null) if (codec == null)
{ {
@@ -141,7 +141,7 @@ namespace PepperDash.Essentials.Fusion
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e) void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
{ {
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
CodecIsInCall.InputSig.BoolValue = codec.IsInCall; CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
} }
@@ -174,11 +174,11 @@ namespace PepperDash.Essentials.Fusion
// Moved to // Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly); CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet. // Don't think we need to get current status of this as nothing should be alive yet.
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; (Room as IEssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as IEssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
@@ -187,7 +187,7 @@ namespace PepperDash.Essentials.Fusion
protected override void SetUpSources() protected override void SetUpSources()
{ {
// Sources // Sources
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey); var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as IEssentialsHuddleVtc1Room).SourceListKey);
if (dict != null) if (dict != null)
{ {
// NEW PROCESS: // NEW PROCESS:
@@ -238,7 +238,7 @@ namespace PepperDash.Essentials.Fusion
else else
{ {
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key); (Room as IEssentialsHuddleVtc1Room).SourceListKey, Room.Key);
} }
} }
@@ -259,7 +259,7 @@ namespace PepperDash.Essentials.Fusion
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded); display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
} }
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; var defaultDisplay = (Room as IEssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
if (defaultDisplay == null) if (defaultDisplay == null)
{ {
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
@@ -332,7 +332,7 @@ namespace PepperDash.Essentials.Fusion
string displayName = string.Format("Display {0} - ", displayIndex); string displayName = string.Format("Display {0} - ", displayIndex);
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay) if (display == (Room as IEssentialsHuddleVtc1Room).DefaultDisplay)
{ {
// Power on // Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
@@ -351,7 +351,7 @@ namespace PepperDash.Essentials.Fusion
// Current Source // Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ; defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
} }
} }
} }

View File

@@ -149,6 +149,7 @@
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" /> <Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomConfig.cs" /> <Compile Include="Room\Config\EssentialsRoomConfig.cs" />
<Compile Include="Room\Types\EssentialsTechRoom.cs" /> <Compile Include="Room\Types\EssentialsTechRoom.cs" />
<Compile Include="Room\Types\IEssentialsHuddleSpaceRoom.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" /> <Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" /> <Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" /> <Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />

View File

@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Room.Config
/// Gets and operating, standalone emergegncy object that can be plugged into a room. /// Gets and operating, standalone emergegncy object that can be plugged into a room.
/// Returns null if there is no emergency defined /// Returns null if there is no emergency defined
/// </summary> /// </summary>
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room) public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room)
{ {
// This emergency // This emergency
var emergency = props.Emergency; var emergency = props.Emergency;
@@ -96,7 +96,7 @@ namespace PepperDash.Essentials.Room.Config
if (behaviour == "trackroomstate") if (behaviour == "trackroomstate")
{ {
// Tie LED enable to room power state // Tie LED enable to room power state
var essRoom = room as EssentialsRoomBase; var essRoom = room as IEssentialsRoom;
essRoom.OnFeedback.OutputChange += (o, a) => essRoom.OnFeedback.OutputChange += (o, a) =>
{ {
if (essRoom.OnFeedback.BoolValue) if (essRoom.OnFeedback.BoolValue)

View File

@@ -17,11 +17,11 @@ namespace PepperDash.Essentials.Room
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
{ {
EssentialsRoomBase Room; IEssentialsRoom Room;
string Behavior; string Behavior;
bool TriggerOnClose; bool TriggerOnClose;
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, EssentialsRoomBase room) : public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
base(key) base(key)
{ {
Room = room; Room = room;

View File

@@ -207,7 +207,7 @@ namespace PepperDash.Essentials
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
Initialize(); InitializeRoom();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -215,7 +215,7 @@ namespace PepperDash.Essentials
} }
} }
void Initialize() void InitializeRoom()
{ {
if (DefaultAudioDevice is IBasicVolumeControls) if (DefaultAudioDevice is IBasicVolumeControls)
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls; DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
@@ -645,9 +645,9 @@ namespace PepperDash.Essentials
public static void AllRoomsOff() public static void AllRoomsOff()
{ {
var allRooms = DeviceManager.AllDevices.Where(d => var allRooms = DeviceManager.AllDevices.Where(d =>
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); d is IEssentialsHuddleSpaceRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
foreach (var room in allRooms) foreach (var room in allRooms)
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey); (room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as IEssentialsHuddleSpaceRoom).SourceListKey);
} }
#region IPrivacy Members #region IPrivacy Members

View File

@@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials namespace PepperDash.Essentials
{ {
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IEssentialsHuddleSpaceRoom
{ {
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange; public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSourceChange; public event SourceInfoChangeHandler CurrentSourceChange;
@@ -156,7 +156,7 @@ namespace PepperDash.Essentials
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching; DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
Initialize(); InitializeRoom();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -164,7 +164,7 @@ namespace PepperDash.Essentials
} }
} }
void Initialize() void InitializeRoom()
{ {
if (DefaultAudioDevice is IBasicVolumeControls) if (DefaultAudioDevice is IBasicVolumeControls)
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls; DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;

View File

@@ -17,8 +17,7 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials namespace PepperDash.Essentials
{ {
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
{ {
private bool _codecExternalSourceChange; private bool _codecExternalSourceChange;
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange; public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
@@ -227,7 +226,7 @@ namespace PepperDash.Essentials
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
Initialize(); InitializeRoom();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -235,7 +234,7 @@ namespace PepperDash.Essentials
} }
} }
void Initialize() void InitializeRoom()
{ {
try try
{ {
@@ -455,7 +454,8 @@ namespace PepperDash.Essentials
else else
{ {
Debug.Console(1, this, "sourceListKey present but not yet implemented"); Debug.Console(1, this, "sourceListKey present but not yet implemented");
throw new NotImplementedException();
RunRouteAction(routeKey, new Action(() => { }));
} }
} }
@@ -472,7 +472,11 @@ namespace PepperDash.Essentials
RunRouteAction(routeKey, successCallback); RunRouteAction(routeKey, successCallback);
} }
else else
throw new NotImplementedException(); {
Debug.Console(1, this, "sourceListKey present but not yet implemented");
RunRouteAction(routeKey, successCallback);
}
} }
/// <summary> /// <summary>
@@ -733,10 +737,10 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public static void AllRoomsOff() public static void AllRoomsOff()
{ {
var allRooms = DeviceManager.AllDevices.Where(d => var allRooms = DeviceManager.AllDevices.Where(d =>
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
foreach (var room in allRooms) foreach (var room in allRooms)
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); (room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
} }

View File

@@ -0,0 +1,44 @@
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, IHasDefaultDisplay
{
bool ExcludeFromGlobalFunctions { get; }
void RunRouteAction(string routeKey);
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
IBasicVolumeControls CurrentVolumeControls { get; }
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
}
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay
{
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
void RunRouteAction(string routeKey);
IHasScheduleAwareness ScheduleSource { get; }
string DefaultCodecRouteString { get; }
}
}

View File

@@ -232,7 +232,7 @@ namespace PepperDash.Essentials
// spin up different room drivers depending on room type // spin up different room drivers depending on room type
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey); var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
if (room is EssentialsHuddleSpaceRoom) if (room is IEssentialsHuddleSpaceRoom)
{ {
// Screen Saver Driver // Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props); mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props);
@@ -246,7 +246,7 @@ namespace PepperDash.Essentials
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props); var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
avDriver.DefaultRoomKey = props.DefaultRoomKey; avDriver.DefaultRoomKey = props.DefaultRoomKey;
mainDriver.AvDriver = avDriver; mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom; avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom;
// Environment Driver // Environment Driver
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
@@ -280,7 +280,7 @@ namespace PepperDash.Essentials
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress); tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
} }
} }
else if (room is EssentialsHuddleVtc1Room) else if (room is IEssentialsHuddleVtc1Room)
{ {
Debug.Console(0, panelController, "Adding huddle space VTC AV driver"); Debug.Console(0, panelController, "Adding huddle space VTC AV driver");
@@ -294,11 +294,11 @@ namespace PepperDash.Essentials
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props); var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props);
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver, var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
(room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); (room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
avDriver.SetVideoCodecDriver(codecDriver); avDriver.SetVideoCodecDriver(codecDriver);
avDriver.DefaultRoomKey = props.DefaultRoomKey; avDriver.DefaultRoomKey = props.DefaultRoomKey;
mainDriver.AvDriver = avDriver; mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room; avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room;
// Environment Driver // Environment Driver
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)

View File

@@ -103,7 +103,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// 1202 /// 1202
/// </summary> /// </summary>
public const uint VCStagingInactivePopoverVisible = 1202; public const uint VCStagingInactivePopoverWithRecentsVisible = 1202;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@@ -121,6 +121,11 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public const uint VCRecentsVisible = 1206; public const uint VCRecentsVisible = 1206;
/// <summary>
/// 1202
/// </summary>
public const uint VCStagingInactivePopoverWithoutRecentsVisible = 1207;
/// <summary> /// <summary>
/// 1208 /// 1208
/// </summary> /// </summary>
@@ -243,6 +248,10 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public const uint VCCameraSelectBarWithoutModeVisible = 1261; public const uint VCCameraSelectBarWithoutModeVisible = 1261;
/// <summary>
/// 1262
/// </summary>
public const uint VCCameraAutoModeIsOnFb = 1262;
/// <summary> /// <summary>
/// 1271 /// 1271
@@ -743,10 +752,10 @@ namespace PepperDash.Essentials
/// 15044 Close button for source modal overlay /// 15044 Close button for source modal overlay
/// </summary> /// </summary>
public const uint SourceBackgroundOverlayClosePress = 15044; public const uint SourceBackgroundOverlayClosePress = 15044;
/// <summary> ///// <summary>
/// 15045 - Visibility for the bar containing call navigation button list ///// 15045 - Visibility for the bar containing call navigation button list
/// </summary> ///// </summary>
public const uint CallStagingBarVisible = 15045; //public const uint CallStagingBarVisible = 15045;
/// <summary> /// <summary>
/// 15046 /// 15046
/// </summary> /// </summary>
@@ -764,6 +773,10 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public const uint NextMeetingModalVisible = 15049; public const uint NextMeetingModalVisible = 15049;
/// <summary> /// <summary>
/// 15050
/// </summary>
public const uint NextMeetingNotificationRibbonVisible = 15050;
/// <summary>
/// 15051 /// 15051
/// </summary> /// </summary>
public const uint Display1SelectPressAndFb = 15051; public const uint Display1SelectPressAndFb = 15051;
@@ -935,5 +948,24 @@ namespace PepperDash.Essentials
/// 15214 /// 15214
/// </summary> /// </summary>
public const uint PinDialogDot4 = 15214; public const uint PinDialogDot4 = 15214;
// Password Prompt Dialog **************************
/// <summary>
/// 15301
/// </summary>
public const uint PasswordPromptDialogVisible = 15301;
/// <summary>
/// 15302
/// </summary>
public const uint PasswordPromptTextPress = 15302;
/// <summary>
/// 15306
/// </summary>
public const uint PasswordPromptCancelPress = 15306;
/// <summary>
/// 15307
/// </summary>
public const uint PasswordPromptErrorVisible = 15307;
} }
} }

View File

@@ -118,6 +118,14 @@ namespace PepperDash.Essentials
//----- through 3120 //----- through 3120
/// <summary>
/// 3201
/// </summary>
public const uint PasswordPromptMessageText = 3201;
/// <summary>
/// 3202
/// </summary>
public const uint PasswordPromptPasswordText = 3202;
/// <summary> /// <summary>
/// 3812 /// 3812

View File

@@ -146,18 +146,18 @@
// } // }
// void CurrentRoom_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) // void CurrentRoom_CurrentSourceInfoChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// { // {
// } // }
// void CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) // void CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// { // {
// TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName; // TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName;
// } // }
// void CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) // void CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// { // {
// TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName; // TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName;
// } // }

View File

@@ -52,7 +52,7 @@ namespace PepperDash.Essentials
CaretInterlock = new JoinedSigInterlock(TriList); CaretInterlock = new JoinedSigInterlock(TriList);
} }
void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom) void SetUpGear(IAVDriver avDriver, IEssentialsRoom currentRoom)
{ {
// Gear // Gear
TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear"); TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear");
@@ -105,7 +105,7 @@ namespace PepperDash.Essentials
{ {
string message = null; string message = null;
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey) var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
as EssentialsHuddleSpaceRoom; as IEssentialsHuddleSpaceRoom;
if (room != null) if (room != null)
message = room.PropertiesConfig.HelpMessage; message = room.PropertiesConfig.HelpMessage;
else else
@@ -222,7 +222,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Sets up Header Buttons for the EssentialsHuddleVtc1Room type /// Sets up Header Buttons for the EssentialsHuddleVtc1Room type
/// </summary> /// </summary>
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom) public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, IEssentialsHuddleVtc1Room currentRoom)
{ {
HeaderButtonsAreSetUp = false; HeaderButtonsAreSetUp = false;
@@ -284,7 +284,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type /// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type
/// </summary> /// </summary>
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom) public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, IEssentialsHuddleSpaceRoom currentRoom)
{ {
HeaderButtonsAreSetUp = false; HeaderButtonsAreSetUp = false;

View File

@@ -983,7 +983,7 @@
// /// <summary> // /// <summary>
// /// Handles source change // /// Handles source change
// /// </summary> // /// </summary>
// void _CurrentRoom_SourceInfoChange(EssentialsRoomBase room, // void _CurrentRoom_SourceInfoChange(IEssentialsRoom room,
// SourceListItem info, ChangeType change) // SourceListItem info, ChangeType change)
// { // {
// if (change == ChangeType.WillChange) // if (change == ChangeType.WillChange)
@@ -995,7 +995,7 @@
// /// <summary> // /// <summary>
// /// // ///
// /// </summary> // /// </summary>
// void _CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) // void _CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// { // {
// if (type == ChangeType.DidChange) // if (type == ChangeType.DidChange)
// { // {
@@ -1021,7 +1021,7 @@
// /// <summary> // /// <summary>
// /// // ///
// /// </summary> // /// </summary>
// void _CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) // void _CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// { // {
// if (type == ChangeType.DidChange) // if (type == ChangeType.DidChange)
// { // {

View File

@@ -78,7 +78,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public EssentialsHuddleSpaceRoom CurrentRoom public IEssentialsHuddleSpaceRoom CurrentRoom
{ {
get { return _CurrentRoom; } get { return _CurrentRoom; }
set set
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials
SetCurrentRoom(value); SetCurrentRoom(value);
} }
} }
EssentialsHuddleSpaceRoom _CurrentRoom; IEssentialsHuddleSpaceRoom _CurrentRoom;
/// <summary> /// <summary>
/// ///
@@ -498,7 +498,7 @@ namespace PepperDash.Essentials
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true; TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
// Run default source when room is off and share is pressed // Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue) if (!CurrentRoom.OnFeedback.BoolValue)
CurrentRoom.RunDefaultPresentRoute(); (CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute();
} }
@@ -583,7 +583,7 @@ namespace PepperDash.Essentials
void UiSelectSource(string key) void UiSelectSource(string key)
{ {
// Run the route and when it calls back, show the source // Run the route and when it calls back, show the source
CurrentRoom.RunRouteAction(key, new Action(() => { })); CurrentRoom.RunRouteAction(key);
} }
/// <summary> /// <summary>
@@ -745,7 +745,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Helper for property setter. Sets the panel to the given room, latching up all functionality /// Helper for property setter. Sets the panel to the given room, latching up all functionality
/// </summary> /// </summary>
public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room) public void RefreshCurrentRoom(IEssentialsHuddleSpaceRoom room)
{ {
if (_CurrentRoom != null) if (_CurrentRoom != null)
{ {
@@ -836,7 +836,7 @@ namespace PepperDash.Essentials
} }
} }
void SetCurrentRoom(EssentialsHuddleSpaceRoom room) void SetCurrentRoom(IEssentialsHuddleSpaceRoom room)
{ {
if (_CurrentRoom == room) return; if (_CurrentRoom == room) return;
// Disconnect current (probably never called) // Disconnect current (probably never called)
@@ -871,7 +871,7 @@ namespace PepperDash.Essentials
UpdateMCJoins(_CurrentRoom); UpdateMCJoins(_CurrentRoom);
} }
void UpdateMCJoins(EssentialsHuddleSpaceRoom room) void UpdateMCJoins(IEssentialsHuddleSpaceRoom room)
{ {
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl); TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl); TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
@@ -918,6 +918,7 @@ namespace PepperDash.Essentials
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
} }
} }

View File

@@ -1,326 +1,326 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials; using PepperDash.Essentials;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.Touchpanels.Keyboards; using PepperDash.Essentials.Core.Touchpanels.Keyboards;
using PepperDash.Essentials.Devices.Displays; using PepperDash.Essentials.Devices.Displays;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials.UIDrivers namespace PepperDash.Essentials.UIDrivers
{ {
public class EssentialsHuddleTechPageDriver : PanelDriverBase public class EssentialsHuddleTechPageDriver : PanelDriverBase
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
SmartObjectDynamicList MenuList; SmartObjectDynamicList MenuList;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
SubpageReferenceList StatusList; SubpageReferenceList StatusList;
/// <summary> /// <summary>
/// The list of display controls /// The list of display controls
/// </summary> /// </summary>
SubpageReferenceList DisplayList; SubpageReferenceList DisplayList;
/// <summary> /// <summary>
/// References lines in the list against device instances /// References lines in the list against device instances
/// </summary> /// </summary>
Dictionary<ICommunicationMonitor, uint> StatusListDeviceIndexes; Dictionary<ICommunicationMonitor, uint> StatusListDeviceIndexes;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
JoinedSigInterlock PagesInterlock; JoinedSigInterlock PagesInterlock;
/// <summary> /// <summary>
/// 1 /// 1
/// </summary> /// </summary>
public const uint JoinText = 1; public const uint JoinText = 1;
CTimer PinAuthorizedTimer; CTimer PinAuthorizedTimer;
EssentialsRoomTechConfig Config; EssentialsRoomTechConfig Config;
StringBuilder PinEntryBuilder = new StringBuilder(4); StringBuilder PinEntryBuilder = new StringBuilder(4);
bool IsAuthorized; bool IsAuthorized;
SmartObjectNumeric PinKeypad; SmartObjectNumeric PinKeypad;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="trilist"></param> /// <param name="trilist"></param>
/// <param name="parent"></param> /// <param name="parent"></param>
public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config) public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config)
: base(trilist) : base(trilist)
{ {
Config = config; Config = config;
PagesInterlock = new JoinedSigInterlock(trilist); PagesInterlock = new JoinedSigInterlock(trilist);
PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible); PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible);
trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide); trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide);
MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList], MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList],
true, 3100); true, 3100);
MenuList.SetFeedback(1, true); // initial fb MenuList.SetFeedback(1, true); // initial fb
ushort count = 0; ushort count = 0;
MenuList.SetItemMainText(1, "System Status"); MenuList.SetItemMainText(1, "System Status");
MenuList.SetItemButtonAction(1, b => { MenuList.SetItemButtonAction(1, b => {
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible); if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible);
MenuList.SetFeedback(1, true); MenuList.SetFeedback(1, true);
}); });
MenuList.SetItemMainText(2, "Display Controls"); MenuList.SetItemMainText(2, "Display Controls");
MenuList.SetItemButtonAction(2, b => { MenuList.SetItemButtonAction(2, b => {
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible); if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible);
MenuList.SetFeedback(2, true); MenuList.SetFeedback(2, true);
}); });
count = 2; count = 2;
// Don't show panel setup on iPad or xpanel // Don't show panel setup on iPad or xpanel
if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button) if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button)
{ {
count++; count++;
MenuList.SetItemMainText(count, "Panel Setup"); MenuList.SetItemMainText(count, "Panel Setup");
MenuList.SetItemButtonAction(count, b => MenuList.SetItemButtonAction(count, b =>
{ {
if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible); if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible);
MenuList.SetFeedback(count, true); MenuList.SetFeedback(count, true);
}); });
} }
MenuList.Count = count; MenuList.Count = count;
BuildStatusList(); BuildStatusList();
BuildDisplayList(); BuildDisplayList();
SetupPinModal(); SetupPinModal();
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public override void Show() public override void Show()
{ {
// divert to PIN if we need auth // divert to PIN if we need auth
if (IsAuthorized) if (IsAuthorized)
{ {
// Cancel the auth timer so we don't deauth after coming back in // Cancel the auth timer so we don't deauth after coming back in
if (PinAuthorizedTimer != null) if (PinAuthorizedTimer != null)
PinAuthorizedTimer.Stop(); PinAuthorizedTimer.Stop();
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true); TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true);
PagesInterlock.Show(); PagesInterlock.Show();
base.Show(); base.Show();
} }
else else
{ {
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true); TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public override void Hide() public override void Hide()
{ {
// Leave it authorized for 60 seconds. // Leave it authorized for 60 seconds.
if (IsAuthorized) if (IsAuthorized)
PinAuthorizedTimer = new CTimer(o => { PinAuthorizedTimer = new CTimer(o => {
IsAuthorized = false; IsAuthorized = false;
PinAuthorizedTimer = null; PinAuthorizedTimer = null;
}, 60000); }, 60000);
TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false); TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false);
PagesInterlock.Hide(); PagesInterlock.Hide();
base.Hide(); base.Hide();
} }
/// <summary> /// <summary>
/// Wire up the keypad and buttons /// Wire up the keypad and buttons
/// </summary> /// </summary>
void SetupPinModal() void SetupPinModal()
{ {
TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog); TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog);
PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true); PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true);
PinKeypad.Digit0.UserObject = new Action<bool>(b => { if (b)DialPinDigit('0'); }); PinKeypad.Digit0.UserObject = new Action<bool>(b => { if (b)DialPinDigit('0'); });
PinKeypad.Digit1.UserObject = new Action<bool>(b => { if (b)DialPinDigit('1'); }); PinKeypad.Digit1.UserObject = new Action<bool>(b => { if (b)DialPinDigit('1'); });
PinKeypad.Digit2.UserObject = new Action<bool>(b => { if (b)DialPinDigit('2'); }); PinKeypad.Digit2.UserObject = new Action<bool>(b => { if (b)DialPinDigit('2'); });
PinKeypad.Digit3.UserObject = new Action<bool>(b => { if (b)DialPinDigit('3'); }); PinKeypad.Digit3.UserObject = new Action<bool>(b => { if (b)DialPinDigit('3'); });
PinKeypad.Digit4.UserObject = new Action<bool>(b => { if (b)DialPinDigit('4'); }); PinKeypad.Digit4.UserObject = new Action<bool>(b => { if (b)DialPinDigit('4'); });
PinKeypad.Digit5.UserObject = new Action<bool>(b => { if (b)DialPinDigit('5'); }); PinKeypad.Digit5.UserObject = new Action<bool>(b => { if (b)DialPinDigit('5'); });
PinKeypad.Digit6.UserObject = new Action<bool>(b => { if (b)DialPinDigit('6'); }); PinKeypad.Digit6.UserObject = new Action<bool>(b => { if (b)DialPinDigit('6'); });
PinKeypad.Digit7.UserObject = new Action<bool>(b => { if (b)DialPinDigit('7'); }); PinKeypad.Digit7.UserObject = new Action<bool>(b => { if (b)DialPinDigit('7'); });
PinKeypad.Digit8.UserObject = new Action<bool>(b => { if (b)DialPinDigit('8'); }); PinKeypad.Digit8.UserObject = new Action<bool>(b => { if (b)DialPinDigit('8'); });
PinKeypad.Digit9.UserObject = new Action<bool>(b => { if (b)DialPinDigit('9'); }); PinKeypad.Digit9.UserObject = new Action<bool>(b => { if (b)DialPinDigit('9'); });
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="d"></param> /// <param name="d"></param>
void DialPinDigit(char d) void DialPinDigit(char d)
{ {
PinEntryBuilder.Append(d); PinEntryBuilder.Append(d);
var len = PinEntryBuilder.Length; var len = PinEntryBuilder.Length;
SetPinDotsFeedback(len); SetPinDotsFeedback(len);
// check it! // check it!
if (len == 4) if (len == 4)
{ {
if (Config.Password == PinEntryBuilder.ToString()) if (Config.Password == PinEntryBuilder.ToString())
{ {
IsAuthorized = true; IsAuthorized = true;
SetPinDotsFeedback(0); SetPinDotsFeedback(0);
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false);
Show(); Show();
} }
else else
{ {
SetPinDotsFeedback(0); SetPinDotsFeedback(0);
TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true); TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true);
new CTimer(o => new CTimer(o =>
{ {
TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false); TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false);
}, 1500); }, 1500);
} }
PinEntryBuilder.Remove(0, len); // clear it either way PinEntryBuilder.Remove(0, len); // clear it either way
} }
} }
/// <summary> /// <summary>
/// Draws the dots as pin is entered /// Draws the dots as pin is entered
/// </summary> /// </summary>
/// <param name="len"></param> /// <param name="len"></param>
void SetPinDotsFeedback(int len) void SetPinDotsFeedback(int len)
{ {
TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1); TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1);
TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2); TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2);
TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3); TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3);
TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4); TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4);
} }
/// <summary> /// <summary>
/// Does what it says /// Does what it says
/// </summary> /// </summary>
void CancelPinDialog() void CancelPinDialog()
{ {
PinEntryBuilder.Remove(0, PinEntryBuilder.Length); PinEntryBuilder.Remove(0, PinEntryBuilder.Length);
TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
void BuildStatusList() void BuildStatusList()
{ {
StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3); StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3);
StatusListDeviceIndexes = new Dictionary<ICommunicationMonitor, uint>(); StatusListDeviceIndexes = new Dictionary<ICommunicationMonitor, uint>();
uint i = 0; uint i = 0;
foreach (var d in DeviceManager.AllDevices) foreach (var d in DeviceManager.AllDevices)
{ {
// make sure it is both ICommunicationMonitor and a Device // make sure it is both ICommunicationMonitor and a Device
var sd = d as ICommunicationMonitor; var sd = d as ICommunicationMonitor;
if (sd == null) if (sd == null)
continue; continue;
var dd = sd as Device; var dd = sd as Device;
if(dd == null) if(dd == null)
continue; continue;
i++; i++;
StatusList.StringInputSig(i, 1).StringValue = dd.Name; StatusList.StringInputSig(i, 1).StringValue = dd.Name;
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status; StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status;
StatusListDeviceIndexes.Add(sd, i); StatusListDeviceIndexes.Add(sd, i);
sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ; sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ;
} }
StatusList.Count = (ushort)i; StatusList.Count = (ushort)i;
} }
/// <summary> /// <summary>
/// Builds the list of display controls /// Builds the list of display controls
/// </summary> /// </summary>
void BuildDisplayList() void BuildDisplayList()
{ {
DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3); DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3);
var devKeys = ConfigReader.ConfigObject.Devices.Where(d => var devKeys = ConfigReader.ConfigObject.Devices.Where(d =>
d.Group.Equals("display", StringComparison.OrdinalIgnoreCase) d.Group.Equals("display", StringComparison.OrdinalIgnoreCase)
|| d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase)) || d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase))
.Select(dd => dd.Key); .Select(dd => dd.Key);
var disps = DeviceManager.AllDevices.Where(d => var disps = DeviceManager.AllDevices.Where(d =>
devKeys.Contains(d.Key)); devKeys.Contains(d.Key));
ushort i = 0; ushort i = 0;
foreach (var disp in disps) foreach (var disp in disps)
{ {
var display = disp as DisplayBase; var display = disp as DisplayBase;
if (display != null) if (display != null)
{ {
i++; i++;
DisplayList.StringInputSig(i, 1).StringValue = display.Name; DisplayList.StringInputSig(i, 1).StringValue = display.Name;
DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn); DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn);
DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff); DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff);
if (display is TwoWayDisplayBase) if (display is TwoWayDisplayBase)
{ {
var powerOnSig = DisplayList.BoolInputSig(i, 1); var powerOnSig = DisplayList.BoolInputSig(i, 1);
(display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig); (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig);
var powerOffSig = DisplayList.BoolInputSig(1, 2); var powerOffSig = DisplayList.BoolInputSig(1, 2);
(display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig); (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig);
} }
DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() => DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() =>
{ if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); }); { if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); });
DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() => DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() =>
{ if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); }); { if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); });
DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() => DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() =>
{ if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); }); { if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); });
//DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => //DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() =>
//{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); }); //{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); });
DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() =>
{ if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); }); { if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); });
// Figure out some way to provide current input feedback // Figure out some way to provide current input feedback
if (display is TwoWayDisplayBase) if (display is TwoWayDisplayBase)
{ {
(display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange; (display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange;
} }
} }
} }
DisplayList.Count = i; DisplayList.Count = i;
} }
void CurrentInputFeedback_OutputChange(object sender, EventArgs e) void CurrentInputFeedback_OutputChange(object sender, EventArgs e)
{ {
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e) void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
{ {
var c = sender as ICommunicationMonitor; var c = sender as ICommunicationMonitor;
if (StatusListDeviceIndexes.ContainsKey(c)) if (c != null && StatusListDeviceIndexes.ContainsKey(c))
{ {
var i = StatusListDeviceIndexes[c]; var i = StatusListDeviceIndexes[c];
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status; StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;
} }
} }
} }
} }

View File

@@ -50,7 +50,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public EssentialsHuddleVtc1Room CurrentRoom public IEssentialsHuddleVtc1Room CurrentRoom
{ {
get { return _CurrentRoom; } get { return _CurrentRoom; }
set set
@@ -58,7 +58,7 @@ namespace PepperDash.Essentials
SetCurrentRoom(value); SetCurrentRoom(value);
} }
} }
EssentialsHuddleVtc1Room _CurrentRoom; IEssentialsHuddleVtc1Room _CurrentRoom;
/// <summary> /// <summary>
/// For hitting feedbacks /// For hitting feedbacks
@@ -173,10 +173,28 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; } public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; }
private UiDisplayMode _currentMode;
/// <summary> /// <summary>
/// The mode showing. Presentation or call. /// The mode showing. Presentation or call.
/// </summary> /// </summary>
UiDisplayMode CurrentMode = UiDisplayMode.Start; UiDisplayMode CurrentMode
{
get
{
return _currentMode;
}
set
{
if (value != _currentMode)
{
_currentMode = value;
SetActivityFooterFeedbacks();
}
}
}
CTimer NextMeetingTimer; CTimer NextMeetingTimer;
@@ -207,6 +225,7 @@ namespace PepperDash.Essentials
MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5); MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5);
CurrentMode = UiDisplayMode.Start;
// buttons are added in SetCurrentRoom // buttons are added in SetCurrentRoom
//HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]); //HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]);
@@ -607,11 +626,24 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
void SetActivityFooterFeedbacks() void SetActivityFooterFeedbacks()
{ {
CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call if (CurrentRoom != null)
&& CurrentRoom.ShutdownType == eShutdownType.None; {
ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation var startMode = CurrentMode == UiDisplayMode.Start;
&& CurrentRoom.ShutdownType == eShutdownType.None; var presentationMode = CurrentMode == UiDisplayMode.Presentation;
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None; var callMode = CurrentMode == UiDisplayMode.Call;
TriList.SetBool(StartPageVisibleJoin, startMode ? true : false);
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false);
if (!presentationMode)
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
CallButtonSig.BoolValue = callMode
&& CurrentRoom.ShutdownType == eShutdownType.None;
ShareButtonSig.BoolValue = presentationMode
&& CurrentRoom.ShutdownType == eShutdownType.None;
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
}
} }
/// <summary> /// <summary>
@@ -623,14 +655,13 @@ namespace PepperDash.Essentials
return; return;
HideLogo(); HideLogo();
HideNextMeetingPopup(); HideNextMeetingPopup();
TriList.SetBool(StartPageVisibleJoin, false); //TriList.SetBool(StartPageVisibleJoin, false);
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); //TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); //TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
if (CurrentSourcePageManager != null) if (CurrentSourcePageManager != null)
CurrentSourcePageManager.Hide(); CurrentSourcePageManager.Hide();
PowerOnFromCall(); PowerOnFromCall();
CurrentMode = UiDisplayMode.Call; CurrentMode = UiDisplayMode.Call;
SetActivityFooterFeedbacks();
VCDriver.Show(); VCDriver.Show();
} }
@@ -643,29 +674,25 @@ namespace PepperDash.Essentials
if (VCDriver.IsVisible) if (VCDriver.IsVisible)
VCDriver.Hide(); VCDriver.Hide();
HideNextMeetingPopup(); 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 // Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue) if (!CurrentRoom.OnFeedback.BoolValue)
{ {
if (!CurrentRoom.OnFeedback.BoolValue) // If there's no default, show UI elements
{ if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute())
// If there's no default, show UI elements TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
if (!CurrentRoom.RunDefaultPresentRoute()) }
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
}
}
else // room is on show what's active or select a source if nothing is yet active else // room is on show what's active or select a source if nothing is yet active
{ {
if(CurrentRoom.CurrentSourceInfo == null || CurrentRoom.CurrentSourceInfoKey == CurrentRoom.DefaultCodecRouteString) if(CurrentRoom.CurrentSourceInfo == null || (CurrentRoom.VideoCodec != null && CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key))
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
else if (CurrentSourcePageManager != null) else if (CurrentSourcePageManager != null)
{
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
CurrentSourcePageManager.Show(); CurrentSourcePageManager.Show();
}
} }
CurrentMode = UiDisplayMode.Presentation; CurrentMode = UiDisplayMode.Presentation;
SetupSourceList(); SetupSourceList();
SetActivityFooterFeedbacks();
} }
/// <summary> /// <summary>
@@ -707,6 +734,8 @@ namespace PepperDash.Essentials
if (CurrentRoom.CurrentSourceInfo == null) if (CurrentRoom.CurrentSourceInfo == null)
return; return;
CurrentMode = UiDisplayMode.Presentation;
if (CurrentRoom.CurrentSourceInfo.SourceDevice == null) if (CurrentRoom.CurrentSourceInfo.SourceDevice == null)
{ {
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
@@ -743,7 +772,7 @@ namespace PepperDash.Essentials
void UiSelectSource(string key) void UiSelectSource(string key)
{ {
// Run the route and when it calls back, show the source // Run the route and when it calls back, show the source
CurrentRoom.RunRouteAction(key, new Action(() => { })); CurrentRoom.RunRouteAction(key);
} }
/// <summary> /// <summary>
@@ -894,7 +923,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Helper for property setter. Sets the panel to the given room, latching up all functionality /// Helper for property setter. Sets the panel to the given room, latching up all functionality
/// </summary> /// </summary>
void RefreshCurrentRoom(EssentialsHuddleVtc1Room room) void RefreshCurrentRoom(IEssentialsHuddleVtc1Room room)
{ {
if (_CurrentRoom != null) if (_CurrentRoom != null)
@@ -969,7 +998,7 @@ namespace PepperDash.Essentials
} }
} }
void SetCurrentRoom(EssentialsHuddleVtc1Room room) void SetCurrentRoom(IEssentialsHuddleVtc1Room room)
{ {
if (_CurrentRoom == room) return; if (_CurrentRoom == room) return;
// Disconnect current (probably never called) // Disconnect current (probably never called)
@@ -1004,7 +1033,7 @@ namespace PepperDash.Essentials
UpdateMCJoins(_CurrentRoom); UpdateMCJoins(_CurrentRoom);
} }
void UpdateMCJoins(EssentialsHuddleVtc1Room room) void UpdateMCJoins(IEssentialsHuddleVtc1Room room)
{ {
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl); TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl); TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
@@ -1105,6 +1134,30 @@ namespace PepperDash.Essentials
/// <param name="type"></param> /// <param name="type"></param>
void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type) void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type)
{ {
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange");
// Show the Select a source subpage
if (TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue)
{
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange SourceStagingBarVisisble: true");
if (_CurrentRoom.CurrentSourceInfo == null || (_CurrentRoom.VideoCodec != null && _CurrentRoom.CurrentSourceInfo.SourceDevice.Key == _CurrentRoom.VideoCodec.OsdSource.Key))
{
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Showing SelectASourceVisible");
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
}
else
{
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible");
}
}
else
{
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible");
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
}
if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null) if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null)
TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = _CurrentRoom.CurrentSourceInfo.PreferredName; TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = _CurrentRoom.CurrentSourceInfo.PreferredName;
} }
@@ -1202,12 +1255,12 @@ namespace PepperDash.Essentials
var value = _CurrentRoom.OnFeedback.BoolValue; var value = _CurrentRoom.OnFeedback.BoolValue;
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value; TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; //TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value;
if (value) //ON if (value) //ON
{ {
SetupActivityFooterWhenRoomOn(); SetupActivityFooterWhenRoomOn();
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; //TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = true; TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = true;
} }
@@ -1218,9 +1271,8 @@ namespace PepperDash.Essentials
VCDriver.Hide(); VCDriver.Hide();
SetupActivityFooterWhenRoomOff(); SetupActivityFooterWhenRoomOff();
ShowLogo(); ShowLogo();
SetActivityFooterFeedbacks(); //TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false; //TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
// Clear this so that the pesky meeting warning can resurface every minute when off // Clear this so that the pesky meeting warning can resurface every minute when off
LastMeetingDismissedId = null; LastMeetingDismissedId = null;
} }
@@ -1443,7 +1495,7 @@ namespace PepperDash.Essentials
/// </summary> /// </summary>
public interface IAVWithVCDriver : IAVDriver public interface IAVWithVCDriver : IAVDriver
{ {
EssentialsHuddleVtc1Room CurrentRoom { get; } IEssentialsHuddleVtc1Room CurrentRoom { get; }
PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; } PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; }
/// <summary> /// <summary>

View File

@@ -38,7 +38,7 @@ namespace PepperDash.Essentials
/// <summary> /// <summary>
/// Sets feedback for the given room /// Sets feedback for the given room
/// </summary> /// </summary>
public void SetFeedbackForRoom(EssentialsHuddleSpaceRoom room) public void SetFeedbackForRoom(IEssentialsHuddleSpaceRoom room)
{ {
var itemToSet = Items.FirstOrDefault(i => i.Room == room); var itemToSet = Items.FirstOrDefault(i => i.Room == room);
if (itemToSet != null) if (itemToSet != null)
@@ -48,11 +48,11 @@ namespace PepperDash.Essentials
public class SmartObjectRoomsListItem public class SmartObjectRoomsListItem
{ {
public EssentialsHuddleSpaceRoom Room { get; private set; } public IEssentialsHuddleSpaceRoom Room { get; private set; }
SmartObjectRoomsList Parent; SmartObjectRoomsList Parent;
public uint Index { get; private set; } public uint Index { get; private set; }
public SmartObjectRoomsListItem(EssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent, public SmartObjectRoomsListItem(IEssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent,
Action<bool> buttonAction) Action<bool> buttonAction)
{ {
Room = room; Room = room;

View File

@@ -12,5 +12,5 @@ namespace PepperDash.Essentials
///// <summary> ///// <summary>
///// The handler type for a Room's SourceInfoChange ///// The handler type for a Room's SourceInfoChange
///// </summary> ///// </summary>
//public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type); //public delegate void SourceInfoChangeHandler(IEssentialsRoom room, SourceListItem info, ChangeType type);
} }

View File

@@ -83,6 +83,9 @@ namespace PepperDash.Essentials.UIDrivers.VC
StringBuilder SearchStringBuilder = new StringBuilder(); StringBuilder SearchStringBuilder = new StringBuilder();
BoolFeedback SearchStringBackspaceVisibleFeedback; BoolFeedback SearchStringBackspaceVisibleFeedback;
StringFeedback PasswordStringFeedback;
StringBuilder PasswordStringBuilder = new StringBuilder();
ModalDialog IncomingCallModal; ModalDialog IncomingCallModal;
eKeypadMode KeypadMode; eKeypadMode KeypadMode;
@@ -142,7 +145,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible); VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible);
StagingBarsInterlock = new JoinedSigInterlock(triList); StagingBarsInterlock = new JoinedSigInterlock(triList);
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible); if(Codec is IHasCallHistory)
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible);
else
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible);
StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList); StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList);
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
@@ -177,8 +183,22 @@ namespace PepperDash.Essentials.UIDrivers.VC
}); });
SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]); SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]);
SetupDirectoryList(); PasswordStringFeedback = new StringFeedback(() =>
{
if (PasswordStringBuilder.Length > 0)
{
Parent.Keyboard.EnableGoButton();
return PasswordStringBuilder.ToString();
}
else
{
Parent.Keyboard.DisableGoButton();
return "";
}
});
PasswordStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.PasswordPromptPasswordText]);
SetupDirectoryList();
SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0); SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0);
SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]); SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]);
@@ -196,6 +216,12 @@ namespace PepperDash.Essentials.UIDrivers.VC
triList.SetSigHeldAction(UIBoolJoin.VCDirectoryBackspacePress, 500, triList.SetSigHeldAction(UIBoolJoin.VCDirectoryBackspacePress, 500,
StartSearchBackspaceRepeat, StopSearchBackspaceRepeat, SearchKeypadBackspacePress); StartSearchBackspaceRepeat, StopSearchBackspaceRepeat, SearchKeypadBackspacePress);
if (Codec is IPasswordPrompt)
{
SetupPasswordPrompt();
}
} }
catch (Exception e) catch (Exception e)
{ {
@@ -296,6 +322,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
{ {
case eCodecCallStatus.Connected: case eCodecCallStatus.Connected:
// fire at SRL item // fire at SRL item
HidePasswordPrompt();
KeypadMode = eKeypadMode.DTMF; KeypadMode = eKeypadMode.DTMF;
DialStringBuilder.Remove(0, DialStringBuilder.Length); DialStringBuilder.Remove(0, DialStringBuilder.Length);
DialStringFeedback.FireUpdate(); DialStringFeedback.FireUpdate();
@@ -351,10 +378,15 @@ namespace PepperDash.Essentials.UIDrivers.VC
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0); TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0);
uint stageJoin; uint stageJoin;
if (Codec.IsInCall) if (Codec.IsInCall)
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible; stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
else else
stageJoin = UIBoolJoin.VCStagingInactivePopoverVisible; {
if (Codec is IHasCallHistory)
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible;
else
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible;
}
if (IsVisible) if (IsVisible)
StagingBarsInterlock.ShowInterlocked(stageJoin); StagingBarsInterlock.ShowInterlocked(stageJoin);
else else
@@ -513,13 +545,18 @@ namespace PepperDash.Essentials.UIDrivers.VC
var codecOffCameras = Codec as IHasCameraOff; var codecOffCameras = Codec as IHasCameraOff;
var supportsCameraOffMode = Codec.SupportsCameraOff;
var codecAutoCameras = Codec as IHasCameraAutoMode; var codecAutoCameras = Codec as IHasCameraAutoMode;
if (codecAutoCameras != null) var supportsAutoCameraMode = Codec.SupportsCameraAutoMode;
if (codecAutoCameras != null && supportsAutoCameraMode)
{ {
CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn()); CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn());
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true; TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true;
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]); 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( //TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 1 Pressed"].SetSigFalseAction(
//() => codecAutoCameras.CameraAutoModeOn()); //() => codecAutoCameras.CameraAutoModeOn());
@@ -554,7 +591,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction( //TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction(
// () => ShowCameraManualMode()); // () => ShowCameraManualMode());
if (codecOffCameras != null) if (codecOffCameras != null && supportsCameraOffMode)
{ {
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true; TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true;
codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]); codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]);
@@ -769,12 +806,14 @@ namespace PepperDash.Essentials.UIDrivers.VC
if (camerasCodec != null && camerasCodec.SelectedCamera != null) 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 dpad = CameraPtzPad;
var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl; var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl;
if (camera != null) if (camera != null)
{ {
Debug.Console(2, "Selected camera is IHasCameraPtzControl");
if (camerasCodec.SelectedCamera.CanTilt) if (camerasCodec.SelectedCamera.CanTilt)
{ {
dpad.SigUp.SetBoolSigAction((b) => dpad.SigUp.SetBoolSigAction((b) =>
@@ -839,25 +878,46 @@ namespace PepperDash.Essentials.UIDrivers.VC
} }
} }
else
{
Debug.Console(2, "Selected Camera is not IHasCameraPtzControl. No controls to map");
}
}
else
{
Debug.Console(2, "Codec does not have cameras of selected camera is null");
} }
} }
// Determines if codec is in manual camera control mode and shows feedback // Determines if codec is in manual camera control mode and shows feedback
void ShowCameraManualMode() void ShowCameraManualMode()
{ {
Debug.Console(2, "ShowCameraManualMode");
var inManualMode = true; var inManualMode = true;
var codecOffCameras = Codec as IHasCameraOff; var codecOffCameras = Codec as IHasCameraOff;
var codecAutoCameras = Codec as IHasCameraAutoMode; var codecAutoCameras = Codec as IHasCameraAutoMode;
var supportsAutoCameras = codecAutoCameras != null && Codec.SupportsCameraAutoMode;
if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue) if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue)
{ {
inManualMode = false; inManualMode = false;
var codecCameraMute = Codec as IHasCameraMute;
if (codecCameraMute != null)
{
codecCameraMute.CameraMuteOff();
inManualMode = true;
}
} }
// Clear auto mode // Clear auto mode
if (codecAutoCameras != null ) if (supportsAutoCameras)
{ {
if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue) if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue)
{ {
@@ -1005,22 +1065,21 @@ namespace PepperDash.Essentials.UIDrivers.VC
void SetupDirectoryList() void SetupDirectoryList()
{ {
var codec = Codec as IHasDirectory; var codec = Codec as IHasDirectory;
if (codec != null) if (codec == null)
{ {
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList], return;
true, 1300); }
codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
if (codec.PhonebookSyncState.InitialSyncComplete) DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
SetCurrentDirectoryToRoot(); true, 1300);
else codec.DirectoryResultReturned += dir_DirectoryResultReturned;
{
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
}
RefreshDirectory(); if (codec.PhonebookSyncState.InitialSyncComplete)
SetCurrentDirectoryToRoot();
} else
{
codec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
}
} }
/// <summary> /// <summary>
@@ -1028,11 +1087,15 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// </summary> /// </summary>
void SetCurrentDirectoryToRoot() void SetCurrentDirectoryToRoot()
{ {
(Codec as IHasDirectory).SetCurrentDirectoryToRoot(); var hasDirectory = Codec as IHasDirectory;
if (hasDirectory == null)
{
return;
}
hasDirectory.SetCurrentDirectoryToRoot();
SearchKeypadClear(); SearchKeypadClear();
RefreshDirectory();
} }
/// <summary> /// <summary>
@@ -1044,10 +1107,17 @@ namespace PepperDash.Essentials.UIDrivers.VC
{ {
var codec = Codec as IHasDirectory; var codec = Codec as IHasDirectory;
SetCurrentDirectoryToRoot(); if (codec == null)
{
return;
}
RefreshDirectory(); if (!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
{
return;
}
SetCurrentDirectoryToRoot();
} }
/// <summary> /// <summary>
@@ -1057,8 +1127,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// <param name="e"></param> /// <param name="e"></param>
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e) void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{ {
RefreshDirectory(e.Directory);
RefreshDirectory();
} }
/// <summary> /// <summary>
@@ -1087,16 +1156,27 @@ namespace PepperDash.Essentials.UIDrivers.VC
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="dir"></param> void RefreshDirectory()
void RefreshDirectory()
{ {
if ((Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults.Count > 0) var codec = Codec as IHasDirectory;
if (codec == null)
{
return;
}
RefreshDirectory(codec.CurrentDirectoryResult);
}
void RefreshDirectory(CodecDirectory directory)
{
if (directory.CurrentDirectoryResults.Count > 0)
{ {
ushort i = 0; ushort i = 0;
foreach (var r in (Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults) foreach (var r in directory.CurrentDirectoryResults)
{ {
if (i == DirectoryList.MaxCount) if (i == DirectoryList.MaxCount)
{ {
@@ -1116,19 +1196,33 @@ namespace PepperDash.Essentials.UIDrivers.VC
// If more than one contact method, show contact method modal dialog // If more than one contact method, show contact method modal dialog
DirectoryList.SetItemButtonAction(i, b => DirectoryList.SetItemButtonAction(i, b =>
{ {
if (!b) if (b)
{ {
// Refresh the contact methods list return;
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 else
{ {
// If only one contact method, just dial that method Debug.Console(1, "Unable to dial contact. No availble ContactMethod(s) specified");
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
} }
} }
else // is DirectoryFolder else // is DirectoryFolder
@@ -1155,8 +1249,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
DirectoryList.SetItemMainText(1, "No Results Found"); DirectoryList.SetItemMainText(1, "No Results Found");
} }
}
}
void RefreshContactMethodsModalList(DirectoryContact contact) void RefreshContactMethodsModalList(DirectoryContact contact)
{ {
@@ -1201,7 +1294,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
var lc = Codec as IHasCodecLayouts; var lc = Codec as IHasCodecLayouts;
if (lc != null) if (lc != null)
{ {
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]); lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]);
lc.LocalLayoutFeedback.OutputChange += (o,a) => lc.LocalLayoutFeedback.OutputChange += (o,a) =>
{ {
@@ -1214,14 +1307,24 @@ namespace PepperDash.Essentials.UIDrivers.VC
var cisco = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec; var cisco = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec;
if (cisco != null) if (cisco != null)
{ {
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
// Cisco has min/max buttons that need special sauce // Cisco has min/max buttons that need special sauce
cisco.SharingContentIsOnFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges; cisco.SharingContentIsOnFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
//cisco.PresentationViewMaximizedFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges; //cisco.PresentationViewMaximizedFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
TriList.SetSigFalseAction(UIBoolJoin.VCMinMaxPress, cisco.MinMaxLayoutToggle); 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> /// <summary>
@@ -1249,7 +1352,21 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// </summary> /// </summary>
void RevealKeyboard() void RevealKeyboard()
{ {
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial) if (_passwordPromptDialogVisible)
{
Debug.Console(2, "Attaching Keyboard to PasswordPromptDialog");
DetachDialKeyboard();
DetachSearchKeyboard();
var kb = Parent.Keyboard;
kb.KeyPress -= Keyboard_PasswordKeyPress;
kb.KeyPress += Keyboard_PasswordKeyPress;
kb.HideAction = this.DetachPasswordKeyboard;
kb.GoButtonText = "Submit";
kb.GoButtonVisible = true;
PasswordStringCheckEnables();
kb.Show();
}
else if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial)
{ {
var kb = Parent.Keyboard; var kb = Parent.Keyboard;
kb.KeyPress -= Keyboard_DialKeyPress; kb.KeyPress -= Keyboard_DialKeyPress;
@@ -1271,6 +1388,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
SearchStringKeypadCheckEnables(); SearchStringKeypadCheckEnables();
kb.Show(); kb.Show();
} }
} }
/// <summary> /// <summary>
@@ -1326,6 +1444,32 @@ namespace PepperDash.Essentials.UIDrivers.VC
} }
} }
/// <summary>
/// Event handler for keyboard dialing
/// </summary>
void Keyboard_PasswordKeyPress(object sender, PepperDash.Essentials.Core.Touchpanels.Keyboards.KeyboardControllerPressEventArgs e)
{
if (_passwordPromptDialogVisible)
{
if (e.Text != null)
PasswordStringBuilder.Append(e.Text);
else
{
if (e.SpecialKey == KeyboardSpecialKey.Backspace)
PasswordKeypadBackspacePress();
else if (e.SpecialKey == KeyboardSpecialKey.Clear)
PasswordKeypadClear();
else if (e.SpecialKey == KeyboardSpecialKey.GoButton)
{
(Codec as IPasswordPrompt).SubmitPassword(PasswordStringBuilder.ToString());
HidePasswordPrompt();
}
}
PasswordStringFeedback.FireUpdate();
PasswordStringCheckEnables();
}
}
/// <summary> /// <summary>
/// Call /// Call
/// </summary> /// </summary>
@@ -1339,6 +1483,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
Parent.Keyboard.KeyPress -= Keyboard_SearchKeyPress; Parent.Keyboard.KeyPress -= Keyboard_SearchKeyPress;
} }
void DetachPasswordKeyboard()
{
Parent.Keyboard.KeyPress -= Keyboard_PasswordKeyPress;
}
/// <summary> /// <summary>
/// Shows the camera controls subpage /// Shows the camera controls subpage
/// </summary> /// </summary>
@@ -1592,6 +1741,40 @@ namespace PepperDash.Essentials.UIDrivers.VC
Parent.Keyboard.DisableGoButton(); Parent.Keyboard.DisableGoButton();
} }
/// <summary>
/// Clears the Password keypad
/// </summary>
void PasswordKeypadClear()
{
PasswordStringBuilder.Remove(0, SearchStringBuilder.Length);
PasswordStringFeedback.FireUpdate();
PasswordStringCheckEnables();
}
/// <summary>
///
/// </summary>
void PasswordKeypadBackspacePress()
{
PasswordStringBuilder.Remove(PasswordStringBuilder.Length - 1, 1);
PasswordStringFeedback.FireUpdate();
PasswordStringCheckEnables();
}
/// <summary>
/// Checks the enabled states of various elements around the keypad
/// </summary>
void PasswordStringCheckEnables()
{
var textIsEntered = PasswordStringBuilder.Length > 0;
if (textIsEntered)
Parent.Keyboard.EnableGoButton();
else
Parent.Keyboard.DisableGoButton();
}
/// <summary> /// <summary>
/// Returns the text value for the keypad dial entry field /// Returns the text value for the keypad dial entry field
@@ -1637,5 +1820,61 @@ namespace PepperDash.Essentials.UIDrivers.VC
Dial = 0, Dial = 0,
DTMF DTMF
} }
void SetupPasswordPrompt()
{
var passwordPromptCodec = Codec as IPasswordPrompt;
passwordPromptCodec.PasswordRequired += new EventHandler<PasswordPromptEventArgs>(passwordPromptCodec_PasswordRequired);
TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptCancelPress, HidePasswordPrompt);
TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptTextPress, RevealKeyboard);
}
void passwordPromptCodec_PasswordRequired(object sender, PasswordPromptEventArgs e)
{
if (e.LoginAttemptCancelled)
{
HidePasswordPrompt();
return;
}
if (!string.IsNullOrEmpty(e.Message))
{
TriList.SetString(UIStringJoin.PasswordPromptMessageText, e.Message);
}
if (e.LoginAttemptFailed)
{
// TODO: Show a message modal to indicate the login attempt failed
return;
}
TriList.SetBool(UIBoolJoin.PasswordPromptErrorVisible, e.LastAttemptWasIncorrect);
ShowPasswordPrompt();
}
private bool _passwordPromptDialogVisible;
void ShowPasswordPrompt()
{
// Clear out any previous data
PasswordKeypadClear();
_passwordPromptDialogVisible = true;
TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible);
RevealKeyboard();
}
void HidePasswordPrompt()
{
if (_passwordPromptDialogVisible)
{
_passwordPromptDialogVisible = false;
Parent.Keyboard.Hide();
TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible);
}
}
} }
} }

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO
{
public class C2NIoController:CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IRelayPorts
{
private C2nIo _device;
public C2NIoController(string key, Func<DeviceConfig, C2nIo> preActivationFunc, DeviceConfig config):base(key, config.Name)
{
AddPreActivationAction(() =>
{
_device = preActivationFunc(config);
RegisterCrestronGenericBase(_device);
});
}
#region Implementation of IComPorts
public CrestronCollection<ComPort> ComPorts
{
get { return _device.ComPorts; }
}
public int NumberOfComPorts
{
get { return _device.NumberOfComPorts; }
}
#endregion
#region Implementation of IIROutputPorts
public CrestronCollection<IROutputPort> IROutputPorts
{
get { return _device.IROutputPorts; }
}
public int NumberOfIROutputPorts
{
get { return _device.NumberOfIROutputPorts; }
}
#endregion
#region Implementation of IRelayPorts
public CrestronCollection<Relay> RelayPorts
{
get { return _device.RelayPorts; }
}
public int NumberOfRelayPorts
{
get { return _device.NumberOfRelayPorts; }
}
#endregion
}
public class C2NIoControllerFactory : EssentialsDeviceFactory<C2nRthsController>
{
public C2NIoControllerFactory()
{
TypeNames = new List<string>() { "c2nio" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new C2N-IO Device");
return new C2NIoController(dc.Key, GetC2NIoDevice, dc);
}
static C2nIo GetC2NIoDevice(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
var branchId = control.ControlPortNumber;
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nIo", parentKey);
return new C2nIo(cresnetId, Global.ControlSystem);
}
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
if (cresnetBridge != null)
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nIo", parentKey);
return new C2nIo(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
}
}

View File

@@ -13,6 +13,14 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
void LinkSystemMonitorToAppServer(); void LinkSystemMonitorToAppServer();
} }
/// <summary>
/// Describes a MobileSystemController that accepts IEssentialsRoom
/// </summary>
public interface IMobileControl3 : IMobileControl
{
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
}
/// <summary> /// <summary>
/// Describes a MobileControl Room Bridge /// Describes a MobileControl Room Bridge
/// </summary> /// </summary>

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Describes the functionality required to prompt a user to enter a password
/// </summary>
public interface IPasswordPrompt
{
/// <summary>
/// Notifies when a password is required or is entered incorrectly
/// </summary>
event EventHandler<PasswordPromptEventArgs> PasswordRequired;
/// <summary>
/// Submits the password
/// </summary>
/// <param name="password"></param>
void SubmitPassword(string password);
}
public class PasswordPromptEventArgs : EventArgs
{
/// <summary>
/// Indicates if the last submitted password was incorrect
/// </summary>
public bool LastAttemptWasIncorrect { get; private set; }
/// <summary>
/// Indicates that the login attempt has failed
/// </summary>
public bool LoginAttemptFailed { get; private set; }
/// <summary>
/// Indicates that the process was cancelled and the prompt should be dismissed
/// </summary>
public bool LoginAttemptCancelled { get; private set; }
/// <summary>
/// A message to be displayed to the user
/// </summary>
public string Message { get; private set; }
public PasswordPromptEventArgs(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message)
{
LastAttemptWasIncorrect = lastAttemptIncorrect;
LoginAttemptFailed = loginFailed;
LoginAttemptCancelled = loginCancelled;
Message = message;
}
}
}

View File

@@ -77,10 +77,9 @@ namespace PepperDash.Essentials.Core
var mParams = method.GetParameters(); var mParams = method.GetParameters();
var convertedParams = mParams var convertedParams = mParams
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType, .Select((p, i) => ConvertType(action.Params[i], p.ParameterType))
System.Globalization.CultureInfo.InvariantCulture))
.ToArray(); .ToArray();
var ret = method.Invoke(obj, convertedParams); method.Invoke(obj, convertedParams);
CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name, CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name,
action.DeviceKey); action.DeviceKey);
@@ -91,6 +90,23 @@ namespace PepperDash.Essentials.Core
ex.Message);} ex.Message);}
} }
private static object ConvertType(object value, Type conversionType)
{
if (!conversionType.IsEnum)
{
return Convert.ChangeType(value, conversionType, System.Globalization.CultureInfo.InvariantCulture);
}
var stringValue = Convert.ToString(value);
if (String.IsNullOrEmpty(stringValue))
{
throw new InvalidCastException(
String.Format("{0} cannot be converted to a string prior to conversion to enum"));
}
return Enum.Parse(conversionType, stringValue, true);
}
/// <summary> /// <summary>
/// Gets the properties on a device /// Gets the properties on a device
/// </summary> /// </summary>
@@ -275,6 +291,8 @@ namespace PepperDash.Essentials.Core
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj)); //var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
//return JsonConvert.SerializeObject(props, Formatting.Indented); //return JsonConvert.SerializeObject(props, Formatting.Indented);
} }
} }
public class DeviceActionWrapper public class DeviceActionWrapper

View File

@@ -435,7 +435,7 @@ namespace PepperDash.Essentials.Core
var min = Convert.ToUInt32(timeout); var min = Convert.ToUInt32(timeout);
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min); device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min); Debug.Console(0, "Device: '{0}' debug level set to {1} for {2} minutes", deviceKey, debugSetting, min);
} }
catch (Exception e) catch (Exception e)

View File

@@ -1,113 +1,113 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection; using Crestron.SimplSharp.Reflection;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
/// <summary> /// <summary>
/// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class /// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class
/// </summary> /// </summary>
[Description("The base Essentials Device Class")] [Description("The base Essentials Device Class")]
public abstract class EssentialsDevice : Device public abstract class EssentialsDevice : Device
{ {
protected EssentialsDevice(string key) protected EssentialsDevice(string key)
: base(key) : base(key)
{ {
} }
protected EssentialsDevice(string key, string name) protected EssentialsDevice(string key, string name)
: base(key, name) : base(key, name)
{ {
} }
} }
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DescriptionAttribute : Attribute public class DescriptionAttribute : Attribute
{ {
private string _Description; private string _Description;
public DescriptionAttribute(string description) public DescriptionAttribute(string description)
{ {
Debug.Console(2, "Setting Description: {0}", description); Debug.Console(2, "Setting Description: {0}", description);
_Description = description; _Description = description;
} }
public string Description public string Description
{ {
get { return _Description; } get { return _Description; }
} }
} }
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class ConfigSnippetAttribute : Attribute public class ConfigSnippetAttribute : Attribute
{ {
private string _ConfigSnippet; private string _ConfigSnippet;
public ConfigSnippetAttribute(string configSnippet) public ConfigSnippetAttribute(string configSnippet)
{ {
Debug.Console(2, "Setting Config Snippet {0}", configSnippet); Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
_ConfigSnippet = configSnippet; _ConfigSnippet = configSnippet;
} }
public string ConfigSnippet public string ConfigSnippet
{ {
get { return _ConfigSnippet; } get { return _ConfigSnippet; }
} }
} }
/// <summary> /// <summary>
/// Devices the basic needs for a Device Factory /// Devices the basic needs for a Device Factory
/// </summary> /// </summary>
public abstract class EssentialsDeviceFactory<T> : IDeviceFactory where T:EssentialsDevice public abstract class EssentialsDeviceFactory<T> : IDeviceFactory where T:EssentialsDevice
{ {
#region IDeviceFactory Members #region IDeviceFactory Members
/// <summary> /// <summary>
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device /// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
/// </summary> /// </summary>
public List<string> TypeNames { get; protected set; } public List<string> TypeNames { get; protected set; }
/// <summary> /// <summary>
/// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list /// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list
/// </summary> /// </summary>
public void LoadTypeFactories() public void LoadTypeFactories()
{ {
foreach (var typeName in TypeNames) foreach (var typeName in TypeNames)
{ {
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName); Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[]; var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute[0].Description; string description = descriptionAttribute[0].Description;
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[]; var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice); DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
} }
} }
/// <summary> /// <summary>
/// The method that will build the device /// The method that will build the device
/// </summary> /// </summary>
/// <param name="dc">The device config</param> /// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns> /// <returns>An instance of the device</returns>
public abstract EssentialsDevice BuildDevice(DeviceConfig dc); public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
#endregion #endregion
} }
/// <summary> /// <summary>
/// Devices the basic needs for a Device Factory /// Devices the basic needs for a Device Factory
/// </summary> /// </summary>
public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice
{ {
/// <summary> /// <summary>
/// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33") /// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33")
/// </summary> /// </summary>
public string MinimumEssentialsFrameworkVersion { get; protected set; } public string MinimumEssentialsFrameworkVersion { get; protected set; }
} }
} }

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.Devices
{
public interface IReconfigurableDevice
{
event EventHandler<EventArgs> ConfigChanged;
DeviceConfig Config { get; }
void SetConfig(DeviceConfig config);
}
}

View File

@@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Core.Devices
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public abstract class ReconfigurableDevice : EssentialsDevice public abstract class ReconfigurableDevice : EssentialsDevice, IReconfigurableDevice
{ {
public event EventHandler<EventArgs> ConfigChanged; public event EventHandler<EventArgs> ConfigChanged;

View File

@@ -59,6 +59,9 @@ namespace PepperDash.Essentials.Core
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; }); VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted); MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
WarmupTime = 10000;
CooldownTime = 5000;
} }
public override void PowerOn() public override void PowerOn()

View File

@@ -1,90 +1,90 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO; using Crestron.SimplSharpPro.GeneralIO;
using Crestron.SimplSharp.Reflection; using Crestron.SimplSharp.Reflection;
using PepperDash.Core; using PepperDash.Core;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.CrestronIO; using PepperDash.Essentials.Core.CrestronIO;
using PepperDash.Essentials.Core.Touchpanels; using PepperDash.Essentials.Core.Touchpanels;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
public class DeviceFactoryWrapper public class DeviceFactoryWrapper
{ {
public CType CType { get; set; } public CType CType { get; set; }
public string Description { get; set; } public string Description { get; set; }
public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; } public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; }
public DeviceFactoryWrapper() public DeviceFactoryWrapper()
{ {
CType = null; CType = null;
Description = "Not Available"; Description = "Not Available";
} }
} }
public class DeviceFactory public class DeviceFactory
{ {
public DeviceFactory() public DeviceFactory()
{ {
var assy = Assembly.GetExecutingAssembly(); var assy = Assembly.GetExecutingAssembly();
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
if (types != null) if (types != null)
{ {
foreach (var type in types) foreach (var type in types)
{ {
try try
{ {
var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
factory.LoadTypeFactories(); factory.LoadTypeFactories();
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name);
} }
} }
} }
} }
/// <summary> /// <summary>
/// A dictionary of factory methods, keyed by config types, added by plugins. /// A dictionary of factory methods, keyed by config types, added by plugins.
/// These methods are looked up and called by GetDevice in this class. /// These methods are looked up and called by GetDevice in this class.
/// </summary> /// </summary>
static Dictionary<string, DeviceFactoryWrapper> FactoryMethods = static Dictionary<string, DeviceFactoryWrapper> FactoryMethods =
new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase); new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
/// <summary> /// <summary>
/// Adds a plugin factory method /// Adds a plugin factory method
/// </summary> /// </summary>
/// <param name="dc"></param> /// <param name="dc"></param>
/// <returns></returns> /// <returns></returns>
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method) public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
{ {
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
} }
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> 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); Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
if(FactoryMethods.ContainsKey(typeName)) if(FactoryMethods.ContainsKey(typeName))
{ {
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName); Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName);
return; return;
} }
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method }; var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
DeviceFactory.FactoryMethods.Add(typeName, wrapper); DeviceFactory.FactoryMethods.Add(typeName, wrapper);
} }
private static void CheckForSecrets(IEnumerable<JProperty> obj) private static void CheckForSecrets(IEnumerable<JProperty> obj)
@@ -156,44 +156,53 @@ namespace PepperDash.Essentials.Core
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message); Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
Debug.Console(2, "{0}", ex.StackTrace); 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; return null;
} }
} }
/// <summary> /// <summary>
/// Prints the type names and associated metadata from the FactoryMethods collection. /// Prints the type names and associated metadata from the FactoryMethods collection.
/// </summary> /// </summary>
/// <param name="command"></param> /// <param name="command"></param>
public static void GetDeviceFactoryTypes(string filter) public static void GetDeviceFactoryTypes(string filter)
{ {
Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>(); Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>();
if (!string.IsNullOrEmpty(filter)) if (!string.IsNullOrEmpty(filter))
{ {
types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value); types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
} }
else else
{ {
types = FactoryMethods; types = FactoryMethods;
} }
Debug.Console(0, "Device Types:"); Debug.Console(0, "Device Types:");
foreach (var type in types.OrderBy(t => t.Key)) foreach (var type in types.OrderBy(t => t.Key))
{ {
var description = type.Value.Description; var description = type.Value.Description;
var cType = "Not Specified by Plugin"; var cType = "Not Specified by Plugin";
if(type.Value.CType != null) if(type.Value.CType != null)
{ {
cType = type.Value.CType.FullName; cType = type.Value.CType.FullName;
} }
Debug.Console(0, Debug.Console(0,
@"Type: '{0}' @"Type: '{0}'
CType: '{1}' CType: '{1}'
Description: {2}", type.Key, cType, description); Description: {2}", type.Key, cType, description);
} }
} }
} }
} }

View File

@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core
protected bool ComputedValue; protected bool ComputedValue;
public BoolFeedbackLogic() protected BoolFeedbackLogic()
{ {
Output = new BoolFeedback(() => ComputedValue); Output = new BoolFeedback(() => ComputedValue);
} }
@@ -40,21 +40,18 @@ namespace PepperDash.Essentials.Core
public void AddOutputsIn(List<BoolFeedback> outputs) public void AddOutputsIn(List<BoolFeedback> outputs)
{ {
foreach (var o in outputs) foreach (var o in outputs.Where(o => !OutputsIn.Contains(o)))
{ {
// skip existing OutputsIn.Add(o);
if (OutputsIn.Contains(o)) continue; o.OutputChange += AnyInput_OutputChange;
}
OutputsIn.Add(o); Evaluate();
o.OutputChange += AnyInput_OutputChange;
}
Evaluate();
} }
public void RemoveOutputIn(BoolFeedback output) public void RemoveOutputIn(BoolFeedback output)
{ {
// Don't double up outputs // Don't double up outputs
if (OutputsIn.Contains(output)) return; if (!OutputsIn.Contains(output)) return;
OutputsIn.Remove(output); OutputsIn.Remove(output);
output.OutputChange -= AnyInput_OutputChange; output.OutputChange -= AnyInput_OutputChange;
@@ -71,6 +68,12 @@ namespace PepperDash.Essentials.Core
Evaluate(); Evaluate();
} }
public void ClearOutputs()
{
OutputsIn.Clear();
Evaluate();
}
void AnyInput_OutputChange(object sender, EventArgs e) void AnyInput_OutputChange(object sender, EventArgs e)
{ {
Evaluate(); Evaluate();
@@ -85,11 +88,12 @@ namespace PepperDash.Essentials.Core
{ {
var prevValue = ComputedValue; var prevValue = ComputedValue;
var newValue = OutputsIn.All(o => o.BoolValue); var newValue = OutputsIn.All(o => o.BoolValue);
if (newValue != prevValue) if (newValue == prevValue)
{ {
ComputedValue = newValue; return;
Output.FireUpdate(); }
} ComputedValue = newValue;
Output.FireUpdate();
} }
} }
@@ -99,33 +103,35 @@ namespace PepperDash.Essentials.Core
{ {
var prevValue = ComputedValue; var prevValue = ComputedValue;
var newValue = OutputsIn.Any(o => o.BoolValue); var newValue = OutputsIn.Any(o => o.BoolValue);
if (newValue != prevValue) if (newValue == prevValue)
{ {
ComputedValue = newValue; return;
Output.FireUpdate(); }
} ComputedValue = newValue;
Output.FireUpdate();
} }
} }
public class BoolFeedbackLinq : BoolFeedbackLogic public class BoolFeedbackLinq : BoolFeedbackLogic
{ {
Func<IEnumerable<BoolFeedback>, bool> Predicate; readonly Func<IEnumerable<BoolFeedback>, bool> _predicate;
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate) public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
: base() : base()
{ {
Predicate = predicate; _predicate = predicate;
} }
protected override void Evaluate() protected override void Evaluate()
{ {
var prevValue = ComputedValue; var prevValue = ComputedValue;
var newValue = Predicate(OutputsIn); var newValue = _predicate(OutputsIn);
if (newValue != prevValue) if (newValue == prevValue)
{ {
ComputedValue = newValue; return;
Output.FireUpdate(); }
} ComputedValue = newValue;
Output.FireUpdate();
} }
} }
} }

View File

@@ -33,7 +33,7 @@ namespace PepperDash.Essentials.Core.Fusion
protected FusionRoom FusionRoom; protected FusionRoom FusionRoom;
protected Dictionary<int, FusionAsset> FusionStaticAssets; protected Dictionary<int, FusionAsset> FusionStaticAssets;
public long PushNotificationTimeout = 5000; public long PushNotificationTimeout = 5000;
protected EssentialsRoomBase Room; protected IEssentialsRoom Room;
public long SchedulePollInterval = 300000; public long SchedulePollInterval = 300000;
private Event _currentMeeting; private Event _currentMeeting;
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials.Core.Fusion
#endregion #endregion
public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey) public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey)
: base(room.Key + "-fusion") : base(room.Key + "-fusion")
{ {
try try

View File

@@ -82,7 +82,7 @@ namespace PepperDash.Essentials.Core.Fusion
deviceConfig.Properties = JToken.FromObject(devProps); deviceConfig.Properties = JToken.FromObject(devProps);
} }
else if (device is EssentialsRoomBase) else if (device is IEssentialsRoom)
{ {
// Set the room name // Set the room name
if (!string.IsNullOrEmpty(roomInfo.Name)) if (!string.IsNullOrEmpty(roomInfo.Name))

View File

@@ -2,17 +2,18 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
/// <summary> /// <summary>
/// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects /// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects
/// </summary> /// </summary>
public class IOccupancyStatusProviderAggregator : Device, IOccupancyStatusProvider public class IOccupancyStatusProviderAggregator : EssentialsDevice, IOccupancyStatusProvider
{ {
/// <summary> /// <summary>
/// Aggregated feedback of all linked IOccupancyStatusProvider devices /// Aggregated feedback of all linked IOccupancyStatusProvider devices
@@ -21,16 +22,51 @@ namespace PepperDash.Essentials.Core
{ {
get get
{ {
return AggregatedOccupancyStatus.Output; return _aggregatedOccupancyStatus.Output;
} }
} }
private BoolFeedbackOr AggregatedOccupancyStatus; private readonly BoolFeedbackOr _aggregatedOccupancyStatus;
public IOccupancyStatusProviderAggregator(string key, string name) public IOccupancyStatusProviderAggregator(string key, string name)
: base(key, name) : base(key, name)
{ {
AggregatedOccupancyStatus = new BoolFeedbackOr(); _aggregatedOccupancyStatus = new BoolFeedbackOr();
}
public IOccupancyStatusProviderAggregator(string key, string name, OccupancyAggregatorConfig config)
: this(key, name)
{
AddPostActivationAction(() =>
{
if (config.DeviceKeys.Count == 0)
{
return;
}
foreach (var deviceKey in config.DeviceKeys)
{
var device = DeviceManager.GetDeviceForKey(deviceKey);
if (device == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
"Unable to retrieve Occupancy provider with key {0}", deviceKey);
continue;
}
var provider = device as IOccupancyStatusProvider;
if (provider == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
"Device with key {0} does NOT implement IOccupancyStatusProvider. Please check configuration.");
continue;
}
AddOccupancyStatusProvider(provider);
}
});
} }
/// <summary> /// <summary>
@@ -39,7 +75,35 @@ namespace PepperDash.Essentials.Core
/// <param name="statusProvider"></param> /// <param name="statusProvider"></param>
public void AddOccupancyStatusProvider(IOccupancyStatusProvider statusProvider) public void AddOccupancyStatusProvider(IOccupancyStatusProvider statusProvider)
{ {
AggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback); _aggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback);
}
public void RemoveOccupancyStatusProvider(IOccupancyStatusProvider statusProvider)
{
_aggregatedOccupancyStatus.RemoveOutputIn(statusProvider.RoomIsOccupiedFeedback);
}
public void ClearOccupancyStatusProviders()
{
_aggregatedOccupancyStatus.ClearOutputs();
} }
}
public class OccupancyAggregatorFactory : EssentialsDeviceFactory<IOccupancyStatusProviderAggregator>
{
public OccupancyAggregatorFactory()
{
TypeNames = new List<string> { "occupancyAggregator", "occAggregate" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
var config = dc.Properties.ToObject<OccupancyAggregatorConfig>();
return new IOccupancyStatusProviderAggregator(dc.Key, dc.Name, config);
}
} }
} }

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
public class OccupancyAggregatorConfig
{
[JsonProperty("deviceKeys")] public List<string> DeviceKeys { get; set; }
public OccupancyAggregatorConfig()
{
DeviceKeys = new List<string>();
}
}
}

View File

@@ -162,6 +162,7 @@
<Compile Include="Config\Essentials\ConfigWriter.cs" /> <Compile Include="Config\Essentials\ConfigWriter.cs" />
<Compile Include="Config\Essentials\EssentialsConfig.cs" /> <Compile Include="Config\Essentials\EssentialsConfig.cs" />
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" /> <Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
<Compile Include="Crestron IO\C2nIo\C2nIoController.cs" />
<Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" /> <Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" />
<Compile Include="Crestron IO\Cards\C3CardControllerBase.cs" /> <Compile Include="Crestron IO\Cards\C3CardControllerBase.cs" />
<Compile Include="Crestron IO\Cards\C3Com3Controller.cs" /> <Compile Include="Crestron IO\Cards\C3Com3Controller.cs" />
@@ -197,10 +198,12 @@
<Compile Include="Devices\GenericIRController.cs" /> <Compile Include="Devices\GenericIRController.cs" />
<Compile Include="Devices\IDspPreset.cs" /> <Compile Include="Devices\IDspPreset.cs" />
<Compile Include="Devices\IProjectorInterfaces.cs" /> <Compile Include="Devices\IProjectorInterfaces.cs" />
<Compile Include="Devices\IReconfigurableDevice.cs" />
<Compile Include="Devices\PC\InRoomPc.cs" /> <Compile Include="Devices\PC\InRoomPc.cs" />
<Compile Include="Devices\PC\Laptop.cs" /> <Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" /> <Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" /> <Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" />
<Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" /> <Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" />
<Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" /> <Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" />
<Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" /> <Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" />
@@ -232,6 +235,7 @@
<Compile Include="Interfaces\ILogStringsWithLevel.cs" /> <Compile Include="Interfaces\ILogStringsWithLevel.cs" />
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" /> <Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" /> <Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
<Compile Include="Occupancy\OccupancyAggregatorConfig.cs" />
<Compile Include="Queues\ComsMessage.cs" /> <Compile Include="Queues\ComsMessage.cs" />
<Compile Include="Queues\ProcessStringMessage.cs" /> <Compile Include="Queues\ProcessStringMessage.cs" />
<Compile Include="Queues\GenericQueue.cs" /> <Compile Include="Queues\GenericQueue.cs" />
@@ -288,6 +292,7 @@
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" /> <Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
<Compile Include="Room\EssentialsRoomBase.cs" /> <Compile Include="Room\EssentialsRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" /> <Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
<Compile Include="Room\IEssentialsRoom.cs" />
<Compile Include="Room\Interfaces.cs" /> <Compile Include="Room\Interfaces.cs" />
<Compile Include="Room\iOccupancyStatusProvider.cs" /> <Compile Include="Room\iOccupancyStatusProvider.cs" />
<Compile Include="Routing\DummyRoutingInputsDevice.cs" /> <Compile Include="Routing\DummyRoutingInputsDevice.cs" />

View File

@@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Core
ScheduledEventGroup FeatureEventGroup; ScheduledEventGroup FeatureEventGroup;
public EssentialsRoomBase Room { get; private set; } public IEssentialsRoom Room { get; private set; }
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom; private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
@@ -84,7 +84,7 @@ namespace PepperDash.Essentials.Core
/// </summary> /// </summary>
void SetUpDevice() void SetUpDevice()
{ {
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as EssentialsRoomBase; Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as IEssentialsRoom;
if (Room != null) if (Room != null)
{ {

View File

@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public abstract class EssentialsRoomBase : ReconfigurableDevice public abstract class EssentialsRoomBase : ReconfigurableDevice, IEssentialsRoom
{ {
/// <summary> /// <summary>
/// ///

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Describes the basic functionality of an EssentialsRoom
/// </summary>
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute
{
BoolFeedback OnFeedback { get; }
event EventHandler<EventArgs> RoomOccupancyIsSet;
BoolFeedback IsWarmingUpFeedback { get; }
BoolFeedback IsCoolingDownFeedback { get; }
IOccupancyStatusProvider RoomOccupancy { get; }
bool OccupancyStatusProviderIsRemote { get; }
bool IsMobileControlEnabled { get; }
IMobileControlRoomBridge MobileControlRoomBridge { get; }
string SourceListKey { get; }
SecondsCountdownTimer ShutdownPromptTimer { get; }
int ShutdownPromptSeconds { get; }
int ShutdownVacancySeconds { get; }
eShutdownType ShutdownType { get; }
EssentialsRoomEmergencyBase Emergency { get; }
Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; }
string LogoUrlLightBkgnd { get; }
string LogoUrlDarkBkgnd { get; }
eVacancyMode VacancyMode { get; }
bool ZeroVolumeWhenSwtichingVolumeDevices { get; }
void StartShutdown(eShutdownType type);
void StartRoomVacancyTimer(eVacancyMode mode);
void Shutdown();
void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes);
void PowerOnToDefaultOrLastSource();
void SetDefaultLevels();
void RoomVacatedForTimeoutPeriod(object o);
}
}

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
/// <summary> /// <summary>
@@ -64,5 +65,7 @@ namespace PepperDash.Essentials.Core
{ {
bool RunDefaultCallRoute(); bool RunDefaultCallRoute();
} }
} }

View File

@@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// <summary> /// <summary>
/// For rooms that have audio codec /// For rooms that have audio codec
/// </summary> /// </summary>
public interface IHasAudioCodec public interface IHasAudioCodec:IHasInCallFeedback
{ {
AudioCodecBase AudioCodec { get; } AudioCodecBase AudioCodec { get; }
BoolFeedback InCallFeedback { get; }
///// <summary> ///// <summary>
///// Make this more specific ///// Make this more specific

View File

@@ -69,6 +69,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec
[JsonProperty("directoryResults")] [JsonProperty("directoryResults")]
public List<DirectoryItem> CurrentDirectoryResults { get; private set; } 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> /// <summary>
/// Used to store the ID of the current folder for CurrentDirectoryResults /// Used to store the ID of the current folder for CurrentDirectoryResults
/// </summary> /// </summary>
@@ -104,6 +120,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
SortDirectory(); 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> /// <summary>
/// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically /// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically
/// </summary> /// </summary>

View File

@@ -4,15 +4,20 @@ using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec namespace PepperDash.Essentials.Devices.Common.Codec
{ {
[Flags]
public enum eMeetingEventChangeType public enum eMeetingEventChangeType
{ {
Unkown = 0, Unknown = 0,
MeetingStartWarning, MeetingStartWarning = 1,
MeetingStart, MeetingStart = 2,
MeetingEndWarning, MeetingEndWarning = 4,
MeetingEnd MeetingEnd = 8
} }
public interface IHasScheduleAwareness public interface IHasScheduleAwareness
@@ -32,6 +37,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
private int _meetingWarningMinutes = 5; private int _meetingWarningMinutes = 5;
private Meeting _previousChangedMeeting;
private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
public int MeetingWarningMinutes public int MeetingWarningMinutes
{ {
get { return _meetingWarningMinutes; } get { return _meetingWarningMinutes; }
@@ -75,38 +84,72 @@ namespace PepperDash.Essentials.Devices.Common.Codec
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime); _scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
} }
/// <summary>
/// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting
/// </summary>
/// <param name="changeType"></param>
/// <param name="meeting"></param>
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting) private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
{ {
var handler = MeetingEventChange; Debug.Console(2, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
if (handler != null) if (changeType != (changeType & meeting.NotifiedChangeTypes))
{ {
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting }); // Add this change type to the NotifiedChangeTypes
meeting.NotifiedChangeTypes |= changeType;
var handler = MeetingEventChange;
if (handler != null)
{
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
}
}
else
{
Debug.Console(2, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
} }
} }
/// <summary>
/// Checks the schedule to see if any MeetingEventChange updates should be fired
/// </summary>
/// <param name="o"></param>
private void CheckSchedule(object o) private void CheckSchedule(object o)
{ {
// Iterate the meeting list and check if any meeting need to do anythingk // Iterate the meeting list and check if any meeting need to do anything
const double meetingTimeEpsilon = 0.0001; const double meetingTimeEpsilon = 0.05;
foreach (var m in Meetings) foreach (var m in Meetings)
{ {
var changeType = eMeetingEventChangeType.Unkown; var changeType = eMeetingEventChangeType.Unknown;
if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
{
Debug.Console(2, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
changeType = eMeetingEventChangeType.MeetingStartWarning; changeType = eMeetingEventChangeType.MeetingStartWarning;
else if (Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start }
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
{
Debug.Console(2, "********************* MeetingStart");
changeType = eMeetingEventChangeType.MeetingStart; changeType = eMeetingEventChangeType.MeetingStart;
else if (m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to end }
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
{
Debug.Console(2, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
changeType = eMeetingEventChangeType.MeetingEndWarning; changeType = eMeetingEventChangeType.MeetingEndWarning;
else if (Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended }
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
{
Debug.Console(2, "********************* MeetingEnd");
changeType = eMeetingEventChangeType.MeetingEnd; changeType = eMeetingEventChangeType.MeetingEnd;
}
if (changeType != eMeetingEventChangeType.Unkown) if (changeType != eMeetingEventChangeType.Unknown)
OnMeetingChange(changeType, m); {
OnMeetingChange(changeType, m);
}
} }
} }
} }
@@ -115,17 +158,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary> /// </summary>
public class Meeting public class Meeting
{ {
[JsonProperty("minutesBeforeMeeting")]
public int MinutesBeforeMeeting; public int MinutesBeforeMeeting;
[JsonProperty("id")]
public string Id { get; set; } public string Id { get; set; }
[JsonProperty("organizer")]
public string Organizer { get; set; } public string Organizer { get; set; }
[JsonProperty("title")]
public string Title { get; set; } public string Title { get; set; }
[JsonProperty("agenda")]
public string Agenda { get; set; } public string Agenda { get; set; }
[JsonProperty("meetingWarningMinutes")]
public TimeSpan MeetingWarningMinutes public TimeSpan MeetingWarningMinutes
{ {
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); } get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
} }
[JsonProperty("timeToMeetingStart")]
public TimeSpan TimeToMeetingStart public TimeSpan TimeToMeetingStart
{ {
get get
@@ -133,6 +183,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
return StartTime - DateTime.Now; return StartTime - DateTime.Now;
} }
} }
[JsonProperty("timeToMeetingEnd")]
public TimeSpan TimeToMeetingEnd public TimeSpan TimeToMeetingEnd
{ {
get get
@@ -140,8 +191,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec
return EndTime - DateTime.Now; return EndTime - DateTime.Now;
} }
} }
[JsonProperty("startTime")]
public DateTime StartTime { get; set; } public DateTime StartTime { get; set; }
[JsonProperty("endTime")]
public DateTime EndTime { get; set; } public DateTime EndTime { get; set; }
[JsonProperty("duration")]
public TimeSpan Duration public TimeSpan Duration
{ {
get get
@@ -149,21 +203,34 @@ namespace PepperDash.Essentials.Devices.Common.Codec
return EndTime - StartTime; return EndTime - StartTime;
} }
} }
[JsonProperty("privacy")]
public eMeetingPrivacy Privacy { get; set; } public eMeetingPrivacy Privacy { get; set; }
[JsonProperty("joinable")]
public bool Joinable public bool Joinable
{ {
get get
{ {
return StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
&& DateTime.Now <= EndTime; //.AddMinutes(-5); && DateTime.Now <= EndTime.AddMinutes(-5);
//Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable);
return joinable;
} }
} }
//public string ConferenceNumberToDial { get; set; } //public string ConferenceNumberToDial { get; set; }
[JsonProperty("conferencePassword")]
public string ConferencePassword { get; set; } public string ConferencePassword { get; set; }
[JsonProperty("isOneButtonToPushMeeting")]
public bool IsOneButtonToPushMeeting { get; set; } public bool IsOneButtonToPushMeeting { get; set; }
[JsonProperty("calls")]
public List<Call> Calls { get; private set; } public List<Call> Calls { get; private set; }
/// <summary>
/// Tracks the change types that have already been notified for
/// </summary>
[JsonIgnore]
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
public Meeting() public Meeting()
{ {
Calls = new List<Call>(); Calls = new List<Call>();

View File

@@ -1,17 +1,17 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Displays namespace PepperDash.Essentials.Devices.Displays
{ {
public interface IInputHdmi1 { void InputHdmi1(); } public interface IInputHdmi1 { void InputHdmi1(); }
public interface IInputHdmi2 { void InputHdmi2(); } public interface IInputHdmi2 { void InputHdmi2(); }
public interface IInputHdmi3 { void InputHdmi3(); } public interface IInputHdmi3 { void InputHdmi3(); }
public interface IInputHdmi4 { void InputHdmi4(); } public interface IInputHdmi4 { void InputHdmi4(); }
public interface IInputDisplayPort1 { void InputDisplayPort1(); } public interface IInputDisplayPort1 { void InputDisplayPort1(); }
public interface IInputDisplayPort2 { void InputDisplayPort2(); } public interface IInputDisplayPort2 { void InputDisplayPort2(); }
public interface IInputVga1 { void InputVga1(); } public interface IInputVga1 { void InputVga1(); }
} }

View File

@@ -314,7 +314,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
FarEndIsSharingContentFeedback = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); FarEndIsSharingContentFeedback = new BoolFeedback(FarEndIsSharingContentFeedbackFunc);
CameraIsOffFeedback = new BoolFeedback(() => CodecStatus.Status.Video.Input.MainVideoMute.BoolValue); CameraIsOffFeedback = new BoolFeedback(() => CodecStatus.Status.Video.Input.MainVideoMute.BoolValue);
CameraIsMutedFeedback = CameraIsOffFeedback; CameraIsMutedFeedback = CameraIsOffFeedback;
SupportsCameraOff = true;
PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized"); PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized");
@@ -417,6 +417,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate;
CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate;
CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.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.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate;
CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus; CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus;
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;

View File

@@ -277,9 +277,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public SoftwareID SoftwareID { get; set; } public SoftwareID SoftwareID { get; set; }
} }
public class Availability public class Availability : ValueProperty
{ {
public string Value { get; set; } string _Value;
public bool BoolValue { get; private set; }
public string Value
{
get
{
return _Value;
}
set
{
// If the incoming value is "Available" it sets the BoolValue true, otherwise sets it false
_Value = value;
BoolValue = value == "Available";
OnValueChanged();
}
}
} }
public class Status2 : ValueProperty public class Status2 : ValueProperty
@@ -311,6 +327,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public SpeakerTrack() public SpeakerTrack()
{ {
Status = new Status2(); Status = new Status2();
Availability = new Availability();
} }
} }

View File

@@ -1,100 +1,102 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{ {
/// <summary> /// <summary>
/// Describes a device that has call participants /// Describes a device that has call participants
/// </summary> /// </summary>
public interface IHasParticipants public interface IHasParticipants
{ {
CodecParticipants Participants { get; } CodecParticipants Participants { get; }
} }
/// <summary> /// <summary>
/// Describes the ability to mute and unmute a participant's video in a meeting /// Describes the ability to mute and unmute a participant's video in a meeting
/// </summary> /// </summary>
public interface IHasParticipantVideoMute:IHasParticipants public interface IHasParticipantVideoMute : IHasParticipants
{ {
void MuteVideoForParticipant(int userId); void MuteVideoForParticipant(int userId);
void UnmuteVideoForParticipant(int userId); void UnmuteVideoForParticipant(int userId);
void ToggleVideoForParticipant(int userId); void ToggleVideoForParticipant(int userId);
} }
/// <summary> /// <summary>
/// Describes the ability to mute and unmute a participant's audio in a meeting /// Describes the ability to mute and unmute a participant's audio in a meeting
/// </summary> /// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{ {
void MuteAudioForParticipant(int userId); void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId); void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId); void ToggleAudioForParticipant(int userId);
} }
/// <summary> /// <summary>
/// Describes the ability to pin and unpin a participant in a meeting /// Describes the ability to pin and unpin a participant in a meeting
/// </summary> /// </summary>
public interface IHasParticipantPinUnpin : IHasParticipants public interface IHasParticipantPinUnpin : IHasParticipants
{ {
IntFeedback NumberOfScreensFeedback { get; } IntFeedback NumberOfScreensFeedback { get; }
int ScreenIndexToPinUserTo { get; } int ScreenIndexToPinUserTo { get; }
void PinParticipant(int userId, int screenIndex); void PinParticipant(int userId, int screenIndex);
void UnPinParticipant(int userId); void UnPinParticipant(int userId);
void ToggleParticipantPinState(int userId, int screenIndex); void ToggleParticipantPinState(int userId, int screenIndex);
} }
public class CodecParticipants public class CodecParticipants
{ {
private List<Participant> _currentParticipants; private List<Participant> _currentParticipants;
public List<Participant> CurrentParticipants {
get { return _currentParticipants; }
set
{
_currentParticipants = value;
OnParticipantsChanged();
}
}
public event EventHandler<EventArgs> ParticipantsListHasChanged; public List<Participant> CurrentParticipants
{
get { return _currentParticipants; }
set
{
_currentParticipants = value;
OnParticipantsChanged();
}
}
public CodecParticipants() public event EventHandler<EventArgs> ParticipantsListHasChanged;
{
_currentParticipants = new List<Participant>();
}
public void OnParticipantsChanged() public CodecParticipants()
{ {
var handler = ParticipantsListHasChanged; _currentParticipants = new List<Participant>();
}
if (handler == null) return; public void OnParticipantsChanged()
{
var handler = ParticipantsListHasChanged;
handler(this, new EventArgs()); if (handler == null) return;
}
}
/// <summary> handler(this, new EventArgs());
/// 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() /// <summary>
{ /// Represents a call participant
// Initialize to -1 (no screen) /// </summary>
ScreenIndexIsPinnedToFb = -1; 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;
}
}
} }

View File

@@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// <summary> /// <summary>
/// For rooms that have video codec /// For rooms that have video codec
/// </summary> /// </summary>
public interface IHasVideoCodec public interface IHasVideoCodec:IHasInCallFeedback,IPrivacy
{ {
VideoCodecBase VideoCodec { get; } VideoCodecBase VideoCodec { get; }
BoolFeedback InCallFeedback { get; }
///// <summary> ///// <summary>
///// Make this more specific ///// Make this more specific
@@ -26,11 +25,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary> /// </summary>
IntFeedback CallTypeFeedback { get; } IntFeedback CallTypeFeedback { get; }
/// <summary>
///
/// </summary>
BoolFeedback PrivacyModeIsOnFeedback { get; }
/// <summary> /// <summary>
/// When something in the room is sharing with the far end or through other means /// When something in the room is sharing with the far end or through other means
/// </summary> /// </summary>

View File

@@ -139,7 +139,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public override void Dial(Meeting meeting) public override void Dial(Meeting meeting)
{ {
throw new NotImplementedException(); Debug.Console(1, this, "Dial Meeting: {0}", meeting.Id);
var call = new CodecActiveCallItem() { Name = meeting.Title, Number = meeting.Id, Id = meeting.Id, Status = eCodecCallStatus.Dialing, Direction = eCodecCallDirection.Outgoing, Type = eCodecCallType.Video };
ActiveCalls.Add(call);
OnCallStatusChange(call);
//ActiveCallCountFeedback.FireUpdate();
// Simulate 2-second ring, then connecting, then connected
new CTimer(o =>
{
call.Type = eCodecCallType.Video;
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call);
new CTimer(oo => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000);
}, 2000);
} }
/// <summary> /// <summary>
@@ -396,12 +409,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0 if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0
|| _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now) || _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now)
{ {
_CodecSchedule = new CodecScheduleAwareness(); _CodecSchedule = new CodecScheduleAwareness(1000);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
var m = new Meeting(); var m = new Meeting();
m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i); m.MinutesBeforeMeeting = 5;
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30); m.Id = i.ToString();
m.Organizer = "Employee " + 1;
m.StartTime = DateTime.Now.AddMinutes(6).AddHours(i);
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(16);
m.Title = "Meeting " + i; m.Title = "Meeting " + i;
m.Calls.Add(new Call() { Number = i + "meeting@fake.com"}); m.Calls.Add(new Call() { Number = i + "meeting@fake.com"});
_CodecSchedule.Meetings.Add(m); _CodecSchedule.Meetings.Add(m);

View File

@@ -65,8 +65,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public bool ShowSelfViewByDefault { get; protected set; } public bool ShowSelfViewByDefault { get; protected set; }
protected bool SupportsCameraOff; public bool SupportsCameraOff { get; protected set; }
protected bool SupportsCameraAutoMode; public bool SupportsCameraAutoMode { get; protected set; }
public bool IsReady { get; protected set; } public bool IsReady { get; protected set; }

View File

@@ -276,6 +276,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
if (zoomRooms.Count > 0) if (zoomRooms.Count > 0)
{ {
// If so, setup a rooms and contacts folder and add them. // If so, setup a rooms and contacts folder and add them.
directory.ResultsFolderId = "root";
roomFolder.Name = "Rooms"; roomFolder.Name = "Rooms";
roomFolder.ParentFolderId = "root"; roomFolder.ParentFolderId = "root";
roomFolder.FolderId = "rooms"; roomFolder.FolderId = "rooms";
@@ -292,22 +295,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
try try
{ {
if (zoomContacts.Count == 0) return directory; if (zoomContacts.Count == 0)
{
return directory;
}
foreach (Contact c in zoomContacts)
{ {
foreach (Contact c in zoomContacts) var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
contact.ContactMethods.Add(new ContactMethod() { Number = c.Jid, Device = eContactMethodDevice.Video, CallType = eContactMethodCallType.Video, ContactMethodId = c.Jid });
if (folders.Count > 0)
{ {
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid }; contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
if (folders.Count > 0)
{
contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
}
contacts.Add(contact);
} }
directory.AddContactsToDirectory(contacts); contacts.Add(contact);
} }
directory.AddContactsToDirectory(contacts);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -920,6 +927,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
PhoneCallStatus_InCall, PhoneCallStatus_InCall,
PhoneCallStatus_Init, PhoneCallStatus_Init,
} }
public class MeetingNeedsPassword
{
[JsonProperty("needsPassword")]
public bool NeedsPassword { get; set; }
[JsonProperty("wrongAndRetry")]
public bool WrongAndRetry { get; set; }
}
} }
/// <summary> /// <summary>
@@ -1161,11 +1177,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
} }
set set
{ {
if (value != _hideConfSelfVideo) //if (value != _hideConfSelfVideo)
{ //{
_hideConfSelfVideo = value; _hideConfSelfVideo = value;
NotifyPropertyChanged("HideConfSelfVideo"); NotifyPropertyChanged("HideConfSelfVideo");
} //}
} }
} }

View File

@@ -63,6 +63,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
: base(key, name) : base(key, name)
{ {
ParentCodec = codec; ParentCodec = codec;
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom;
} }
/// <summary> /// <summary>