Compare commits

..

100 Commits

Author SHA1 Message Date
Jason DeVito
3de2ba03c1 feat: Added configuration for US and PIR sensitivity values from configuration. Add public method to set identity mode on/off for debugging and identifying remotely. 2021-10-29 17:05:36 -05:00
Jason DeVito
6fcb47e0ef feat: Add configuraiton values for setting ultrasonic (US) and PIR sensor sensitivity from configuration. 2021-10-25 13:09:42 -05:00
Andrew Welker
3a162ee9dd Merge pull request #847 from PepperDash/hotfix/zoom-meetings-simpl
Hotfix/zoom meetings simpl
2021-10-07 13:44:56 -06:00
Neil Dorin
033f6e12f1 Merge branch 'development' into hotfix/zoom-meetings-simpl 2021-10-07 12:49:01 -06:00
Neil Dorin
493b391d6f Merge pull request #843 from PepperDash/feature/dm-endpoint-registration-testing
fix(essentials): #842 Adds back in code to register Crestron devices …
2021-09-29 16:21:03 -06:00
Neil Dorin
805022631b Merge branch 'development' into feature/dm-endpoint-registration-testing 2021-09-29 15:17:56 -06:00
Neil Dorin
5442a1db48 fix(essentials): #842 Adds back in code to register Crestron devices under normal circumstances 2021-09-29 15:14:07 -06:00
Neil Dorin
61be312826 Merge pull request #841 from PepperDash/hotfix/PD-Core-update-initialize
Hotfix/pd core update initialize
2021-09-28 13:22:10 -06:00
Neil Dorin
fb624ef20c Merge branch 'development' into hotfix/PD-Core-update-initialize 2021-09-28 13:11:13 -06:00
Andrew Welker
e855359f61 Merge pull request #839 from PepperDash/feature/merge-fork
Feature/merge fork
2021-09-27 13:49:18 -06:00
Neil Dorin
5f50f14a71 feat(essentials): Updates timeout to 30s 2021-09-24 17:26:13 -06:00
Neil Dorin
1e9139f38e feat(essentials): Reworks logic in InitializeSystem() to be a bit cleaner using a CEvent and the existing AllDeviceActivated event 2021-09-24 17:25:14 -06:00
Neil Dorin
c521a1d551 Merge pull request #825 from UMD-AV/feature/dmps-endpoint-fixes
Feature/dmps endpoint fixes
2021-09-24 16:57:26 -06:00
Andrew Welker
d22c1bf344 Merge pull request #837 from PepperDash/feature/add-entering-standby-state-for-cisco
feat(essentails): #830 Adds EnteringStandbyModeFeedback to IHasHalfWakeMode
2021-09-24 15:38:51 -06:00
Neil Dorin
fd232beae1 feat(essentails): #830 Adds EnteringStandbyModeFeedback to IHasHalfWakeMode 2021-09-24 15:26:45 -06:00
Alex Johnson
35edbeacfc Fix join map details for DMPS 2021-09-23 16:01:07 -04:00
Alex Johnson
b5cabfc644 Merge remote-tracking branch 'PepperDash_Essentials/development' into feature/dmps-endpoint-fixes 2021-09-23 12:01:33 -04:00
Alex Johnson
bead782bd5 Waits to return InitializeSystem until devices are registered. Adds DMPS system power on/off to device bridge. 2021-09-23 12:01:15 -04:00
Neil Dorin
e7915b1e99 Merge pull request #836 from PepperDash/feature/add-cisco-features
Feature/add cisco features
2021-09-22 17:17:58 -06:00
Neil Dorin
23600d8bc9 Merge branch 'development' into feature/add-cisco-features 2021-09-22 16:55:42 -06:00
Neil Dorin
a165ba911f feat(essentials): Minor updates after testing against codec hardware 2021-09-22 15:31:13 -06:00
Neil Dorin
16db2663a6 feat(essentials): #835 comments out some debug messages to clean up console at startup 2021-09-22 11:56:06 -06:00
Neil Dorin
8d1f187643 feat(essentials): #830 Adds new Cisco features
Adds IHasDoNotDisturbMode, IHasStandbyMode and IHasHalfWakeMode interfaces.
Implements all interfaces on CiscoSparkCodec class.
Adds CiscoCodecJoinMap to allow for bridging new Cisco specific functions.
2021-09-21 17:59:12 -06:00
Andrew Welker
a6741e47e4 Merge pull request #833 from PepperDash/hotfix/hd-md-outputname
Hotfix/hd md outputname
2021-09-21 16:16:32 -06:00
Andrew Welker
5a81ce9137 Merge branch 'development' into hotfix/hd-md-outputname 2021-09-21 15:47:31 -06:00
Neil Dorin
149c1dd22d Merge pull request #832 from PepperDash/hotfix/dm-resolution-issues
Hotfix/dm resolution issues
2021-09-21 11:57:49 -06:00
Neil Dorin
79f9d09558 Merge branch 'development' into hotfix/dm-resolution-issues 2021-09-21 10:32:54 -06:00
Neil Dorin
c7d9789ffb Merge pull request #823 from PepperDash/hotfix/ci-newtonsoft-issues
Hotfix/ci newtonsoft issues
2021-09-20 14:38:40 -06:00
Neil Dorin
9c4c1d99b8 Merge branch 'development' into hotfix/ci-newtonsoft-issues 2021-09-20 14:24:27 -06:00
Neil Dorin
d06c73e994 Merge pull request #828 from PepperDash/hotfix/zoom-updates
Hotfix/zoom updates
2021-09-20 13:43:12 -06:00
Neil Dorin
54697e0eaf Merge branch 'development' into hotfix/zoom-updates 2021-09-20 13:26:47 -06:00
Alex Johnson
3d543dfd09 Fixes odd error where dm event comes in with input xx name even though input xx doesn't exist on the dmps 2021-09-17 15:05:59 -04:00
Alex Johnson
9c22c4cb5f Fixes adding a DM-TX to a DMPS system 2021-09-17 09:47:06 -04:00
Alex Johnson
f0942a3932 Fixes for DM endpoints on DMPS3 non-4k types 2021-09-17 09:46:20 -04:00
Andrew Welker
c0cdb09544 Merge pull request #817 from PepperDash/hotfix/glspartcn-enable-feedback
Hotfix/glspartcn enable feedback
2021-09-07 09:11:59 -06:00
Andrew Welker
8c2c58d756 Merge branch 'development' into hotfix/glspartcn-enable-feedback 2021-09-02 08:39:13 -06:00
Andrew Welker
44e5753138 Merge pull request #810 from PepperDash/hotfix/mockvc-fixes
Hotfix/mockvc fixes
2021-09-02 08:38:58 -06:00
Andrew Welker
c71805cfc4 Merge branch 'development' into hotfix/glspartcn-enable-feedback 2021-09-02 07:42:52 -06:00
Andrew Welker
5d177104d8 Merge branch 'development' into hotfix/mockvc-fixes 2021-09-02 07:42:42 -06:00
Andrew Welker
d6878df267 Merge pull request #814 from PepperDash/hotfix/zoom-meetnow-updates
Hotfix/zoom meetnow updates
2021-08-31 20:02:44 -06:00
Andrew Welker
a379641595 Merge branch 'development' into hotfix/zoom-meetnow-updates 2021-08-31 19:00:26 -06:00
Andrew Welker
50aafb088e Merge branch 'development' into hotfix/mockvc-fixes 2021-08-27 10:11:47 -06:00
Andrew Welker
b853e8ed37 Merge pull request #808 from PepperDash/hotfix/4series-cultureinfo-for-time-formats-and-dm-4kz-fix
Hotfix/4series cultureinfo for time formats and dm 4kz fix
2021-08-26 18:15:18 -06:00
Andrew Welker
60c2d4df01 Merge branch 'development' into hotfix/4series-cultureinfo-for-time-formats-and-dm-4kz-fix 2021-08-26 17:59:32 -06:00
Andrew Welker
55766b21ba Merge pull request #799 from PepperDash/hotfix/room-method-updates
Hotfix/room method updates
2021-08-18 16:17:23 -06:00
Andrew Welker
21bc6a05de Merge branch 'development' into hotfix/room-method-updates 2021-08-18 16:05:46 -06:00
Andrew Welker
3c352bbd20 Merge pull request #795 from PepperDash/hotfix/sg-ui-issue
Hotfix/sg UI issue
2021-08-17 22:04:56 -06:00
Andrew Welker
8ab3e45d96 Merge branch 'development' into hotfix/sg-ui-issue 2021-08-17 21:49:16 -06:00
Andrew Welker
11e5123fdf Merge pull request #790 from PepperDash/hotfix/zoomroom-duplicate-participant-in-list
Hotfix/zoomroom duplicate participant in list
2021-08-17 21:49:03 -06:00
Andrew Welker
c6d10ba87e Merge branch 'development' into hotfix/zoomroom-duplicate-participant-in-list 2021-08-17 16:52:52 -06:00
Andrew Welker
f3ab364a4d Merge pull request #787 from PepperDash/hotfix/IMobileControl3
Hotfix/i mobile control3
2021-08-16 15:32:30 -06:00
Andrew Welker
538f81c18e Merge branch 'development' into hotfix/IMobileControl3 2021-08-16 15:16:44 -06:00
Neil Dorin
002cc07b52 Merge pull request #784 from PepperDash/hotfix/UI-codec-directory-fixes
Hotfix/UI codec directory fixes
2021-08-16 12:43:28 -06:00
Neil Dorin
16f993852c Merge branch 'development' into hotfix/UI-codec-directory-fixes 2021-08-16 11:52:35 -06:00
Neil Dorin
9ac1d77c2a Merge pull request #777 from PepperDash/feature/visca-presets-fix
Feature/visca presets fix
2021-08-16 11:47:35 -06:00
Neil Dorin
2dd0c53a08 Merge branch 'development' into feature/visca-presets-fix 2021-08-16 11:35:13 -06:00
Andrew Welker
fab1219146 Merge pull request #780 from PepperDash/hotfix/zoomroom-fixes
Hotfix/zoomroom fixes
2021-08-16 11:22:48 -06:00
Andrew Welker
60d0f50cd2 Merge branch 'development' into hotfix/zoomroom-fixes 2021-08-16 08:22:38 -06:00
Louis Iacovelli
c26d7d73f8 Removed commented line. 2021-08-12 15:14:23 -04:00
Andrew Welker
854a0691d3 Merge branch 'development' into feature/visca-presets-fix 2021-08-12 12:12:31 -06:00
Neil Dorin
61c638452b Merge pull request #775 from PepperDash/hotfix/zoom-camera-fixes
Hotfix/zoom camera fixes
2021-08-12 12:06:16 -06:00
Louis Iacovelli
072411e4f6 Added method to set preset for multiple situations 2021-08-12 11:49:59 -04:00
Andrew Welker
7dc9afa119 Merge branch 'development' into hotfix/zoom-camera-fixes 2021-08-11 11:47:48 -06:00
Jason T Alborough
6f0bfedac1 Merge branch 'main' into feature/visca-presets-fix 2021-08-11 13:31:06 -04:00
Jason Alborough
71881addab fix(Devices.Common.Cameras.CameraVisca): add and fire the event OnPresetsListHasChanged() after LinkToApi so that the camera presets populate to the bridge correctly 2021-08-11 13:00:51 -04:00
Andrew Welker
3aab807631 Merge pull request #770 from PepperDash/bugfix/FixLargeFrameInstantiation
Bugfix/fix large frame instantiation
2021-08-03 12:13:39 -06:00
Andrew Welker
9ec090397f Merge branch 'development' into bugfix/FixLargeFrameInstantiation 2021-08-02 18:10:10 -06:00
Neil Dorin
86916c4357 Merge pull request #772 from PepperDash/hotfix/zoomroom-updates
Hotfix/zoomroom updates
2021-08-02 17:56:11 -06:00
Andrew Welker
40151c5f8f Merge branch 'development' into hotfix/zoomroom-updates 2021-08-02 17:42:53 -06:00
Andrew Welker
4210df693a Merge pull request #766 from PepperDash/release/1.9.2
Release/1.9.2
2021-08-02 17:42:39 -06:00
Andrew Welker
56bb872d2b Merge branch 'development' into hotfix/zoomroom-updates 2021-08-02 17:36:51 -06:00
Trevor Payne
864e0675ea Resolves #769
Fix issues with large dm frame instantiation
2021-08-02 10:34:41 -05:00
Andrew Welker
c306e2c1a1 Merge branch 'development' into release/1.9.2 2021-07-29 14:37:12 -06:00
Andrew Welker
82af1366df Merge pull request #765 from PepperDash/hotfix/add-tsw7xx-types-to-factory
Hotfix/add tsw7xx types to factory
2021-07-28 17:39:54 -06:00
Andrew Welker
56492a00cd Merge branch 'development' into hotfix/add-tsw7xx-types-to-factory 2021-07-28 17:07:13 -06:00
Neil Dorin
28bac18667 Merge pull request #756 from PepperDash/feature/fixes-for-multiple-room
Feature/fixes for multiple room
2021-07-27 12:15:29 -06:00
Andrew Welker
ea254ef983 feat: Update some internal Essentials devices to use Initialize method 2021-07-23 19:56:29 -06:00
Andrew Welker
76e4d4a82d feat: Add method call to constructor for EssentialsDevice 2021-07-23 19:44:41 -06:00
Andrew Welker
4bd777f6b9 feat: Update Essentials Device to call Initialize method 2021-07-23 16:53:36 -06:00
Andrew Welker
f607394ee7 chore: Update PD Core to 1.0.48 2021-07-23 16:53:11 -06:00
Andrew Welker
085a64c87b fix: Correct functioning while in test mode 2021-07-23 13:41:21 -06:00
Andrew Welker
290e887903 refactor: Modify debug messages
Exceptions now print the device key and the error message. To see stack traces, use `appdebug:XX 1`.

There are also now debug messages indicating when the different activation cycles are complete.
2021-07-20 17:32:00 -06:00
Andrew Welker
de7a74eaff feat: Update Fusion to create a GUID file per room
This allows for multiple rooms to be designated and created without any issues. Also moved post Activation action to it's own method rather than a lambda.

In the interest of backwards compatibility, the Fusion class will look for a GUID file with the old file name and migrate it to the new file name.
2021-07-20 17:30:45 -06:00
Andrew Welker
88e5c49663 refactor: Add Fusion IP-ID info to debug messages 2021-07-20 17:29:02 -06:00
Andrew Welker
1415999d86 refactor: Update a debug message with IP-ID info 2021-07-20 17:28:40 -06:00
Andrew Welker
5f6b650dba fix: Update fusion IP-ID for multiple rooms 2021-07-20 11:15:37 -06:00
Andrew Welker
94c0e92f6b fix: Initialize lists for partitions and scenarios
also removed unnecessary else
2021-07-20 08:28:25 -06:00
Neil Dorin
a5046df671 Merge branch 'development' into feature/room-combining 2021-07-19 15:45:56 -06:00
Neil Dorin
5a4f7b6a28 Adds new keyword to intentionally hide properties 2021-07-19 15:44:28 -06:00
Neil Dorin
dfaaa3f6bc #742 Adds factory for EssentialsRoomCombiner 2021-07-19 15:41:10 -06:00
Neil Dorin
377cccf912 Updates type for Partitions on IEssentialsRoomController 2021-07-16 16:10:06 -06:00
Neil Dorin
9795637d75 #742 EssentialsRoomCombiner substantially complete. Adds debounce timer when changing scenarios 2021-07-16 16:09:38 -06:00
Neil Dorin
6f6ca50c37 Removes set from interface 2021-07-16 15:36:59 -06:00
Neil Dorin
7b7ec53355 #742 Updates to room combination interfaces and EssentialsRoomCombiner and EssentialsPartitionController 2021-07-16 15:35:52 -06:00
Neil Dorin
e3920132bf #743 Adds SetValueFunc() to all Feedback types 2021-07-16 14:11:27 -06:00
Neil Dorin
c2e5bd290a #742 Adding EssentialsRoomCombiner device (in progress) 2021-07-15 16:40:25 -06:00
Neil Dorin
7fd52814a0 implements IKeyName as required on config classes 2021-07-15 10:11:27 -06:00
Neil Dorin
06a3dda2e4 Starts on interfaces for room combination 2021-07-14 22:12:41 -06:00
Neil Dorin
d97ca6d5a4 #741 Adds EssentialsRoomCombinerPropertiesConfig 2021-07-14 14:42:13 -06:00
Neil Dorin
4c50d6980f #740 Adds IPartitionStateProvider interface and adds to GlsParitionSensorController 2021-07-14 14:38:18 -06:00
59 changed files with 4988 additions and 4117 deletions

View File

@@ -28,6 +28,7 @@ namespace PepperDash.Essentials
HttpLogoServer LogoServer;
private CTimer _startTimer;
private CEvent _initializeEvent;
private const long StartupTime = 500;
public ControlSystem()
@@ -46,6 +47,24 @@ namespace PepperDash.Essentials
public override void InitializeSystem()
{
_startTimer = new CTimer(StartSystem,StartupTime);
// If the control system is a DMPS type, we need to wait to exit this method until all devices have had time to activate
// to allow any HD-BaseT DM endpoints to register first.
if (Global.ControlSystemIsDmpsType)
{
Debug.Console(2, "******************* InitializeSystem() Entering **********************");
_initializeEvent = new CEvent();
DeviceManager.AllDevicesActivated += (o, a) =>
{
_initializeEvent.Set();
Debug.Console(2, "******************* InitializeSystem() Exiting **********************");
};
_initializeEvent.Wait(30000);
}
}
private void StartSystem(object obj)
@@ -343,7 +362,7 @@ namespace PepperDash.Essentials
{
var prompt = Global.ControlSystem.ControllerPrompt;
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) &&
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) ||
String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase);
if (!typeMatch)
@@ -361,9 +380,7 @@ namespace PepperDash.Essentials
if(propertiesConfig == null)
propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig();
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig);
DeviceManager.AddDevice(dmpsRoutingController);
DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig));
}
else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
{
@@ -450,14 +467,13 @@ namespace PepperDash.Essentials
return;
}
uint fusionIpId = 0xf1;
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
if (room != null)
{
// default IPID
uint fusionIpId = 0xf1;
// default to no join map key
string fusionJoinMapKey = string.Empty;
@@ -478,7 +494,7 @@ namespace PepperDash.Essentials
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
@@ -490,7 +506,7 @@ namespace PepperDash.Essentials
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
@@ -502,7 +518,7 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice,
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
@@ -515,9 +531,13 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(room);
}
fusionIpId += 1;
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
}
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");

View File

@@ -150,7 +150,7 @@ namespace PepperDash.Essentials.Fusion
protected override void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();

View File

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

View File

@@ -147,24 +147,6 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("helpMessage")]
public string HelpMessage { get; set; }
/// <summary>
/// Read this value to get the help message. It checks for the old and new config format.
/// </summary>
public string HelpMessageForDisplay
{
get
{
if(Help != null && !string.IsNullOrEmpty(Help.Message))
{
return Help.Message;
}
else
{
return HelpMessage;
}
}
}
[JsonProperty("environment")]
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }

View File

@@ -202,28 +202,11 @@ namespace PepperDash.Essentials
};
}
SetupEnvironmentalControlDevices();
SetSourceListKey();
EnablePowerOnToLastSource = true;
}
private void SetupEnvironmentalControlDevices()
{
if (PropertiesConfig.Environment != null)
{
if (PropertiesConfig.Environment.Enabled)
{
foreach (var d in PropertiesConfig.Environment.DeviceKeys)
{
var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
EnvironmentalControlDevices.Add(envDevice);
}
}
}
}
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))

View File

@@ -214,25 +214,17 @@ namespace PepperDash.Essentials
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
if (VideoCodec == null)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "No Video Codec set. Please check 'videoCodecKey' property in room config");
throw new ArgumentNullException("VideoCodec cannot be null");
}
throw new ArgumentNullException("codec cannot be null");
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
if (AudioCodec == null)
Debug.Console(0, this, "No Audio Codec Found");
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
if (DefaultAudioDevice == null)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "No Default Audio Device set. Please check 'defaultAudioKey' property in room config");
throw new ArgumentNullException("DefaultAudioDevice cannot be null");
}
InitializeRoom();
}
@@ -334,8 +326,6 @@ namespace PepperDash.Essentials
CallTypeFeedback = new IntFeedback(() => 0);
SetupEnvironmentalControlDevices();
SetSourceListKey();
EnablePowerOnToLastSource = true;
@@ -346,21 +336,6 @@ namespace PepperDash.Essentials
}
}
private void SetupEnvironmentalControlDevices()
{
if (PropertiesConfig.Environment != null)
{
if (PropertiesConfig.Environment.Enabled)
{
foreach (var d in PropertiesConfig.Environment.DeviceKeys)
{
var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
EnvironmentalControlDevices.Add(envDevice);
}
}
}
}
private void SetSourceListKey()
{

View File

@@ -0,0 +1,24 @@
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay
{
bool ExcludeFromGlobalFunctions { get; }
void RunRouteAction(string routeKey);
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
IBasicVolumeControls CurrentVolumeControls { get; }
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
}
}

View File

@@ -0,0 +1,25 @@
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials
{
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
{
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
void RunRouteAction(string routeKey);
IHasScheduleAwareness ScheduleSource { get; }
new BoolFeedback InCallFeedback { get; }
new BoolFeedback PrivacyModeIsOnFeedback { get; }
string DefaultCodecRouteString { get; }
}
}

View File

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

View File

@@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinMetadata
{
Description = "DM Chassis enable audio breakaway routing",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
@@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinMetadata
{
Description = "DM Chassis enable USB breakaway routing",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});

View File

@@ -1,9 +1,17 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced
{
namespace PepperDash.Essentials.Core.Bridges
{
public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced
{
[JoinName("SystemPowerOn")]
public JoinDataComplete SystemPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS System Power On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SystemPowerOff")]
public JoinDataComplete SystemPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS System Power Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("VideoSyncStatus")]
public JoinDataComplete VideoSyncStatus = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
new JoinMetadata { Description = "DM Input Video Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
@@ -61,5 +69,5 @@ namespace PepperDash.Essentials.Core.Bridges
protected DmpsRoutingControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
{
}
}
}
}

View File

@@ -69,19 +69,28 @@ namespace PepperDash.Essentials.Core
public override bool CustomActivate()
{
Debug.Console(0, this, "Activating");
if (!PreventRegistration)
{
if (!PreventRegistration)
{
//Debug.Console(1, this, " Does not require registration. Skipping");
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
IsRegistered.FireUpdate();
}
}
else
{
AddPostActivationAction(() =>
{
var response = Hardware.RegisterWithLogging(Key);
IsRegistered.FireUpdate();
});
}
foreach (var f in Feedbacks)
{

View File

@@ -60,6 +60,7 @@ namespace PepperDash.Essentials.Core
DeviceCriticalSection.Enter();
AddDeviceEnabled = false;
// PreActivate all devices
Debug.Console(0,"****PreActivation starting...****");
foreach (var d in Devices.Values)
{
try
@@ -69,9 +70,12 @@ namespace PepperDash.Essentials.Core
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
Debug.Console(0, d, "ERROR: Device {1} PreActivation failure: {0}", e.Message, d.Key);
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
}
}
Debug.Console(0, "****PreActivation complete****");
Debug.Console(0, "****Activation starting...****");
// Activate all devices
foreach (var d in Devices.Values)
@@ -83,10 +87,14 @@ namespace PepperDash.Essentials.Core
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
Debug.Console(0, d, "ERROR: Device {1} Activation failure: {0}", e.Message, d.Key);
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
}
}
Debug.Console(0, "****Activation complete****");
Debug.Console(0, "****PostActivation starting...****");
// PostActivate all devices
foreach (var d in Devices.Values)
{
@@ -97,10 +105,13 @@ namespace PepperDash.Essentials.Core
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
Debug.Console(0, d, "ERROR: Device {1} PostActivation failure: {0}", e.Message, d.Key);
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
}
}
Debug.Console(0, "****PostActivation complete****");
OnAllDevicesActivated();
}
finally

View File

@@ -57,7 +57,7 @@ namespace PepperDash.Essentials.Core
public DescriptionAttribute(string description)
{
Debug.Console(2, "Setting Description: {0}", description);
//Debug.Console(2, "Setting Description: {0}", description);
_Description = description;
}
@@ -74,7 +74,7 @@ namespace PepperDash.Essentials.Core
public ConfigSnippetAttribute(string configSnippet)
{
Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
//Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
_ConfigSnippet = configSnippet;
}
@@ -103,7 +103,7 @@ namespace PepperDash.Essentials.Core
{
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[];
string description = descriptionAttribute[0].Description;
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];

View File

@@ -69,13 +69,13 @@ namespace PepperDash.Essentials.Core
/// <returns></returns>
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
//Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
}
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
//Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
if(FactoryMethods.ContainsKey(typeName))
{

View File

@@ -62,6 +62,11 @@ namespace PepperDash.Essentials.Core
ValueFunc = valueFunc;
}
public void SetValueFunc(Func<bool> newFunc)
{
ValueFunc = newFunc;
}
public override void FireUpdate()
{
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();

View File

@@ -51,6 +51,12 @@ namespace PepperDash.Essentials.Core
ValueFunc = valueFunc;
}
public void SetValueFunc(Func<int> newFunc)
{
ValueFunc = newFunc;
}
public override void FireUpdate()
{
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();

View File

@@ -52,7 +52,10 @@ namespace PepperDash.Essentials.Core
ValueFunc = valueFunc;
}
public void SetValueFunc(Func<string> newFunc)
{
ValueFunc = newFunc;
}
public override void FireUpdate()
{

View File

@@ -119,9 +119,21 @@ namespace PepperDash.Essentials.Core.Fusion
var slot = Global.ControlSystem.ProgramNumber;
var guidFilePath = Global.FilePathPrefix +
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
_guidFileExists = File.Exists(guidFilePath);
var oldGuidFilePath = Global.FilePathPrefix +
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
if (File.Exists(oldGuidFilePath))
{
Debug.Console(0, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
File.Copy(oldGuidFilePath, guidFilePath);
File.Delete(oldGuidFilePath);
}
_guidFileExists = File.Exists(guidFilePath);
// Check if file exists
if (!_guidFileExists)
@@ -149,19 +161,7 @@ namespace PepperDash.Essentials.Core.Fusion
}
AddPostActivationAction(() =>
{
CreateSymbolAndBasicSigs(_ipId);
SetUpSources();
SetUpCommunitcationMonitors();
SetUpDisplay();
SetUpError();
ExecuteCustomSteps();
FusionRVI.GenerateFileForAllFusionDevices();
GenerateGuidFile(guidFilePath);
});
AddPostActivationAction(() => PostActivate(guidFilePath));
}
catch (Exception e)
{
@@ -169,6 +169,20 @@ namespace PepperDash.Essentials.Core.Fusion
}
}
private void PostActivate(string guidFilePath)
{
CreateSymbolAndBasicSigs(_ipId);
SetUpSources();
SetUpCommunitcationMonitors();
SetUpDisplay();
SetUpError();
ExecuteCustomSteps();
FusionRVI.GenerateFileForAllFusionDevices();
GenerateGuidFile(guidFilePath);
}
protected string RoomGuid
{
get { return _guiDs.RoomGuid; }
@@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Fusion
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();

View File

@@ -32,6 +32,27 @@ namespace PepperDash.Essentials.Core
// TODO: consider making this configurable later
public static IFormatProvider Culture = CultureInfo.CreateSpecificCulture("en-US");
/// <summary>
/// True when the processor type is a DMPS variant
/// </summary>
public static bool ControlSystemIsDmpsType
{
get
{
return ControlSystem.ControllerPrompt.ToLower().IndexOf("dmps") > -1;
}
}
/// <summary>
/// True when the processor type is a DMPS 4K variant
/// </summary>
public static bool ControlSystemIsDmps4kType
{
get
{
return ControlSystemIsDmpsType && ControlSystem.ControllerPrompt.ToLower().IndexOf("4k") > -1;
}
}
/// <summary>
/// The file path prefix to the folder containing configuration files

View File

@@ -1,83 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core.Lighting
{
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
{
#region ILightingScenes Members
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
public List<LightingScene> LightingScenes { get; protected set; }
public LightingScene CurrentLightingScene { get; protected set; }
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
#endregion
protected LightingBase(string key, string name)
: base(key, name)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core.Lighting
{
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
{
#region ILightingScenes Members
public event EventHandler<LightingSceneChangeEventArgs> LightingSceneChange;
public List<LightingScene> LightingScenes { get; protected set; }
public LightingScene CurrentLightingScene { get; protected set; }
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
#endregion
protected LightingBase(string key, string name)
: base(key, name)
{
LightingScenes = new List<LightingScene>();
CurrentLightingScene = new LightingScene();
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
}
public abstract void SelectScene(LightingScene scene);
public void SimulateSceneSelect(string sceneName)
{
Debug.Console(1, this, "Simulating selection of scene '{0}'", sceneName);
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
if (scene != null)
{
CurrentLightingScene = scene;
OnLightingSceneChange();
}
}
/// <summary>
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
/// </summary>
protected void OnLightingSceneChange()
{
foreach (var scene in LightingScenes)
{
if (scene == CurrentLightingScene)
scene.IsActive = true;
else
scene.IsActive = false;
}
var handler = LightingSceneChange;
if (handler != null)
{
handler(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
}
}
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge)
{
LightingScenes = new List<LightingScene>();
CurrentLightingScene = new LightingScene();
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
}
public abstract void SelectScene(LightingScene scene);
public void SimulateSceneSelect(string sceneName)
{
Debug.Console(1, this, "Simulating selection of scene '{0}'", sceneName);
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
if (scene != null)
{
CurrentLightingScene = scene;
OnLightingSceneChange();
}
}
/// <summary>
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
/// </summary>
protected void OnLightingSceneChange()
{
foreach (var scene in LightingScenes)
{
if (scene == CurrentLightingScene)
scene.IsActive = true;
else
scene.IsActive = false;
}
var handler = LightingSceneChange;
if (handler != null)
{
handler(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
}
}
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GenericLightingJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
var joinMap = new GenericLightingJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
if (bridge != null)
@@ -87,52 +87,52 @@ namespace PepperDash.Essentials.Core.Lighting
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
// GenericLighitng Actions & FeedBack
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[sceneIndex]));
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[sceneIndex]));
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)]);
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true;
sceneIndex++;
}
return joinMap;
}
}
public class LightingScene
{
public string Name { get; set; }
public string ID { get; set; }
bool _IsActive;
public bool IsActive
{
get
{
return _IsActive;
}
set
{
_IsActive = value;
IsActiveFeedback.FireUpdate();
}
}
public BoolFeedback IsActiveFeedback { get; set; }
public LightingScene()
{
IsActiveFeedback = new BoolFeedback(new Func<bool>(() => IsActive));
}
}
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true;
sceneIndex++;
}
return joinMap;
}
}
public class LightingScene
{
public string Name { get; set; }
public string ID { get; set; }
bool _IsActive;
public bool IsActive
{
get
{
return _IsActive;
}
set
{
_IsActive = value;
IsActiveFeedback.FireUpdate();
}
}
public BoolFeedback IsActiveFeedback { get; set; }
public LightingScene()
{
IsActiveFeedback = new BoolFeedback(new Func<bool>(() => IsActive));
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Resources;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
@@ -199,6 +200,27 @@ namespace PepperDash.Essentials.Core
{
SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState);
}
// TODO [ ] feature/cenoodtcpoe-sensor-sensitivity-configuration
if (PropertiesConfig.UsSensitivityOccupied != null)
{
SetUsSensitivityOccupied((ushort)PropertiesConfig.UsSensitivityOccupied);
}
if (PropertiesConfig.UsSensitivityVacant != null)
{
SetUsSensitivityVacant((ushort)PropertiesConfig.UsSensitivityVacant);
}
if (PropertiesConfig.PirSensitivityOccupied != null)
{
SetPirSensitivityOccupied((ushort)PropertiesConfig.PirSensitivityOccupied);
}
if (PropertiesConfig.PirSensitivityVacant != null)
{
SetPirSensitivityVacant((ushort)PropertiesConfig.PirSensitivityVacant);
}
}
/// <summary>
@@ -279,7 +301,21 @@ namespace PepperDash.Essentials.Core
}
}
/// <summary>
/// <summary>
/// Sets the identity mode on or off
/// </summary>
/// <param name="state"></param>
public void SetIdentityMode(bool state)
{
if (state)
OccSensor.IdentityModeOn();
else
OccSensor.IdentityModeOff();
Debug.Console(1, this, "Identity Mode: {0}", OccSensor.IdentityModeOnFeedback.BoolValue ? "On" : "Off");
}
/// <summary>
/// Enables or disables the PIR sensor
/// </summary>
/// <param name="state"></param>
@@ -506,6 +542,54 @@ namespace PepperDash.Essentials.Core
}
}
/// <summary>
/// Sets the US sensor sensitivity for occupied state
/// </summary>
/// <param name="sensitivity"></param>
public void SetUsSensitivityOccupied(ushort sensitivity)
{
var level = (eSensitivityLevel) sensitivity;
if (level == 0) return;
OccSensor.UltrasonicSensorSensitivityInOccupiedState = level;
}
/// <summary>
/// Sets the US sensor sensitivity for vacant state
/// </summary>
/// <param name="sensitivity"></param>
public void SetUsSensitivityVacant(ushort sensitivity)
{
var level = (eSensitivityLevel)sensitivity;
if (level == 0) return;
OccSensor.UltrasonicSensorSensitivityInVacantState = level;
}
/// <summary>
/// Sets the PIR sensor sensitivity for occupied state
/// </summary>
/// <param name="sensitivity"></param>
public void SetPirSensitivityOccupied(ushort sensitivity)
{
var level = (eSensitivityLevel)sensitivity;
if (level == 0) return;
OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = level;
}
/// <summary>
/// Sets the PIR sensor sensitivity for vacant state
/// </summary>
/// <param name="sensitivity"></param>
public void SetPirSensitivityVacant(ushort sensitivity)
{
var level = (eSensitivityLevel)sensitivity;
if (level == 0) return;
OccSensor.PassiveInfraredSensorSensitivityInVacantState = level;
}
/// <summary>
/// Method to print current settings to console
/// </summary>
@@ -647,8 +731,7 @@ namespace PepperDash.Essentials.Core
//Sensor Raw States
occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
}
public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<CenOdtOccupancySensorBaseController>

View File

@@ -47,5 +47,35 @@ namespace PepperDash.Essentials.Core
[JsonProperty("andWhenVacatedState")]
public bool? AndWhenVacatedState { get; set; }
// PoE Sensors: CenOdtCPoe
/// <summary>
/// Sets the sensitivity level for US while sensor is in occupied state
/// 1 = low; 2 = medium; 3 = high; 4 = xlow; 5 = 2xlow; 6 = 3xlow
/// </summary>
[JsonProperty("usSensitivityOccupied")]
public ushort? UsSensitivityOccupied { get; set; }
/// <summary>
/// Sets the sensitivity level for US while sensor is in vacant state
/// 1 = low; 2 = medium; 3 = high; 4 = xlow; 5 = 2xlow; 6 = 3xlow
/// </summary>
[JsonProperty("usSensitivityVacant")]
public ushort? UsSensitivityVacant { get; set; }
/// <summary>
/// Sets the sensitivity level for PIR while sensor is in occupied state
/// 1 = low; 2 = medium; 3 = high
/// </summary>
[JsonProperty("pirSensitivityOccupied")]
public ushort? PirSensitivityOccupied { get; set; }
/// <summary>
/// Sets the sensitivity level for PIR while sensor is in vacant state
/// 1 = low; 2 = medium; 3 = high
/// </summary>
[JsonProperty("PirSensitivityVacant")]
public ushort? PirSensitivityVacant { get; set; }
}
}

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Represents an abstract controller device for a partition dividing rooms that are combinable
///
/// In Auto mode, it can use a partition sensor to automatically determine whether the partition is present.
///
/// In Manual mode it accepts user input to tell it whether the partition is present.
/// </summary>
public class EssentialsPartitionController : IPartitionController
{
private IPartitionStateProvider _partitionSensor;
private bool isInAutoMode;
private bool partitionPresent;
public EssentialsPartitionController(string key, string name, IPartitionStateProvider sensor, bool defaultToManualMode, List<string> adjacentRoomKeys)
{
Key = key;
Name = name;
AdjacentRoomKeys = adjacentRoomKeys;
if (sensor != null)
{
_partitionSensor = sensor;
if (!defaultToManualMode)
{
SetAutoMode();
}
else
{
SetManualMode();
}
}
else
{
SetManualMode();
}
PartitionPresentFeedback.FireUpdate();
}
void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
if (isInAutoMode)
{
PartitionPresentFeedback.FireUpdate();
}
}
#region IPartitionController Members
public List<string> AdjacentRoomKeys { get; private set; }
public void SetAutoMode()
{
isInAutoMode = true;
if (PartitionPresentFeedback != null)
{
PartitionPresentFeedback.SetValueFunc(() => _partitionSensor.PartitionPresentFeedback.BoolValue);
}
else
{
PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionPresentFeedback.BoolValue);
}
if (_partitionSensor != null)
{
_partitionSensor.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange;
}
}
public void SetManualMode()
{
isInAutoMode = false;
if (PartitionPresentFeedback != null)
{
PartitionPresentFeedback.SetValueFunc(() => partitionPresent);
}
else
{
PartitionPresentFeedback = new BoolFeedback(() => partitionPresent);
}
if (_partitionSensor != null)
{
_partitionSensor.PartitionPresentFeedback.OutputChange -= PartitionPresentFeedback_OutputChange;
}
}
public void SetPartitionStatePresent()
{
if (!isInAutoMode)
{
partitionPresent = true;
PartitionPresentFeedback.FireUpdate();
}
}
public void SetPartitionStateNotPresent()
{
if (!isInAutoMode)
{
partitionPresent = false;
PartitionPresentFeedback.FireUpdate();
}
}
public void ToggglePartitionState()
{
if (!isInAutoMode)
{
partitionPresent = !partitionPresent;
PartitionPresentFeedback.FireUpdate();
}
}
#endregion
#region IPartitionStateProvider Members
public BoolFeedback PartitionPresentFeedback { get; private set; }
#endregion
#region IKeyName Members
public string Name { get; private set; }
#endregion
#region IKeyed Members
public string Key { get; private set; }
#endregion
}
}

View File

@@ -13,13 +13,13 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for GLS Cresnet Partition Sensor")]
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice, IPartitionStateProvider
{
private GlsPartCn _partitionSensor;
public StringFeedback NameFeedback { get; private set; }
public BoolFeedback EnableFeedback { get; private set; }
public BoolFeedback PartitionSensedFeedback { get; private set; }
public BoolFeedback PartitionPresentFeedback { get; private set; }
public BoolFeedback PartitionNotSensedFeedback { get; private set; }
public IntFeedback SensitivityFeedback { get; private set; }
@@ -39,10 +39,10 @@ namespace PepperDash.Essentials.Core
RegisterCrestronGenericBase(_partitionSensor);
NameFeedback = new StringFeedback(() => Name);
EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue);
PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue);
PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue);
SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue);
EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue);
PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue);
PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue);
SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue);
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
});
@@ -61,7 +61,7 @@ namespace PepperDash.Essentials.Core
}
case (GlsPartCn.PartitionSensedFeedbackEventId):
{
PartitionSensedFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate();
break;
}
case (GlsPartCn.PartitionNotSensedFeedbackEventId):
@@ -93,6 +93,9 @@ namespace PepperDash.Essentials.Core
if (InTestMode)
{
TestEnableFeedback = state;
EnableFeedback.FireUpdate();
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
return;
}
@@ -105,6 +108,10 @@ namespace PepperDash.Essentials.Core
if (InTestMode)
{
TestPartitionSensedFeedback = state;
PartitionPresentFeedback.FireUpdate();
PartitionNotSensedFeedback.FireUpdate();
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
return;
}
@@ -117,6 +124,8 @@ namespace PepperDash.Essentials.Core
if (InTestMode)
{
TestSensitivityFeedback = value;
SensitivityFeedback.FireUpdate();
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
return;
}
@@ -189,7 +198,7 @@ namespace PepperDash.Essentials.Core
// link output to simpl
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]);
PartitionSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
PartitionPresentFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]);
SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]);
@@ -219,7 +228,7 @@ namespace PepperDash.Essentials.Core
IsOnline.FireUpdate();
NameFeedback.FireUpdate();
EnableFeedback.FireUpdate();
PartitionSensedFeedback.FireUpdate();
PartitionPresentFeedback.FireUpdate();
PartitionNotSensedFeedback.FireUpdate();
SensitivityFeedback.FireUpdate();
}
@@ -260,7 +269,7 @@ namespace PepperDash.Essentials.Core
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
Debug.Console(1, "Factory Attempting to create new GlsPartitionSensorController Device");
return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc);
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Describes the functionality of a device that senses and provides partition state
/// </summary>
public interface IPartitionStateProvider : IKeyName
{
BoolFeedback PartitionPresentFeedback { get; }
}
/// <summary>
/// Describes the functionality of a device that can provide partition state either manually via user input or optionally via a sensor state
/// </summary>
public interface IPartitionController : IPartitionStateProvider
{
List<string> AdjacentRoomKeys { get; }
void SetPartitionStatePresent();
void SetPartitionStateNotPresent();
void ToggglePartitionState();
void SetManualMode();
void SetAutoMode();
}
}

View File

@@ -235,6 +235,8 @@
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
<Compile Include="PartitionSensor\EssentialsPartitionController.cs" />
<Compile Include="PartitionSensor\IPartitionStateProvider.cs" />
<Compile Include="Occupancy\OccupancyAggregatorConfig.cs" />
<Compile Include="Queues\ComsMessage.cs" />
<Compile Include="Queues\ProcessStringMessage.cs" />
@@ -290,6 +292,10 @@
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
<Compile Include="Room\Combining\EssentialsRoomCombiner.cs" />
<Compile Include="Room\Combining\EssentialsRoomCombinerPropertiesConfig.cs" />
<Compile Include="Room\Combining\IEssentialsRoomCombiner.cs" />
<Compile Include="Room\Combining\RoomCombinationScenario.cs" />
<Compile Include="Room\EssentialsRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
<Compile Include="Room\IEssentialsRoom.cs" />

View File

@@ -123,7 +123,7 @@ namespace PepperDash.Essentials
/// <param name="fileName"></param>
static LoadedAssembly LoadAssembly(string filePath)
{
Debug.Console(2, "Attempting to load {0}", filePath);
//Debug.Console(2, "Attempting to load {0}", filePath);
var assembly = Assembly.LoadFrom(filePath);
if (assembly != null)
{

View File

@@ -0,0 +1,264 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner
{
private EssentialsRoomCombinerPropertiesConfig _propertiesConfig;
private IRoomCombinationScenario _currentScenario;
private List<IEssentialsRoom> _rooms;
private bool isInAutoMode;
private CTimer _scenarioChangeDebounceTimer;
private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s
public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props)
: base(key)
{
_propertiesConfig = props;
Partitions = new List<IPartitionController>();
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
if (_propertiesConfig.ScenarioChangeDebounceTimeSeconds > 0)
{
_scenarioChangeDebounceTimeSeconds = _propertiesConfig.ScenarioChangeDebounceTimeSeconds;
}
IsInAutoModeFeedback = new BoolFeedback(() => isInAutoMode);
// default to auto mode
isInAutoMode = true;
if (_propertiesConfig.defaultToManualMode)
{
isInAutoMode = false;
}
IsInAutoModeFeedback.FireUpdate();
CreateScenarios();
AddPostActivationAction(() =>
{
SetupPartitionStateProviders();
SetRooms();
});
}
void CreateScenarios()
{
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
foreach (var scenarioConfig in _propertiesConfig.Scenarios)
{
var scenario = new RoomCombinationScenario(scenarioConfig);
RoomCombinationScenarios.Add(scenario);
}
}
void SetRooms()
{
_rooms = new List<IEssentialsRoom>();
foreach (var roomKey in _propertiesConfig.RoomKeys)
{
var room = DeviceManager.GetDeviceForKey(roomKey) as IEssentialsRoom;
if (room != null)
{
_rooms.Add(room);
}
}
}
void SetupPartitionStateProviders()
{
foreach (var pConfig in _propertiesConfig.Partitions)
{
var sensor = DeviceManager.GetDeviceForKey(pConfig.DeviceKey) as IPartitionStateProvider;
var partition = new EssentialsPartitionController(pConfig.Key, pConfig.Name, sensor, _propertiesConfig.defaultToManualMode, pConfig.AdjacentRoomKeys);
partition.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange;
Partitions.Add(partition);
}
}
void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
StartDebounceTimer();
}
void StartDebounceTimer()
{
var time = _scenarioChangeDebounceTimeSeconds * 1000;
if (_scenarioChangeDebounceTimer == null)
{
_scenarioChangeDebounceTimer = new CTimer((o) => DetermineRoomCombinationScenario(), time);
}
else
{
_scenarioChangeDebounceTimer.Reset(time);
}
}
/// <summary>
/// Determines the current room combination scenario based on the state of the partition sensors
/// </summary>
void DetermineRoomCombinationScenario()
{
if (_scenarioChangeDebounceTimer != null)
{
_scenarioChangeDebounceTimer.Dispose();
_scenarioChangeDebounceTimer = null;
}
var currentScenario = RoomCombinationScenarios.FirstOrDefault((s) =>
{
// iterate the partition states
foreach (var partitionState in s.PartitionStates)
{
// get the partition by key
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey));
if (partition != null && partitionState.PartitionPresent != partition.PartitionPresentFeedback.BoolValue)
{
// the partition can't be found or the state doesn't match
return false;
}
}
// if it hasn't returned false by now we have the matching scenario
return true;
});
if (currentScenario != null)
{
CurrentScenario = currentScenario;
}
}
#region IEssentialsRoomCombiner Members
public event EventHandler<EventArgs> RoomCombinationScenarioChanged;
public IRoomCombinationScenario CurrentScenario
{
get
{
return _currentScenario;
}
set
{
if (value != _currentScenario)
{
_currentScenario = value;
Debug.Console(1, this, "Current Scenario: {0}", _currentScenario.Name);
var handler = RoomCombinationScenarioChanged;
if (handler != null)
{
handler(this, new EventArgs());
}
}
}
}
public BoolFeedback IsInAutoModeFeedback { get; private set; }
public void SetAutoMode()
{
isInAutoMode = true;
IsInAutoModeFeedback.FireUpdate();
}
public void SetManualMode()
{
isInAutoMode = false;
IsInAutoModeFeedback.FireUpdate();
}
public void ToggleMode()
{
isInAutoMode = !isInAutoMode;
IsInAutoModeFeedback.FireUpdate();
}
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; private set; }
public List<IPartitionController> Partitions { get; private set; }
public void TogglePartitionState(string partitionKey)
{
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey)) as IPartitionController;
if (partition != null)
{
partition.ToggglePartitionState();
}
}
public void SetRoomCombinationScenario(string scenarioKey)
{
if (isInAutoMode)
{
Debug.Console(0, this, "Cannot set room combination scenario when in auto mode. Set to auto mode first.");
return;
}
// Get the scenario
var scenario = RoomCombinationScenarios.FirstOrDefault((s) => s.Key.Equals(scenarioKey));
// Set the parition states from the scenario manually
if (scenario != null)
{
foreach (var partitionState in scenario.PartitionStates)
{
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey));
if (partition != null)
{
if (partitionState.PartitionPresent)
{
partition.SetPartitionStatePresent();
}
else
{
partition.SetPartitionStateNotPresent();
}
}
}
}
}
#endregion
}
public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory<EssentialsRoomCombiner>
{
public EssentialsRoomCombinerFactory()
{
TypeNames = new List<string> { "essentialsroomcombiner" };
}
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new EssentialsRoomCombiner Device");
var props = dc.Properties.ToObject<EssentialsRoomCombinerPropertiesConfig>();
return new EssentialsRoomCombiner(dc.Key, props);
}
}
}

View File

@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Config properties for an EssentialsRoomCombiner device
/// </summary>
public class EssentialsRoomCombinerPropertiesConfig
{
/// <summary>
/// The list of partitions that device the rooms
/// </summary>
[JsonProperty("partitions")]
public List<PartitionConfig> Partitions {get; set;}
/// <summary>
/// The list of combinations scenarios for the rooms
/// </summary>
[JsonProperty("scenarios")]
public List<RoomCombinationScenarioConfig> Scenarios { get; set; }
/// <summary>
/// The list of rooms keys that can be combined
/// </summary>
[JsonProperty("roomMap")]
public List<string> RoomKeys {get; set;}
/// <summary>
/// Set to true to default to manual mode
/// </summary>
[JsonProperty("defaultToManualMode")]
public bool defaultToManualMode { get; set; }
/// <summary>
/// The key of the scenario to default to at system startup if in manual mode
/// </summary>
[JsonProperty("defaultScenarioKey")]
public string defaultScenarioKey { get; set; }
[JsonProperty("scenarioChangeDebounceTimeSeconds")]
public int ScenarioChangeDebounceTimeSeconds { get; set; }
}
/// <summary>
/// Config properties for a partition that separates rooms
/// </summary>
public class PartitionConfig : IKeyName
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Key of the device that implements IPartitionStateProvider to provide the state of the partition
/// </summary>
[JsonProperty("deviceKey")]
public string DeviceKey { get; set; }
/// <summary>
/// Keys of the rooms that this partion would be located between
/// </summary>
[JsonProperty("adjacentRoomKeys")]
public List<string> AdjacentRoomKeys { get; set; }
}
/// <summary>
/// Config propeties for a room combination scenario
/// </summary>
public class RoomCombinationScenarioConfig : IKeyName
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("partitionStates")]
public List<PartitionState> PartitionStates { get; set; }
[JsonProperty("uiMap")]
public Dictionary<string, string> UiMap { get; set; }
[JsonProperty("activationActions")]
public List<DeviceActionWrapper> ActivationActions { get; set; }
[JsonProperty("deactivationActions")]
public List<DeviceActionWrapper> DeactivationActions { get; set; }
}
/// <summary>
/// Config properties to represent the state of a partition sensor in a RoomCombinationScenario
/// </summary>
public class PartitionState
{
[JsonProperty("partitionKey")]
public string PartitionKey { get; set; }
[JsonProperty("partitionSensedState")]
public bool PartitionPresent { get; set; }
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Describes the functionality for an EssentailsRoomCombiner device
/// </summary>
public interface IEssentialsRoomCombiner : IKeyed
{
/// <summary>
/// Indicates that the room combination scenario has changed
/// </summary>
event EventHandler<EventArgs> RoomCombinationScenarioChanged;
/// <summary>
/// The current room combination scenario
/// </summary>
IRoomCombinationScenario CurrentScenario { get; }
/// <summary>
/// When true, indicates the current mode is auto mode
/// </summary>
BoolFeedback IsInAutoModeFeedback {get;}
/// <summary>
/// Sets auto mode
/// </summary>
void SetAutoMode();
/// <summary>
/// Sets manual mode
/// </summary>
void SetManualMode();
/// <summary>
/// Toggles the current mode between auto and manual
/// </summary>
void ToggleMode();
/// <summary>
/// The available room combinatino scenarios
/// </summary>
List<IRoomCombinationScenario> RoomCombinationScenarios { get; }
/// <summary>
/// The partition
/// </summary>
List<IPartitionController> Partitions { get; }
/// <summary>
/// Toggles the state of a manual partition sensor
/// </summary>
/// <param name="partitionKey"></param>
void TogglePartitionState(string partitionKey);
/// <summary>
/// Sets the room combination scenario (if in manual mode)
/// </summary>
/// <param name="scenarioKey"></param>
void SetRoomCombinationScenario(string scenarioKey);
}
public interface IRoomCombinationScenario : IKeyName
{
/// <summary>
/// When true, indicates that this room combination scenario is active
/// </summary>
BoolFeedback IsActiveFeedback { get; }
/// <summary>
/// Activates this room combination scenario
/// </summary>
void Activate();
/// <summary>
/// The state of the partitions that would activate this scenario
/// </summary>
List<PartitionState> PartitionStates { get; }
/// <summary>
/// The mapping of UIs by key to rooms by key
/// </summary>
Dictionary<string, string> UiMap { get; set; }
}
}

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Represents a room combination scenario
/// </summary>
public class RoomCombinationScenario: IRoomCombinationScenario
{
private RoomCombinationScenarioConfig _config;
public string Key { get; set; }
public string Name { get; set; }
public List<PartitionState> PartitionStates { get; private set; }
public Dictionary<string, string> UiMap { get; set; }
private bool _isActive;
public BoolFeedback IsActiveFeedback { get; private set; }
List<DeviceActionWrapper> activationActions;
List<DeviceActionWrapper> deactivationActions;
public RoomCombinationScenario(RoomCombinationScenarioConfig config)
{
Key = config.Key;
Name = config.Name;
PartitionStates = config.PartitionStates;
UiMap = config.UiMap;
activationActions = config.ActivationActions;
deactivationActions = config.DeactivationActions;
_config = config;
IsActiveFeedback = new BoolFeedback(() => _isActive);
}
public void Activate()
{
if (activationActions != null)
{
foreach (var action in activationActions)
{
DeviceJsonApi.DoDeviceAction(action);
}
}
_isActive = true;
IsActiveFeedback.FireUpdate();
}
public void Deactivate()
{
if (deactivationActions != null)
{
foreach (var action in deactivationActions)
{
DeviceJsonApi.DoDeviceAction(action);
}
}
_isActive = false;
IsActiveFeedback.FireUpdate();
}
}
}

View File

@@ -11,8 +11,6 @@ using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
/// <summary>
@@ -20,8 +18,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
public abstract class EssentialsRoomBase : ReconfigurableDevice, IEssentialsRoom
{
/// <summary>
///
/// </summary>
@@ -39,16 +35,6 @@ namespace PepperDash.Essentials.Core
public bool OccupancyStatusProviderIsRemote { get; private set; }
public List<EssentialsDevice> EnvironmentalControlDevices { get; protected set; }
public bool HasEnvironmentalControlDevices
{
get
{
return EnvironmentalControlDevices != null && EnvironmentalControlDevices.Count > 0;
}
}
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
@@ -133,8 +119,6 @@ namespace PepperDash.Essentials.Core
public EssentialsRoomBase(DeviceConfig config)
: base(config)
{
EnvironmentalControlDevices = new List<EssentialsDevice>();
// Setup the ShutdownPromptTimer
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>

View File

@@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// Describes the basic functionality of an EssentialsRoom
/// </summary>
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute, IEnvironmentalControls
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute
{
BoolFeedback OnFeedback { get; }

View File

@@ -4,8 +4,6 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
@@ -68,14 +66,6 @@ namespace PepperDash.Essentials.Core
bool RunDefaultCallRoute();
}
/// <summary>
/// Describes environmental controls available on a room such as lighting, shades, temperature, etc.
/// </summary>
public interface IEnvironmentalControls
{
List<EssentialsDevice> EnvironmentalControlDevices { get; }
bool HasEnvironmentalControlDevices { get; }
}
}

View File

@@ -31,7 +31,6 @@ namespace PepperDash.Essentials.Core.Shades
public interface IShadesOpenCloseStop : IShadesOpenClose
{
void StopOrPreset();
string StopOrPresetButtonLabel { get; }
}
/// <summary>

View File

@@ -16,7 +16,8 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM {
namespace PepperDash.Essentials.DM
{
/// <summary>
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
///
@@ -75,8 +76,10 @@ namespace PepperDash.Essentials.DM {
/// Factory method to create a new chassis controller from config data. Limited to 8x8 right now
/// </summary>
public static DmBladeChassisController GetDmChassisController(string key, string name,
string type, DMChassisPropertiesConfig properties) {
try {
string type, DMChassisPropertiesConfig properties)
{
try
{
type = type.ToLower();
uint ipid = properties.Control.IpIdInt;
@@ -85,7 +88,8 @@ namespace PepperDash.Essentials.DM {
else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); }
if (chassis == null) {
if (chassis == null)
{
return null;
}
@@ -93,11 +97,13 @@ namespace PepperDash.Essentials.DM {
// add the cards and port names
foreach (var kvp in properties.InputSlots)
controller.AddInputBlade(kvp.Value, kvp.Key);
foreach (var kvp in properties.OutputSlots) {
foreach (var kvp in properties.OutputSlots)
{
controller.AddOutputBlade(kvp.Value, kvp.Key);
}
foreach (var kvp in properties.VolumeControls) {
foreach (var kvp in properties.VolumeControls)
{
// get the card
// check it for an audio-compatible type
// make a something-something that will make it work
@@ -123,7 +129,8 @@ namespace PepperDash.Essentials.DM {
controller.PropertiesConfig = properties;
return controller;
}
catch (System.Exception e) {
catch (System.Exception e)
{
Debug.Console(0, "Error creating DM chassis:\r{0}", e);
}
return null;
@@ -137,7 +144,8 @@ namespace PepperDash.Essentials.DM {
/// <param name="name"></param>
/// <param name="chassis"></param>
public DmBladeChassisController(string key, string name, BladeSwitch chassis)
: base(key, name, chassis) {
: base(key, name, chassis)
{
Chassis = chassis;
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
@@ -161,68 +169,87 @@ namespace PepperDash.Essentials.DM {
InputCardHdcpCapabilityFeedbacks = new Dictionary<uint, IntFeedback>();
InputCardHdcpCapabilityTypes = new Dictionary<uint, eHdcpCapabilityType>();
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) {
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
{
var tempX = x;
if (Chassis.Outputs[tempX] != null) {
VideoOutputFeedbacks[tempX] = new IntFeedback(() => {
if (Chassis.Outputs[tempX] != null)
{
VideoOutputFeedbacks[tempX] = new IntFeedback(() =>
{
if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; }
else { return 0; };
});
OutputNameFeedbacks[tempX] = new StringFeedback(() => {
if (Chassis.Outputs[tempX].NameFeedback != null) {
OutputNameFeedbacks[tempX] = new StringFeedback(() =>
{
if (Chassis.Outputs[tempX].NameFeedback != null)
{
return Chassis.Outputs[tempX].NameFeedback.StringValue;
}
else {
else
{
return "";
}
});
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => {
if (Chassis.Outputs[tempX].VideoOutFeedback != null) {
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() =>
{
if (Chassis.Outputs[tempX].VideoOutFeedback != null)
{
return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue;
}
else {
else
{
return "";
}
});
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
{
//if (Chassis.Outputs[tempX].Endpoint != null)
// return Chassis.Outputs[tempX].Endpoint.IsOnline;
//else
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
});
}
if (Chassis.Inputs[tempX] != null) {
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => {
if (Chassis.Inputs[tempX] != null)
{
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() =>
{
if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; }
else { return 0; };
});
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => {
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() =>
{
if (Chassis.Inputs[tempX].VideoDetectedFeedback != null)
return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue;
else
return false;
});
InputNameFeedbacks[tempX] = new StringFeedback(() => {
if (Chassis.Inputs[tempX].NameFeedback != null) {
InputNameFeedbacks[tempX] = new StringFeedback(() =>
{
if (Chassis.Inputs[tempX].NameFeedback != null)
{
return Chassis.Inputs[tempX].NameFeedback.StringValue;
}
else {
else
{
return "";
}
});
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
{
return Chassis.Inputs[tempX].EndpointOnlineFeedback;
});
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => {
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() =>
{
var inputCard = Chassis.Inputs[tempX];
if (inputCard.Card is DmHdmi4kInputBladeCard) {
if (inputCard.Card is DmHdmi4kInputBladeCard)
{
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue)
@@ -231,7 +258,8 @@ namespace PepperDash.Essentials.DM {
return 0;
}
if (inputCard.Card is DmC4kInputBladeCard) {
if (inputCard.Card is DmC4kInputBladeCard)
{
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff))
@@ -252,45 +280,56 @@ namespace PepperDash.Essentials.DM {
/// </summary>
/// <param name="type"></param>
/// <param name="number"></param>
public void AddInputBlade(string type, uint number) {
public void AddInputBlade(string type, uint number)
{
Debug.Console(2, this, "Adding input blade '{0}', slot {1}", type, number);
type = type.ToLower();
if (type == "dmb4kihd") {
if (type == "dmb4kihd")
{
var inputBlade = new Dmb4kIHd(number, this.Chassis);
foreach (var item in inputBlade.Inputs) {
foreach (var item in inputBlade.Inputs)
{
var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
var cecPort = card as ICec;
AddHdmiInBladePorts(item.Number, cecPort);
}
}
else if (type == "dmb4kihddnt") {
else if (type == "dmb4kihddnt")
{
var inputBlade = new Dmb4kIHd(number, this.Chassis);
foreach (var item in inputBlade.Inputs) {
foreach (var item in inputBlade.Inputs)
{
var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
var cecPort = card as ICec;
AddHdmiInBladePorts(item.Number, cecPort);
}
}
else if (type == "dmb4kic") {
else if (type == "dmb4kic")
{
var inputBlade = new Dmb4kIC(number, this.Chassis);
foreach (var item in inputBlade.Inputs) {
foreach (var item in inputBlade.Inputs)
{
AddDmInBladePorts(item.Number);
}
}
else if (type == "dmbis") {
else if (type == "dmbis")
{
var inputBlade = new DmbIS(number, this.Chassis);
foreach (var item in inputBlade.Inputs) {
foreach (var item in inputBlade.Inputs)
{
AddDmInMmFiberPorts(item.Number);
}
}
else if (type == "dmbis2") {
else if (type == "dmbis2")
{
var inputBlade = new DmbIS2(number, this.Chassis);
foreach (var item in inputBlade.Inputs) {
foreach (var item in inputBlade.Inputs)
{
AddDmInSmFiberPorts(item.Number);
}
}
@@ -307,19 +346,23 @@ namespace PepperDash.Essentials.DM {
}
void AddHdmiInBladePorts(uint number, ICec cecPort) {
void AddHdmiInBladePorts(uint number, ICec cecPort)
{
AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort);
}
void AddDmInBladePorts(uint number) {
void AddDmInBladePorts(uint number)
{
AddInputPortWithDebug(number, "dmCIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat);
}
void AddDmInMmFiberPorts(uint number) {
void AddDmInMmFiberPorts(uint number)
{
AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
}
void AddDmInSmFiberPorts(uint number) {
void AddDmInSmFiberPorts(uint number)
{
AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
}
@@ -328,64 +371,81 @@ namespace PepperDash.Essentials.DM {
/// </summary>
/// <param name="type"></param>
/// <param name="number"></param>
public void AddOutputBlade(string type, uint number) {
public void AddOutputBlade(string type, uint number)
{
type = type.ToLower();
Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number);
if (type == "dmb4kohd") {
if (type == "dmb4kohd")
{
var outputBlade = new Dmb4KOHD(number, Chassis);
foreach (var item in outputBlade.Outputs) {
foreach (var item in outputBlade.Outputs)
{
AddHdmiOutBladePorts(item.Number);
}
}
else if (type == "dmb4kohddnt") {
else if (type == "dmb4kohddnt")
{
var outputBlade = new Dmb4KOHD(number, Chassis);
foreach (var item in outputBlade.Outputs) {
foreach (var item in outputBlade.Outputs)
{
AddHdmiOutBladePorts(item.Number);
}
}
else if (type == "dmb4koc") {
else if (type == "dmb4koc")
{
var outputBlade = new Dmb4KOC(number, Chassis);
foreach (var item in outputBlade.Outputs) {
foreach (var item in outputBlade.Outputs)
{
AddDmOutBladePorts(item.Number);
}
}
else if (type == "dmb4koc") {
else if (type == "dmb4koc")
{
var outputBlade = new Dmb4KOC(number, Chassis);
foreach (var item in outputBlade.Outputs) {
foreach (var item in outputBlade.Outputs)
{
AddDmOutBladePorts(item.Number);
}
}
else if (type == "dmbos") {
else if (type == "dmbos")
{
var outputBlade = new DmbOS(number, Chassis);
foreach (var item in outputBlade.Outputs) {
foreach (var item in outputBlade.Outputs)
{
AddDmOutMmFiberBladePorts(item.Number);
}
}
else if (type == "dmbos2") {
else if (type == "dmbos2")
{
var outputBlade = new DmbOS2(number, Chassis);
foreach (var item in outputBlade.Outputs) {
foreach (var item in outputBlade.Outputs)
{
AddDmOutSmFiberBladePorts(item.Number);
}
}
}
void AddHdmiOutBladePorts(uint number) {
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
void AddHdmiOutBladePorts(uint number)
{
AddOutputPortWithDebug(number, "hdmiOut", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
}
void AddDmOutBladePorts(uint number) {
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
void AddDmOutBladePorts(uint number)
{
AddOutputPortWithDebug(number, "dmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
}
void AddDmOutMmFiberBladePorts(uint number) {
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
void AddDmOutMmFiberBladePorts(uint number)
{
AddOutputPortWithDebug(number, "dmMmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
}
void AddDmOutSmFiberBladePorts(uint number) {
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
void AddDmOutSmFiberBladePorts(uint number)
{
AddOutputPortWithDebug(number, "dmSmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
}
@@ -417,23 +477,44 @@ namespace PepperDash.Essentials.DM {
}
/// <summary>
/// Adds OutputPort
/// </summary>
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
/*void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
var portKey = string.Format("{0}--{1}", cardName, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey);
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
{
FeedbackMatchObject = selector
FeedbackMatchObject = Chassis.Outputs[(uint)selector]
});
}*/
/// <summary>
/// Adds OutputPort
/// </summary>
void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector)
{
try
{
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey);
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this)
{
FeedbackMatchObject = Chassis.Outputs[cardNum]
};
OutputPorts.Add(outputPort);
}
catch (Exception ex)
{
Debug.Console(0, this, "Exception : {0}", ex);
}
}
/// <summary>
///
/// </summary>
void AddVolumeControl(uint number, Audio.Output audio) {
void AddVolumeControl(uint number, Audio.Output audio)
{
VolumeControls.Add(number, new DmCardAudioOutputController(audio));
}
@@ -443,35 +524,43 @@ namespace PepperDash.Essentials.DM {
//}
void Chassis_DMInputChange(Switch device, DMInputEventArgs args) {
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
{
switch (args.EventId) {
case DMInputEventIds.EndpointOnlineEventId: {
switch (args.EventId)
{
case DMInputEventIds.EndpointOnlineEventId:
{
Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break;
}
case DMInputEventIds.OnlineFeedbackEventId: {
case DMInputEventIds.OnlineFeedbackEventId:
{
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break;
}
case DMInputEventIds.VideoDetectedEventId: {
case DMInputEventIds.VideoDetectedEventId:
{
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
VideoInputSyncFeedbacks[args.Number].FireUpdate();
break;
}
case DMInputEventIds.InputNameEventId: {
case DMInputEventIds.InputNameEventId:
{
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
InputNameFeedbacks[args.Number].FireUpdate();
break;
}
case DMInputEventIds.HdcpCapabilityFeedbackEventId: {
case DMInputEventIds.HdcpCapabilityFeedbackEventId:
{
Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number);
InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate();
break;
}
default: {
default:
{
Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId);
break;
}
@@ -487,74 +576,74 @@ namespace PepperDash.Essentials.DM {
switch (args.EventId)
{
case DMOutputEventIds.VolumeEventId:
{
if (VolumeControls.ContainsKey(output))
{
VolumeControls[args.Number].VolumeEventFromChassis();
if (VolumeControls.ContainsKey(output))
{
VolumeControls[args.Number].VolumeEventFromChassis();
}
break;
}
break;
}
case DMOutputEventIds.EndpointOnlineEventId:
{
Debug.Console(2, this,
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
if (Chassis.Outputs[output].Endpoint != null)
{
Debug.Console(2, this,
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
if (Chassis.Outputs[output].Endpoint != null)
Debug.Console(2, this,
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
OutputEndpointOnlineFeedbacks[output].FireUpdate();
break;
}
OutputEndpointOnlineFeedbacks[output].FireUpdate();
break;
}
case DMOutputEventIds.OnlineFeedbackEventId:
{
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
OutputEndpointOnlineFeedbacks[output].FireUpdate();
break;
}
{
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
OutputEndpointOnlineFeedbacks[output].FireUpdate();
break;
}
case DMOutputEventIds.VideoOutEventId:
{
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
inputNumber, output);
if (VideoOutputFeedbacks.ContainsKey(output))
{
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
var localOutputPort =
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
inputNumber, output);
if (VideoOutputFeedbacks.ContainsKey(output))
{
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
var localOutputPort =
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]);
VideoOutputFeedbacks[output].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output,
inputNumber,
localOutputPort,
localInputPort,
eRoutingSignalType.AudioVideo));
VideoOutputFeedbacks[output].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output,
inputNumber,
localOutputPort,
localInputPort,
eRoutingSignalType.AudioVideo));
}
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
{
OutputVideoRouteNameFeedbacks[output].FireUpdate();
}
break;
}
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
{
OutputVideoRouteNameFeedbacks[output].FireUpdate();
}
break;
}
case DMOutputEventIds.OutputNameEventId:
{
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
OutputNameFeedbacks[output].FireUpdate();
break;
}
{
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
OutputNameFeedbacks[output].FireUpdate();
break;
}
default:
{
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
args.Number, args.EventId);
break;
}
{
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
args.Number, args.EventId);
break;
}
}
}
@@ -564,7 +653,8 @@ namespace PepperDash.Essentials.DM {
///
/// </summary>
/// <param name="pnt"></param>
void StartOffTimer(PortNumberType pnt) {
void StartOffTimer(PortNumberType pnt)
{
if (RouteOffTimers.ContainsKey(pnt))
return;
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime);
@@ -572,8 +662,10 @@ namespace PepperDash.Essentials.DM {
// Send out sigs when coming online
void IsOnline_OutputChange(object sender, EventArgs e) {
if (IsOnline.BoolValue) {
void IsOnline_OutputChange(object sender, EventArgs e)
{
if (IsOnline.BoolValue)
{
Chassis.EnableUSBBreakaway.BoolValue = true;
if (InputNames != null)
@@ -587,12 +679,13 @@ namespace PepperDash.Essentials.DM {
#region IRouting Members
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) {
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType)
{
Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType);
var input = inputSelector as DMInput; // Cast can sometimes fail
var output = outputSelector as DMOutput;
if (output == null)
{
@@ -605,11 +698,14 @@ namespace PepperDash.Essentials.DM {
// Check to see if there's an off timer waiting on this and if so, cancel
var key = new PortNumberType(output, sigType);
if (input == null) {
if (input == null)
{
StartOffTimer(key);
}
else {
if (RouteOffTimers.ContainsKey(key)) {
else
{
if (RouteOffTimers.ContainsKey(key))
{
Debug.Console(2, this, "{0} cancelling route off due to new source", output);
RouteOffTimers[key].Stop();
RouteOffTimers.Remove(key);
@@ -671,7 +767,7 @@ namespace PepperDash.Essentials.DM {
var ioSlotJoin = ioSlot - 1;
// Control
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video));
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort)ioSlot, eRoutingSignalType.Video));
if (TxDictionary.ContainsKey(ioSlot))
{

View File

@@ -1285,10 +1285,7 @@ namespace PepperDash.Essentials.DM
var output = outputSelector as DMOutput;
var isUsbInput = (sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput;
var isUsbOutput = (sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput;
if (output == null && !(isUsbOutput || isUsbInput))
if (output == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Warning,
"Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector,
@@ -1319,10 +1316,7 @@ namespace PepperDash.Essentials.DM
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
Chassis.VideoEnter.BoolValue = true;
if (output != null)
{
output.VideoOut = input; //Chassis.Outputs[output].VideoOut = inCard;
}
output.VideoOut = input; //Chassis.Outputs[output].VideoOut = inCard;
}
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
@@ -1332,66 +1326,17 @@ namespace PepperDash.Essentials.DM
{
dmMdMnxn.AudioEnter.BoolValue = true;
}
if (output != null)
{
output.AudioOut = input;
}
output.AudioOut = input;
//Chassis.Outputs[output].AudioOut = inCard;
}
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
{
Chassis.USBEnter.BoolValue = true;
if (inputSelector == null && output != null)
{
//clearing the route is intended
output.USBRoutedTo = null;
return;
}
if (inputSelector != null && input == null)
{
//input selector is DMOutput...we're doing a out to out route
var tempInput = inputSelector as DMOutput;
if (tempInput == null || output == null)
{
return;
}
output.USBRoutedTo = tempInput;
return;
}
if (input != null & output != null)
{
output.USBRoutedTo = input;
}
}
if((sigType & eRoutingSignalType.UsbInput) != eRoutingSignalType.UsbInput)
{
return;
}
Chassis.USBEnter.BoolValue = true;
if (output != null)
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput || (sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput)
{
Chassis.USBEnter.BoolValue = true;
output.USBRoutedTo = input;
return;
}
var tempOutput = outputSelector as DMInput;
if (tempOutput == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Warning,
"Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector,
outputSelector);
return;
}
tempOutput.USBRoutedTo = input;
}
#endregion
#region IRoutingNumeric Members
@@ -1404,10 +1349,8 @@ namespace PepperDash.Essentials.DM
DMInputOutputBase dmCard;
//Routing Input to Input or Output to Input
if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput)
{
Debug.Console(2, this, "Executing USB Input switch.\r\n in:{0} output: {1}", inputSelector, outputSelector);
if (outputSelector > chassisSize)
{
uint outputIndex;
@@ -1427,14 +1370,13 @@ namespace PepperDash.Essentials.DM
dmCard = Chassis.Inputs[inputSelector];
}
ExecuteSwitch(dmCard, Chassis.Inputs[outputSelector], sigType);
ExecuteSwitch(dmCard, Chassis.Outputs[outputSelector], sigType);
return;
}
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
{
Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", inputSelector, outputSelector);
//routing Output to Output or Input to Output
if (inputSelector > chassisSize)
{
//wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8

View File

@@ -25,9 +25,16 @@ namespace PepperDash.Essentials.DM
public CrestronControlSystem Dmps { get; set; }
public ISystemControl SystemControl { get; private set; }
//Check if DMPS is a DMPS3-4K type for endpoint creation
public bool Dmps4kType { get; private set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
//Feedback for DMPS System Power
public BoolFeedback SystemPowerOnFeedback { get; private set; }
public BoolFeedback SystemPowerOffFeedback { get; private set; }
// Feedbacks for EssentialDM
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
@@ -112,10 +119,29 @@ namespace PepperDash.Essentials.DM
/// <param name="chassis"></param>
public DmpsRoutingController(string key, string name, ISystemControl systemControl)
: base(key, name)
{
{
Dmps = Global.ControlSystem;
SystemControl = systemControl;
switch (name.Replace("-", "").Replace("c", "").Replace("C", ""))
{
case "dmps34k50":
case "dmps34k100":
case "dmps34k150":
SystemControl = systemControl as Dmps34K150CSystemControl;
Dmps4kType = true;
break;
case "dmps34k200":
case "dmps34k250":
case "dmps34k300":
case "dmps34k350":
SystemControl = systemControl as Dmps34K300CSystemControl;
Dmps4kType = true;
break;
default:
SystemControl = systemControl as Dmps3SystemControl;
Dmps4kType = false;
break;
}
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
@@ -123,6 +149,29 @@ namespace PepperDash.Essentials.DM
TxDictionary = new Dictionary<uint, string>();
RxDictionary = new Dictionary<uint, string>();
SystemPowerOnFeedback = new BoolFeedback(() =>
{
if (SystemControl is Dmps3SystemControl)
{
return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue;
}
else
{
return false;
}
});
SystemPowerOffFeedback = new BoolFeedback(() =>
{
if (SystemControl is Dmps3SystemControl)
{
return ((Dmps3SystemControl)SystemControl).SystemPowerOffFeedBack.BoolValue;
}
else
{
return false;
}
});
VideoOutputFeedbacks = new Dictionary<uint, IntFeedback>();
AudioOutputFeedbacks = new Dictionary<uint, IntFeedback>();
VideoInputSyncFeedbacks = new Dictionary<uint, BoolFeedback>();
@@ -154,6 +203,7 @@ namespace PepperDash.Essentials.DM
// Subscribe to events
Dmps.DMInputChange += Dmps_DMInputChange;
Dmps.DMOutputChange += Dmps_DMOutputChange;
Dmps.DMSystemChange += Dmps_DMSystemChange;
return base.CustomActivate();
}
@@ -191,6 +241,22 @@ namespace PepperDash.Essentials.DM
}
}
public void SetPowerOn(bool a)
{
if (SystemControl is Dmps3SystemControl)
{
((Dmps3SystemControl)SystemControl).SystemPowerOn();
}
}
public void SetPowerOff(bool a)
{
if (SystemControl is Dmps3SystemControl)
{
((Dmps3SystemControl)SystemControl).SystemPowerOff();
}
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmpsRoutingControllerJoinMap(joinStart);
@@ -211,9 +277,22 @@ namespace PepperDash.Essentials.DM
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
//Link up system
trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, SetPowerOn);
trilist.SetBoolSigAction(joinMap.SystemPowerOff.JoinNumber, SetPowerOff);
if (SystemPowerOnFeedback != null)
{
SystemPowerOnFeedback.LinkInputSig(
trilist.BooleanInput[joinMap.SystemPowerOn.JoinNumber]);
}
if (SystemPowerOffFeedback != null)
{
SystemPowerOffFeedback.LinkInputSig(
trilist.BooleanInput[joinMap.SystemPowerOff.JoinNumber]);
}
// Link up outputs
LinkInputsToApi(trilist, joinMap);
LinkOutputsToApi(trilist, joinMap);
}
@@ -719,28 +798,36 @@ namespace PepperDash.Essentials.DM
void Dmps_DMInputChange(Switch device, DMInputEventArgs args)
{
//Debug.Console(2, this, "DMSwitch:{0} Input:{1} Event:{2}'", this.Name, args.Number, args.EventId.ToString());
switch (args.EventId)
try
{
case (DMInputEventIds.OnlineFeedbackEventId):
{
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break;
}
case (DMInputEventIds.VideoDetectedEventId):
{
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
VideoInputSyncFeedbacks[args.Number].FireUpdate();
break;
}
case (DMInputEventIds.InputNameEventId):
{
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
InputNameFeedbacks[args.Number].FireUpdate();
break;
}
switch (args.EventId)
{
case (DMInputEventIds.OnlineFeedbackEventId):
{
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break;
}
case (DMInputEventIds.VideoDetectedEventId):
{
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
VideoInputSyncFeedbacks[args.Number].FireUpdate();
break;
}
case (DMInputEventIds.InputNameEventId):
{
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
if(InputNameFeedbacks.ContainsKey(args.Number))
{
InputNameFeedbacks[args.Number].FireUpdate();
}
break;
}
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "DMSwitch Input Change:{0} Input:{1} Event:{2}\rException: {3}", this.Name, args.Number, args.EventId.ToString(), e.ToString());
}
}
void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args)
@@ -812,6 +899,23 @@ namespace PepperDash.Essentials.DM
}
void Dmps_DMSystemChange(Switch device, DMSystemEventArgs args)
{
switch (args.EventId)
{
case DMSystemEventIds.SystemPowerOnEventId:
{
SystemPowerOnFeedback.FireUpdate();
break;
}
case DMSystemEventIds.SystemPowerOffEventId:
{
SystemPowerOffFeedback.FireUpdate();
break;
}
}
}
/// <summary>
///
/// </summary>
@@ -879,7 +983,6 @@ namespace PepperDash.Essentials.DM
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
output.VideoOut = input;
}
@@ -903,7 +1006,6 @@ namespace PepperDash.Essentials.DM
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
{
output.USBRoutedTo = input;
}

View File

@@ -329,7 +329,14 @@ namespace PepperDash.Essentials.DM
var parentDev = DeviceManager.GetDeviceForKey(pKey);
if (parentDev is DmpsRoutingController)
{
return GetDmRmcControllerForDmps(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber);
if ((parentDev as DmpsRoutingController).Dmps4kType)
{
return GetDmRmcControllerForDmps4k(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber);
}
else
{
return GetDmRmcControllerForDmps(key, name, typeName, ipid, parentDev as DmpsRoutingController, props.ParentOutputNumber);
}
}
if (!(parentDev is IDmSwitch))
{
@@ -395,25 +402,47 @@ namespace PepperDash.Essentials.DM
return null;
}
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName,
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName,
uint ipid, DmpsRoutingController controller, uint num)
{
Func<string, string, uint, DMOutput, CrestronGenericBaseDevice> dmpsHandler;
if (ChassisDict.TryGetValue(typeName.ToLower(), out dmpsHandler))
{
var output = controller.Dmps.SwitcherOutputs[num] as DMOutput;
if (output != null)
{
return dmpsHandler(key, name, ipid, output);
}
Debug.Console(0, Debug.ErrorLogLevel.Error,
"Cannot attach DM-RMC of type '{0}' to output {1} on DMPS chassis. Output is not a DM Output.",
typeName, num);
return null;
}
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS chassis", typeName, num);
return null;
}
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps4k(string key, string name, string typeName,
DmpsRoutingController controller, uint num)
{
Func<string, string, DMOutput, CrestronGenericBaseDevice> dmpsHandler;
if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmpsHandler))
Func<string, string, DMOutput, CrestronGenericBaseDevice> dmps4kHandler;
if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmps4kHandler))
{
var output = controller.Dmps.SwitcherOutputs[num] as DMOutput;
if (output != null)
{
return dmpsHandler(key, name, output);
return dmps4kHandler(key, name, output);
}
Debug.Console(0, Debug.ErrorLogLevel.Error,
"Cannot attach DM-RMC of type '{0}' to output {1} on DMPS chassis. Output is not a DM Output.",
"Cannot attach DM-RMC of type '{0}' to output {1} on DMPS-4K chassis. Output is not a DM Output.",
typeName, num);
return null;
}
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS chassis", typeName, num);
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS-4K chassis", typeName, num);
return null;
}

View File

@@ -36,7 +36,7 @@ namespace PepperDash.Essentials.DM
var ipid = props.Control.IpIdInt;
var pKey = props.ParentDeviceKey.ToLower();
if (pKey == "processor")
if (pKey == "processor")
{
// Catch constructor failures, mainly dues to IPID
try
@@ -65,99 +65,135 @@ namespace PepperDash.Essentials.DM
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
}
return null;
}
else
{
var parentDev = DeviceManager.GetDeviceForKey(pKey);
if (!(parentDev is IDmSwitch))
{
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.",
key, pKey);
return null;
}
var parentDev = DeviceManager.GetDeviceForKey(pKey);
DMInput dmInput;
bool isCpu3 = false;
if (parentDev is IDmSwitch)
{
// Get the Crestron chassis and link stuff up
var switchDev = (parentDev as IDmSwitch);
var chassis = switchDev.Chassis;
var switchDev = (parentDev as IDmSwitch);
var chassis = switchDev.Chassis;
var num = props.ParentInputNumber;
if (num <= 0 || num > chassis.NumberOfInputs)
{
Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
key, num);
return null;
}
else
//Check that the input is within range of this chassis' possible inputs
var num = props.ParentInputNumber;
if (num <= 0 || num > chassis.NumberOfInputs)
{
Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
key, num);
return null;
}
switchDev.TxDictionary.Add(num, key);
dmInput = chassis.Inputs[num];
//Determine if IpId is needed for this chassis type
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps ||
chassis is DmMd128x128 || chassis is DmMd64x64)
{
var controller = (parentDev as IDmSwitch);
controller.TxDictionary.Add(num, key);
isCpu3 = true;
}
// Catch constructor failures, mainly dues to IPID
try
{
// Must use different constructor for CPU3 chassis types. No IPID
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps||
chassis is DmMd128x128 || chassis is DmMd64x64)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num]));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num]));
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(chassis.Inputs[num]));
}
else
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num]));
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, chassis.Inputs[num]));
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
}
}
else if(parentDev is DmpsRoutingController)
{
// Get the DMPS chassis and link stuff up
var dmpsDev = (parentDev as DmpsRoutingController);
var chassis = dmpsDev.Dmps;
//Check that the input is within range of this chassis' possible inputs
var num = props.ParentInputNumber;
if (num <= 0 || num > chassis.SwitcherInputs.Count)
{
Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is out of range",
key, num);
return null;
}
dmpsDev.TxDictionary.Add(num, key);
try
{
dmInput = chassis.SwitcherInputs[num] as DMInput;
}
catch
{
Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is not a DM input", key, num);
return null;
}
}
else
{
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey);
return null;
}
return null;
try
{
// Must use different constructor for CPU3 or DMPS3-4K types. No IPID
if (isCpu3 || Global.ControlSystemIsDmps4kType)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(dmInput));
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(dmInput));
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(dmInput));
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(dmInput));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(dmInput));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(dmInput));
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(dmInput));
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(dmInput));
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(dmInput));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(dmInput));
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
}
else
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, dmInput));
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, dmInput));
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, dmInput));
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, dmInput));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, dmInput));
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, dmInput));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, dmInput));
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, dmInput));
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
}
return null;
}
}
@@ -185,11 +221,12 @@ namespace PepperDash.Essentials.DM
protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
: base(key, name, hardware)
{
// if wired to a chassis, skip registration step in base class
if (hardware.DMInput != null)
{
this.PreventRegistration = true;
}
// if wired to a chassis or DMPS, skip registration step in base class
if (hardware.DMInput != null || (Global.ControlSystemIsDmpsType && hardware.DMInput != null))
{
this.PreventRegistration = true;
}
AddToFeedbackList(ActiveVideoInputFeedback);
}

View File

@@ -216,21 +216,11 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
var presetsCamera = cameraDevice as IHasCameraPresets;
presetsCamera.PresetsListHasChanged += new EventHandler<EventArgs>((o, a) =>
{
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
{
int tempNum = i - 1;
string label = "";
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
if (preset != null)
label = preset.Description;
trilist.SetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum), label);
}
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
});
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++)
{
int tempNum = i;
@@ -246,10 +236,35 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
presetsCamera.PresetStore(tempNum, label);
});
}
trilist.OnlineStatusChange += (sender, args) =>
{
if (!args.DeviceOnLine)
{ return; }
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
};
}
}
private void SendCameraPresetNamesToApi(IHasCameraPresets presetsCamera, CameraControllerJoinMap joinMap, BasicTriList trilist)
{
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
{
int tempNum = i - 1;
string label = "";
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
if (preset != null)
label = preset.Description;
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
}
}
}
public class CameraPreset : PresetBase
{
public CameraPreset(int id, string description, bool isDefined, bool isDefinable)

View File

@@ -525,6 +525,15 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
public event EventHandler<EventArgs> PresetsListHasChanged;
protected void OnPresetsListHasChanged()
{
var handler = PresetsListHasChanged;
if (handler == null)
return;
handler.Invoke(this, EventArgs.Empty);
}
public List<CameraPreset> Presets { get; private set; }
public void PresetSelect(int preset)
@@ -537,6 +546,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
SavePreset(preset);
}
#endregion
#region IHasCameraFocusControl Members

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Describes a device that has Do Not Disturb mode capability
/// </summary>
public interface IHasDoNotDisturbMode
{
/// <summary>
/// Indictes whether Do Not Disturb mode is on (Activated)
/// </summary>
BoolFeedback DoNotDisturbModeIsOnFeedback { get; }
/// <summary>
/// Activates Do Not Disturb mode
/// </summary>
void ActivateDoNotDisturbMode();
/// <summary>
/// Deactivates Do Not Disturb mode
/// </summary>
void DeactivateDoNotDisturbMode();
/// <summary>
/// Toggles Do Not Disturb mode
/// </summary>
void ToggleDoNotDisturbMode();
}
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
{
/// <summary>
/// Activates Do Not Disturb mode with a timeout
/// </summary>
/// <param name="timeout"></param>
void ActivateDoNotDisturbMode(int timeout);
}
}

View File

@@ -108,6 +108,7 @@
<Compile Include="Codec\eCodecCallStatus.cs" />
<Compile Include="Codec\eMeetingPrivacy.cs" />
<Compile Include="Codec\iCodecAudio.cs" />
<Compile Include="Codec\IHasDoNotDisturb.cs" />
<Compile Include="Codec\IHasExternalSourceSwitching.cs" />
<Compile Include="ImageProcessors\TVOneCorio.cs" />
<Compile Include="ImageProcessors\TVOneCorioPropertiesConfig.cs" />
@@ -117,16 +118,16 @@
<Compile Include="ImageProcessors\AnalogWay\AnalogWayLiveCorePropertiesConfig.cs" />
<Compile Include="SoftCodec\BlueJeansPc.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCamera.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCodecJoinMap.cs" />
<Compile Include="VideoCodec\CiscoCodec\RoomPresets.cs" />
<Compile Include="Cameras\CameraControl.cs" />
<Compile Include="Display\PanasonicThDisplay.cs" />
<Compile Include="VideoCodec\Interfaces\IHasMeetingInfo.cs" />
<Compile Include="VideoCodec\Interfaces\IHasMeetingLock.cs" />
<Compile Include="VideoCodec\Interfaces\IHasMeetingRecording.cs" />
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
<Compile Include="VideoCodec\Interfaces\IHasPresentationOnlyMeeting.cs" />
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
<Compile Include="VideoCodec\Interfaces\IHasSelfviewSize.cs" />
<Compile Include="VideoCodec\Interfaces\IHasStandbyMode.cs" />
<Compile Include="VideoCodec\Interfaces\IHasStartMeeting.cs" />
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
<Compile Include="Codec\iHasCallFavorites.cs" />

View File

@@ -0,0 +1,134 @@
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges.JoinMaps;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
public class CiscoCodecJoinMap : VideoCodecControllerJoinMap
{
#region Digital
[JoinName("ActivateDoNotDisturbMode")]
public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Activates Do Not Disturb Mode. FB High if active.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DeactivateDoNotDisturbMode")]
public JoinDataComplete DeactivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 222,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Deactivates Do Not Disturb Mode. FB High if deactivated.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ToggleDoNotDisturbMode")]
public JoinDataComplete ToggleDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 223,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Toggles Do Not Disturb Mode.",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ActivateStandby")]
public JoinDataComplete ActivateStandby = new JoinDataComplete(
new JoinData
{
JoinNumber = 226,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Activates Standby Mode. FB High if active.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DeactivateStandby")]
public JoinDataComplete DeactivateStandby = new JoinDataComplete(
new JoinData
{
JoinNumber = 227,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Deactivates Standby Mode. FB High if deactivated.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ActivateHalfWakeMode")]
public JoinDataComplete ActivateHalfWakeMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 228,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Activates Half Wake Mode. FB High if active.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("EnteringStandbyMode")]
public JoinDataComplete EnteringStandbyMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 229,
JoinSpan = 1
},
new JoinMetadata
{
Description = "High to indicate that the codec is entering standby mode",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
#endregion
#region Analog
#endregion
#region Serials
#endregion
public CiscoCodecJoinMap(uint joinStart)
: base(joinStart, typeof(CiscoCodecJoinMap))
{
}
public CiscoCodecJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -440,9 +440,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public CallId CallId { get; set; }
}
public class DoNotDisturb
public class DoNotDisturb : ValueProperty
{
public string Value { get; set; }
string _Value;
public bool BoolValue { get; private set; }
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
// If the incoming value is "On" it sets the BoolValue true, otherwise sets it false
BoolValue = value == "On" || value == "Active";
OnValueChanged();
}
}
}
public class Mode
@@ -600,6 +617,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Conference2()
{
Presentation = new Presentation();
DoNotDisturb = new DoNotDisturb();
}
}
@@ -1380,12 +1398,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public class State : ValueProperty
{
string _value;
public bool BoolValue { get; private set; }
public string Value // Valid values are Standby/EnteringStandby/Halfwake/Off
{
get { return _value; }
set
{
_value = value;
// If the incoming value is "On" it sets the BoolValue true, otherwise sets it false
BoolValue = value == "On" || value == "Standby";
OnValueChanged();
@@ -2091,6 +2113,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Conference = new Conference2();
SystemUnit = new SystemUnit();
Video = new Video();
Conference = new Conference2();
}
}

View File

@@ -6,8 +6,6 @@ using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
@@ -27,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary>
public interface IHasZoomRoomLayouts : IHasCodecLayouts
{
event EventHandler<LayoutInfoChangedEventArgs> LayoutInfoChanged;
event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
@@ -47,17 +45,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public class LayoutInfoChangedEventArgs : EventArgs
{
[JsonProperty("availableLayouts", NullValueHandling = NullValueHandling.Ignore)]
public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; }
[JsonProperty("currentSelectedLayout", NullValueHandling = NullValueHandling.Ignore)]
public ZoomRoom.zConfiguration.eLayoutStyle CurrentSelectedLayout { get; set; }
[JsonProperty("canSwapContentWithThumbnail", NullValueHandling = NullValueHandling.Ignore)]
public bool CanSwapContentWithThumbnail { get; set; }
[JsonProperty("contentSwappedWithThumbnail", NullValueHandling = NullValueHandling.Ignore)]
public bool ContentSwappedWithThumbnail { get; set; }
[JsonProperty("layoutViewIsOnFirstPage", NullValueHandling = NullValueHandling.Ignore)]
public bool LayoutViewIsOnFirstPage { get; set; }
[JsonProperty("layoutViewIsOnLastPage", NullValueHandling = NullValueHandling.Ignore)]
public bool LayoutViewIsOnLastPage { get; set; }
}
}

View File

@@ -24,27 +24,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
/// </summary>
public class MeetingInfo
{
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("id")]
public string Id { get; private set; }
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("name")]
public string Name { get; private set; }
[JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("host")]
public string Host { get; private set; }
[JsonProperty("password", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("password")]
public string Password { get; private set; }
[JsonProperty("shareStatus", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("shareStatus")]
public string ShareStatus { get; private set; }
[JsonProperty("isHost", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("isHost")]
public Boolean IsHost { get; private set; }
[JsonProperty("isSharingMeeting", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("isSharingMeeting")]
public Boolean IsSharingMeeting { get; private set; }
[JsonProperty("waitingForHost", NullValueHandling = NullValueHandling.Ignore)]
[JsonProperty("waitingForHost")]
public Boolean WaitingForHost { get; private set; }
[JsonProperty("isLocked", NullValueHandling = NullValueHandling.Ignore)]
public Boolean IsLocked { get; private set; }
public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked)
public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost)
{
Id = id;
Name = name;
@@ -54,7 +51,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
IsHost = isHost;
IsSharingMeeting = isSharingMeeting;
WaitingForHost = waitingForHost;
IsLocked = isLocked;
}
}

View File

@@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
public interface IHasMeetingLock
{
BoolFeedback MeetingIsLockedFeedback { get; }
void LockMeeting();
void UnLockMeeting();
void ToggleMeetingLock();
}
}

View File

@@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
public interface IHasMeetingRecording
{
BoolFeedback MeetingIsRecordingFeedback { get; }
void StartRecording();
void StopRecording();
void ToggleRecording();
}
}

View File

@@ -12,18 +12,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
public interface IHasParticipants
{
CodecParticipants Participants { get; }
/// <summary>
/// Removes the participant from the meeting
/// </summary>
/// <param name="participant"></param>
void RemoveParticipant(int userId);
/// <summary>
/// Sets the participant as the new host
/// </summary>
/// <param name="participant"></param>
void SetParticipantAsHost(int userId);
}
/// <summary>
@@ -41,11 +29,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
/// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{
/// <summary>
/// Mute audio of all participants
/// </summary>
void MuteAudioForAllParticipants();
void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId);

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Describes a device that has Standby Mode capability
/// </summary>
public interface IHasStandbyMode
{
BoolFeedback StandbyIsOnFeedback { get; }
void StandbyActivate();
void StandbyDeactivate();
}
/// <summary>
/// Describes a device that has Half Waek Mode capability
/// </summary>
public interface IHasHalfWakeMode : IHasStandbyMode
{
BoolFeedback HalfWakeModeIsOnFeedback { get; }
BoolFeedback EnteringStandbyModeFeedback { get; }
void HalfwakeActivate();
}
}

View File

@@ -4,8 +4,6 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
@@ -21,19 +19,12 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public abstract class VideoCodecInfo
{
[JsonProperty("multiSiteOptionIsEnabled", NullValueHandling = NullValueHandling.Ignore)]
public abstract bool MultiSiteOptionIsEnabled { get; }
[JsonProperty("ipAddress", NullValueHandling = NullValueHandling.Ignore)]
public abstract string IpAddress { get; }
[JsonProperty("sipPhoneNumber", NullValueHandling = NullValueHandling.Ignore)]
public abstract string SipPhoneNumber { get; }
[JsonProperty("e164Alias", NullValueHandling = NullValueHandling.Ignore)]
public abstract string E164Alias { get; }
[JsonProperty("h323Id", NullValueHandling = NullValueHandling.Ignore)]
public abstract string H323Id { get; }
[JsonProperty("sipUri", NullValueHandling = NullValueHandling.Ignore)]
public abstract string SipUri { get; }
[JsonProperty("autoAnswerEnabled", NullValueHandling = NullValueHandling.Ignore)]
public abstract bool AutoAnswerEnabled { get; }
}
}

View File

@@ -25,7 +25,7 @@ using Feedback = PepperDash.Essentials.Core.Feedback;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode
{
private const int XSigEncoding = 28591;
protected const int MaxParticipants = 50;
@@ -302,6 +302,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC");
};
}
@@ -551,15 +553,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
UpdateParticipantsXSig(codec, trilist, joinMap);
};
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, "\xFC");
UpdateParticipantsXSig(codec, trilist, joinMap);
};
}
private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
@@ -791,16 +784,7 @@ ScreenIndexIsPinnedTo: {8} (a{17})
UpdateMeetingsList(codec, trilist, joinMap);
}
};
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC");
UpdateMeetingsList(codec, trilist, joinMap);
};
}
}
private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{
@@ -821,15 +805,6 @@ ScreenIndexIsPinnedTo: {8} (a{17})
var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC");
UpdateMeetingsListXSig(_currentMeetings);
};
}
private string UpdateMeetingsListXSig(List<Meeting> meetings)
@@ -943,16 +918,6 @@ ScreenIndexIsPinnedTo: {8} (a{17})
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig);
};
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, "\xFC");
UpdateDirectoryXSig(codec.CurrentDirectoryResult,
!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue);
};
}
private void SelectDirectoryEntry(IHasDirectory codec, ushort i)
@@ -1034,15 +999,6 @@ ScreenIndexIsPinnedTo: {8} (a{17})
trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
};
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC");
UpdateCallStatusXSig();
};
}
private string UpdateCallStatusXSig()
@@ -1310,15 +1266,6 @@ ScreenIndexIsPinnedTo: {8} (a{17})
trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty);
trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
});
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868
trilist.SetString(joinMap.CameraPresetNames.JoinNumber, "\xFC");
SetCameraPresetNames(presetCodec.NearEndPresets);
};
}
private string SetCameraPresetNames(IEnumerable<CodecRoomPreset> presets)

View File

@@ -618,31 +618,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
private bool _can_Switch_Speaker_View;
private bool _can_Switch_Wall_View;
private bool _can_Switch_Share_On_All_Screens;
private bool _can_Switch_Floating_Share_Content;
private bool _is_In_First_Page;
private bool _is_In_Last_Page;
private string _video_type;
public bool can_Adjust_Floating_Video { get; set; }
public bool can_Switch_Floating_Share_Content
{
get
{
return _can_Switch_Floating_Share_Content;
}
set
{
if (value != _can_Switch_Floating_Share_Content)
{
_can_Switch_Floating_Share_Content = value;
NotifyPropertyChanged("can_Switch_Floating_Share_Content");
}
}
}
public bool can_Switch_Floating_Share_Content { get; set; }
/// <summary>
/// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors.
@@ -762,29 +744,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
}
public class CallRecordInfo : NotifiableObject
public class CallRecordInfo
{
private bool _meetingIsBeingRecorded;
public bool canRecord { get; set; }
public bool emailRequired { get; set; }
public bool amIRecording { get; set; }
public bool meetingIsBeingRecorded
{
get
{
return _meetingIsBeingRecorded;
}
set
{
if (value != _meetingIsBeingRecorded)
{
_meetingIsBeingRecorded = value;
NotifyPropertyChanged("meetingIsBeingRecorded");
}
}
}
public bool meetingIsBeingRecorded { get; set; }
}
}
@@ -1158,25 +1123,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
}
public class Lock : NotifiableObject
public class Lock
{
private bool _enable;
public bool Enable
{
get
{
return _enable;
}
set
{
if (value != _enable)
{
_enable = value;
NotifyPropertyChanged("Enable");
}
}
}
public bool Enable { get; set; }
}
public class ClosedCaption

View File

@@ -26,8 +26,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
IRouting,
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin,
IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting,
IHasMeetingLock, IHasMeetingRecording
IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting
{
private const long MeetingRefreshTimer = 60000;
public uint DefaultMeetingDurationMin { get; private set; }
@@ -148,10 +147,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc);
NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc);
MeetingIsLockedFeedback = new BoolFeedback(() => Configuration.Call.Lock.Enable );
MeetingIsRecordingFeedback = new BoolFeedback(() => Status.Call.CallRecordInfo.meetingIsBeingRecorded );
}
public CommunicationGather PortGather { get; private set; }
@@ -504,19 +499,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
var sharingStatus = GetSharingStatus();
MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true, false, MeetingIsLockedFeedback.BoolValue);
MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true, false);
return;
}
var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host != null ? Participants.Host.Name : "None",
MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost, MeetingIsLockedFeedback.BoolValue);
MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost);
MeetingInfo = meetingInfo;
}
catch (Exception e)
{
Debug.Console(1, this, "Error processing state property update. {0}", e.Message);
Debug.Console(2, this, e.StackTrace);
MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false, false, MeetingIsLockedFeedback.BoolValue);
MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false, false);
}
}
@@ -583,13 +578,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
case "ShareThumb":
{
ContentSwappedWithThumbnailFeedback.FireUpdate();
OnLayoutInfoChanged();
break;
}
case "Style":
{
LocalLayoutFeedback.FireUpdate();
OnLayoutInfoChanged();
break;
}
case "Size":
@@ -604,26 +597,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
};
Configuration.Call.Lock.PropertyChanged += (o, a) =>
{
if (a.PropertyName == "Enable")
{
MeetingIsLockedFeedback.FireUpdate();
MeetingInfo = new MeetingInfo
(
MeetingInfo.Id,
MeetingInfo.Name,
MeetingInfo.Host,
MeetingInfo.Password,
GetSharingStatus(),
MeetingInfo.IsHost,
MeetingInfo.IsSharingMeeting,
MeetingInfo.WaitingForHost,
MeetingIsLockedFeedback.BoolValue
);
}
};
// This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3
Configuration.Client.Call.Layout.PropertyChanged += (o, a) =>
{
@@ -640,13 +613,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
case "ShareThumb":
{
ContentSwappedWithThumbnailFeedback.FireUpdate();
OnLayoutInfoChanged();
break;
}
case "Style":
{
LocalLayoutFeedback.FireUpdate();
OnLayoutInfoChanged();
break;
}
}
@@ -663,31 +634,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
Status.Call.PropertyChanged += (o, a) =>
{
switch(a.PropertyName)
{
case "Info":
if (a.PropertyName == "Info")
{
Debug.Console(1, this, "Updating Call Status");
UpdateCallStatus();
break;
}
case "Status":
{
UpdateCallStatus();
break;
}
}
};
Status.Call.CallRecordInfo.PropertyChanged += (o, a) =>
{
if (a.PropertyName == "meetingIsBeingRecorded")
{
MeetingIsRecordingFeedback.FireUpdate();
}
};
Status.Sharing.PropertyChanged += (o, a) =>
{
switch (a.PropertyName)
@@ -710,15 +663,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
return;
}
// Update the share status of the meeting info
var meetingInfo = new MeetingInfo(MeetingInfo.Id,
MeetingInfo.Name,
MeetingInfo.Host,
MeetingInfo.Password,
GetSharingStatus(),
GetIsHostMyself(),
MeetingInfo.IsSharingMeeting,
MeetingInfo.WaitingForHost,
MeetingIsLockedFeedback.BoolValue);
var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost);
MeetingInfo = meetingInfo;
break;
}
@@ -769,13 +714,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
LayoutViewIsOnLastPageFeedback.FireUpdate();
break;
}
case "can_Switch_Floating_Share_Content":
{
CanSwapContentWithThumbnailFeedback.FireUpdate();
break;
}
//case "video_type":
// {
// It appears as though the actual value we want to watch is Configuration.Call.Layout.Style
// LocalLayoutFeedback.FireUpdate();
// break;
// }
}
OnLayoutInfoChanged();
};
Status.NumberOfScreens.PropertyChanged += (o, a) =>
@@ -1299,16 +1244,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
Participants.CurrentParticipants = participants;
// Update the share status of the meeting info
var meetingInfo = new MeetingInfo(
MeetingInfo.Id,
MeetingInfo.Name,
Participants.Host.Name,
MeetingInfo.Password,
MeetingInfo.ShareStatus,
GetIsHostMyself(),
MeetingInfo.IsSharingMeeting,
MeetingInfo.WaitingForHost,
MeetingIsLockedFeedback.BoolValue);
var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost);
MeetingInfo = meetingInfo;
PrintCurrentCallParticipants();
@@ -1510,21 +1446,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
Status.NeedWaitForHost = JsonConvert.DeserializeObject<zEvent.NeedWaitForHost>(responseObj.ToString());
Debug.Console(1, this, "WaitingForHost: {0}", Status.NeedWaitForHost.Wait);
Debug.Console(1, this, "NeedWaitForHost: {0}", Status.NeedWaitForHost.Wait);
if (Status.NeedWaitForHost.Wait)
{
if (MeetingInfo == null)
{
MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "",
GetSharingStatus(), false, false, true, MeetingIsLockedFeedback.BoolValue);
GetSharingStatus(), false, false, true);
UpdateCallStatus();
break;
}
MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "",
GetSharingStatus(), false, false, true, MeetingIsLockedFeedback.BoolValue);
GetSharingStatus(), false, false, true);
UpdateCallStatus();
@@ -1534,12 +1470,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
if (MeetingInfo == null)
{
MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "",
GetSharingStatus(), false, false, false, MeetingIsLockedFeedback.BoolValue);
GetSharingStatus(), false, false, false);
break;
}
MeetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password,
GetSharingStatus(), GetIsHostMyself(), false, false, MeetingIsLockedFeedback.BoolValue);
GetSharingStatus(), GetIsHostMyself(), false, false);
break;
}
@@ -1623,7 +1559,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
if (result.Success)
{
MeetingInfo = new MeetingInfo("", "", "", "", "", true, true, MeetingInfo.WaitingForHost, MeetingIsLockedFeedback.BoolValue);
MeetingInfo = new MeetingInfo("", "", "", "", "", true, true, MeetingInfo.WaitingForHost);
break;
}
@@ -1968,22 +1904,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
GetSharingStatus(),
GetIsHostMyself(),
!String.Equals(Status.Call.Info.meeting_type,"NORMAL"),
false,
MeetingIsLockedFeedback.BoolValue
);
}
// TODO [ ] Issue #868
else if (item.Status == eCodecCallStatus.Disconnected)
{
MeetingInfo = new MeetingInfo(
string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
false,
false,
false,
false
);
}
@@ -2212,7 +2132,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
var layoutsCodec = this as IHasZoomRoomLayouts;
if (layoutsCodec != null)
{
layoutsCodec.LayoutInfoChanged += (o, a) =>
layoutsCodec.AvailableLayoutsChanged += (o, a) =>
{
trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery
==
@@ -2298,48 +2218,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]);
}
// TODO [ ] Issue #868
MeetingInfoChanged += (device, args) =>
{
trilist.SetString(joinMap.MeetingInfoId.JoinNumber, args.Info.Id);
trilist.SetString(joinMap.MeetingInfoHost.JoinNumber, args.Info.Host);
trilist.SetString(joinMap.MeetingInfoPassword.JoinNumber, args.Info.Password);
trilist.SetBool(joinMap.IsHost.JoinNumber, args.Info.IsHost);
trilist.SetBool(joinMap.ShareOnlyMeeting.JoinNumber, args.Info.IsSharingMeeting);
trilist.SetBool(joinMap.WaitingForHost.JoinNumber, args.Info.WaitingForHost);
//trilist.SetString(joinMap.CurrentSource.JoinNumber, args.Info.ShareStatus);
};
// TODO [ ] Issue #868
trilist.SetSigTrueAction(joinMap.StartMeetingNow.JoinNumber, () => StartMeeting(0));
trilist.SetSigTrueAction(joinMap.ShareOnlyMeeting.JoinNumber, StartSharingOnlyMeeting);
trilist.SetSigTrueAction(joinMap.StartNormalMeetingFromSharingOnlyMeeting.JoinNumber, StartNormalMeetingFromSharingOnlyMeeting);
// TODO [ ] Issue #868
trilist.SetStringSigAction(joinMap.SubmitPassword.JoinNumber, SubmitPassword);
PasswordRequired += (devices, args) =>
{
if (args.LoginAttemptCancelled)
{
trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, false);
return;
}
if (!string.IsNullOrEmpty(args.Message))
{
trilist.SetString(joinMap.PasswordPromptMessage.JoinNumber, args.Message);
}
if (args.LoginAttemptFailed)
{
// login attempt failed
return;
}
trilist.SetBool(joinMap.PasswordIncorrect.JoinNumber, args.LastAttemptWasIncorrect);
trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, true);
};
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
@@ -2456,56 +2334,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
}
/// <summary>
/// Invites contacts to a new meeting for a specified duration
/// </summary>
/// <param name="contacts"></param>
/// <param name="duration"></param>
public void InviteContactsToNewMeeting(List<InvitableDirectoryContact> contacts, uint duration)
{
if(duration == 0)
{
duration = DefaultMeetingDurationMin;
}
StringBuilder message = new StringBuilder();
// Add the prefix
message.Append(string.Format("zCommand Invite Duration: {0}", duration));
// Add each invitee
foreach (var contact in contacts)
{
var invitee = string.Format(" user: {0}", contact.ContactId);
message.Append(invitee);
}
SendText(message.ToString());
}
/// <summary>
/// Invites contacts to an existing meeting
/// </summary>
/// <param name="contacts"></param>
public void InviteContactsToExistingMeeting(List<InvitableDirectoryContact> contacts)
{
StringBuilder message = new StringBuilder();
// Add the prefix
message.Append(string.Format("zCommand Call Invite"));
// Add each invitee
foreach (var contact in contacts)
{
var invitee = string.Format(" user: {0}", contact.ContactId);
message.Append(invitee);
}
SendText(message.ToString());
}
/// <summary>
/// Starts a PMI Meeting for the specified duration (or default meeting duration if 0 is specified)
@@ -2641,25 +2469,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public CodecParticipants Participants { get; private set; }
public void RemoveParticipant(int userId)
{
SendText(string.Format("zCommand Call Expel Id: {0}", userId));
}
public void SetParticipantAsHost(int userId)
{
SendText(string.Format("zCommand Call HostChange Id: {0}", userId));
}
#endregion
#region IHasParticipantAudioMute Members
public void MuteAudioForAllParticipants()
{
SendText(string.Format("zCommand Call MuteAll Mute: on"));
}
public void MuteAudioForParticipant(int userId)
{
SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId));
@@ -2957,7 +2770,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
#region IHasZoomRoomLayouts Members
public event EventHandler<LayoutInfoChangedEventArgs> LayoutInfoChanged;
public event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
private Func<bool> LayoutViewIsOnFirstPageFeedbackFunc
{
@@ -3023,26 +2836,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
Debug.Console(1, this, "availablelayouts: {0}", availableLayouts);
var handler = AvailableLayoutsChanged;
if (handler != null)
{
handler(this, new LayoutInfoChangedEventArgs() {AvailableLayouts = availableLayouts});
}
AvailableLayouts = availableLayouts;
}
private void OnLayoutInfoChanged()
{
var handler = LayoutInfoChanged;
if (handler != null)
{
handler(this, new LayoutInfoChangedEventArgs()
{
AvailableLayouts = AvailableLayouts,
CurrentSelectedLayout = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle),LocalLayoutFeedback.StringValue, true),
LayoutViewIsOnFirstPage = LayoutViewIsOnFirstPageFeedback.BoolValue,
LayoutViewIsOnLastPage = LayoutViewIsOnLastPageFeedback.BoolValue,
CanSwapContentWithThumbnail = CanSwapContentWithThumbnailFeedback.BoolValue,
ContentSwappedWithThumbnail = ContentSwappedWithThumbnailFeedback.BoolValue,
});
}
}
public void GetAvailableLayouts()
{
SendText("zStatus Call Layout");
@@ -3232,63 +3034,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
#endregion
#region IHasMeetingLock Members
public BoolFeedback MeetingIsLockedFeedback { get; private set; }
public void LockMeeting()
{
SendText(string.Format("zConfiguration Call Lock Enable: on"));
}
public void UnLockMeeting()
{
SendText(string.Format("zConfiguration Call Lock Enable: off"));
}
public void ToggleMeetingLock()
{
if (MeetingIsLockedFeedback.BoolValue)
{
UnLockMeeting();
}
else
{
LockMeeting();
}
}
#endregion
#region IHasMeetingRecording Members
public BoolFeedback MeetingIsRecordingFeedback { get; private set; }
public void StartRecording()
{
SendText(string.Format("Command Call Record Enable: on"));
}
public void StopRecording()
{
SendText(string.Format("Command Call Record Enable: off"));
}
public void ToggleRecording()
{
if (MeetingIsRecordingFeedback.BoolValue)
{
StopRecording();
}
else
{
StartRecording();
}
}
#endregion
}
}
/// <summary>
/// Zoom Room specific info object
@@ -3301,10 +3047,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
Configuration = configuration;
}
[JsonIgnore]
public ZoomRoomStatus Status { get; private set; }
[JsonIgnore]
public ZoomRoomConfiguration Configuration { get; private set; }
public ZoomRoomConfiguration Configuration { get; private set; }
public override bool AutoAnswerEnabled
{

View File

@@ -1,481 +1,301 @@
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges.JoinMaps;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public class ZoomRoomJoinMap : VideoCodecControllerJoinMap
{
#region Digital
// TODO [ ] Issue #868
[JoinName("ShowPasswordPrompt")]
public JoinDataComplete ShowPasswordPrompt = new JoinDataComplete(
new JoinData
{
JoinNumber = 6,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates to show the password prompt",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
// TODO [ ] Issue #868
[JoinName("PasswordIncorrect")]
public JoinDataComplete PasswordIncorrect = new JoinDataComplete(
new JoinData
{
JoinNumber = 7,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates the password entered is incorrect",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
// TODO [ ] Issue #868
[JoinName("WaitingForHost")]
public JoinDataComplete WaitingForHost = new JoinDataComplete(
new JoinData
{
JoinNumber = 8,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates system is waiting for host",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
// TODO [ ] Issue #868
[JoinName("IsHost")]
public JoinDataComplete IsHost = new JoinDataComplete(
new JoinData
{
JoinNumber = 9,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates system is the host",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
// TODO [ ] Issue #868
[JoinName("StartMeetingNow")]
public JoinDataComplete StartMeetingNow = new JoinDataComplete(
new JoinData
{
JoinNumber = 25,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates the password prompt is active",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
// TODO [ ] Issue #868
[JoinName("ShareOnlyMeeting")]
public JoinDataComplete ShareOnlyMeeting = new JoinDataComplete(
new JoinData
{
JoinNumber = 26,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Triggers a share only meeting, feedback indicates the current meeting is share only",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
// TODO [ ] Issue #868
[JoinName("StartNormalMeetingFromSharingOnlyMeeting")]
public JoinDataComplete StartNormalMeetingFromSharingOnlyMeeting = new JoinDataComplete(
new JoinData
{
JoinNumber = 27,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Starts a normal meeting from a share only meeting",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("CanSwapContentWithThumbnail")]
public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if content can be swapped with thumbnail",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("SwapContentWithThumbnail")]
public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Pulse to swap content with thumbnail. FB reports current state",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("GetAvailableLayouts")]
public JoinDataComplete GetAvailableLayouts = new JoinDataComplete(
new JoinData
{
JoinNumber = 215,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutIsOnFirstPage")]
public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 216,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Indicates if layout is on first page",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutIsOnLastPage")]
public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 217,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Indicates if layout is on first page",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutTurnToNextPage")]
public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 216,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Turns layout view to next page",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutTurnToPreviousPage")]
public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 217,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Turns layout view to previous page",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutGalleryIsAvailable")]
public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Gallery' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutSpeakerIsAvailable")]
public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 222,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Speaker' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutStripIsAvailable")]
public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 223,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Strip' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutShareAllIsAvailable")]
public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 224,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'ShareAll' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
// TODO: #714 [ ] JoinMap >> SelfivewPipSizeToggle
[JoinName("SelfviewPipSizeToggle")]
public JoinDataComplete SelfviewPipSizeToggle = new JoinDataComplete(
new JoinData
{
JoinNumber = 231,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Toggles the selfview pip size, (aka layout size)",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
//[JoinName("ParticipantAudioMuteToggleStart")]
//public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 500,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's audio mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantVideoMuteToggleStart")]
//public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 800,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's video mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantPinToggleStart")]
//public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 1100,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's pin status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
#endregion
#region Analog
[JoinName("NumberOfScreens")]
public JoinDataComplete NumberOfScreens = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Reports the number of screens connected",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("ScreenIndexToPinUserTo")]
public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Specifies the screen index a participant should be pinned to",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
#endregion
#region Serials
// TODO [ ] Issue #868
[JoinName("SubmitPassword")]
public JoinDataComplete SubmitPassword = new JoinDataComplete(
new JoinData
{
JoinNumber = 6,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Submit password text",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
// TODO [ ] Issue #868
[JoinName("PasswordPromptMessage")]
public JoinDataComplete PasswordPromptMessage = new JoinDataComplete(
new JoinData
{
JoinNumber = 6,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Password prompt message",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
// TODO [ ] Issue #868
[JoinName("MeetingInfoId")]
public JoinDataComplete MeetingInfoId = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Meeting info ID text feedback",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
// TODO [ ] Issue #868
[JoinName("MeetingInfoHostt")]
public JoinDataComplete MeetingInfoHost = new JoinDataComplete(
new JoinData
{
JoinNumber = 12,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Meeting info Host text feedback",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
// TODO [ ] Issue #868
[JoinName("MeetingInfoPassword")]
public JoinDataComplete MeetingInfoPassword = new JoinDataComplete(
new JoinData
{
JoinNumber = 13,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Meeting info Password text feedback",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("GetSetCurrentLayout")]
public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 215,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
// TODO: #714 [ ] JoinMap >> GetSetSelfviewPipSize
[JoinName("GetSetSelfviewPipSize")]
public JoinDataComplete GetSetSelfviewPipSize = new JoinDataComplete(
new JoinData
{
JoinNumber = 230,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets and reports the selfview pip size, (aka layout size).",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.DigitalSerial
});
#endregion
public ZoomRoomJoinMap(uint joinStart)
: base(joinStart, typeof(ZoomRoomJoinMap))
{
}
public ZoomRoomJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges.JoinMaps;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public class ZoomRoomJoinMap : VideoCodecControllerJoinMap
{
#region Digital
[JoinName("CanSwapContentWithThumbnail")]
public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if content can be swapped with thumbnail",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("SwapContentWithThumbnail")]
public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Pulse to swap content with thumbnail. FB reports current state",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("GetAvailableLayouts")]
public JoinDataComplete GetAvailableLayouts = new JoinDataComplete(
new JoinData
{
JoinNumber = 215,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutIsOnFirstPage")]
public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 216,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Indicates if layout is on first page",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutIsOnLastPage")]
public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 217,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Indicates if layout is on first page",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutTurnToNextPage")]
public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 216,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Turns layout view to next page",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutTurnToPreviousPage")]
public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete(
new JoinData
{
JoinNumber = 217,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Turns layout view to previous page",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("LayoutGalleryIsAvailable")]
public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Gallery' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutSpeakerIsAvailable")]
public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 222,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Speaker' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutStripIsAvailable")]
public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 223,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'Strip' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutShareAllIsAvailable")]
public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete(
new JoinData
{
JoinNumber = 224,
JoinSpan = 1
},
new JoinMetadata
{
Description = "FB Indicates if layout 'ShareAll' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.DigitalSerial
});
// TODO: #714 [ ] JoinMap >> SelfivewPipSizeToggle
[JoinName("SelfviewPipSizeToggle")]
public JoinDataComplete SelfviewPipSizeToggle = new JoinDataComplete(
new JoinData
{
JoinNumber = 231,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Toggles the selfview pip size, (aka layout size)",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
//[JoinName("ParticipantAudioMuteToggleStart")]
//public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 500,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's audio mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantVideoMuteToggleStart")]
//public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 800,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's video mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantPinToggleStart")]
//public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 1100,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's pin status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
#endregion
#region Analog
[JoinName("NumberOfScreens")]
public JoinDataComplete NumberOfScreens = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Reports the number of screens connected",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("ScreenIndexToPinUserTo")]
public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete(
new JoinData
{
JoinNumber = 11,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Specifies the screen index a participant should be pinned to",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
#endregion
#region Serials
[JoinName("GetSetCurrentLayout")]
public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 215,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
// TODO: #714 [ ] JoinMap >> GetSetSelfviewPipSize
[JoinName("GetSetSelfviewPipSize")]
public JoinDataComplete GetSetSelfviewPipSize = new JoinDataComplete(
new JoinData
{
JoinNumber = 230,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets and reports the selfview pip size, (aka layout size).",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.DigitalSerial
});
#endregion
public ZoomRoomJoinMap(uint joinStart)
: base(joinStart, typeof(ZoomRoomJoinMap))
{
}
public ZoomRoomJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}