mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-22 08:05:00 +00:00
Compare commits
140 Commits
1.8.5-hotf
...
1.9.3-hotf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
864e0675ea | ||
|
|
82af1366df | ||
|
|
56492a00cd | ||
|
|
f4ac4e6319 | ||
|
|
66ff6b2e07 | ||
|
|
e7bbfbd40a | ||
|
|
eec86fde48 | ||
|
|
7b57ce439e | ||
|
|
28bac18667 | ||
|
|
ea254ef983 | ||
|
|
76e4d4a82d | ||
|
|
4bd777f6b9 | ||
|
|
f607394ee7 | ||
|
|
085a64c87b | ||
|
|
5d120391a5 | ||
|
|
290e887903 | ||
|
|
de7a74eaff | ||
|
|
88e5c49663 | ||
|
|
1415999d86 | ||
|
|
db5aa319ec | ||
|
|
5f6b650dba | ||
|
|
94c0e92f6b | ||
|
|
a5046df671 | ||
|
|
5a4f7b6a28 | ||
|
|
10f5516a5a | ||
|
|
dfaaa3f6bc | ||
|
|
45e6dff26d | ||
|
|
10129b8178 | ||
|
|
9128e108f7 | ||
|
|
760ec8be92 | ||
|
|
bbcdd3e179 | ||
|
|
7a649f4ea8 | ||
|
|
6946946c12 | ||
|
|
dca73e1508 | ||
|
|
990090e1de | ||
|
|
377cccf912 | ||
|
|
9795637d75 | ||
|
|
6f6ca50c37 | ||
|
|
7b7ec53355 | ||
|
|
e3920132bf | ||
|
|
c2e5bd290a | ||
|
|
7fd52814a0 | ||
|
|
06a3dda2e4 | ||
|
|
d97ca6d5a4 | ||
|
|
4c50d6980f | ||
|
|
3b843104d8 | ||
|
|
a37814ab3c | ||
|
|
2181410927 | ||
|
|
d4191ceb75 | ||
|
|
5f6d15c6c0 | ||
|
|
4cc40227fd | ||
|
|
d0dbbe095f | ||
|
|
c7180db2b7 | ||
|
|
d95ee27979 | ||
|
|
e964172200 | ||
|
|
840934502b | ||
|
|
a76f4c15dc | ||
|
|
b19e2e38ad | ||
|
|
9a7fe553f9 | ||
|
|
e6ecaf3a1e | ||
|
|
895b76a0cd | ||
|
|
5c9996e728 | ||
|
|
0cc2328276 | ||
|
|
8fadfa98f2 | ||
|
|
1ccf54003f | ||
|
|
54769ce270 | ||
|
|
6b85323949 | ||
|
|
319d8f99c5 | ||
|
|
cc742f4291 | ||
|
|
6beff106ec | ||
|
|
cb35aa13f5 | ||
|
|
b71523bd2d | ||
|
|
0c56da112c | ||
|
|
08f4d8e9a2 | ||
|
|
25e7e9634a | ||
|
|
7ac3f81ea5 | ||
|
|
1c06e8381b | ||
|
|
f5305197b3 | ||
|
|
1805ebaf0f | ||
|
|
ca8207f2bd | ||
|
|
4e81859695 | ||
|
|
655bb954fa | ||
|
|
1ebacf3f0f | ||
|
|
7de0251188 | ||
|
|
492e593263 | ||
|
|
afe2046c81 | ||
|
|
98d3a4a2fa | ||
|
|
1702c69b73 | ||
|
|
722d28b1b3 | ||
|
|
ef7da0d7af | ||
|
|
77d8e63a31 | ||
|
|
d2d99d4bfa | ||
|
|
4bd71b04bf | ||
|
|
c5bcd89695 | ||
|
|
c7cc98bff7 | ||
|
|
db60f8f1be | ||
|
|
e82efdde2d | ||
|
|
d00c8bed5f | ||
|
|
a91af6bd75 | ||
|
|
2d36b80800 | ||
|
|
e152b9a504 | ||
|
|
eac7c91327 | ||
|
|
ac0d5e59a0 | ||
|
|
78be8ec5f2 | ||
|
|
5fc4ff6027 | ||
|
|
63853739f3 | ||
|
|
c14193f9ac | ||
|
|
da179c01f5 | ||
|
|
0ded3e30f9 | ||
|
|
8d215930d9 | ||
|
|
b4edb021ee | ||
|
|
52caa98f33 | ||
|
|
4e041d1773 | ||
|
|
118bd5a54a | ||
|
|
116abbf962 | ||
|
|
a06333e1c3 | ||
|
|
d937dc14fc | ||
|
|
604f4ca22d | ||
|
|
2d7ad8ba2a | ||
|
|
e4a3933743 | ||
|
|
d6445861f5 | ||
|
|
03b076c8eb | ||
|
|
7c58221acc | ||
|
|
14f7c27b33 | ||
|
|
9ea65883b7 | ||
|
|
9d0020d999 | ||
|
|
fb44a3b93c | ||
|
|
6b7c5c01f8 | ||
|
|
1a3eb9a546 | ||
|
|
44c171c8f4 | ||
|
|
ae9833ffaa | ||
|
|
685c344785 | ||
|
|
e6f5142fc3 | ||
|
|
3c9ca1e527 | ||
|
|
452d0a5a39 | ||
|
|
8643ed2caf | ||
|
|
2787c7fc52 | ||
|
|
babc3e4f1a | ||
|
|
0a4ff82af0 | ||
|
|
b455e1af21 |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,6 +7,9 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
**Was this bug identified in a specific build version?**
|
||||||
|
Please note the build version where this bug was identified
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
|||||||
27
.github/ISSUE_TEMPLATE/rfi_request.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/rfi_request.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
name: Request for Information
|
||||||
|
about: Request specific information about capabilities of the framework
|
||||||
|
title: "[RFI]-"
|
||||||
|
labels: RFI
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**What is your request?**
|
||||||
|
Please provide as much detail as possible.
|
||||||
|
|
||||||
|
|
||||||
|
**What is the intended use case**
|
||||||
|
- [ ] Essentials Standalone Application
|
||||||
|
- [ ] Essentials + SIMPL Windows Hybrid
|
||||||
|
|
||||||
|
**User Interface Requirements**
|
||||||
|
- [ ] Not Applicable (logic only)
|
||||||
|
- [ ] Crestron Smart Graphics Touchpanel
|
||||||
|
- [ ] Cisco Touch10
|
||||||
|
- [ ] Mobile Control
|
||||||
|
- [ ] Crestron CH5 Touchpanel interface
|
||||||
|
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the request here.
|
||||||
1
.github/workflows/docker.yml
vendored
1
.github/workflows/docker.yml
vendored
@@ -90,7 +90,6 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# Upload the build package to the release
|
# Upload the build package to the release
|
||||||
- name: Upload Release Package
|
- name: Upload Release Package
|
||||||
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
|
|
||||||
id: upload_release
|
id: upload_release
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace PepperDash.Essentials
|
|||||||
Thread.MaxNumberOfUserThreads = 400;
|
Thread.MaxNumberOfUserThreads = 400;
|
||||||
Global.ControlSystem = this;
|
Global.ControlSystem = this;
|
||||||
DeviceManager.Initialize(this);
|
DeviceManager.Initialize(this);
|
||||||
|
SecretsManager.Initialize();
|
||||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ namespace PepperDash.Essentials
|
|||||||
CrestronConsole.AddNewConsoleCommand(s =>
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
{
|
{
|
||||||
foreach (var tl in TieLineCollection.Default)
|
foreach (var tl in TieLineCollection.Default)
|
||||||
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
|
CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl);
|
||||||
},
|
},
|
||||||
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
|
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
@@ -85,8 +86,8 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
CrestronConsole.AddNewConsoleCommand(s =>
|
CrestronConsole.AddNewConsoleCommand(s =>
|
||||||
{
|
{
|
||||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" +
|
||||||
"System URL: {0}\r" +
|
"System URL: {0}\r\n" +
|
||||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
||||||
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
@@ -130,29 +131,46 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
|
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
|
||||||
{
|
{
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString());
|
string userFolder;
|
||||||
|
string nvramFolder;
|
||||||
|
bool is4series = false;
|
||||||
|
|
||||||
|
if (eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4)) // Handle 4-series
|
||||||
|
{
|
||||||
|
is4series = true;
|
||||||
|
// Set path to user/
|
||||||
|
userFolder = "user";
|
||||||
|
nvramFolder = "nvram";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
userFolder = "User";
|
||||||
|
nvramFolder = "Nvram";
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, is4series ? "4-series" : "3-series");
|
||||||
|
|
||||||
// Check if User/ProgramX exists
|
// Check if User/ProgramX exists
|
||||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
|
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + userFolder
|
||||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
||||||
{
|
{
|
||||||
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
Debug.Console(0, @"{0}/program{1} directory found", userFolder, InitialParametersClass.ApplicationNumber);
|
||||||
filePathPrefix = directoryPrefix + dirSeparator + "User"
|
filePathPrefix = directoryPrefix + dirSeparator + userFolder
|
||||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||||
}
|
}
|
||||||
// Check if Nvram/Programx exists
|
// Check if Nvram/Programx exists
|
||||||
else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram"
|
else if (Directory.Exists(directoryPrefix + dirSeparator + nvramFolder
|
||||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
||||||
{
|
{
|
||||||
Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
Debug.Console(0, @"{0}/program{1} directory found", nvramFolder, InitialParametersClass.ApplicationNumber);
|
||||||
filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
|
filePathPrefix = directoryPrefix + dirSeparator + nvramFolder
|
||||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||||
}
|
}
|
||||||
// If neither exists, set path to User/ProgramX
|
// If neither exists, set path to User/ProgramX
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
|
Debug.Console(0, @"No previous directory found. Using {0}/program{1}", userFolder, InitialParametersClass.ApplicationNumber);
|
||||||
filePathPrefix = directoryPrefix + dirSeparator + "User"
|
filePathPrefix = directoryPrefix + dirSeparator + userFolder
|
||||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,14 +450,13 @@ namespace PepperDash.Essentials
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
|
|
||||||
{
|
|
||||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
|
||||||
if (room != null)
|
|
||||||
{
|
|
||||||
// default IPID
|
|
||||||
uint fusionIpId = 0xf1;
|
uint fusionIpId = 0xf1;
|
||||||
|
|
||||||
|
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
|
||||||
|
{
|
||||||
|
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
|
||||||
|
if (room != null)
|
||||||
|
{
|
||||||
// default to no join map key
|
// default to no join map key
|
||||||
string fusionJoinMapKey = string.Empty;
|
string fusionJoinMapKey = string.Empty;
|
||||||
|
|
||||||
@@ -456,11 +473,11 @@ namespace PepperDash.Essentials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (room is EssentialsHuddleSpaceRoom)
|
if (room is IEssentialsHuddleSpaceRoom)
|
||||||
{
|
{
|
||||||
DeviceManager.AddDevice(room);
|
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));
|
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||||
|
|
||||||
|
|
||||||
@@ -468,12 +485,12 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
CreateMobileControlBridge(room);
|
CreateMobileControlBridge(room);
|
||||||
}
|
}
|
||||||
else if (room is EssentialsHuddleVtc1Room)
|
else if (room is IEssentialsHuddleVtc1Room)
|
||||||
{
|
{
|
||||||
DeviceManager.AddDevice(room);
|
DeviceManager.AddDevice(room);
|
||||||
|
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||||
|
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||||
|
|
||||||
@@ -484,7 +501,7 @@ namespace PepperDash.Essentials
|
|||||||
DeviceManager.AddDevice(room);
|
DeviceManager.AddDevice(room);
|
||||||
|
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
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));
|
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
|
||||||
|
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||||
@@ -497,16 +514,20 @@ namespace PepperDash.Essentials
|
|||||||
DeviceManager.AddDevice(room);
|
DeviceManager.AddDevice(room);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fusionIpId += 1;
|
||||||
}
|
}
|
||||||
else
|
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, "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.");
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateMobileControlBridge(EssentialsRoomBase room)
|
private static void CreateMobileControlBridge(IEssentialsRoom room)
|
||||||
{
|
{
|
||||||
var mobileControl = GetMobileControlDevice();
|
var mobileControl = GetMobileControlDevice();
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
{
|
{
|
||||||
BooleanSigData CodecIsInCall;
|
BooleanSigData CodecIsInCall;
|
||||||
|
|
||||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
public EssentialsHuddleVtc1FusionController(IEssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||||
: base(room, ipId, joinMapKey)
|
: base(room, ipId, joinMapKey)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
|
||||||
|
|
||||||
if (codec == null)
|
if (codec == null)
|
||||||
{
|
{
|
||||||
@@ -141,7 +141,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
|
|
||||||
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||||
{
|
{
|
||||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
|
||||||
|
|
||||||
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
|
|
||||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
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 = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||||
@@ -174,11 +174,11 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
// Moved to
|
// Moved to
|
||||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
|
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||||
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
(Room as IEssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||||
|
|
||||||
|
|
||||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as IEssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||||
|
|
||||||
|
|
||||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||||
@@ -187,7 +187,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
protected override void SetUpSources()
|
protected override void SetUpSources()
|
||||||
{
|
{
|
||||||
// Sources
|
// Sources
|
||||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as IEssentialsHuddleVtc1Room).SourceListKey);
|
||||||
if (dict != null)
|
if (dict != null)
|
||||||
{
|
{
|
||||||
// NEW PROCESS:
|
// NEW PROCESS:
|
||||||
@@ -238,7 +238,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
|
||||||
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
(Room as IEssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
var defaultDisplay = (Room as IEssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||||
if (defaultDisplay == null)
|
if (defaultDisplay == null)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||||
@@ -332,7 +332,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
string displayName = string.Format("Display {0} - ", displayIndex);
|
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||||
|
|
||||||
|
|
||||||
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
|
if (display == (Room as IEssentialsHuddleVtc1Room).DefaultDisplay)
|
||||||
{
|
{
|
||||||
// Power on
|
// Power on
|
||||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||||
@@ -351,7 +351,7 @@ namespace PepperDash.Essentials.Fusion
|
|||||||
|
|
||||||
// Current Source
|
// Current Source
|
||||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||||
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
|
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,6 +149,8 @@
|
|||||||
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||||
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
||||||
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
|
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
|
||||||
|
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleSpaceRoom.cs" />
|
||||||
|
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleVtc1Room.cs" />
|
||||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
|
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
|
||||||
/// Returns null if there is no emergency defined
|
/// Returns null if there is no emergency defined
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room)
|
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room)
|
||||||
{
|
{
|
||||||
// This emergency
|
// This emergency
|
||||||
var emergency = props.Emergency;
|
var emergency = props.Emergency;
|
||||||
@@ -96,7 +96,7 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
if (behaviour == "trackroomstate")
|
if (behaviour == "trackroomstate")
|
||||||
{
|
{
|
||||||
// Tie LED enable to room power state
|
// Tie LED enable to room power state
|
||||||
var essRoom = room as EssentialsRoomBase;
|
var essRoom = room as IEssentialsRoom;
|
||||||
essRoom.OnFeedback.OutputChange += (o, a) =>
|
essRoom.OnFeedback.OutputChange += (o, a) =>
|
||||||
{
|
{
|
||||||
if (essRoom.OnFeedback.BoolValue)
|
if (essRoom.OnFeedback.BoolValue)
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ namespace PepperDash.Essentials.Room
|
|||||||
|
|
||||||
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
||||||
{
|
{
|
||||||
EssentialsRoomBase Room;
|
IEssentialsRoom Room;
|
||||||
string Behavior;
|
string Behavior;
|
||||||
bool TriggerOnClose;
|
bool TriggerOnClose;
|
||||||
|
|
||||||
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, EssentialsRoomBase room) :
|
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
|
||||||
base(key)
|
base(key)
|
||||||
{
|
{
|
||||||
Room = room;
|
Room = room;
|
||||||
|
|||||||
@@ -645,9 +645,9 @@ namespace PepperDash.Essentials
|
|||||||
public static void AllRoomsOff()
|
public static void AllRoomsOff()
|
||||||
{
|
{
|
||||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
d is IEssentialsHuddleSpaceRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
foreach (var room in allRooms)
|
foreach (var room in allRooms)
|
||||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey);
|
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as IEssentialsHuddleSpaceRoom).SourceListKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IPrivacy Members
|
#region IPrivacy Members
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IEssentialsHuddleSpaceRoom
|
||||||
{
|
{
|
||||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange,
|
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
|
||||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
|
||||||
{
|
{
|
||||||
private bool _codecExternalSourceChange;
|
private bool _codecExternalSourceChange;
|
||||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
@@ -734,9 +733,9 @@ namespace PepperDash.Essentials
|
|||||||
public static void AllRoomsOff()
|
public static void AllRoomsOff()
|
||||||
{
|
{
|
||||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
foreach (var room in allRooms)
|
foreach (var room in allRooms)
|
||||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -107,14 +107,18 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
||||||
{
|
{
|
||||||
|
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
|
||||||
|
|
||||||
if (!_currentPresets.ContainsKey(device.Key))
|
if (!_currentPresets.ContainsKey(device.Key))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
|
||||||
|
|
||||||
_currentPresets[device.Key] = channel;
|
_currentPresets[device.Key] = channel;
|
||||||
|
|
||||||
if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
if (CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||||
{
|
{
|
||||||
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay
|
||||||
|
{
|
||||||
|
bool ExcludeFromGlobalFunctions { get; }
|
||||||
|
|
||||||
|
void RunRouteAction(string routeKey);
|
||||||
|
|
||||||
|
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||||
|
|
||||||
|
IBasicVolumeControls CurrentVolumeControls { get; }
|
||||||
|
|
||||||
|
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
|
||||||
|
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||||
|
{
|
||||||
|
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||||
|
|
||||||
|
void RunRouteAction(string routeKey);
|
||||||
|
|
||||||
|
IHasScheduleAwareness ScheduleSource { get; }
|
||||||
|
|
||||||
|
new BoolFeedback InCallFeedback { get; }
|
||||||
|
|
||||||
|
new BoolFeedback PrivacyModeIsOnFeedback { get; }
|
||||||
|
|
||||||
|
string DefaultCodecRouteString { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,6 +79,16 @@ namespace PepperDash.Essentials
|
|||||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||||
else if (type == "tsw1060")
|
else if (type == "tsw1060")
|
||||||
Panel = new Tsw1060(id, Global.ControlSystem);
|
Panel = new Tsw1060(id, Global.ControlSystem);
|
||||||
|
else if (type == "tsw570")
|
||||||
|
Panel = new Tsw570(id, Global.ControlSystem);
|
||||||
|
else if (type == "tsw770")
|
||||||
|
Panel = new Tsw770(id, Global.ControlSystem);
|
||||||
|
else if (type == "ts770")
|
||||||
|
Panel = new Ts770(id, Global.ControlSystem);
|
||||||
|
else if (type == "tsw1070")
|
||||||
|
Panel = new Tsw1070(id, Global.ControlSystem);
|
||||||
|
else if (type == "ts1070")
|
||||||
|
Panel = new Ts1070(id, Global.ControlSystem);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||||
@@ -203,7 +213,7 @@ namespace PepperDash.Essentials
|
|||||||
{
|
{
|
||||||
public EssentialsTouchpanelControllerFactory()
|
public EssentialsTouchpanelControllerFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" };
|
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
@@ -222,7 +232,7 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
// spin up different room drivers depending on room type
|
// spin up different room drivers depending on room type
|
||||||
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
||||||
if (room is EssentialsHuddleSpaceRoom)
|
if (room is IEssentialsHuddleSpaceRoom)
|
||||||
{
|
{
|
||||||
// Screen Saver Driver
|
// Screen Saver Driver
|
||||||
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props);
|
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props);
|
||||||
@@ -236,7 +246,7 @@ namespace PepperDash.Essentials
|
|||||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||||
mainDriver.AvDriver = avDriver;
|
mainDriver.AvDriver = avDriver;
|
||||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom;
|
||||||
|
|
||||||
// Environment Driver
|
// Environment Driver
|
||||||
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
|
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
|
||||||
@@ -270,7 +280,7 @@ namespace PepperDash.Essentials
|
|||||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (room is EssentialsHuddleVtc1Room)
|
else if (room is IEssentialsHuddleVtc1Room)
|
||||||
{
|
{
|
||||||
Debug.Console(0, panelController, "Adding huddle space VTC AV driver");
|
Debug.Console(0, panelController, "Adding huddle space VTC AV driver");
|
||||||
|
|
||||||
@@ -284,11 +294,11 @@ namespace PepperDash.Essentials
|
|||||||
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props);
|
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props);
|
||||||
|
|
||||||
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
|
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
|
||||||
(room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
|
(room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
|
||||||
avDriver.SetVideoCodecDriver(codecDriver);
|
avDriver.SetVideoCodecDriver(codecDriver);
|
||||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||||
mainDriver.AvDriver = avDriver;
|
mainDriver.AvDriver = avDriver;
|
||||||
avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room;
|
avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room;
|
||||||
|
|
||||||
// Environment Driver
|
// Environment Driver
|
||||||
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
|
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
|
||||||
|
|||||||
@@ -764,6 +764,10 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint NextMeetingModalVisible = 15049;
|
public const uint NextMeetingModalVisible = 15049;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 15050
|
||||||
|
/// </summary>
|
||||||
|
public const uint NextMeetingNotificationRibbonVisible = 15050;
|
||||||
|
/// <summary>
|
||||||
/// 15051
|
/// 15051
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint Display1SelectPressAndFb = 15051;
|
public const uint Display1SelectPressAndFb = 15051;
|
||||||
|
|||||||
@@ -146,18 +146,18 @@
|
|||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void CurrentRoom_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
// void CurrentRoom_CurrentSourceInfoChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||||
// {
|
// {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
// void CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||||
// {
|
// {
|
||||||
// TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName;
|
// TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName;
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// void CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
// void CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||||
// {
|
// {
|
||||||
// TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName;
|
// TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName;
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace PepperDash.Essentials
|
|||||||
CaretInterlock = new JoinedSigInterlock(TriList);
|
CaretInterlock = new JoinedSigInterlock(TriList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom)
|
void SetUpGear(IAVDriver avDriver, IEssentialsRoom currentRoom)
|
||||||
{
|
{
|
||||||
// Gear
|
// Gear
|
||||||
TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear");
|
TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear");
|
||||||
@@ -105,7 +105,7 @@ namespace PepperDash.Essentials
|
|||||||
{
|
{
|
||||||
string message = null;
|
string message = null;
|
||||||
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
|
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
|
||||||
as EssentialsHuddleSpaceRoom;
|
as IEssentialsHuddleSpaceRoom;
|
||||||
if (room != null)
|
if (room != null)
|
||||||
message = room.PropertiesConfig.HelpMessage;
|
message = room.PropertiesConfig.HelpMessage;
|
||||||
else
|
else
|
||||||
@@ -207,6 +207,7 @@ namespace PepperDash.Essentials
|
|||||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
||||||
|
|
||||||
// Set the call status text
|
// Set the call status text
|
||||||
|
Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count);
|
||||||
if (codec.ActiveCalls.Count > 0)
|
if (codec.ActiveCalls.Count > 0)
|
||||||
{
|
{
|
||||||
if (codec.ActiveCalls.Count == 1)
|
if (codec.ActiveCalls.Count == 1)
|
||||||
@@ -221,7 +222,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets up Header Buttons for the EssentialsHuddleVtc1Room type
|
/// Sets up Header Buttons for the EssentialsHuddleVtc1Room type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom)
|
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, IEssentialsHuddleVtc1Room currentRoom)
|
||||||
{
|
{
|
||||||
HeaderButtonsAreSetUp = false;
|
HeaderButtonsAreSetUp = false;
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type
|
/// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom)
|
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, IEssentialsHuddleSpaceRoom currentRoom)
|
||||||
{
|
{
|
||||||
HeaderButtonsAreSetUp = false;
|
HeaderButtonsAreSetUp = false;
|
||||||
|
|
||||||
|
|||||||
@@ -983,7 +983,7 @@
|
|||||||
// /// <summary>
|
// /// <summary>
|
||||||
// /// Handles source change
|
// /// Handles source change
|
||||||
// /// </summary>
|
// /// </summary>
|
||||||
// void _CurrentRoom_SourceInfoChange(EssentialsRoomBase room,
|
// void _CurrentRoom_SourceInfoChange(IEssentialsRoom room,
|
||||||
// SourceListItem info, ChangeType change)
|
// SourceListItem info, ChangeType change)
|
||||||
// {
|
// {
|
||||||
// if (change == ChangeType.WillChange)
|
// if (change == ChangeType.WillChange)
|
||||||
@@ -995,7 +995,7 @@
|
|||||||
// /// <summary>
|
// /// <summary>
|
||||||
// ///
|
// ///
|
||||||
// /// </summary>
|
// /// </summary>
|
||||||
// void _CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
// void _CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||||
// {
|
// {
|
||||||
// if (type == ChangeType.DidChange)
|
// if (type == ChangeType.DidChange)
|
||||||
// {
|
// {
|
||||||
@@ -1021,7 +1021,7 @@
|
|||||||
// /// <summary>
|
// /// <summary>
|
||||||
// ///
|
// ///
|
||||||
// /// </summary>
|
// /// </summary>
|
||||||
// void _CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
// void _CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||||
// {
|
// {
|
||||||
// if (type == ChangeType.DidChange)
|
// if (type == ChangeType.DidChange)
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EssentialsHuddleSpaceRoom CurrentRoom
|
public IEssentialsHuddleSpaceRoom CurrentRoom
|
||||||
{
|
{
|
||||||
get { return _CurrentRoom; }
|
get { return _CurrentRoom; }
|
||||||
set
|
set
|
||||||
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials
|
|||||||
SetCurrentRoom(value);
|
SetCurrentRoom(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EssentialsHuddleSpaceRoom _CurrentRoom;
|
IEssentialsHuddleSpaceRoom _CurrentRoom;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -498,7 +498,7 @@ namespace PepperDash.Essentials
|
|||||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
||||||
// Run default source when room is off and share is pressed
|
// Run default source when room is off and share is pressed
|
||||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||||
CurrentRoom.RunDefaultPresentRoute();
|
(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -583,7 +583,7 @@ namespace PepperDash.Essentials
|
|||||||
void UiSelectSource(string key)
|
void UiSelectSource(string key)
|
||||||
{
|
{
|
||||||
// Run the route and when it calls back, show the source
|
// Run the route and when it calls back, show the source
|
||||||
CurrentRoom.RunRouteAction(key, new Action(() => { }));
|
CurrentRoom.RunRouteAction(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -745,7 +745,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
|
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room)
|
public void RefreshCurrentRoom(IEssentialsHuddleSpaceRoom room)
|
||||||
{
|
{
|
||||||
if (_CurrentRoom != null)
|
if (_CurrentRoom != null)
|
||||||
{
|
{
|
||||||
@@ -836,7 +836,7 @@ namespace PepperDash.Essentials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
|
void SetCurrentRoom(IEssentialsHuddleSpaceRoom room)
|
||||||
{
|
{
|
||||||
if (_CurrentRoom == room) return;
|
if (_CurrentRoom == room) return;
|
||||||
// Disconnect current (probably never called)
|
// Disconnect current (probably never called)
|
||||||
@@ -871,7 +871,7 @@ namespace PepperDash.Essentials
|
|||||||
UpdateMCJoins(_CurrentRoom);
|
UpdateMCJoins(_CurrentRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateMCJoins(EssentialsHuddleSpaceRoom room)
|
void UpdateMCJoins(IEssentialsHuddleSpaceRoom room)
|
||||||
{
|
{
|
||||||
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
|
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
|
||||||
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
|
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EssentialsHuddleVtc1Room CurrentRoom
|
public IEssentialsHuddleVtc1Room CurrentRoom
|
||||||
{
|
{
|
||||||
get { return _CurrentRoom; }
|
get { return _CurrentRoom; }
|
||||||
set
|
set
|
||||||
@@ -58,7 +58,7 @@ namespace PepperDash.Essentials
|
|||||||
SetCurrentRoom(value);
|
SetCurrentRoom(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EssentialsHuddleVtc1Room _CurrentRoom;
|
IEssentialsHuddleVtc1Room _CurrentRoom;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For hitting feedbacks
|
/// For hitting feedbacks
|
||||||
@@ -652,7 +652,7 @@ namespace PepperDash.Essentials
|
|||||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||||
{
|
{
|
||||||
// If there's no default, show UI elements
|
// If there's no default, show UI elements
|
||||||
if (!CurrentRoom.RunDefaultPresentRoute())
|
if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute())
|
||||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -743,7 +743,7 @@ namespace PepperDash.Essentials
|
|||||||
void UiSelectSource(string key)
|
void UiSelectSource(string key)
|
||||||
{
|
{
|
||||||
// Run the route and when it calls back, show the source
|
// Run the route and when it calls back, show the source
|
||||||
CurrentRoom.RunRouteAction(key, new Action(() => { }));
|
CurrentRoom.RunRouteAction(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -894,7 +894,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
|
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void RefreshCurrentRoom(EssentialsHuddleVtc1Room room)
|
void RefreshCurrentRoom(IEssentialsHuddleVtc1Room room)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (_CurrentRoom != null)
|
if (_CurrentRoom != null)
|
||||||
@@ -969,7 +969,7 @@ namespace PepperDash.Essentials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCurrentRoom(EssentialsHuddleVtc1Room room)
|
void SetCurrentRoom(IEssentialsHuddleVtc1Room room)
|
||||||
{
|
{
|
||||||
if (_CurrentRoom == room) return;
|
if (_CurrentRoom == room) return;
|
||||||
// Disconnect current (probably never called)
|
// Disconnect current (probably never called)
|
||||||
@@ -1004,7 +1004,7 @@ namespace PepperDash.Essentials
|
|||||||
UpdateMCJoins(_CurrentRoom);
|
UpdateMCJoins(_CurrentRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateMCJoins(EssentialsHuddleVtc1Room room)
|
void UpdateMCJoins(IEssentialsHuddleVtc1Room room)
|
||||||
{
|
{
|
||||||
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
|
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
|
||||||
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
|
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
|
||||||
@@ -1035,7 +1035,7 @@ namespace PepperDash.Essentials
|
|||||||
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
||||||
{
|
{
|
||||||
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
||||||
CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey);
|
CurrentRoom.RunRouteAction("codecOsd");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1443,7 +1443,7 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAVWithVCDriver : IAVDriver
|
public interface IAVWithVCDriver : IAVDriver
|
||||||
{
|
{
|
||||||
EssentialsHuddleVtc1Room CurrentRoom { get; }
|
IEssentialsHuddleVtc1Room CurrentRoom { get; }
|
||||||
|
|
||||||
PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; }
|
PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace PepperDash.Essentials
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets feedback for the given room
|
/// Sets feedback for the given room
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetFeedbackForRoom(EssentialsHuddleSpaceRoom room)
|
public void SetFeedbackForRoom(IEssentialsHuddleSpaceRoom room)
|
||||||
{
|
{
|
||||||
var itemToSet = Items.FirstOrDefault(i => i.Room == room);
|
var itemToSet = Items.FirstOrDefault(i => i.Room == room);
|
||||||
if (itemToSet != null)
|
if (itemToSet != null)
|
||||||
@@ -48,11 +48,11 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
public class SmartObjectRoomsListItem
|
public class SmartObjectRoomsListItem
|
||||||
{
|
{
|
||||||
public EssentialsHuddleSpaceRoom Room { get; private set; }
|
public IEssentialsHuddleSpaceRoom Room { get; private set; }
|
||||||
SmartObjectRoomsList Parent;
|
SmartObjectRoomsList Parent;
|
||||||
public uint Index { get; private set; }
|
public uint Index { get; private set; }
|
||||||
|
|
||||||
public SmartObjectRoomsListItem(EssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent,
|
public SmartObjectRoomsListItem(IEssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent,
|
||||||
Action<bool> buttonAction)
|
Action<bool> buttonAction)
|
||||||
{
|
{
|
||||||
Room = room;
|
Room = room;
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ namespace PepperDash.Essentials
|
|||||||
///// <summary>
|
///// <summary>
|
||||||
///// The handler type for a Room's SourceInfoChange
|
///// The handler type for a Room's SourceInfoChange
|
||||||
///// </summary>
|
///// </summary>
|
||||||
//public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
|
//public delegate void SourceInfoChangeHandler(IEssentialsRoom room, SourceListItem info, ChangeType type);
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
{
|
{
|
||||||
public EiscApiAdvancedFactory()
|
public EiscApiAdvancedFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "vceiscapiadv", "vceiscapiadvanced" };
|
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
@@ -403,6 +403,16 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
||||||
return new EiscApiAdvanced(dc, eisc);
|
return new EiscApiAdvanced(dc, eisc);
|
||||||
}
|
}
|
||||||
|
case "eiscapiadvancedserver":
|
||||||
|
{
|
||||||
|
var eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
|
||||||
|
return new EiscApiAdvanced(dc, eisc);
|
||||||
|
}
|
||||||
|
case "eiscapiadvancedclient":
|
||||||
|
{
|
||||||
|
var eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
||||||
|
return new EiscApiAdvanced(dc, eisc);
|
||||||
|
}
|
||||||
case "vceiscapiadv":
|
case "vceiscapiadv":
|
||||||
case "vceiscapiadvanced":
|
case "vceiscapiadvanced":
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,15 +24,6 @@ namespace PepperDash.Essentials.Core.Bridges
|
|||||||
public JoinDataComplete OutputAudio = new JoinDataComplete(new JoinData { JoinNumber = 301, JoinSpan = 32 },
|
public JoinDataComplete OutputAudio = new JoinDataComplete(new JoinData { JoinNumber = 301, JoinSpan = 32 },
|
||||||
new JoinMetadata { Description = "DM Chassis Output Audio Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
|
new JoinMetadata { Description = "DM Chassis Output Audio Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
|
||||||
|
|
||||||
[JoinName("OutputAudioSourceDevice")] public JoinDataComplete OutputAudioSourceDevice =
|
|
||||||
new JoinDataComplete(new JoinData {JoinNumber = 401, JoinSpan = 32},
|
|
||||||
new JoinMetadata
|
|
||||||
{
|
|
||||||
Description = "DMPS HDMI/DM Output Source Device selection",
|
|
||||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
|
||||||
JoinType = eJoinType.Analog
|
|
||||||
});
|
|
||||||
|
|
||||||
[JoinName("InputNames")]
|
[JoinName("InputNames")]
|
||||||
public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
|
public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
|
||||||
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
public GenericComm(DeviceConfig config)
|
public GenericComm(DeviceConfig config)
|
||||||
: base(config)
|
: base(config)
|
||||||
{
|
{
|
||||||
|
|
||||||
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
||||||
|
|
||||||
var commPort = CommFactory.CreateCommForDevice(config);
|
var commPort = CommFactory.CreateCommForDevice(config);
|
||||||
|
|||||||
@@ -31,6 +31,18 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
[JsonProperty("properties")]
|
[JsonProperty("properties")]
|
||||||
[JsonConverter(typeof(DevicePropertiesConverter))]
|
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||||
public JToken Properties { get; set; }
|
public JToken Properties { get; set; }
|
||||||
|
|
||||||
|
public DeviceConfig(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Key = dc.Key;
|
||||||
|
Uid = dc.Uid;
|
||||||
|
Name = dc.Name;
|
||||||
|
Group = dc.Group;
|
||||||
|
Type = dc.Type;
|
||||||
|
Properties = JToken.FromObject(dc.Properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceConfig() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
|
var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key));
|
||||||
|
|
||||||
if (deviceConfig != null)
|
if (deviceConfigIndex >= 0)
|
||||||
{
|
{
|
||||||
deviceConfig = config;
|
ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config;
|
||||||
|
|
||||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||||
|
|
||||||
@@ -74,13 +74,13 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
|
var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key));
|
||||||
|
|
||||||
if (deviceConfig != null)
|
if (roomConfigIndex >= 0)
|
||||||
{
|
{
|
||||||
deviceConfig = config;
|
ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config;
|
||||||
|
|
||||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
Debug.Console(1, "Updated room of device: '{0}'", config.Key);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.GeneralIO;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.CrestronIO
|
||||||
|
{
|
||||||
|
public class C2NIoController:CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IRelayPorts
|
||||||
|
{
|
||||||
|
private C2nIo _device;
|
||||||
|
|
||||||
|
public C2NIoController(string key, Func<DeviceConfig, C2nIo> preActivationFunc, DeviceConfig config):base(key, config.Name)
|
||||||
|
{
|
||||||
|
AddPreActivationAction(() =>
|
||||||
|
{
|
||||||
|
_device = preActivationFunc(config);
|
||||||
|
|
||||||
|
RegisterCrestronGenericBase(_device);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Implementation of IComPorts
|
||||||
|
|
||||||
|
public CrestronCollection<ComPort> ComPorts
|
||||||
|
{
|
||||||
|
get { return _device.ComPorts; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfComPorts
|
||||||
|
{
|
||||||
|
get { return _device.NumberOfComPorts; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implementation of IIROutputPorts
|
||||||
|
|
||||||
|
public CrestronCollection<IROutputPort> IROutputPorts
|
||||||
|
{
|
||||||
|
get { return _device.IROutputPorts; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfIROutputPorts
|
||||||
|
{
|
||||||
|
get { return _device.NumberOfIROutputPorts; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implementation of IRelayPorts
|
||||||
|
|
||||||
|
public CrestronCollection<Relay> RelayPorts
|
||||||
|
{
|
||||||
|
get { return _device.RelayPorts; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumberOfRelayPorts
|
||||||
|
{
|
||||||
|
get { return _device.NumberOfRelayPorts; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class C2NIoControllerFactory : EssentialsDeviceFactory<C2nRthsController>
|
||||||
|
{
|
||||||
|
public C2NIoControllerFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "c2nio" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Factory Attempting to create new C2N-IO Device");
|
||||||
|
|
||||||
|
return new C2NIoController(dc.Key, GetC2NIoDevice, dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static C2nIo GetC2NIoDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
var control = CommFactory.GetControlPropertiesConfig(dc);
|
||||||
|
var cresnetId = control.CresnetIdInt;
|
||||||
|
var branchId = control.ControlPortNumber;
|
||||||
|
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
|
||||||
|
|
||||||
|
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nIo", parentKey);
|
||||||
|
return new C2nIo(cresnetId, Global.ControlSystem);
|
||||||
|
}
|
||||||
|
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
|
||||||
|
|
||||||
|
if (cresnetBridge != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nIo", parentKey);
|
||||||
|
return new C2nIo(cresnetId, cresnetBridge.CresnetBranches[branchId]);
|
||||||
|
}
|
||||||
|
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IMobileControl : IKeyed
|
public interface IMobileControl : IKeyed
|
||||||
{
|
{
|
||||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
|
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
|
||||||
|
|
||||||
void LinkSystemMonitorToAppServer();
|
void LinkSystemMonitorToAppServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,25 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="json"></param>
|
/// <param name="json"></param>
|
||||||
public static void DoDeviceActionWithJson(string json)
|
public static void DoDeviceActionWithJson(string json)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse(
|
||||||
|
"Please provide a JSON object matching the format {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}.\r\nIf the method has no parameters, the \"params\" object may be omitted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
|
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
|
||||||
|
|
||||||
DoDeviceAction(action);
|
DoDeviceAction(action);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -34,28 +49,62 @@ namespace PepperDash.Essentials.Core
|
|||||||
var key = action.DeviceKey;
|
var key = action.DeviceKey;
|
||||||
var obj = FindObjectOnPath(key);
|
var obj = FindObjectOnPath(key);
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.Params == null)
|
||||||
|
{
|
||||||
|
//no params, so setting action.Params to empty array
|
||||||
|
action.Params = new object[0];
|
||||||
|
}
|
||||||
|
|
||||||
CType t = obj.GetType();
|
CType t = obj.GetType();
|
||||||
var method = t.GetMethod(action.MethodName);
|
try
|
||||||
|
{
|
||||||
|
var methods = t.GetMethods().Where(m => m.Name == action.MethodName).ToList();
|
||||||
|
|
||||||
|
var method = methods.Count == 1 ? methods[0] : methods.FirstOrDefault(m => m.GetParameters().Length == action.Params.Length);
|
||||||
|
|
||||||
if (method == null)
|
if (method == null)
|
||||||
{
|
{
|
||||||
Debug.Console(0, "Method '{0}' not found", action.MethodName);
|
CrestronConsole.ConsoleCommandResponse(
|
||||||
|
"Unable to find method with name {0} and that matches parameters {1}", action.MethodName,
|
||||||
|
action.Params);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var mParams = method.GetParameters();
|
var mParams = method.GetParameters();
|
||||||
// Add empty params if not provided
|
|
||||||
if (action.Params == null) action.Params = new object[0];
|
var convertedParams = mParams
|
||||||
if (mParams.Length > action.Params.Length)
|
.Select((p, i) => ConvertType(action.Params[i], p.ParameterType))
|
||||||
{
|
|
||||||
Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
object[] convertedParams = mParams
|
|
||||||
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
|
|
||||||
System.Globalization.CultureInfo.InvariantCulture))
|
|
||||||
.ToArray();
|
.ToArray();
|
||||||
object ret = method.Invoke(obj, convertedParams);
|
method.Invoke(obj, convertedParams);
|
||||||
|
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name,
|
||||||
|
action.DeviceKey);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
CrestronConsole.ConsoleCommandResponse("Unable to call method with name {0}. {1}", action.MethodName,
|
||||||
|
ex.Message);}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object ConvertType(object value, Type conversionType)
|
||||||
|
{
|
||||||
|
if (!conversionType.IsEnum)
|
||||||
|
{
|
||||||
|
return Convert.ChangeType(value, conversionType, System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringValue = Convert.ToString(value);
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(stringValue))
|
||||||
|
{
|
||||||
|
throw new InvalidCastException(
|
||||||
|
String.Format("{0} cannot be converted to a string prior to conversion to enum"));
|
||||||
|
}
|
||||||
|
return Enum.Parse(conversionType, stringValue, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -242,6 +291,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
|
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
|
||||||
//return JsonConvert.SerializeObject(props, Formatting.Indented);
|
//return JsonConvert.SerializeObject(props, Formatting.Indented);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeviceActionWrapper
|
public class DeviceActionWrapper
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
DeviceCriticalSection.Enter();
|
DeviceCriticalSection.Enter();
|
||||||
AddDeviceEnabled = false;
|
AddDeviceEnabled = false;
|
||||||
// PreActivate all devices
|
// PreActivate all devices
|
||||||
|
Debug.Console(0,"****PreActivation starting...****");
|
||||||
foreach (var d in Devices.Values)
|
foreach (var d in Devices.Values)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -69,9 +70,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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
|
// Activate all devices
|
||||||
foreach (var d in Devices.Values)
|
foreach (var d in Devices.Values)
|
||||||
@@ -83,10 +87,14 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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
|
// PostActivate all devices
|
||||||
foreach (var d in Devices.Values)
|
foreach (var d in Devices.Values)
|
||||||
{
|
{
|
||||||
@@ -97,10 +105,13 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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();
|
OnAllDevicesActivated();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -435,7 +446,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
var min = Convert.ToUInt32(timeout);
|
var min = Convert.ToUInt32(timeout);
|
||||||
|
|
||||||
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
||||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
|
Debug.Console(0, "Device: '{0}' debug level set to {1} for {2} minutes", deviceKey, debugSetting, min);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -19,13 +19,34 @@ namespace PepperDash.Essentials.Core
|
|||||||
protected EssentialsDevice(string key)
|
protected EssentialsDevice(string key)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
|
SubscribeToActivateComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EssentialsDevice(string key, string name)
|
protected EssentialsDevice(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
|
SubscribeToActivateComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToActivateComplete()
|
||||||
|
{
|
||||||
|
DeviceManager.AllDevicesActivated += DeviceManagerOnAllDevicesActivated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeviceManagerOnAllDevicesActivated(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
|
CrestronInvoke.BeginInvoke((o) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Exception initializing device: {0}", ex.Message);
|
||||||
|
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Devices
|
||||||
|
{
|
||||||
|
public interface IReconfigurableDevice
|
||||||
|
{
|
||||||
|
event EventHandler<EventArgs> ConfigChanged;
|
||||||
|
|
||||||
|
DeviceConfig Config { get; }
|
||||||
|
|
||||||
|
void SetConfig(DeviceConfig config);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,13 +7,15 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
|||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core.Devices
|
namespace PepperDash.Essentials.Core.Devices
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ReconfigurableDevice : EssentialsDevice
|
public abstract class ReconfigurableDevice : EssentialsDevice, IReconfigurableDevice
|
||||||
{
|
{
|
||||||
public event EventHandler<EventArgs> ConfigChanged;
|
public event EventHandler<EventArgs> ConfigChanged;
|
||||||
|
|
||||||
@@ -52,6 +54,8 @@ namespace PepperDash.Essentials.Core.Devices
|
|||||||
Name = config.Name;
|
Name = config.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
|
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
|
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
|
||||||
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
|
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
|
||||||
|
|
||||||
|
WarmupTime = 10000;
|
||||||
|
CooldownTime = 5000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PowerOn()
|
public override void PowerOn()
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class JsonExtensions
|
||||||
|
{
|
||||||
|
public static List<JToken> FindTokens(this JToken containerToken, string name)
|
||||||
|
{
|
||||||
|
List<JToken> matches = new List<JToken>();
|
||||||
|
FindTokens(containerToken, name, matches);
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
|
||||||
|
{
|
||||||
|
if (containerToken.Type == JTokenType.Object)
|
||||||
|
{
|
||||||
|
foreach (JProperty child in containerToken.Children<JProperty>())
|
||||||
|
{
|
||||||
|
if (child.Name == name)
|
||||||
|
{
|
||||||
|
matches.Add(child.Value);
|
||||||
|
}
|
||||||
|
FindTokens(child.Value, name, matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (containerToken.Type == JTokenType.Array)
|
||||||
|
{
|
||||||
|
foreach (JToken child in containerToken.Children())
|
||||||
|
{
|
||||||
|
FindTokens(child, name, matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ using Crestron.SimplSharpPro;
|
|||||||
using Crestron.SimplSharpPro.GeneralIO;
|
using Crestron.SimplSharpPro.GeneralIO;
|
||||||
using Crestron.SimplSharp.Reflection;
|
using Crestron.SimplSharp.Reflection;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.CrestronIO;
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
@@ -85,6 +87,35 @@ namespace PepperDash.Essentials.Core
|
|||||||
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CheckForSecrets(IEnumerable<JProperty> obj)
|
||||||
|
{
|
||||||
|
foreach (var prop in obj.Where(prop => prop.Value as JObject != null))
|
||||||
|
{
|
||||||
|
if (prop.Name.ToLower() == "secret")
|
||||||
|
{
|
||||||
|
var secret = GetSecret(prop.Children().First().ToObject<SecretsPropertiesConfig>());
|
||||||
|
//var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
|
||||||
|
prop.Parent.Replace(secret);
|
||||||
|
}
|
||||||
|
var recurseProp = prop.Value as JObject;
|
||||||
|
if (recurseProp == null) return;
|
||||||
|
CheckForSecrets(recurseProp.Properties());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetSecret(SecretsPropertiesConfig data)
|
||||||
|
{
|
||||||
|
var secretProvider = SecretsManager.GetSecretProviderByKey(data.Provider);
|
||||||
|
if (secretProvider == null) return null;
|
||||||
|
var secret = secretProvider.GetSecret(data.Key);
|
||||||
|
if (secret != null) return (string) secret.Value;
|
||||||
|
Debug.Console(1,
|
||||||
|
"Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider",
|
||||||
|
data.Provider, data.Key);
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The factory method for Core "things". Also iterates the Factory methods that have
|
/// The factory method for Core "things". Also iterates the Factory methods that have
|
||||||
/// been loaded from plugins
|
/// been loaded from plugins
|
||||||
@@ -93,22 +124,41 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IKeyed GetDevice(DeviceConfig dc)
|
public static IKeyed GetDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
var key = dc.Key;
|
try
|
||||||
var name = dc.Name;
|
|
||||||
var type = dc.Type;
|
|
||||||
var properties = dc.Properties;
|
|
||||||
|
|
||||||
var typeName = dc.Type.ToLower();
|
|
||||||
|
|
||||||
// Check for types that have been added by plugin dlls.
|
|
||||||
if (FactoryMethods.ContainsKey(typeName))
|
|
||||||
{
|
{
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
||||||
return FactoryMethods[typeName].FactoryMethod(dc);
|
|
||||||
|
var localDc = new DeviceConfig(dc);
|
||||||
|
|
||||||
|
var key = localDc.Key;
|
||||||
|
var name = localDc.Name;
|
||||||
|
var type = localDc.Type;
|
||||||
|
var properties = localDc.Properties;
|
||||||
|
//var propRecurse = properties;
|
||||||
|
|
||||||
|
var typeName = localDc.Type.ToLower();
|
||||||
|
|
||||||
|
|
||||||
|
var jObject = properties as JObject;
|
||||||
|
if (jObject != null)
|
||||||
|
{
|
||||||
|
var jProp = jObject.Properties();
|
||||||
|
|
||||||
|
CheckForSecrets(jProp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Console(2, "typeName = {0}", typeName);
|
||||||
|
// Check for types that have been added by plugin dlls.
|
||||||
|
return !FactoryMethods.ContainsKey(typeName) ? null : FactoryMethods[typeName].FactoryMethod(localDc);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
|
||||||
|
|
||||||
|
Debug.Console(2, "{0}", ex.StackTrace);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ namespace PepperDash.Essentials.Core
|
|||||||
ValueFunc = valueFunc;
|
ValueFunc = valueFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValueFunc(Func<bool> newFunc)
|
||||||
|
{
|
||||||
|
ValueFunc = newFunc;
|
||||||
|
}
|
||||||
|
|
||||||
public override void FireUpdate()
|
public override void FireUpdate()
|
||||||
{
|
{
|
||||||
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
protected bool ComputedValue;
|
protected bool ComputedValue;
|
||||||
|
|
||||||
public BoolFeedbackLogic()
|
protected BoolFeedbackLogic()
|
||||||
{
|
{
|
||||||
Output = new BoolFeedback(() => ComputedValue);
|
Output = new BoolFeedback(() => ComputedValue);
|
||||||
}
|
}
|
||||||
@@ -40,11 +40,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
public void AddOutputsIn(List<BoolFeedback> outputs)
|
public void AddOutputsIn(List<BoolFeedback> outputs)
|
||||||
{
|
{
|
||||||
foreach (var o in outputs)
|
foreach (var o in outputs.Where(o => !OutputsIn.Contains(o)))
|
||||||
{
|
{
|
||||||
// skip existing
|
|
||||||
if (OutputsIn.Contains(o)) continue;
|
|
||||||
|
|
||||||
OutputsIn.Add(o);
|
OutputsIn.Add(o);
|
||||||
o.OutputChange += AnyInput_OutputChange;
|
o.OutputChange += AnyInput_OutputChange;
|
||||||
}
|
}
|
||||||
@@ -54,7 +51,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
public void RemoveOutputIn(BoolFeedback output)
|
public void RemoveOutputIn(BoolFeedback output)
|
||||||
{
|
{
|
||||||
// Don't double up outputs
|
// Don't double up outputs
|
||||||
if (OutputsIn.Contains(output)) return;
|
if (!OutputsIn.Contains(output)) return;
|
||||||
|
|
||||||
OutputsIn.Remove(output);
|
OutputsIn.Remove(output);
|
||||||
output.OutputChange -= AnyInput_OutputChange;
|
output.OutputChange -= AnyInput_OutputChange;
|
||||||
@@ -71,6 +68,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
Evaluate();
|
Evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearOutputs()
|
||||||
|
{
|
||||||
|
OutputsIn.Clear();
|
||||||
|
Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
void AnyInput_OutputChange(object sender, EventArgs e)
|
void AnyInput_OutputChange(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Evaluate();
|
Evaluate();
|
||||||
@@ -85,13 +88,14 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
var prevValue = ComputedValue;
|
var prevValue = ComputedValue;
|
||||||
var newValue = OutputsIn.All(o => o.BoolValue);
|
var newValue = OutputsIn.All(o => o.BoolValue);
|
||||||
if (newValue != prevValue)
|
if (newValue == prevValue)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
ComputedValue = newValue;
|
ComputedValue = newValue;
|
||||||
Output.FireUpdate();
|
Output.FireUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class BoolFeedbackOr : BoolFeedbackLogic
|
public class BoolFeedbackOr : BoolFeedbackLogic
|
||||||
{
|
{
|
||||||
@@ -99,33 +103,35 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
var prevValue = ComputedValue;
|
var prevValue = ComputedValue;
|
||||||
var newValue = OutputsIn.Any(o => o.BoolValue);
|
var newValue = OutputsIn.Any(o => o.BoolValue);
|
||||||
if (newValue != prevValue)
|
if (newValue == prevValue)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
ComputedValue = newValue;
|
ComputedValue = newValue;
|
||||||
Output.FireUpdate();
|
Output.FireUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class BoolFeedbackLinq : BoolFeedbackLogic
|
public class BoolFeedbackLinq : BoolFeedbackLogic
|
||||||
{
|
{
|
||||||
Func<IEnumerable<BoolFeedback>, bool> Predicate;
|
readonly Func<IEnumerable<BoolFeedback>, bool> _predicate;
|
||||||
|
|
||||||
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
|
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
Predicate = predicate;
|
_predicate = predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Evaluate()
|
protected override void Evaluate()
|
||||||
{
|
{
|
||||||
var prevValue = ComputedValue;
|
var prevValue = ComputedValue;
|
||||||
var newValue = Predicate(OutputsIn);
|
var newValue = _predicate(OutputsIn);
|
||||||
if (newValue != prevValue)
|
if (newValue == prevValue)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
ComputedValue = newValue;
|
ComputedValue = newValue;
|
||||||
Output.FireUpdate();
|
Output.FireUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -51,6 +51,12 @@ namespace PepperDash.Essentials.Core
|
|||||||
ValueFunc = valueFunc;
|
ValueFunc = valueFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValueFunc(Func<int> newFunc)
|
||||||
|
{
|
||||||
|
ValueFunc = newFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void FireUpdate()
|
public override void FireUpdate()
|
||||||
{
|
{
|
||||||
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||||
|
|||||||
@@ -52,7 +52,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
ValueFunc = valueFunc;
|
ValueFunc = valueFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValueFunc(Func<string> newFunc)
|
||||||
|
{
|
||||||
|
ValueFunc = newFunc;
|
||||||
|
}
|
||||||
|
|
||||||
public override void FireUpdate()
|
public override void FireUpdate()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
protected FusionRoom FusionRoom;
|
protected FusionRoom FusionRoom;
|
||||||
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
||||||
public long PushNotificationTimeout = 5000;
|
public long PushNotificationTimeout = 5000;
|
||||||
protected EssentialsRoomBase Room;
|
protected IEssentialsRoom Room;
|
||||||
public long SchedulePollInterval = 300000;
|
public long SchedulePollInterval = 300000;
|
||||||
|
|
||||||
private Event _currentMeeting;
|
private Event _currentMeeting;
|
||||||
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey)
|
public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey)
|
||||||
: base(room.Key + "-fusion")
|
: base(room.Key + "-fusion")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -119,8 +119,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
var slot = Global.ControlSystem.ProgramNumber;
|
var slot = Global.ControlSystem.ProgramNumber;
|
||||||
|
|
||||||
var guidFilePath = Global.FilePathPrefix +
|
var guidFilePath = Global.FilePathPrefix +
|
||||||
|
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
|
||||||
|
|
||||||
|
var oldGuidFilePath = Global.FilePathPrefix +
|
||||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
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);
|
_guidFileExists = File.Exists(guidFilePath);
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
@@ -149,7 +161,15 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AddPostActivationAction(() =>
|
AddPostActivationAction(() => PostActivate(guidFilePath));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error Building Fusion System Controller: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PostActivate(string guidFilePath)
|
||||||
{
|
{
|
||||||
CreateSymbolAndBasicSigs(_ipId);
|
CreateSymbolAndBasicSigs(_ipId);
|
||||||
SetUpSources();
|
SetUpSources();
|
||||||
@@ -161,12 +181,6 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
FusionRVI.GenerateFileForAllFusionDevices();
|
FusionRVI.GenerateFileForAllFusionDevices();
|
||||||
|
|
||||||
GenerateGuidFile(guidFilePath);
|
GenerateGuidFile(guidFilePath);
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error Building Fusion System Controller: {0}", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string RoomGuid
|
protected string RoomGuid
|
||||||
@@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
|
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 = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
|||||||
|
|
||||||
deviceConfig.Properties = JToken.FromObject(devProps);
|
deviceConfig.Properties = JToken.FromObject(devProps);
|
||||||
}
|
}
|
||||||
else if (device is EssentialsRoomBase)
|
else if (device is IEssentialsRoom)
|
||||||
{
|
{
|
||||||
// Set the room name
|
// Set the room name
|
||||||
if (!string.IsNullOrEmpty(roomInfo.Name))
|
if (!string.IsNullOrEmpty(roomInfo.Name))
|
||||||
|
|||||||
@@ -88,11 +88,6 @@ namespace PepperDash.Essentials.Core.Privacy
|
|||||||
else
|
else
|
||||||
Debug.Console(0, this, "Unable to add Red LED device");
|
Debug.Console(0, this, "Unable to add Red LED device");
|
||||||
|
|
||||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
|
||||||
{
|
|
||||||
CheckPrivacyMode();
|
|
||||||
};
|
|
||||||
|
|
||||||
AddPostActivationAction(() => {
|
AddPostActivationAction(() => {
|
||||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
||||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||||
@@ -103,6 +98,15 @@ namespace PepperDash.Essentials.Core.Privacy
|
|||||||
return base.CustomActivate();
|
return base.CustomActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Overrides of Device
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
CheckPrivacyMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public void SetPrivacyDevice(IPrivacy privacyDevice)
|
public void SetPrivacyDevice(IPrivacy privacyDevice)
|
||||||
{
|
{
|
||||||
PrivacyDevice = privacyDevice;
|
PrivacyDevice = privacyDevice;
|
||||||
|
|||||||
@@ -3,16 +3,17 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.GeneralIO;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects
|
/// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IOccupancyStatusProviderAggregator : Device, IOccupancyStatusProvider
|
public class IOccupancyStatusProviderAggregator : EssentialsDevice, IOccupancyStatusProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Aggregated feedback of all linked IOccupancyStatusProvider devices
|
/// Aggregated feedback of all linked IOccupancyStatusProvider devices
|
||||||
@@ -21,16 +22,51 @@ namespace PepperDash.Essentials.Core
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return AggregatedOccupancyStatus.Output;
|
return _aggregatedOccupancyStatus.Output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoolFeedbackOr AggregatedOccupancyStatus;
|
private readonly BoolFeedbackOr _aggregatedOccupancyStatus;
|
||||||
|
|
||||||
public IOccupancyStatusProviderAggregator(string key, string name)
|
public IOccupancyStatusProviderAggregator(string key, string name)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
AggregatedOccupancyStatus = new BoolFeedbackOr();
|
_aggregatedOccupancyStatus = new BoolFeedbackOr();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IOccupancyStatusProviderAggregator(string key, string name, OccupancyAggregatorConfig config)
|
||||||
|
: this(key, name)
|
||||||
|
{
|
||||||
|
AddPostActivationAction(() =>
|
||||||
|
{
|
||||||
|
if (config.DeviceKeys.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var deviceKey in config.DeviceKeys)
|
||||||
|
{
|
||||||
|
var device = DeviceManager.GetDeviceForKey(deviceKey);
|
||||||
|
|
||||||
|
if (device == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||||
|
"Unable to retrieve Occupancy provider with key {0}", deviceKey);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = device as IOccupancyStatusProvider;
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||||
|
"Device with key {0} does NOT implement IOccupancyStatusProvider. Please check configuration.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddOccupancyStatusProvider(provider);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -39,7 +75,35 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <param name="statusProvider"></param>
|
/// <param name="statusProvider"></param>
|
||||||
public void AddOccupancyStatusProvider(IOccupancyStatusProvider statusProvider)
|
public void AddOccupancyStatusProvider(IOccupancyStatusProvider statusProvider)
|
||||||
{
|
{
|
||||||
AggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback);
|
_aggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOccupancyStatusProvider(IOccupancyStatusProvider statusProvider)
|
||||||
|
{
|
||||||
|
_aggregatedOccupancyStatus.RemoveOutputIn(statusProvider.RoomIsOccupiedFeedback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearOccupancyStatusProviders()
|
||||||
|
{
|
||||||
|
_aggregatedOccupancyStatus.ClearOutputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OccupancyAggregatorFactory : EssentialsDeviceFactory<IOccupancyStatusProviderAggregator>
|
||||||
|
{
|
||||||
|
public OccupancyAggregatorFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string> { "occupancyAggregator", "occAggregate" };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
|
||||||
|
|
||||||
|
var config = dc.Properties.ToObject<OccupancyAggregatorConfig>();
|
||||||
|
|
||||||
|
return new IOccupancyStatusProviderAggregator(dc.Key, dc.Name, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class OccupancyAggregatorConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("deviceKeys")] public List<string> DeviceKeys { get; set; }
|
||||||
|
|
||||||
|
public OccupancyAggregatorConfig()
|
||||||
|
{
|
||||||
|
DeviceKeys = new List<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an abstract controller device for a partition dividing rooms that are combinable
|
||||||
|
///
|
||||||
|
/// In Auto mode, it can use a partition sensor to automatically determine whether the partition is present.
|
||||||
|
///
|
||||||
|
/// In Manual mode it accepts user input to tell it whether the partition is present.
|
||||||
|
/// </summary>
|
||||||
|
public class EssentialsPartitionController : IPartitionController
|
||||||
|
{
|
||||||
|
private IPartitionStateProvider _partitionSensor;
|
||||||
|
|
||||||
|
private bool isInAutoMode;
|
||||||
|
|
||||||
|
private bool partitionPresent;
|
||||||
|
|
||||||
|
public EssentialsPartitionController(string key, string name, IPartitionStateProvider sensor, bool defaultToManualMode, List<string> adjacentRoomKeys)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
|
||||||
|
Name = name;
|
||||||
|
|
||||||
|
AdjacentRoomKeys = adjacentRoomKeys;
|
||||||
|
|
||||||
|
if (sensor != null)
|
||||||
|
{
|
||||||
|
_partitionSensor = sensor;
|
||||||
|
|
||||||
|
if (!defaultToManualMode)
|
||||||
|
{
|
||||||
|
SetAutoMode();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetManualMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetManualMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||||
|
{
|
||||||
|
if (isInAutoMode)
|
||||||
|
{
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPartitionController Members
|
||||||
|
|
||||||
|
public List<string> AdjacentRoomKeys { get; private set; }
|
||||||
|
|
||||||
|
public void SetAutoMode()
|
||||||
|
{
|
||||||
|
isInAutoMode = true;
|
||||||
|
if (PartitionPresentFeedback != null)
|
||||||
|
{
|
||||||
|
PartitionPresentFeedback.SetValueFunc(() => _partitionSensor.PartitionPresentFeedback.BoolValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionPresentFeedback.BoolValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_partitionSensor != null)
|
||||||
|
{
|
||||||
|
_partitionSensor.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetManualMode()
|
||||||
|
{
|
||||||
|
isInAutoMode = false;
|
||||||
|
if (PartitionPresentFeedback != null)
|
||||||
|
{
|
||||||
|
PartitionPresentFeedback.SetValueFunc(() => partitionPresent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PartitionPresentFeedback = new BoolFeedback(() => partitionPresent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_partitionSensor != null)
|
||||||
|
{
|
||||||
|
_partitionSensor.PartitionPresentFeedback.OutputChange -= PartitionPresentFeedback_OutputChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetPartitionStatePresent()
|
||||||
|
{
|
||||||
|
if (!isInAutoMode)
|
||||||
|
{
|
||||||
|
partitionPresent = true;
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPartitionStateNotPresent()
|
||||||
|
{
|
||||||
|
if (!isInAutoMode)
|
||||||
|
{
|
||||||
|
partitionPresent = false;
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggglePartitionState()
|
||||||
|
{
|
||||||
|
if (!isInAutoMode)
|
||||||
|
{
|
||||||
|
partitionPresent = !partitionPresent;
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IPartitionStateProvider Members
|
||||||
|
|
||||||
|
public BoolFeedback PartitionPresentFeedback { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IKeyName Members
|
||||||
|
|
||||||
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IKeyed Members
|
||||||
|
|
||||||
|
public string Key { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,13 +13,13 @@ using PepperDash.Essentials.Core.Config;
|
|||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
[Description("Wrapper class for GLS Cresnet Partition Sensor")]
|
[Description("Wrapper class for GLS Cresnet Partition Sensor")]
|
||||||
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice
|
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice, IPartitionStateProvider
|
||||||
{
|
{
|
||||||
private GlsPartCn _partitionSensor;
|
private GlsPartCn _partitionSensor;
|
||||||
|
|
||||||
public StringFeedback NameFeedback { get; private set; }
|
public StringFeedback NameFeedback { get; private set; }
|
||||||
public BoolFeedback EnableFeedback { 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 BoolFeedback PartitionNotSensedFeedback { get; private set; }
|
||||||
public IntFeedback SensitivityFeedback { get; private set; }
|
public IntFeedback SensitivityFeedback { get; private set; }
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
RegisterCrestronGenericBase(_partitionSensor);
|
RegisterCrestronGenericBase(_partitionSensor);
|
||||||
|
|
||||||
NameFeedback = new StringFeedback(() => Name);
|
NameFeedback = new StringFeedback(() => Name);
|
||||||
EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue);
|
EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue);
|
||||||
PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue);
|
PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||||
PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||||
SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue);
|
SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue);
|
||||||
|
|
||||||
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
|
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
|
||||||
});
|
});
|
||||||
@@ -61,7 +61,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
case (GlsPartCn.PartitionSensedFeedbackEventId):
|
case (GlsPartCn.PartitionSensedFeedbackEventId):
|
||||||
{
|
{
|
||||||
PartitionSensedFeedback.FireUpdate();
|
PartitionPresentFeedback.FireUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (GlsPartCn.PartitionNotSensedFeedbackEventId):
|
case (GlsPartCn.PartitionNotSensedFeedbackEventId):
|
||||||
@@ -93,6 +93,9 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (InTestMode)
|
if (InTestMode)
|
||||||
{
|
{
|
||||||
TestEnableFeedback = state;
|
TestEnableFeedback = state;
|
||||||
|
|
||||||
|
EnableFeedback.FireUpdate();
|
||||||
|
|
||||||
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
|
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -105,6 +108,10 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (InTestMode)
|
if (InTestMode)
|
||||||
{
|
{
|
||||||
TestPartitionSensedFeedback = state;
|
TestPartitionSensedFeedback = state;
|
||||||
|
|
||||||
|
PartitionPresentFeedback.FireUpdate();
|
||||||
|
PartitionNotSensedFeedback.FireUpdate();
|
||||||
|
|
||||||
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
|
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -117,6 +124,8 @@ namespace PepperDash.Essentials.Core
|
|||||||
if (InTestMode)
|
if (InTestMode)
|
||||||
{
|
{
|
||||||
TestSensitivityFeedback = value;
|
TestSensitivityFeedback = value;
|
||||||
|
|
||||||
|
SensitivityFeedback.FireUpdate();
|
||||||
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
|
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -186,7 +195,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
// link output to simpl
|
// link output to simpl
|
||||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||||
EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.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]);
|
PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]);
|
||||||
SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]);
|
SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]);
|
||||||
|
|
||||||
@@ -216,7 +225,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
IsOnline.FireUpdate();
|
IsOnline.FireUpdate();
|
||||||
NameFeedback.FireUpdate();
|
NameFeedback.FireUpdate();
|
||||||
EnableFeedback.FireUpdate();
|
EnableFeedback.FireUpdate();
|
||||||
PartitionSensedFeedback.FireUpdate();
|
PartitionPresentFeedback.FireUpdate();
|
||||||
PartitionNotSensedFeedback.FireUpdate();
|
PartitionNotSensedFeedback.FireUpdate();
|
||||||
SensitivityFeedback.FireUpdate();
|
SensitivityFeedback.FireUpdate();
|
||||||
}
|
}
|
||||||
@@ -257,7 +266,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
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);
|
return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the functionality of a device that senses and provides partition state
|
||||||
|
/// </summary>
|
||||||
|
public interface IPartitionStateProvider : IKeyName
|
||||||
|
{
|
||||||
|
BoolFeedback PartitionPresentFeedback { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the functionality of a device that can provide partition state either manually via user input or optionally via a sensor state
|
||||||
|
/// </summary>
|
||||||
|
public interface IPartitionController : IPartitionStateProvider
|
||||||
|
{
|
||||||
|
List<string> AdjacentRoomKeys { get; }
|
||||||
|
|
||||||
|
void SetPartitionStatePresent();
|
||||||
|
|
||||||
|
void SetPartitionStateNotPresent();
|
||||||
|
|
||||||
|
void ToggglePartitionState();
|
||||||
|
|
||||||
|
void SetManualMode();
|
||||||
|
|
||||||
|
void SetAutoMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -162,6 +162,7 @@
|
|||||||
<Compile Include="Config\Essentials\ConfigWriter.cs" />
|
<Compile Include="Config\Essentials\ConfigWriter.cs" />
|
||||||
<Compile Include="Config\Essentials\EssentialsConfig.cs" />
|
<Compile Include="Config\Essentials\EssentialsConfig.cs" />
|
||||||
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
|
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
|
||||||
|
<Compile Include="Crestron IO\C2nIo\C2nIoController.cs" />
|
||||||
<Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" />
|
<Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" />
|
||||||
<Compile Include="Crestron IO\Cards\C3CardControllerBase.cs" />
|
<Compile Include="Crestron IO\Cards\C3CardControllerBase.cs" />
|
||||||
<Compile Include="Crestron IO\Cards\C3Com3Controller.cs" />
|
<Compile Include="Crestron IO\Cards\C3Com3Controller.cs" />
|
||||||
@@ -197,6 +198,7 @@
|
|||||||
<Compile Include="Devices\GenericIRController.cs" />
|
<Compile Include="Devices\GenericIRController.cs" />
|
||||||
<Compile Include="Devices\IDspPreset.cs" />
|
<Compile Include="Devices\IDspPreset.cs" />
|
||||||
<Compile Include="Devices\IProjectorInterfaces.cs" />
|
<Compile Include="Devices\IProjectorInterfaces.cs" />
|
||||||
|
<Compile Include="Devices\IReconfigurableDevice.cs" />
|
||||||
<Compile Include="Devices\PC\InRoomPc.cs" />
|
<Compile Include="Devices\PC\InRoomPc.cs" />
|
||||||
<Compile Include="Devices\PC\Laptop.cs" />
|
<Compile Include="Devices\PC\Laptop.cs" />
|
||||||
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
||||||
@@ -209,6 +211,7 @@
|
|||||||
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
|
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
|
||||||
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
|
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
|
||||||
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
|
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
|
||||||
|
<Compile Include="Extensions\JsonExtensions.cs" />
|
||||||
<Compile Include="Factory\DeviceFactory.cs" />
|
<Compile Include="Factory\DeviceFactory.cs" />
|
||||||
<Compile Include="Factory\IDeviceFactory.cs" />
|
<Compile Include="Factory\IDeviceFactory.cs" />
|
||||||
<Compile Include="Factory\ReadyEventArgs.cs" />
|
<Compile Include="Factory\ReadyEventArgs.cs" />
|
||||||
@@ -231,6 +234,9 @@
|
|||||||
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
|
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
|
||||||
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
|
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
|
||||||
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
|
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
|
||||||
|
<Compile Include="PartitionSensor\EssentialsPartitionController.cs" />
|
||||||
|
<Compile Include="PartitionSensor\IPartitionStateProvider.cs" />
|
||||||
|
<Compile Include="Occupancy\OccupancyAggregatorConfig.cs" />
|
||||||
<Compile Include="Queues\ComsMessage.cs" />
|
<Compile Include="Queues\ComsMessage.cs" />
|
||||||
<Compile Include="Queues\ProcessStringMessage.cs" />
|
<Compile Include="Queues\ProcessStringMessage.cs" />
|
||||||
<Compile Include="Queues\GenericQueue.cs" />
|
<Compile Include="Queues\GenericQueue.cs" />
|
||||||
@@ -285,8 +291,13 @@
|
|||||||
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
|
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
|
||||||
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
|
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
|
||||||
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.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\EssentialsRoomBase.cs" />
|
||||||
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
|
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
|
||||||
|
<Compile Include="Room\IEssentialsRoom.cs" />
|
||||||
<Compile Include="Room\Interfaces.cs" />
|
<Compile Include="Room\Interfaces.cs" />
|
||||||
<Compile Include="Room\iOccupancyStatusProvider.cs" />
|
<Compile Include="Room\iOccupancyStatusProvider.cs" />
|
||||||
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
|
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
|
||||||
@@ -320,6 +331,10 @@
|
|||||||
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
|
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
|
||||||
<Compile Include="Routing\RoutingPortNames.cs" />
|
<Compile Include="Routing\RoutingPortNames.cs" />
|
||||||
<Compile Include="Routing\TieLineConfig.cs" />
|
<Compile Include="Routing\TieLineConfig.cs" />
|
||||||
|
<Compile Include="Secrets\CrestronSecretsProvider.cs" />
|
||||||
|
<Compile Include="Secrets\Interfaces.cs" />
|
||||||
|
<Compile Include="Secrets\SecretsManager.cs" />
|
||||||
|
<Compile Include="Secrets\SecretsPropertiesConfig.cs" />
|
||||||
<Compile Include="Shades\Shade Interfaces.cs" />
|
<Compile Include="Shades\Shade Interfaces.cs" />
|
||||||
<Compile Include="Shades\ShadeBase.cs" />
|
<Compile Include="Shades\ShadeBase.cs" />
|
||||||
<Compile Include="Shades\ShadeController.cs" />
|
<Compile Include="Shades\ShadeController.cs" />
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ namespace PepperDash.Essentials
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (typeof (IPluginDeviceFactory).IsAssignableFrom(type))
|
if (typeof (IPluginDeviceFactory).IsAssignableFrom(type) && !type.IsAbstract)
|
||||||
{
|
{
|
||||||
var plugin =
|
var plugin =
|
||||||
(IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
(IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
ScheduledEventGroup FeatureEventGroup;
|
ScheduledEventGroup FeatureEventGroup;
|
||||||
|
|
||||||
public EssentialsRoomBase Room { get; private set; }
|
public IEssentialsRoom Room { get; private set; }
|
||||||
|
|
||||||
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
|
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void SetUpDevice()
|
void SetUpDevice()
|
||||||
{
|
{
|
||||||
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as EssentialsRoomBase;
|
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as IEssentialsRoom;
|
||||||
|
|
||||||
if (Room != null)
|
if (Room != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,264 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner
|
||||||
|
{
|
||||||
|
private EssentialsRoomCombinerPropertiesConfig _propertiesConfig;
|
||||||
|
|
||||||
|
private IRoomCombinationScenario _currentScenario;
|
||||||
|
|
||||||
|
private List<IEssentialsRoom> _rooms;
|
||||||
|
|
||||||
|
private bool isInAutoMode;
|
||||||
|
|
||||||
|
private CTimer _scenarioChangeDebounceTimer;
|
||||||
|
|
||||||
|
private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s
|
||||||
|
|
||||||
|
public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props)
|
||||||
|
: base(key)
|
||||||
|
{
|
||||||
|
_propertiesConfig = props;
|
||||||
|
|
||||||
|
Partitions = new List<IPartitionController>();
|
||||||
|
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
|
||||||
|
|
||||||
|
if (_propertiesConfig.ScenarioChangeDebounceTimeSeconds > 0)
|
||||||
|
{
|
||||||
|
_scenarioChangeDebounceTimeSeconds = _propertiesConfig.ScenarioChangeDebounceTimeSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsInAutoModeFeedback = new BoolFeedback(() => isInAutoMode);
|
||||||
|
|
||||||
|
// default to auto mode
|
||||||
|
isInAutoMode = true;
|
||||||
|
|
||||||
|
if (_propertiesConfig.defaultToManualMode)
|
||||||
|
{
|
||||||
|
isInAutoMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsInAutoModeFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CreateScenarios();
|
||||||
|
|
||||||
|
AddPostActivationAction(() =>
|
||||||
|
{
|
||||||
|
SetupPartitionStateProviders();
|
||||||
|
|
||||||
|
SetRooms();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateScenarios()
|
||||||
|
{
|
||||||
|
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
|
||||||
|
|
||||||
|
foreach (var scenarioConfig in _propertiesConfig.Scenarios)
|
||||||
|
{
|
||||||
|
var scenario = new RoomCombinationScenario(scenarioConfig);
|
||||||
|
RoomCombinationScenarios.Add(scenario);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRooms()
|
||||||
|
{
|
||||||
|
_rooms = new List<IEssentialsRoom>();
|
||||||
|
|
||||||
|
foreach (var roomKey in _propertiesConfig.RoomKeys)
|
||||||
|
{
|
||||||
|
var room = DeviceManager.GetDeviceForKey(roomKey) as IEssentialsRoom;
|
||||||
|
if (room != null)
|
||||||
|
{
|
||||||
|
_rooms.Add(room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupPartitionStateProviders()
|
||||||
|
{
|
||||||
|
foreach (var pConfig in _propertiesConfig.Partitions)
|
||||||
|
{
|
||||||
|
var sensor = DeviceManager.GetDeviceForKey(pConfig.DeviceKey) as IPartitionStateProvider;
|
||||||
|
|
||||||
|
var partition = new EssentialsPartitionController(pConfig.Key, pConfig.Name, sensor, _propertiesConfig.defaultToManualMode, pConfig.AdjacentRoomKeys);
|
||||||
|
|
||||||
|
partition.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange;
|
||||||
|
|
||||||
|
Partitions.Add(partition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||||
|
{
|
||||||
|
StartDebounceTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartDebounceTimer()
|
||||||
|
{
|
||||||
|
var time = _scenarioChangeDebounceTimeSeconds * 1000;
|
||||||
|
|
||||||
|
if (_scenarioChangeDebounceTimer == null)
|
||||||
|
{
|
||||||
|
_scenarioChangeDebounceTimer = new CTimer((o) => DetermineRoomCombinationScenario(), time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_scenarioChangeDebounceTimer.Reset(time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the current room combination scenario based on the state of the partition sensors
|
||||||
|
/// </summary>
|
||||||
|
void DetermineRoomCombinationScenario()
|
||||||
|
{
|
||||||
|
if (_scenarioChangeDebounceTimer != null)
|
||||||
|
{
|
||||||
|
_scenarioChangeDebounceTimer.Dispose();
|
||||||
|
_scenarioChangeDebounceTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentScenario = RoomCombinationScenarios.FirstOrDefault((s) =>
|
||||||
|
{
|
||||||
|
// iterate the partition states
|
||||||
|
foreach (var partitionState in s.PartitionStates)
|
||||||
|
{
|
||||||
|
// get the partition by key
|
||||||
|
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey));
|
||||||
|
|
||||||
|
if (partition != null && partitionState.PartitionPresent != partition.PartitionPresentFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
// the partition can't be found or the state doesn't match
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if it hasn't returned false by now we have the matching scenario
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentScenario != null)
|
||||||
|
{
|
||||||
|
CurrentScenario = currentScenario;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IEssentialsRoomCombiner Members
|
||||||
|
|
||||||
|
public event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||||
|
|
||||||
|
public IRoomCombinationScenario CurrentScenario
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _currentScenario;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _currentScenario)
|
||||||
|
{
|
||||||
|
_currentScenario = value;
|
||||||
|
Debug.Console(1, this, "Current Scenario: {0}", _currentScenario.Name);
|
||||||
|
var handler = RoomCombinationScenarioChanged;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, new EventArgs());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoolFeedback IsInAutoModeFeedback { get; private set; }
|
||||||
|
|
||||||
|
public void SetAutoMode()
|
||||||
|
{
|
||||||
|
isInAutoMode = true;
|
||||||
|
IsInAutoModeFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetManualMode()
|
||||||
|
{
|
||||||
|
isInAutoMode = false;
|
||||||
|
IsInAutoModeFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleMode()
|
||||||
|
{
|
||||||
|
isInAutoMode = !isInAutoMode;
|
||||||
|
IsInAutoModeFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IRoomCombinationScenario> RoomCombinationScenarios { get; private set; }
|
||||||
|
|
||||||
|
public List<IPartitionController> Partitions { get; private set; }
|
||||||
|
|
||||||
|
public void TogglePartitionState(string partitionKey)
|
||||||
|
{
|
||||||
|
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey)) as IPartitionController;
|
||||||
|
|
||||||
|
if (partition != null)
|
||||||
|
{
|
||||||
|
partition.ToggglePartitionState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRoomCombinationScenario(string scenarioKey)
|
||||||
|
{
|
||||||
|
if (isInAutoMode)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Cannot set room combination scenario when in auto mode. Set to auto mode first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the scenario
|
||||||
|
var scenario = RoomCombinationScenarios.FirstOrDefault((s) => s.Key.Equals(scenarioKey));
|
||||||
|
|
||||||
|
// Set the parition states from the scenario manually
|
||||||
|
if (scenario != null)
|
||||||
|
{
|
||||||
|
foreach (var partitionState in scenario.PartitionStates)
|
||||||
|
{
|
||||||
|
var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey));
|
||||||
|
|
||||||
|
if (partition != null)
|
||||||
|
{
|
||||||
|
if (partitionState.PartitionPresent)
|
||||||
|
{
|
||||||
|
partition.SetPartitionStatePresent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
partition.SetPartitionStateNotPresent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory<EssentialsRoomCombiner>
|
||||||
|
{
|
||||||
|
public EssentialsRoomCombinerFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string> { "essentialsroomcombiner" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Factory Attempting to create new EssentialsRoomCombiner Device");
|
||||||
|
|
||||||
|
var props = dc.Properties.ToObject<EssentialsRoomCombinerPropertiesConfig>();
|
||||||
|
|
||||||
|
return new EssentialsRoomCombiner(dc.Key, props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Config properties for an EssentialsRoomCombiner device
|
||||||
|
/// </summary>
|
||||||
|
public class EssentialsRoomCombinerPropertiesConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The list of partitions that device the rooms
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("partitions")]
|
||||||
|
public List<PartitionConfig> Partitions {get; set;}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of combinations scenarios for the rooms
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("scenarios")]
|
||||||
|
public List<RoomCombinationScenarioConfig> Scenarios { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of rooms keys that can be combined
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("roomMap")]
|
||||||
|
public List<string> RoomKeys {get; set;}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set to true to default to manual mode
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("defaultToManualMode")]
|
||||||
|
public bool defaultToManualMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The key of the scenario to default to at system startup if in manual mode
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("defaultScenarioKey")]
|
||||||
|
public string defaultScenarioKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("scenarioChangeDebounceTimeSeconds")]
|
||||||
|
public int ScenarioChangeDebounceTimeSeconds { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Config properties for a partition that separates rooms
|
||||||
|
/// </summary>
|
||||||
|
public class PartitionConfig : IKeyName
|
||||||
|
{
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key of the device that implements IPartitionStateProvider to provide the state of the partition
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("deviceKey")]
|
||||||
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Keys of the rooms that this partion would be located between
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("adjacentRoomKeys")]
|
||||||
|
public List<string> AdjacentRoomKeys { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Config propeties for a room combination scenario
|
||||||
|
/// </summary>
|
||||||
|
public class RoomCombinationScenarioConfig : IKeyName
|
||||||
|
{
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("partitionStates")]
|
||||||
|
public List<PartitionState> PartitionStates { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("uiMap")]
|
||||||
|
public Dictionary<string, string> UiMap { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("activationActions")]
|
||||||
|
public List<DeviceActionWrapper> ActivationActions { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("deactivationActions")]
|
||||||
|
public List<DeviceActionWrapper> DeactivationActions { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Config properties to represent the state of a partition sensor in a RoomCombinationScenario
|
||||||
|
/// </summary>
|
||||||
|
public class PartitionState
|
||||||
|
{
|
||||||
|
[JsonProperty("partitionKey")]
|
||||||
|
public string PartitionKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("partitionSensedState")]
|
||||||
|
public bool PartitionPresent { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the functionality for an EssentailsRoomCombiner device
|
||||||
|
/// </summary>
|
||||||
|
public interface IEssentialsRoomCombiner : IKeyed
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the room combination scenario has changed
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current room combination scenario
|
||||||
|
/// </summary>
|
||||||
|
IRoomCombinationScenario CurrentScenario { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When true, indicates the current mode is auto mode
|
||||||
|
/// </summary>
|
||||||
|
BoolFeedback IsInAutoModeFeedback {get;}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets auto mode
|
||||||
|
/// </summary>
|
||||||
|
void SetAutoMode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets manual mode
|
||||||
|
/// </summary>
|
||||||
|
void SetManualMode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the current mode between auto and manual
|
||||||
|
/// </summary>
|
||||||
|
void ToggleMode();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The available room combinatino scenarios
|
||||||
|
/// </summary>
|
||||||
|
List<IRoomCombinationScenario> RoomCombinationScenarios { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The partition
|
||||||
|
/// </summary>
|
||||||
|
List<IPartitionController> Partitions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the state of a manual partition sensor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="partitionKey"></param>
|
||||||
|
void TogglePartitionState(string partitionKey);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the room combination scenario (if in manual mode)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scenarioKey"></param>
|
||||||
|
void SetRoomCombinationScenario(string scenarioKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IRoomCombinationScenario : IKeyName
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// When true, indicates that this room combination scenario is active
|
||||||
|
/// </summary>
|
||||||
|
BoolFeedback IsActiveFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activates this room combination scenario
|
||||||
|
/// </summary>
|
||||||
|
void Activate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The state of the partitions that would activate this scenario
|
||||||
|
/// </summary>
|
||||||
|
List<PartitionState> PartitionStates { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The mapping of UIs by key to rooms by key
|
||||||
|
/// </summary>
|
||||||
|
Dictionary<string, string> UiMap { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a room combination scenario
|
||||||
|
/// </summary>
|
||||||
|
public class RoomCombinationScenario: IRoomCombinationScenario
|
||||||
|
{
|
||||||
|
private RoomCombinationScenarioConfig _config;
|
||||||
|
|
||||||
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public List<PartitionState> PartitionStates { get; private set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> UiMap { get; set; }
|
||||||
|
|
||||||
|
private bool _isActive;
|
||||||
|
|
||||||
|
public BoolFeedback IsActiveFeedback { get; private set; }
|
||||||
|
|
||||||
|
List<DeviceActionWrapper> activationActions;
|
||||||
|
|
||||||
|
List<DeviceActionWrapper> deactivationActions;
|
||||||
|
|
||||||
|
public RoomCombinationScenario(RoomCombinationScenarioConfig config)
|
||||||
|
{
|
||||||
|
Key = config.Key;
|
||||||
|
|
||||||
|
Name = config.Name;
|
||||||
|
|
||||||
|
PartitionStates = config.PartitionStates;
|
||||||
|
|
||||||
|
UiMap = config.UiMap;
|
||||||
|
|
||||||
|
activationActions = config.ActivationActions;
|
||||||
|
|
||||||
|
deactivationActions = config.DeactivationActions;
|
||||||
|
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
IsActiveFeedback = new BoolFeedback(() => _isActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
if (activationActions != null)
|
||||||
|
{
|
||||||
|
foreach (var action in activationActions)
|
||||||
|
{
|
||||||
|
DeviceJsonApi.DoDeviceAction(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_isActive = true;
|
||||||
|
IsActiveFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deactivate()
|
||||||
|
{
|
||||||
|
if (deactivationActions != null)
|
||||||
|
{
|
||||||
|
foreach (var action in deactivationActions)
|
||||||
|
{
|
||||||
|
DeviceJsonApi.DoDeviceAction(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_isActive = false;
|
||||||
|
IsActiveFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
public abstract class EssentialsRoomBase : ReconfigurableDevice, IEssentialsRoom
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the basic functionality of an EssentialsRoom
|
||||||
|
/// </summary>
|
||||||
|
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice
|
||||||
|
{
|
||||||
|
BoolFeedback OnFeedback { get; }
|
||||||
|
|
||||||
|
event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||||
|
|
||||||
|
BoolFeedback IsWarmingUpFeedback { get; }
|
||||||
|
BoolFeedback IsCoolingDownFeedback { get; }
|
||||||
|
|
||||||
|
IOccupancyStatusProvider RoomOccupancy { get; }
|
||||||
|
bool OccupancyStatusProviderIsRemote { get; }
|
||||||
|
|
||||||
|
bool IsMobileControlEnabled { get; }
|
||||||
|
IMobileControlRoomBridge MobileControlRoomBridge { get; }
|
||||||
|
|
||||||
|
string SourceListKey { get; }
|
||||||
|
|
||||||
|
SecondsCountdownTimer ShutdownPromptTimer { get; }
|
||||||
|
int ShutdownPromptSeconds { get; }
|
||||||
|
int ShutdownVacancySeconds { get; }
|
||||||
|
eShutdownType ShutdownType { get; }
|
||||||
|
|
||||||
|
EssentialsRoomEmergencyBase Emergency { get; }
|
||||||
|
|
||||||
|
Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; }
|
||||||
|
|
||||||
|
string LogoUrlLightBkgnd { get; }
|
||||||
|
string LogoUrlDarkBkgnd { get; }
|
||||||
|
|
||||||
|
eVacancyMode VacancyMode { get; }
|
||||||
|
|
||||||
|
bool ZeroVolumeWhenSwtichingVolumeDevices { get; }
|
||||||
|
|
||||||
|
void StartShutdown(eShutdownType type);
|
||||||
|
void StartRoomVacancyTimer(eVacancyMode mode);
|
||||||
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes);
|
||||||
|
|
||||||
|
void PowerOnToDefaultOrLastSource();
|
||||||
|
bool RunDefaultPresentRoute();
|
||||||
|
|
||||||
|
void SetDefaultLevels();
|
||||||
|
|
||||||
|
void RoomVacatedForTimeoutPeriod(object o);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -65,4 +66,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
bool RunDefaultCallRoute();
|
bool RunDefaultCallRoute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -123,14 +123,24 @@ namespace PepperDash.Essentials.Core
|
|||||||
// No direct tie? Run back out on the inputs' attached devices...
|
// No direct tie? Run back out on the inputs' attached devices...
|
||||||
// Only the ones that are routing devices
|
// Only the ones that are routing devices
|
||||||
var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
|
var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
|
||||||
|
|
||||||
|
//Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
|
||||||
|
if (alreadyCheckedDevices == null)
|
||||||
|
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
|
||||||
|
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
|
||||||
|
|
||||||
foreach (var inputTieToTry in attachedMidpoints)
|
foreach (var inputTieToTry in attachedMidpoints)
|
||||||
{
|
{
|
||||||
Debug.Console(2, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key);
|
|
||||||
var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
|
var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
|
||||||
var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
|
var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
|
||||||
|
Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key);
|
||||||
|
|
||||||
// Check if this previous device has already been walked
|
// Check if this previous device has already been walked
|
||||||
if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice)))
|
if (alreadyCheckedDevices.Contains(upstreamRoutingDevice))
|
||||||
{
|
{
|
||||||
|
Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// haven't seen this device yet. Do it. Pass the output port to the next
|
// haven't seen this device yet. Do it. Pass the output port to the next
|
||||||
// level to enable switching on success
|
// level to enable switching on success
|
||||||
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
|
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
|
||||||
@@ -143,7 +153,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// we have a route on corresponding inputPort. *** Do the route ***
|
// we have a route on corresponding inputPort. *** Do the route ***
|
||||||
if (goodInputPort != null)
|
if (goodInputPort != null)
|
||||||
@@ -164,10 +173,6 @@ namespace PepperDash.Essentials.Core
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(alreadyCheckedDevices == null)
|
|
||||||
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
|
|
||||||
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
|
|
||||||
|
|
||||||
Debug.Console(2, destination, "No route found to {0}", source.Key);
|
Debug.Console(2, destination, "No route found to {0}", source.Key);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronDataStore;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class CrestronSecretsProvider : ISecretProvider
|
||||||
|
{
|
||||||
|
public string Key { get; set; }
|
||||||
|
//Added for reference
|
||||||
|
private static readonly bool SecureSupported;
|
||||||
|
public CrestronSecretsProvider(string key)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CrestronSecretsProvider()
|
||||||
|
{
|
||||||
|
//Added for future encrypted reference
|
||||||
|
SecureSupported = CrestronSecureStorage.Supported;
|
||||||
|
|
||||||
|
CrestronDataStoreStatic.InitCrestronDataStore();
|
||||||
|
if (SecureSupported)
|
||||||
|
{
|
||||||
|
//doThingsFuture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set secret for item in the CrestronSecretsProvider
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Secret Key</param>
|
||||||
|
/// <param name="value">Secret Value</param>
|
||||||
|
public bool SetSecret(string key, object value)
|
||||||
|
{
|
||||||
|
var secret = value as string;
|
||||||
|
if (String.IsNullOrEmpty(secret))
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
|
||||||
|
switch (setErrorCode)
|
||||||
|
{
|
||||||
|
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
|
||||||
|
Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve secret for item in the CrestronSecretsProvider
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Secret Key</param>
|
||||||
|
/// <returns>ISecret Object containing key, provider, and value</returns>
|
||||||
|
public ISecret GetSecret(string key)
|
||||||
|
{
|
||||||
|
string mySecret;
|
||||||
|
var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret);
|
||||||
|
|
||||||
|
switch (getErrorCode)
|
||||||
|
{
|
||||||
|
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
|
||||||
|
Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key);
|
||||||
|
return new CrestronSecret(key, mySecret, this);
|
||||||
|
default:
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
|
||||||
|
Key, key, getErrorCode.ToString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Special container class for CrestronSecret provider
|
||||||
|
/// </summary>
|
||||||
|
public class CrestronSecret : ISecret
|
||||||
|
{
|
||||||
|
public ISecretProvider Provider { get; private set; }
|
||||||
|
public string Key { get; private set; }
|
||||||
|
|
||||||
|
public object Value { get; private set; }
|
||||||
|
|
||||||
|
public CrestronSecret(string key, string value, ISecretProvider provider)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
Value = value;
|
||||||
|
Provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All ISecrecretProvider classes must implement this interface.
|
||||||
|
/// </summary>
|
||||||
|
public interface ISecretProvider : IKeyed
|
||||||
|
{
|
||||||
|
bool SetSecret(string key, object value);
|
||||||
|
|
||||||
|
ISecret GetSecret(string key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// interface for delivering secrets in Essentials.
|
||||||
|
/// </summary>
|
||||||
|
public interface ISecret
|
||||||
|
{
|
||||||
|
ISecretProvider Provider { get; }
|
||||||
|
string Key { get; }
|
||||||
|
object Value { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class SecretsManager
|
||||||
|
{
|
||||||
|
public static Dictionary<string, ISecretProvider> Secrets { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the SecretsManager
|
||||||
|
/// </summary>
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
AddSecretProvider("default", new CrestronSecretsProvider("default"));
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
|
||||||
|
"Adds secrets to secret provider",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret",
|
||||||
|
"Updates secrets in secret provider",
|
||||||
|
ConsoleAccessLevelEnum.AccessAdministrator);
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
|
||||||
|
"Deletes secrets in secret provider",
|
||||||
|
ConsoleAccessLevelEnum.AccessAdministrator);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SecretsManager()
|
||||||
|
{
|
||||||
|
Secrets = new Dictionary<string, ISecretProvider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Secret Provider from dictionary by key
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Dictionary Key for provider</param>
|
||||||
|
/// <returns>ISecretProvider</returns>
|
||||||
|
public static ISecretProvider GetSecretProviderByKey(string key)
|
||||||
|
{
|
||||||
|
ISecretProvider secret;
|
||||||
|
|
||||||
|
Secrets.TryGetValue(key, out secret);
|
||||||
|
|
||||||
|
if (secret == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key);
|
||||||
|
}
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add secret provider to secrets dictionary
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Key of new entry</param>
|
||||||
|
/// <param name="provider">New Provider Entry</param>
|
||||||
|
public static void AddSecretProvider(string key, ISecretProvider provider)
|
||||||
|
{
|
||||||
|
if (!Secrets.ContainsKey(key))
|
||||||
|
{
|
||||||
|
Secrets.Add(key, provider);
|
||||||
|
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
|
||||||
|
}
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add secret provider to secrets dictionary, with optional overwrite parameter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">Key of new entry</param>
|
||||||
|
/// <param name="provider">New provider entry</param>
|
||||||
|
/// <param name="overwrite">true to overwrite any existing providers in the dictionary</param>
|
||||||
|
public static void AddSecretProvider(string key, ISecretProvider provider, bool overwrite)
|
||||||
|
{
|
||||||
|
if (!Secrets.ContainsKey(key))
|
||||||
|
{
|
||||||
|
Secrets.Add(key, provider);
|
||||||
|
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (overwrite)
|
||||||
|
{
|
||||||
|
Secrets.Add(key, provider);
|
||||||
|
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Provider with the key '{0}' already exists in secrets. Overwriting with new secrets provider.", key);
|
||||||
|
|
||||||
|
}
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetSecretProcess(string cmd)
|
||||||
|
{
|
||||||
|
string response;
|
||||||
|
var args = cmd.Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
//some Instructional Text
|
||||||
|
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length == 1 && args[0] == "?")
|
||||||
|
{
|
||||||
|
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length < 3)
|
||||||
|
{
|
||||||
|
response = "Improper number of arguments";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = GetSecretProviderByKey(args[0]);
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Provider key invalid";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = args[1];
|
||||||
|
var secret = args[2];
|
||||||
|
|
||||||
|
if (provider.GetSecret(key) == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
response = provider.SetSecret(key, secret)
|
||||||
|
? String.Format(
|
||||||
|
"Secret successfully set for {0}:{1}",
|
||||||
|
provider.Key, key)
|
||||||
|
: String.Format(
|
||||||
|
"Unable to set secret for {0}:{1}",
|
||||||
|
provider.Key, key);
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
response =
|
||||||
|
String.Format(
|
||||||
|
"Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it");
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSecretProcess(string cmd)
|
||||||
|
{
|
||||||
|
string response;
|
||||||
|
var args = cmd.Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
//some Instructional Text
|
||||||
|
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length == 1 && args[0] == "?")
|
||||||
|
{
|
||||||
|
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (args.Length < 3)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Improper number of arguments";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = GetSecretProviderByKey(args[0]);
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Provider key invalid";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = args[1];
|
||||||
|
var secret = args[2];
|
||||||
|
|
||||||
|
if (provider.GetSecret(key) != null)
|
||||||
|
{
|
||||||
|
response = provider.SetSecret(key, secret)
|
||||||
|
? String.Format(
|
||||||
|
"Secret successfully set for {0}:{1}",
|
||||||
|
provider.Key, key)
|
||||||
|
: String.Format(
|
||||||
|
"Unable to set secret for {0}:{1}",
|
||||||
|
provider.Key, key);
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response =
|
||||||
|
String.Format(
|
||||||
|
"Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to create a new secret");
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DeleteSecretProcess(string cmd)
|
||||||
|
{
|
||||||
|
string response;
|
||||||
|
var args = cmd.Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
//some Instructional Text
|
||||||
|
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (args.Length == 1 && args[0] == "?")
|
||||||
|
{
|
||||||
|
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Improper number of arguments";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = GetSecretProviderByKey(args[0]);
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Provider key invalid";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = args[1];
|
||||||
|
|
||||||
|
|
||||||
|
provider.SetSecret(key, "");
|
||||||
|
response = provider.SetSecret(key, "")
|
||||||
|
? String.Format(
|
||||||
|
"Secret successfully deleted for {0}:{1}",
|
||||||
|
provider.Key, key)
|
||||||
|
: String.Format(
|
||||||
|
"Unable to delete secret for {0}:{1}",
|
||||||
|
provider.Key, key);
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provide a way to easily deserialize into a secret object from config
|
||||||
|
/// </summary>
|
||||||
|
public class SecretsPropertiesConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("provider")]
|
||||||
|
public string Provider { get; set; }
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,8 @@ using PepperDash.Essentials.Core;
|
|||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.DM.Config;
|
using PepperDash.Essentials.DM.Config;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.DM {
|
namespace PepperDash.Essentials.DM
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
|
/// 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
|
/// Factory method to create a new chassis controller from config data. Limited to 8x8 right now
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static DmBladeChassisController GetDmChassisController(string key, string name,
|
public static DmBladeChassisController GetDmChassisController(string key, string name,
|
||||||
string type, DMChassisPropertiesConfig properties) {
|
string type, DMChassisPropertiesConfig properties)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
type = type.ToLower();
|
type = type.ToLower();
|
||||||
uint ipid = properties.Control.IpIdInt;
|
uint ipid = properties.Control.IpIdInt;
|
||||||
|
|
||||||
@@ -85,7 +88,8 @@ namespace PepperDash.Essentials.DM {
|
|||||||
else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); }
|
else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); }
|
||||||
|
|
||||||
|
|
||||||
if (chassis == null) {
|
if (chassis == null)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,11 +97,13 @@ namespace PepperDash.Essentials.DM {
|
|||||||
// add the cards and port names
|
// add the cards and port names
|
||||||
foreach (var kvp in properties.InputSlots)
|
foreach (var kvp in properties.InputSlots)
|
||||||
controller.AddInputBlade(kvp.Value, kvp.Key);
|
controller.AddInputBlade(kvp.Value, kvp.Key);
|
||||||
foreach (var kvp in properties.OutputSlots) {
|
foreach (var kvp in properties.OutputSlots)
|
||||||
|
{
|
||||||
controller.AddOutputBlade(kvp.Value, kvp.Key);
|
controller.AddOutputBlade(kvp.Value, kvp.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var kvp in properties.VolumeControls) {
|
foreach (var kvp in properties.VolumeControls)
|
||||||
|
{
|
||||||
// get the card
|
// get the card
|
||||||
// check it for an audio-compatible type
|
// check it for an audio-compatible type
|
||||||
// make a something-something that will make it work
|
// make a something-something that will make it work
|
||||||
@@ -123,7 +129,8 @@ namespace PepperDash.Essentials.DM {
|
|||||||
controller.PropertiesConfig = properties;
|
controller.PropertiesConfig = properties;
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
catch (System.Exception e) {
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
Debug.Console(0, "Error creating DM chassis:\r{0}", e);
|
Debug.Console(0, "Error creating DM chassis:\r{0}", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -137,7 +144,8 @@ namespace PepperDash.Essentials.DM {
|
|||||||
/// <param name="name"></param>
|
/// <param name="name"></param>
|
||||||
/// <param name="chassis"></param>
|
/// <param name="chassis"></param>
|
||||||
public DmBladeChassisController(string key, string name, BladeSwitch chassis)
|
public DmBladeChassisController(string key, string name, BladeSwitch chassis)
|
||||||
: base(key, name, chassis) {
|
: base(key, name, chassis)
|
||||||
|
{
|
||||||
Chassis = chassis;
|
Chassis = chassis;
|
||||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||||
@@ -161,33 +169,43 @@ namespace PepperDash.Essentials.DM {
|
|||||||
InputCardHdcpCapabilityFeedbacks = new Dictionary<uint, IntFeedback>();
|
InputCardHdcpCapabilityFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||||
InputCardHdcpCapabilityTypes = new Dictionary<uint, eHdcpCapabilityType>();
|
InputCardHdcpCapabilityTypes = new Dictionary<uint, eHdcpCapabilityType>();
|
||||||
|
|
||||||
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) {
|
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
|
||||||
|
{
|
||||||
var tempX = x;
|
var tempX = x;
|
||||||
|
|
||||||
if (Chassis.Outputs[tempX] != null) {
|
if (Chassis.Outputs[tempX] != null)
|
||||||
VideoOutputFeedbacks[tempX] = new IntFeedback(() => {
|
{
|
||||||
|
VideoOutputFeedbacks[tempX] = new IntFeedback(() =>
|
||||||
|
{
|
||||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; }
|
if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; }
|
||||||
else { return 0; };
|
else { return 0; };
|
||||||
});
|
});
|
||||||
|
|
||||||
OutputNameFeedbacks[tempX] = new StringFeedback(() => {
|
OutputNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||||
if (Chassis.Outputs[tempX].NameFeedback != null) {
|
{
|
||||||
|
if (Chassis.Outputs[tempX].NameFeedback != null)
|
||||||
|
{
|
||||||
return Chassis.Outputs[tempX].NameFeedback.StringValue;
|
return Chassis.Outputs[tempX].NameFeedback.StringValue;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => {
|
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null) {
|
{
|
||||||
|
if (Chassis.Outputs[tempX].VideoOutFeedback != null)
|
||||||
|
{
|
||||||
return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue;
|
return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
|
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
|
||||||
|
{
|
||||||
//if (Chassis.Outputs[tempX].Endpoint != null)
|
//if (Chassis.Outputs[tempX].Endpoint != null)
|
||||||
// return Chassis.Outputs[tempX].Endpoint.IsOnline;
|
// return Chassis.Outputs[tempX].Endpoint.IsOnline;
|
||||||
//else
|
//else
|
||||||
@@ -195,34 +213,43 @@ namespace PepperDash.Essentials.DM {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Chassis.Inputs[tempX] != null) {
|
if (Chassis.Inputs[tempX] != null)
|
||||||
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => {
|
{
|
||||||
|
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() =>
|
||||||
|
{
|
||||||
if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; }
|
if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; }
|
||||||
else { return 0; };
|
else { return 0; };
|
||||||
});
|
});
|
||||||
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => {
|
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() =>
|
||||||
|
{
|
||||||
if (Chassis.Inputs[tempX].VideoDetectedFeedback != null)
|
if (Chassis.Inputs[tempX].VideoDetectedFeedback != null)
|
||||||
return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue;
|
return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
InputNameFeedbacks[tempX] = new StringFeedback(() => {
|
InputNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||||
if (Chassis.Inputs[tempX].NameFeedback != null) {
|
{
|
||||||
|
if (Chassis.Inputs[tempX].NameFeedback != null)
|
||||||
|
{
|
||||||
return Chassis.Inputs[tempX].NameFeedback.StringValue;
|
return Chassis.Inputs[tempX].NameFeedback.StringValue;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
|
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
|
||||||
|
{
|
||||||
return Chassis.Inputs[tempX].EndpointOnlineFeedback;
|
return Chassis.Inputs[tempX].EndpointOnlineFeedback;
|
||||||
});
|
});
|
||||||
|
|
||||||
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => {
|
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() =>
|
||||||
|
{
|
||||||
var inputCard = Chassis.Inputs[tempX];
|
var inputCard = Chassis.Inputs[tempX];
|
||||||
|
|
||||||
if (inputCard.Card is DmHdmi4kInputBladeCard) {
|
if (inputCard.Card is DmHdmi4kInputBladeCard)
|
||||||
|
{
|
||||||
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
||||||
|
|
||||||
if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue)
|
if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue)
|
||||||
@@ -231,7 +258,8 @@ namespace PepperDash.Essentials.DM {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputCard.Card is DmC4kInputBladeCard) {
|
if (inputCard.Card is DmC4kInputBladeCard)
|
||||||
|
{
|
||||||
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
||||||
|
|
||||||
if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff))
|
if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff))
|
||||||
@@ -252,45 +280,56 @@ namespace PepperDash.Essentials.DM {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="number"></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);
|
Debug.Console(2, this, "Adding input blade '{0}', slot {1}", type, number);
|
||||||
|
|
||||||
type = type.ToLower();
|
type = type.ToLower();
|
||||||
|
|
||||||
if (type == "dmb4kihd") {
|
if (type == "dmb4kihd")
|
||||||
|
{
|
||||||
var inputBlade = new Dmb4kIHd(number, this.Chassis);
|
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 card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
|
||||||
var cecPort = card as ICec;
|
var cecPort = card as ICec;
|
||||||
AddHdmiInBladePorts(item.Number, cecPort);
|
AddHdmiInBladePorts(item.Number, cecPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == "dmb4kihddnt") {
|
else if (type == "dmb4kihddnt")
|
||||||
|
{
|
||||||
var inputBlade = new Dmb4kIHd(number, this.Chassis);
|
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 card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
|
||||||
var cecPort = card as ICec;
|
var cecPort = card as ICec;
|
||||||
AddHdmiInBladePorts(item.Number, cecPort);
|
AddHdmiInBladePorts(item.Number, cecPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == "dmb4kic") {
|
else if (type == "dmb4kic")
|
||||||
|
{
|
||||||
var inputBlade = new Dmb4kIC(number, this.Chassis);
|
var inputBlade = new Dmb4kIC(number, this.Chassis);
|
||||||
foreach (var item in inputBlade.Inputs) {
|
foreach (var item in inputBlade.Inputs)
|
||||||
|
{
|
||||||
AddDmInBladePorts(item.Number);
|
AddDmInBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == "dmbis") {
|
else if (type == "dmbis")
|
||||||
|
{
|
||||||
var inputBlade = new DmbIS(number, this.Chassis);
|
var inputBlade = new DmbIS(number, this.Chassis);
|
||||||
foreach (var item in inputBlade.Inputs) {
|
foreach (var item in inputBlade.Inputs)
|
||||||
|
{
|
||||||
AddDmInMmFiberPorts(item.Number);
|
AddDmInMmFiberPorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == "dmbis2") {
|
else if (type == "dmbis2")
|
||||||
|
{
|
||||||
var inputBlade = new DmbIS2(number, this.Chassis);
|
var inputBlade = new DmbIS2(number, this.Chassis);
|
||||||
foreach (var item in inputBlade.Inputs) {
|
foreach (var item in inputBlade.Inputs)
|
||||||
|
{
|
||||||
AddDmInSmFiberPorts(item.Number);
|
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);
|
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);
|
AddInputPortWithDebug(number, "dmCIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDmInMmFiberPorts(uint number) {
|
void AddDmInMmFiberPorts(uint number)
|
||||||
|
{
|
||||||
AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
|
AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDmInSmFiberPorts(uint number) {
|
void AddDmInSmFiberPorts(uint number)
|
||||||
|
{
|
||||||
AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
|
AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,64 +371,81 @@ namespace PepperDash.Essentials.DM {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="number"></param>
|
/// <param name="number"></param>
|
||||||
public void AddOutputBlade(string type, uint number) {
|
public void AddOutputBlade(string type, uint number)
|
||||||
|
{
|
||||||
type = type.ToLower();
|
type = type.ToLower();
|
||||||
|
|
||||||
Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number);
|
Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number);
|
||||||
if (type == "dmb4kohd") {
|
if (type == "dmb4kohd")
|
||||||
|
{
|
||||||
var outputBlade = new Dmb4KOHD(number, Chassis);
|
var outputBlade = new Dmb4KOHD(number, Chassis);
|
||||||
foreach (var item in outputBlade.Outputs) {
|
foreach (var item in outputBlade.Outputs)
|
||||||
|
{
|
||||||
AddHdmiOutBladePorts(item.Number);
|
AddHdmiOutBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == "dmb4kohddnt") {
|
else if (type == "dmb4kohddnt")
|
||||||
|
{
|
||||||
var outputBlade = new Dmb4KOHD(number, Chassis);
|
var outputBlade = new Dmb4KOHD(number, Chassis);
|
||||||
foreach (var item in outputBlade.Outputs) {
|
foreach (var item in outputBlade.Outputs)
|
||||||
|
{
|
||||||
AddHdmiOutBladePorts(item.Number);
|
AddHdmiOutBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == "dmb4koc") {
|
else if (type == "dmb4koc")
|
||||||
|
{
|
||||||
var outputBlade = new Dmb4KOC(number, Chassis);
|
var outputBlade = new Dmb4KOC(number, Chassis);
|
||||||
foreach (var item in outputBlade.Outputs) {
|
foreach (var item in outputBlade.Outputs)
|
||||||
|
{
|
||||||
AddDmOutBladePorts(item.Number);
|
AddDmOutBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == "dmb4koc") {
|
else if (type == "dmb4koc")
|
||||||
|
{
|
||||||
var outputBlade = new Dmb4KOC(number, Chassis);
|
var outputBlade = new Dmb4KOC(number, Chassis);
|
||||||
foreach (var item in outputBlade.Outputs) {
|
foreach (var item in outputBlade.Outputs)
|
||||||
|
{
|
||||||
AddDmOutBladePorts(item.Number);
|
AddDmOutBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == "dmbos") {
|
else if (type == "dmbos")
|
||||||
|
{
|
||||||
var outputBlade = new DmbOS(number, Chassis);
|
var outputBlade = new DmbOS(number, Chassis);
|
||||||
foreach (var item in outputBlade.Outputs) {
|
foreach (var item in outputBlade.Outputs)
|
||||||
|
{
|
||||||
AddDmOutMmFiberBladePorts(item.Number);
|
AddDmOutMmFiberBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == "dmbos2") {
|
else if (type == "dmbos2")
|
||||||
|
{
|
||||||
var outputBlade = new DmbOS2(number, Chassis);
|
var outputBlade = new DmbOS2(number, Chassis);
|
||||||
foreach (var item in outputBlade.Outputs) {
|
foreach (var item in outputBlade.Outputs)
|
||||||
|
{
|
||||||
AddDmOutSmFiberBladePorts(item.Number);
|
AddDmOutSmFiberBladePorts(item.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddHdmiOutBladePorts(uint 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]);
|
{
|
||||||
|
AddOutputPortWithDebug(number, "hdmiOut", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDmOutBladePorts(uint 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]);
|
{
|
||||||
|
AddOutputPortWithDebug(number, "dmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDmOutMmFiberBladePorts(uint 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]);
|
{
|
||||||
|
AddOutputPortWithDebug(number, "dmMmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDmOutSmFiberBladePorts(uint 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]);
|
{
|
||||||
|
AddOutputPortWithDebug(number, "dmSmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -417,23 +477,44 @@ namespace PepperDash.Essentials.DM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds OutputPort
|
/*void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
|
||||||
/// </summary>
|
|
||||||
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
|
|
||||||
var portKey = string.Format("{0}--{1}", cardName, portName);
|
var portKey = string.Format("{0}--{1}", cardName, portName);
|
||||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||||
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||||
{
|
{
|
||||||
FeedbackMatchObject = Chassis.Outputs[(uint)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>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void AddVolumeControl(uint number, Audio.Output audio) {
|
void AddVolumeControl(uint number, Audio.Output audio)
|
||||||
|
{
|
||||||
VolumeControls.Add(number, new DmCardAudioOutputController(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) {
|
switch (args.EventId)
|
||||||
case DMInputEventIds.EndpointOnlineEventId: {
|
{
|
||||||
|
case DMInputEventIds.EndpointOnlineEventId:
|
||||||
|
{
|
||||||
Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||||
break;
|
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);
|
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DMInputEventIds.VideoDetectedEventId: {
|
case DMInputEventIds.VideoDetectedEventId:
|
||||||
|
{
|
||||||
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
|
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
|
||||||
VideoInputSyncFeedbacks[args.Number].FireUpdate();
|
VideoInputSyncFeedbacks[args.Number].FireUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DMInputEventIds.InputNameEventId: {
|
case DMInputEventIds.InputNameEventId:
|
||||||
|
{
|
||||||
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
|
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
|
||||||
InputNameFeedbacks[args.Number].FireUpdate();
|
InputNameFeedbacks[args.Number].FireUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DMInputEventIds.HdcpCapabilityFeedbackEventId: {
|
case DMInputEventIds.HdcpCapabilityFeedbackEventId:
|
||||||
|
{
|
||||||
Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number);
|
Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number);
|
||||||
InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate();
|
InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default:
|
||||||
|
{
|
||||||
Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId);
|
Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -526,7 +615,7 @@ namespace PepperDash.Essentials.DM {
|
|||||||
{
|
{
|
||||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
||||||
var localOutputPort =
|
var localOutputPort =
|
||||||
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
|
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]);
|
||||||
|
|
||||||
|
|
||||||
VideoOutputFeedbacks[output].FireUpdate();
|
VideoOutputFeedbacks[output].FireUpdate();
|
||||||
@@ -564,7 +653,8 @@ namespace PepperDash.Essentials.DM {
|
|||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pnt"></param>
|
/// <param name="pnt"></param>
|
||||||
void StartOffTimer(PortNumberType pnt) {
|
void StartOffTimer(PortNumberType pnt)
|
||||||
|
{
|
||||||
if (RouteOffTimers.ContainsKey(pnt))
|
if (RouteOffTimers.ContainsKey(pnt))
|
||||||
return;
|
return;
|
||||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime);
|
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
|
// Send out sigs when coming online
|
||||||
void IsOnline_OutputChange(object sender, EventArgs e) {
|
void IsOnline_OutputChange(object sender, EventArgs e)
|
||||||
if (IsOnline.BoolValue) {
|
{
|
||||||
|
if (IsOnline.BoolValue)
|
||||||
|
{
|
||||||
Chassis.EnableUSBBreakaway.BoolValue = true;
|
Chassis.EnableUSBBreakaway.BoolValue = true;
|
||||||
|
|
||||||
if (InputNames != null)
|
if (InputNames != null)
|
||||||
@@ -587,7 +679,8 @@ namespace PepperDash.Essentials.DM {
|
|||||||
|
|
||||||
#region IRouting Members
|
#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);
|
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 input = inputSelector as DMInput; // Cast can sometimes fail
|
||||||
@@ -605,11 +698,14 @@ namespace PepperDash.Essentials.DM {
|
|||||||
// Check to see if there's an off timer waiting on this and if so, cancel
|
// Check to see if there's an off timer waiting on this and if so, cancel
|
||||||
var key = new PortNumberType(output, sigType);
|
var key = new PortNumberType(output, sigType);
|
||||||
|
|
||||||
if (input == null) {
|
if (input == null)
|
||||||
|
{
|
||||||
StartOffTimer(key);
|
StartOffTimer(key);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (RouteOffTimers.ContainsKey(key)) {
|
{
|
||||||
|
if (RouteOffTimers.ContainsKey(key))
|
||||||
|
{
|
||||||
Debug.Console(2, this, "{0} cancelling route off due to new source", output);
|
Debug.Console(2, this, "{0} cancelling route off due to new source", output);
|
||||||
RouteOffTimers[key].Stop();
|
RouteOffTimers[key].Stop();
|
||||||
RouteOffTimers.Remove(key);
|
RouteOffTimers.Remove(key);
|
||||||
@@ -671,7 +767,7 @@ namespace PepperDash.Essentials.DM {
|
|||||||
var ioSlotJoin = ioSlot - 1;
|
var ioSlotJoin = ioSlot - 1;
|
||||||
|
|
||||||
// Control
|
// 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))
|
if (TxDictionary.ContainsKey(ioSlot))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1220,7 +1220,7 @@ namespace PepperDash.Essentials.DM
|
|||||||
{
|
{
|
||||||
dmMdMnxn.AudioEnter.BoolValue = true;
|
dmMdMnxn.AudioEnter.BoolValue = true;
|
||||||
}
|
}
|
||||||
output.VideoOut = input;
|
output.AudioOut = input;
|
||||||
//Chassis.Outputs[output].AudioOut = inCard;
|
//Chassis.Outputs[output].AudioOut = inCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
// Feedbacks for EssentialDM
|
// Feedbacks for EssentialDM
|
||||||
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
|
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
|
||||||
public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; }
|
public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; }
|
||||||
public Dictionary<uint, IntFeedback> AudioOutputSourceDeviceFeedbacks { get; private set; }
|
|
||||||
public Dictionary<uint, BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
|
public Dictionary<uint, BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
|
||||||
public Dictionary<uint, BoolFeedback> InputEndpointOnlineFeedbacks { get; private set; }
|
public Dictionary<uint, BoolFeedback> InputEndpointOnlineFeedbacks { get; private set; }
|
||||||
public Dictionary<uint, BoolFeedback> OutputEndpointOnlineFeedbacks { get; private set; }
|
public Dictionary<uint, BoolFeedback> OutputEndpointOnlineFeedbacks { get; private set; }
|
||||||
@@ -126,7 +125,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
|
|
||||||
VideoOutputFeedbacks = new Dictionary<uint, IntFeedback>();
|
VideoOutputFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||||
AudioOutputFeedbacks = new Dictionary<uint, IntFeedback>();
|
AudioOutputFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||||
AudioOutputSourceDeviceFeedbacks = new Dictionary<uint, IntFeedback>();
|
|
||||||
VideoInputSyncFeedbacks = new Dictionary<uint, BoolFeedback>();
|
VideoInputSyncFeedbacks = new Dictionary<uint, BoolFeedback>();
|
||||||
InputNameFeedbacks = new Dictionary<uint, StringFeedback>();
|
InputNameFeedbacks = new Dictionary<uint, StringFeedback>();
|
||||||
OutputNameFeedbacks = new Dictionary<uint, StringFeedback>();
|
OutputNameFeedbacks = new Dictionary<uint, StringFeedback>();
|
||||||
@@ -233,8 +231,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video));
|
o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video));
|
||||||
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin,
|
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin,
|
||||||
o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio));
|
o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio));
|
||||||
trilist.SetUShortSigAction(joinMap.OutputAudioSourceDevice.JoinNumber + ioSlotJoin, u =>
|
|
||||||
SetAudioOutputSourceDevice(ioSlot, u));
|
|
||||||
|
|
||||||
trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s =>
|
trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s =>
|
||||||
{
|
{
|
||||||
@@ -273,15 +269,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
{
|
{
|
||||||
AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]);
|
AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntFeedback audioOutSourceDeviceFeedback;
|
|
||||||
|
|
||||||
|
|
||||||
if (AudioOutputSourceDeviceFeedbacks.TryGetValue(ioSlot, out audioOutSourceDeviceFeedback))
|
|
||||||
{
|
|
||||||
audioOutSourceDeviceFeedback.LinkInputSig(
|
|
||||||
trilist.UShortInput[joinMap.OutputAudioSourceDevice.JoinNumber + ioSlotJoin]);
|
|
||||||
}
|
|
||||||
if (OutputNameFeedbacks[ioSlot] != null)
|
if (OutputNameFeedbacks[ioSlot] != null)
|
||||||
{
|
{
|
||||||
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
|
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
|
||||||
@@ -304,33 +291,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAudioOutputSourceDevice(uint output, ushort sourceDevice)
|
|
||||||
{
|
|
||||||
var card = Dmps.SwitcherOutputs[output];
|
|
||||||
|
|
||||||
if (sourceDevice > 3)
|
|
||||||
{
|
|
||||||
Debug.Console(1, this, "Invalid audio out device {0}. Valid values are 0 (NoSource), 1 (DigitalMixer1), 2 (DigitalMixer2), 3(AudioFollowVideo)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//try to cast to dm output
|
|
||||||
var dmOut = card as Card.Dmps3DmOutputBackend;
|
|
||||||
var hdmiOut = card as Card.Dmps3HdmiOutputBackend;
|
|
||||||
|
|
||||||
if (dmOut != null)
|
|
||||||
{
|
|
||||||
dmOut.AudioOutSourceDevice = (eDmps34KAudioOutSourceDevice) sourceDevice;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdmiOut == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdmiOut.AudioOutSourceDevice = (eDmps34KAudioOutSourceDevice) sourceDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
|
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
|
||||||
{
|
{
|
||||||
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
|
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
|
||||||
@@ -612,11 +572,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
|
|
||||||
var cecPort = hdmiOutputCard.HdmiOutputPort;
|
var cecPort = hdmiOutputCard.HdmiOutputPort;
|
||||||
|
|
||||||
hdmiOutputCard.AudioOutSourceDevice = eDmps34KAudioOutSourceDevice.DigitalMixer1;
|
|
||||||
|
|
||||||
AudioOutputSourceDeviceFeedbacks.Add(outputCard.Number,
|
|
||||||
new IntFeedback(() => (int) hdmiOutputCard.AudioOutSourceDeviceFeedback));
|
|
||||||
|
|
||||||
AddHdmiOutputPort(number, cecPort);
|
AddHdmiOutputPort(number, cecPort);
|
||||||
}
|
}
|
||||||
else if (outputCard is Card.Dmps3DmOutput)
|
else if (outputCard is Card.Dmps3DmOutput)
|
||||||
@@ -625,11 +580,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
}
|
}
|
||||||
else if (outputCard is Card.Dmps3DmOutputBackend)
|
else if (outputCard is Card.Dmps3DmOutputBackend)
|
||||||
{
|
{
|
||||||
var dmCard = outputCard as Card.Dmps3DmOutputBackend;
|
|
||||||
|
|
||||||
AudioOutputSourceDeviceFeedbacks.Add(outputCard.Number,
|
|
||||||
new IntFeedback(() => (int) dmCard.AudioOutSourceDeviceFeedback));
|
|
||||||
|
|
||||||
AddDmOutputPort(number);
|
AddDmOutputPort(number);
|
||||||
}
|
}
|
||||||
else if (outputCard is Card.Dmps3ProgramOutput)
|
else if (outputCard is Card.Dmps3ProgramOutput)
|
||||||
@@ -851,12 +801,6 @@ namespace PepperDash.Essentials.DM
|
|||||||
{
|
{
|
||||||
AudioOutputFeedbacks[output].FireUpdate();
|
AudioOutputFeedbacks[output].FireUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AudioOutputSourceDeviceFeedbacks.ContainsKey(output))
|
|
||||||
{
|
|
||||||
AudioOutputSourceDeviceFeedbacks[output].FireUpdate();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (args.EventId == DMOutputEventIds.OutputNameEventId
|
else if (args.EventId == DMOutputEventIds.OutputNameEventId
|
||||||
@@ -927,9 +871,15 @@ namespace PepperDash.Essentials.DM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput;
|
||||||
|
|
||||||
|
//if (inCard != null)
|
||||||
|
//{
|
||||||
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
|
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
|
||||||
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||||
{
|
{
|
||||||
|
|
||||||
output.VideoOut = input;
|
output.VideoOut = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ using Crestron.SimplSharp.Reflection;
|
|||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Presets;
|
using PepperDash.Essentials.Core.Presets;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
@@ -25,7 +27,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
Focus = 8
|
Focus = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class CameraBase : EssentialsDevice, IRoutingOutputs
|
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
|
||||||
{
|
{
|
||||||
public eCameraControlMode ControlMode { get; protected set; }
|
public eCameraControlMode ControlMode { get; protected set; }
|
||||||
|
|
||||||
@@ -70,12 +72,18 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
// A bitmasked value to indicate the movement capabilites of this camera
|
// A bitmasked value to indicate the movement capabilites of this camera
|
||||||
protected eCameraCapabilities Capabilities { get; set; }
|
protected eCameraCapabilities Capabilities { get; set; }
|
||||||
|
|
||||||
protected CameraBase(string key, string name) :
|
protected CameraBase(DeviceConfig config) : base(config)
|
||||||
base(key, name)
|
|
||||||
{
|
{
|
||||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||||
|
|
||||||
ControlMode = eCameraControlMode.Manual;
|
ControlMode = eCameraControlMode.Manual;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CameraBase(string key, string name) :
|
||||||
|
this (new DeviceConfig{Name = name, Key = key})
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||||
|
|||||||
@@ -4,15 +4,20 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
public enum eMeetingEventChangeType
|
public enum eMeetingEventChangeType
|
||||||
{
|
{
|
||||||
Unkown = 0,
|
Unknown = 0,
|
||||||
MeetingStartWarning,
|
MeetingStartWarning = 1,
|
||||||
MeetingStart,
|
MeetingStart = 2,
|
||||||
MeetingEndWarning,
|
MeetingEndWarning = 4,
|
||||||
MeetingEnd
|
MeetingEnd = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IHasScheduleAwareness
|
public interface IHasScheduleAwareness
|
||||||
@@ -32,6 +37,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
|
|
||||||
private int _meetingWarningMinutes = 5;
|
private int _meetingWarningMinutes = 5;
|
||||||
|
|
||||||
|
private Meeting _previousChangedMeeting;
|
||||||
|
|
||||||
|
private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
|
||||||
|
|
||||||
public int MeetingWarningMinutes
|
public int MeetingWarningMinutes
|
||||||
{
|
{
|
||||||
get { return _meetingWarningMinutes; }
|
get { return _meetingWarningMinutes; }
|
||||||
@@ -75,38 +84,72 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
|
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="changeType"></param>
|
||||||
|
/// <param name="meeting"></param>
|
||||||
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
|
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
|
||||||
{
|
{
|
||||||
|
Debug.Console(2, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
|
||||||
|
if (changeType != (changeType & meeting.NotifiedChangeTypes))
|
||||||
|
{
|
||||||
|
// Add this change type to the NotifiedChangeTypes
|
||||||
|
meeting.NotifiedChangeTypes |= changeType;
|
||||||
|
|
||||||
var handler = MeetingEventChange;
|
var handler = MeetingEventChange;
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
{
|
{
|
||||||
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
private void CheckSchedule(object o)
|
|
||||||
{
|
{
|
||||||
// Iterate the meeting list and check if any meeting need to do anythingk
|
Debug.Console(2, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
|
||||||
|
}
|
||||||
const double meetingTimeEpsilon = 0.0001;
|
|
||||||
foreach (var m in Meetings)
|
|
||||||
{
|
|
||||||
var changeType = eMeetingEventChangeType.Unkown;
|
|
||||||
|
|
||||||
if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start
|
|
||||||
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
|
||||||
else if (Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
|
||||||
changeType = eMeetingEventChangeType.MeetingStart;
|
|
||||||
else if (m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to end
|
|
||||||
changeType = eMeetingEventChangeType.MeetingEndWarning;
|
|
||||||
else if (Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
|
||||||
changeType = eMeetingEventChangeType.MeetingEnd;
|
|
||||||
|
|
||||||
if (changeType != eMeetingEventChangeType.Unkown)
|
|
||||||
OnMeetingChange(changeType, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks the schedule to see if any MeetingEventChange updates should be fired
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="o"></param>
|
||||||
|
private void CheckSchedule(object o)
|
||||||
|
{
|
||||||
|
// Iterate the meeting list and check if any meeting need to do anything
|
||||||
|
|
||||||
|
const double meetingTimeEpsilon = 0.05;
|
||||||
|
foreach (var m in Meetings)
|
||||||
|
{
|
||||||
|
var changeType = eMeetingEventChangeType.Unknown;
|
||||||
|
|
||||||
|
if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
|
||||||
|
{
|
||||||
|
Debug.Console(2, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
|
||||||
|
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
||||||
|
}
|
||||||
|
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
||||||
|
{
|
||||||
|
Debug.Console(2, "********************* MeetingStart");
|
||||||
|
changeType = eMeetingEventChangeType.MeetingStart;
|
||||||
|
}
|
||||||
|
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
|
||||||
|
{
|
||||||
|
Debug.Console(2, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
|
||||||
|
changeType = eMeetingEventChangeType.MeetingEndWarning;
|
||||||
|
}
|
||||||
|
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
||||||
|
{
|
||||||
|
Debug.Console(2, "********************* MeetingEnd");
|
||||||
|
changeType = eMeetingEventChangeType.MeetingEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changeType != eMeetingEventChangeType.Unknown)
|
||||||
|
{
|
||||||
|
OnMeetingChange(changeType, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,17 +158,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Meeting
|
public class Meeting
|
||||||
{
|
{
|
||||||
|
[JsonProperty("minutesBeforeMeeting")]
|
||||||
public int MinutesBeforeMeeting;
|
public int MinutesBeforeMeeting;
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
[JsonProperty("organizer")]
|
||||||
public string Organizer { get; set; }
|
public string Organizer { get; set; }
|
||||||
|
[JsonProperty("title")]
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
[JsonProperty("agenda")]
|
||||||
public string Agenda { get; set; }
|
public string Agenda { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("meetingWarningMinutes")]
|
||||||
public TimeSpan MeetingWarningMinutes
|
public TimeSpan MeetingWarningMinutes
|
||||||
{
|
{
|
||||||
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
||||||
}
|
}
|
||||||
|
[JsonProperty("timeToMeetingStart")]
|
||||||
public TimeSpan TimeToMeetingStart
|
public TimeSpan TimeToMeetingStart
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -133,6 +183,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
return StartTime - DateTime.Now;
|
return StartTime - DateTime.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[JsonProperty("timeToMeetingEnd")]
|
||||||
public TimeSpan TimeToMeetingEnd
|
public TimeSpan TimeToMeetingEnd
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -140,8 +191,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
return EndTime - DateTime.Now;
|
return EndTime - DateTime.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[JsonProperty("startTime")]
|
||||||
public DateTime StartTime { get; set; }
|
public DateTime StartTime { get; set; }
|
||||||
|
[JsonProperty("endTime")]
|
||||||
public DateTime EndTime { get; set; }
|
public DateTime EndTime { get; set; }
|
||||||
|
[JsonProperty("duration")]
|
||||||
public TimeSpan Duration
|
public TimeSpan Duration
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -149,21 +203,34 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
|||||||
return EndTime - StartTime;
|
return EndTime - StartTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[JsonProperty("privacy")]
|
||||||
public eMeetingPrivacy Privacy { get; set; }
|
public eMeetingPrivacy Privacy { get; set; }
|
||||||
|
[JsonProperty("joinable")]
|
||||||
public bool Joinable
|
public bool Joinable
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
|
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
|
||||||
&& DateTime.Now <= EndTime; //.AddMinutes(-5);
|
&& DateTime.Now <= EndTime.AddMinutes(-5);
|
||||||
|
//Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable);
|
||||||
|
return joinable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//public string ConferenceNumberToDial { get; set; }
|
//public string ConferenceNumberToDial { get; set; }
|
||||||
|
[JsonProperty("conferencePassword")]
|
||||||
public string ConferencePassword { get; set; }
|
public string ConferencePassword { get; set; }
|
||||||
|
[JsonProperty("isOneButtonToPushMeeting")]
|
||||||
public bool IsOneButtonToPushMeeting { get; set; }
|
public bool IsOneButtonToPushMeeting { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("calls")]
|
||||||
public List<Call> Calls { get; private set; }
|
public List<Call> Calls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tracks the change types that have already been notified for
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
|
||||||
|
|
||||||
public Meeting()
|
public Meeting()
|
||||||
{
|
{
|
||||||
Calls = new List<Call>();
|
Calls = new List<Call>();
|
||||||
|
|||||||
@@ -122,6 +122,7 @@
|
|||||||
<Compile Include="Display\PanasonicThDisplay.cs" />
|
<Compile Include="Display\PanasonicThDisplay.cs" />
|
||||||
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
|
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
|
||||||
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
|
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
|
||||||
|
<Compile Include="VideoCodec\Interfaces\IHasSelfviewSize.cs" />
|
||||||
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
|
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
|
||||||
<Compile Include="Codec\iHasCallFavorites.cs" />
|
<Compile Include="Codec\iHasCallFavorites.cs" />
|
||||||
<Compile Include="Codec\iHasCallHistory.cs" />
|
<Compile Include="Codec\iHasCallHistory.cs" />
|
||||||
@@ -176,6 +177,7 @@
|
|||||||
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
||||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
||||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
||||||
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomJoinMap.cs" />
|
||||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
|
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
|
||||||
<None Include="Properties\ControlSystem.cfg" />
|
<None Include="Properties\ControlSystem.cfg" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -550,6 +550,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(GetBookings, "GetCodecBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(GetBookings, "GetCodecBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
return base.CustomActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Device
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
var socket = Communication as ISocketStatus;
|
var socket = Communication as ISocketStatus;
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
{
|
{
|
||||||
@@ -560,7 +567,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
|
|
||||||
CommunicationMonitor.Start();
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
string prefix = "xFeedback register ";
|
const string prefix = "xFeedback register ";
|
||||||
|
|
||||||
CliFeedbackRegistrationExpression =
|
CliFeedbackRegistrationExpression =
|
||||||
prefix + "/Configuration" + Delimiter +
|
prefix + "/Configuration" + Delimiter +
|
||||||
@@ -579,10 +586,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
prefix + "/Event/Bookings" + Delimiter +
|
prefix + "/Event/Bookings" + Delimiter +
|
||||||
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
|
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
|
||||||
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
||||||
|
|
||||||
return base.CustomActivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc.
|
/// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -19,4 +19,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
void LocalLayoutToggleSingleProminent();
|
void LocalLayoutToggleSingleProminent();
|
||||||
void MinMaxLayoutToggle();
|
void MinMaxLayoutToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the requirements for Zoom Room layout control
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasZoomRoomLayouts : IHasCodecLayouts
|
||||||
|
{
|
||||||
|
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
|
||||||
|
BoolFeedback CanSwapContentWithThumbnailFeedback { get; }
|
||||||
|
BoolFeedback ContentSwappedWithThumbnailFeedback { get; }
|
||||||
|
|
||||||
|
ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; }
|
||||||
|
ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; }
|
||||||
|
|
||||||
|
void GetAvailableLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout
|
||||||
|
void SetLayout(ZoomRoom.zConfiguration.eLayoutStyle layoutStyle);
|
||||||
|
void SwapContentWithThumbnail();
|
||||||
|
|
||||||
|
void LayoutTurnNextPage();
|
||||||
|
void LayoutTurnPreviousPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LayoutInfoChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a device that has call participants
|
||||||
|
/// </summary>
|
||||||
public interface IHasParticipants
|
public interface IHasParticipants
|
||||||
{
|
{
|
||||||
CodecParticipants Participants { get; }
|
CodecParticipants Participants { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the ability to mute and unmute a participant's video in a meeting
|
||||||
|
/// </summary>
|
||||||
public interface IHasParticipantVideoMute:IHasParticipants
|
public interface IHasParticipantVideoMute:IHasParticipants
|
||||||
{
|
{
|
||||||
void MuteVideoForParticipant(int userId);
|
void MuteVideoForParticipant(int userId);
|
||||||
@@ -15,13 +22,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
|||||||
void ToggleVideoForParticipant(int userId);
|
void ToggleVideoForParticipant(int userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IHasParticipantAudioMute:IHasParticipantVideoMute
|
/// <summary>
|
||||||
|
/// Describes the ability to mute and unmute a participant's audio in a meeting
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
|
||||||
{
|
{
|
||||||
void MuteAudioForParticipant(int userId);
|
void MuteAudioForParticipant(int userId);
|
||||||
void UnmuteAudioForParticipant(int userId);
|
void UnmuteAudioForParticipant(int userId);
|
||||||
void ToggleAudioForParticipant(int userId);
|
void ToggleAudioForParticipant(int userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes the ability to pin and unpin a participant in a meeting
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasParticipantPinUnpin : IHasParticipants
|
||||||
|
{
|
||||||
|
IntFeedback NumberOfScreensFeedback { get; }
|
||||||
|
int ScreenIndexToPinUserTo { get; }
|
||||||
|
|
||||||
|
void PinParticipant(int userId, int screenIndex);
|
||||||
|
void UnPinParticipant(int userId);
|
||||||
|
void ToggleParticipantPinState(int userId, int screenIndex);
|
||||||
|
}
|
||||||
|
|
||||||
public class CodecParticipants
|
public class CodecParticipants
|
||||||
{
|
{
|
||||||
private List<Participant> _currentParticipants;
|
private List<Participant> _currentParticipants;
|
||||||
@@ -31,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_currentParticipants = value;
|
_currentParticipants = value;
|
||||||
var handler = ParticipantsListHasChanged;
|
OnParticipantsChanged();
|
||||||
|
|
||||||
if(handler == null) return;
|
|
||||||
|
|
||||||
handler(this, new EventArgs());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,15 +64,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
|||||||
{
|
{
|
||||||
_currentParticipants = new List<Participant>();
|
_currentParticipants = new List<Participant>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnParticipantsChanged()
|
||||||
|
{
|
||||||
|
var handler = ParticipantsListHasChanged;
|
||||||
|
|
||||||
|
if (handler == null) return;
|
||||||
|
|
||||||
|
handler(this, new EventArgs());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a call participant
|
||||||
|
/// </summary>
|
||||||
public class Participant
|
public class Participant
|
||||||
{
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
public bool IsHost { get; set; }
|
public bool IsHost { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool CanMuteVideo { get; set; }
|
public bool CanMuteVideo { get; set; }
|
||||||
public bool CanUnmuteVideo { get; set; }
|
public bool CanUnmuteVideo { get; set; }
|
||||||
public bool VideoMuteFb { get; set; }
|
public bool VideoMuteFb { get; set; }
|
||||||
public bool AudioMuteFb { get; set; }
|
public bool AudioMuteFb { get; set; }
|
||||||
|
public bool HandIsRaisedFb { get; set; }
|
||||||
|
public bool IsPinnedFb { get; set; }
|
||||||
|
public int ScreenIndexIsPinnedToFb { get; set; }
|
||||||
|
|
||||||
|
public Participant()
|
||||||
|
{
|
||||||
|
// Initialize to -1 (no screen)
|
||||||
|
ScreenIndexIsPinnedToFb = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||||
|
{
|
||||||
|
public interface IHasSelfviewSize
|
||||||
|
{
|
||||||
|
StringFeedback SelfviewPipSizeFeedback { get; }
|
||||||
|
|
||||||
|
void SelfviewPipSizeSet(CodecCommandWithLabel size);
|
||||||
|
|
||||||
|
void SelfviewPipSizeToggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -139,7 +139,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
|
|
||||||
public override void Dial(Meeting meeting)
|
public override void Dial(Meeting meeting)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Debug.Console(1, this, "Dial Meeting: {0}", meeting.Id);
|
||||||
|
var call = new CodecActiveCallItem() { Name = meeting.Title, Number = meeting.Id, Id = meeting.Id, Status = eCodecCallStatus.Dialing, Direction = eCodecCallDirection.Outgoing, Type = eCodecCallType.Video };
|
||||||
|
ActiveCalls.Add(call);
|
||||||
|
OnCallStatusChange(call);
|
||||||
|
|
||||||
|
//ActiveCallCountFeedback.FireUpdate();
|
||||||
|
// Simulate 2-second ring, then connecting, then connected
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
call.Type = eCodecCallType.Video;
|
||||||
|
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call);
|
||||||
|
new CTimer(oo => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000);
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -396,12 +409,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0
|
if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0
|
||||||
|| _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now)
|
|| _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now)
|
||||||
{
|
{
|
||||||
_CodecSchedule = new CodecScheduleAwareness();
|
_CodecSchedule = new CodecScheduleAwareness(1000);
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
var m = new Meeting();
|
var m = new Meeting();
|
||||||
m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i);
|
m.MinutesBeforeMeeting = 5;
|
||||||
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30);
|
m.Id = i.ToString();
|
||||||
|
m.Organizer = "Employee " + 1;
|
||||||
|
m.StartTime = DateTime.Now.AddMinutes(6).AddHours(i);
|
||||||
|
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(16);
|
||||||
m.Title = "Meeting " + i;
|
m.Title = "Meeting " + i;
|
||||||
m.Calls.Add(new Call() { Number = i + "meeting@fake.com"});
|
m.Calls.Add(new Call() { Number = i + "meeting@fake.com"});
|
||||||
_CodecSchedule.Meetings.Add(m);
|
_CodecSchedule.Meetings.Add(m);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
|
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
|
||||||
{
|
{
|
||||||
private const int XSigEncoding = 28591;
|
private const int XSigEncoding = 28591;
|
||||||
|
protected const int MaxParticipants = 50;
|
||||||
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
|
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
|
||||||
protected VideoCodecBase(DeviceConfig config)
|
protected VideoCodecBase(DeviceConfig config)
|
||||||
: base(config)
|
: base(config)
|
||||||
@@ -271,6 +272,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
|
|
||||||
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use this method when using a plain VideoCodecControllerJoinMap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="codec"></param>
|
||||||
|
/// <param name="trilist"></param>
|
||||||
|
/// <param name="joinStart"></param>
|
||||||
|
/// <param name="joinMapKey"></param>
|
||||||
|
/// <param name="bridge"></param>
|
||||||
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
|
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||||
EiscApiAdvanced bridge)
|
EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
@@ -288,10 +297,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
bridge.AddJoinMap(Key, joinMap);
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkVideoCodecToApi(codec, trilist, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="codec"></param>
|
||||||
|
/// <param name="trilist"></param>
|
||||||
|
/// <param name="joinMap"></param>
|
||||||
|
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
|
{
|
||||||
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
|
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LinkVideoCodecDtmfToApi(trilist, joinMap);
|
LinkVideoCodecDtmfToApi(trilist, joinMap);
|
||||||
|
|
||||||
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
||||||
@@ -512,7 +530,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
|
|
||||||
private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
{
|
{
|
||||||
|
// make sure to update the values when the EISC comes online
|
||||||
|
trilist.OnlineStatusChange += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (sender.IsOnline)
|
||||||
|
{
|
||||||
|
UpdateParticipantsXSig(codec, trilist, joinMap);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// set actions and update the values when the list changes
|
||||||
codec.Participants.ParticipantsListHasChanged += (sender, args) =>
|
codec.Participants.ParticipantsListHasChanged += (sender, args) =>
|
||||||
|
{
|
||||||
|
SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants);
|
||||||
|
|
||||||
|
UpdateParticipantsXSig(codec, trilist, joinMap);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
{
|
{
|
||||||
string participantsXSig;
|
string participantsXSig;
|
||||||
|
|
||||||
@@ -529,17 +565,61 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||||
|
|
||||||
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
|
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the actions for each participant in the list
|
||||||
|
/// </summary>
|
||||||
|
private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List<Participant> currentParticipants)
|
||||||
|
{
|
||||||
|
uint index = 0; // track the index of the participant in the
|
||||||
|
|
||||||
|
foreach (var participant in currentParticipants)
|
||||||
|
{
|
||||||
|
var p = participant;
|
||||||
|
if (index > MaxParticipants) break;
|
||||||
|
|
||||||
|
var audioMuteCodec = this as IHasParticipantAudioMute;
|
||||||
|
if (audioMuteCodec != null)
|
||||||
|
{
|
||||||
|
trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index,
|
||||||
|
() => audioMuteCodec.ToggleAudioForParticipant(p.UserId));
|
||||||
|
|
||||||
|
trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index,
|
||||||
|
() => audioMuteCodec.ToggleVideoForParticipant(p.UserId));
|
||||||
|
}
|
||||||
|
|
||||||
|
var pinCodec = this as IHasParticipantPinUnpin;
|
||||||
|
if (pinCodec != null)
|
||||||
|
{
|
||||||
|
trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index,
|
||||||
|
() => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo));
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear out any previously set actions
|
||||||
|
while (index < MaxParticipants)
|
||||||
|
{
|
||||||
|
trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index);
|
||||||
|
trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index);
|
||||||
|
trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
||||||
{
|
{
|
||||||
const int maxParticipants = 50;
|
const int maxParticipants = MaxParticipants;
|
||||||
const int maxDigitals = 5;
|
const int maxDigitals = 7;
|
||||||
const int maxStrings = 1;
|
const int maxStrings = 1;
|
||||||
const int offset = maxDigitals + maxStrings;
|
const int maxAnalogs = 1;
|
||||||
var digitalIndex = maxStrings * maxParticipants; //15
|
const int offset = maxDigitals + maxStrings + maxAnalogs; // 9
|
||||||
|
var digitalIndex = (maxStrings + maxAnalogs) * maxParticipants; // 100
|
||||||
var stringIndex = 0;
|
var stringIndex = 0;
|
||||||
|
var analogIndex = stringIndex + maxParticipants;
|
||||||
var meetingIndex = 0;
|
var meetingIndex = 0;
|
||||||
|
|
||||||
var tokenArray = new XSigToken[maxParticipants * offset];
|
var tokenArray = new XSigToken[maxParticipants * offset];
|
||||||
@@ -548,38 +628,91 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
{
|
{
|
||||||
if (meetingIndex >= maxParticipants * offset) break;
|
if (meetingIndex >= maxParticipants * offset) break;
|
||||||
|
|
||||||
|
Debug.Console(2, this,
|
||||||
|
@"Updating Participant on xsig:
|
||||||
|
Name: {0} (s{9})
|
||||||
|
AudioMute: {1} (d{10})
|
||||||
|
VideoMute: {2} (d{11})
|
||||||
|
CanMuteVideo: {3} (d{12})
|
||||||
|
CanUMuteVideo: {4} (d{13})
|
||||||
|
IsHost: {5} (d{14})
|
||||||
|
HandIsRaised: {6} (d{15})
|
||||||
|
IsPinned: {7} (d{16})
|
||||||
|
ScreenIndexIsPinnedTo: {8} (a{17})
|
||||||
|
",
|
||||||
|
participant.Name,
|
||||||
|
participant.AudioMuteFb,
|
||||||
|
participant.VideoMuteFb,
|
||||||
|
participant.CanMuteVideo,
|
||||||
|
participant.CanUnmuteVideo,
|
||||||
|
participant.IsHost,
|
||||||
|
participant.HandIsRaisedFb,
|
||||||
|
participant.IsPinnedFb,
|
||||||
|
participant.ScreenIndexIsPinnedToFb,
|
||||||
|
stringIndex + 1,
|
||||||
|
digitalIndex + 1,
|
||||||
|
digitalIndex + 2,
|
||||||
|
digitalIndex + 3,
|
||||||
|
digitalIndex + 4,
|
||||||
|
digitalIndex + 5,
|
||||||
|
digitalIndex + 6,
|
||||||
|
digitalIndex + 7,
|
||||||
|
analogIndex + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//digitals
|
//digitals
|
||||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
|
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
|
||||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
|
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
|
||||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
|
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
|
||||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
|
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
|
||||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
|
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
|
||||||
|
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
|
||||||
|
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Index: {0} byte value: {1}", digitalIndex + 7, ComTextHelper.GetEscapedText(tokenArray[digitalIndex + 6].GetBytes()));
|
||||||
|
|
||||||
//serials
|
//serials
|
||||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
|
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
|
||||||
|
|
||||||
|
//analogs
|
||||||
|
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb);
|
||||||
|
|
||||||
digitalIndex += maxDigitals;
|
digitalIndex += maxDigitals;
|
||||||
meetingIndex += offset;
|
meetingIndex += offset;
|
||||||
stringIndex += maxStrings;
|
stringIndex += maxStrings;
|
||||||
|
analogIndex += maxAnalogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (meetingIndex < maxParticipants * offset)
|
while (meetingIndex < maxParticipants * offset)
|
||||||
{
|
{
|
||||||
|
//digitals
|
||||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
||||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
||||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
|
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
|
||||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
|
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
|
||||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
|
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
|
||||||
|
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false);
|
||||||
|
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false);
|
||||||
|
|
||||||
//serials
|
//serials
|
||||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
||||||
|
|
||||||
|
//analogs
|
||||||
|
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0);
|
||||||
|
|
||||||
digitalIndex += maxDigitals;
|
digitalIndex += maxDigitals;
|
||||||
meetingIndex += offset;
|
meetingIndex += offset;
|
||||||
stringIndex += maxStrings;
|
stringIndex += maxStrings;
|
||||||
|
analogIndex += maxAnalogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetXSigString(tokenArray);
|
var returnString = GetXSigString(tokenArray);
|
||||||
|
|
||||||
|
//Debug.Console(2, this, "{0}", ComTextHelper.GetEscapedText(Encoding.GetEncoding(28591).GetBytes(returnString)));
|
||||||
|
|
||||||
|
|
||||||
|
return returnString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
@@ -595,7 +728,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
|
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
private List<Meeting> _currentMeetings = new List<Meeting>();
|
private List<Meeting> _currentMeetings = new List<Meeting>();
|
||||||
|
|
||||||
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||||
@@ -607,7 +739,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
codec.CodecSchedule.MeetingWarningMinutes = i;
|
codec.CodecSchedule.MeetingWarningMinutes = i;
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
|
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
var mtg = 1;
|
var mtg = 1;
|
||||||
@@ -617,7 +748,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
if (_currentMeetings[index] != null)
|
if (_currentMeetings[index] != null)
|
||||||
Dial(_currentMeetings[index]);
|
Dial(_currentMeetings[index]);
|
||||||
});
|
});
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
|
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
var mtg = 2;
|
var mtg = 2;
|
||||||
@@ -627,7 +758,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
if (_currentMeetings[index] != null)
|
if (_currentMeetings[index] != null)
|
||||||
Dial(_currentMeetings[index]);
|
Dial(_currentMeetings[index]);
|
||||||
});
|
});
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
|
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
|
||||||
{
|
{
|
||||||
var mtg = 3;
|
var mtg = 3;
|
||||||
@@ -652,14 +783,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
|||||||
{
|
{
|
||||||
var currentTime = DateTime.Now;
|
var currentTime = DateTime.Now;
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
// - changed var currentMeetings >> field _currentMeetings
|
|
||||||
//_currentMeetings.Clear();
|
|
||||||
_currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
|
_currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
|
||||||
|
|
||||||
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
|
|
||||||
// - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi
|
|
||||||
|
|
||||||
var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
|
var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
|
||||||
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
|
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
|
||||||
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
|
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
{
|
{
|
||||||
foreach (Contact c in zoomContacts)
|
foreach (Contact c in zoomContacts)
|
||||||
{
|
{
|
||||||
var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid};
|
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
|
||||||
|
|
||||||
if (folders.Count > 0)
|
if (folders.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -480,12 +480,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
public string wifiName { get; set; }
|
public string wifiName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NumberOfScreens
|
public class NumberOfScreens : NotifiableObject
|
||||||
{
|
{
|
||||||
|
private int _numOfScreens;
|
||||||
|
|
||||||
[JsonProperty("NumberOfCECScreens")]
|
[JsonProperty("NumberOfCECScreens")]
|
||||||
public int NumOfCECScreens { get; set; }
|
public int NumOfCECScreens { get; set; }
|
||||||
[JsonProperty("NumberOfScreens")]
|
[JsonProperty("NumberOfScreens")]
|
||||||
public int NumOfScreens { get; set; }
|
public int NumOfScreens
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _numOfScreens;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _numOfScreens)
|
||||||
|
{
|
||||||
|
_numOfScreens = value;
|
||||||
|
NotifyPropertyChanged("NumberOfScreens");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -551,18 +567,136 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Layout
|
public class Layout : NotifiableObject
|
||||||
{
|
{
|
||||||
|
// backer variables
|
||||||
|
private bool _can_Switch_Speaker_View;
|
||||||
|
private bool _can_Switch_Wall_View;
|
||||||
|
private bool _can_Switch_Share_On_All_Screens;
|
||||||
|
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_Adjust_Floating_Video { get; set; }
|
||||||
public bool can_Switch_Floating_Share_Content { get; set; }
|
public bool can_Switch_Floating_Share_Content { get; set; }
|
||||||
public bool can_Switch_Share_On_All_Screens { get; set; }
|
|
||||||
public bool can_Switch_Speaker_View { get; set; }
|
/// <summary>
|
||||||
public bool can_Switch_Wall_View { get; set; }
|
/// [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.
|
||||||
public bool is_In_First_Page { get; set; }
|
/// </summary>
|
||||||
public bool is_In_Last_Page { get; set; }
|
[JsonProperty("can_Switch_Share_On_All_Screens")]
|
||||||
|
public bool can_Switch_Share_On_All_Screens
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _can_Switch_Share_On_All_Screens;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _can_Switch_Share_On_All_Screens)
|
||||||
|
{
|
||||||
|
_can_Switch_Share_On_All_Screens = value;
|
||||||
|
NotifyPropertyChanged("can_Switch_Share_On_All_Screens");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("can_Switch_Speaker_View")]
|
||||||
|
public bool can_Switch_Speaker_View
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _can_Switch_Speaker_View;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _can_Switch_Speaker_View)
|
||||||
|
{
|
||||||
|
_can_Switch_Speaker_View = value;
|
||||||
|
NotifyPropertyChanged("can_Switch_Speaker_View");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// [on/off] On if it is possible to invoke zConfiguration Call Layout Style: Gallery, to switch to the Gallery mode, showing video participants in tiled windows: The Zoom Room shows up to a 5x5 array of tiled windows per page.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("can_Switch_Wall_View")]
|
||||||
|
public bool can_Switch_Wall_View
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _can_Switch_Wall_View;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _can_Switch_Wall_View)
|
||||||
|
{
|
||||||
|
_can_Switch_Wall_View = value;
|
||||||
|
NotifyPropertyChanged("can_Switch_Wall_View");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("is_In_First_Page")]
|
||||||
|
public bool is_In_First_Page
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _is_In_First_Page;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _is_In_First_Page)
|
||||||
|
{
|
||||||
|
_is_In_First_Page = value;
|
||||||
|
NotifyPropertyChanged("is_In_First_Page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty("is_In_Last_Page")]
|
||||||
|
public bool is_In_Last_Page
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _is_In_Last_Page;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _is_In_Last_Page)
|
||||||
|
{
|
||||||
|
_is_In_Last_Page = value;
|
||||||
|
NotifyPropertyChanged("is_In_Last_Page");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool is_supported { get; set; }
|
public bool is_supported { get; set; }
|
||||||
public int video_Count_In_Current_Page { get; set; }
|
public int video_Count_In_Current_Page { get; set; }
|
||||||
public string video_type { get; set; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// [Gallery | Strip] Indicates which mode applies: Strip or Gallery.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("video_type")]
|
||||||
|
public string video_type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _video_type;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _video_type)
|
||||||
|
{
|
||||||
|
_video_type = value;
|
||||||
|
NotifyPropertyChanged("video_type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CallRecordInfo
|
public class CallRecordInfo
|
||||||
@@ -685,6 +819,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public class PinStatusOfScreenNotification
|
public class PinStatusOfScreenNotification
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
[JsonProperty("can_be_pinned")]
|
[JsonProperty("can_be_pinned")]
|
||||||
public bool CanBePinned { get; set; }
|
public bool CanBePinned { get; set; }
|
||||||
[JsonProperty("can_pin_share")]
|
[JsonProperty("can_pin_share")]
|
||||||
@@ -703,7 +839,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
public string WhyCannotPinShare { get; set; }
|
public string WhyCannotPinShare { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PhoneCallStatus:NotifiableObject
|
public class PhoneCallStatus : NotifiableObject
|
||||||
{
|
{
|
||||||
private bool _isIncomingCall;
|
private bool _isIncomingCall;
|
||||||
private string _peerDisplayName;
|
private string _peerDisplayName;
|
||||||
@@ -712,15 +848,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
private bool _offHook;
|
private bool _offHook;
|
||||||
|
|
||||||
public string CallId { get; set; }
|
public string CallId { get; set; }
|
||||||
public bool IsIncomingCall {
|
public bool IsIncomingCall
|
||||||
|
{
|
||||||
get { return _isIncomingCall; }
|
get { return _isIncomingCall; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(value == _isIncomingCall) return;
|
if (value == _isIncomingCall) return;
|
||||||
|
|
||||||
_isIncomingCall = value;
|
_isIncomingCall = value;
|
||||||
NotifyPropertyChanged("IsIncomingCall");
|
NotifyPropertyChanged("IsIncomingCall");
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string PeerDisplayName
|
public string PeerDisplayName
|
||||||
{
|
{
|
||||||
@@ -826,7 +964,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(value != _mute)
|
if (value != _mute)
|
||||||
{
|
{
|
||||||
_mute = value;
|
_mute = value;
|
||||||
NotifyPropertyChanged("Mute");
|
NotifyPropertyChanged("Mute");
|
||||||
@@ -835,12 +973,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
public enum eLayoutStyle
|
public enum eLayoutStyle
|
||||||
{
|
{
|
||||||
Gallery,
|
None = 0,
|
||||||
Speaker,
|
Gallery = 1,
|
||||||
Strip,
|
Speaker = 2,
|
||||||
ShareAll
|
Strip = 4,
|
||||||
|
ShareAll = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum eLayoutSize
|
public enum eLayoutSize
|
||||||
@@ -865,20 +1005,64 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
DownLeft
|
DownLeft
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Layout:NotifiableObject
|
public class Layout : NotifiableObject
|
||||||
{
|
{
|
||||||
public bool ShareThumb { get; set; }
|
private bool _shareThumb;
|
||||||
public eLayoutStyle Style { get; set; }
|
private eLayoutStyle _style;
|
||||||
public eLayoutSize Size { get; set; }
|
private eLayoutSize _size;
|
||||||
|
|
||||||
private eLayoutPosition _position;
|
private eLayoutPosition _position;
|
||||||
public eLayoutPosition Position {
|
|
||||||
|
public bool ShareThumb
|
||||||
|
{
|
||||||
|
get { return _shareThumb; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _shareThumb)
|
||||||
|
{
|
||||||
|
_shareThumb = value;
|
||||||
|
NotifyPropertyChanged("ShareThumb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public eLayoutStyle Style
|
||||||
|
{
|
||||||
|
get { return _style; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _style)
|
||||||
|
{
|
||||||
|
_style = value;
|
||||||
|
NotifyPropertyChanged("Style");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public eLayoutSize Size
|
||||||
|
{
|
||||||
|
get { return _size; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _size)
|
||||||
|
{
|
||||||
|
_size = value;
|
||||||
|
NotifyPropertyChanged("Size");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public eLayoutPosition Position
|
||||||
|
{
|
||||||
get { return _position; }
|
get { return _position; }
|
||||||
set
|
set
|
||||||
|
{
|
||||||
|
if (value != _position)
|
||||||
{
|
{
|
||||||
_position = value;
|
_position = value;
|
||||||
NotifyPropertyChanged("Position");
|
NotifyPropertyChanged("Position");
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Lock
|
public class Lock
|
||||||
@@ -998,7 +1182,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
private string _selectedId;
|
private string _selectedId;
|
||||||
|
|
||||||
[JsonProperty("selectedId")]
|
[JsonProperty("selectedId")]
|
||||||
public string SelectedId {
|
public string SelectedId
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _selectedId;
|
return _selectedId;
|
||||||
@@ -1020,6 +1205,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
{
|
{
|
||||||
public string appVersion { get; set; }
|
public string appVersion { get; set; }
|
||||||
public string deviceSystem { get; set; }
|
public string deviceSystem { get; set; }
|
||||||
|
|
||||||
|
// This doesn't belong here, but there's a bug in the object structure of Zoom Room 5.6.3 that puts it here
|
||||||
|
public zConfiguration.Call Call { get; set; }
|
||||||
|
|
||||||
|
public Client()
|
||||||
|
{
|
||||||
|
Call = new zConfiguration.Call();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1135,14 +1328,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public class HandStatus
|
public class HandStatus
|
||||||
{
|
{
|
||||||
[JsonProperty("is_raise_hand")]
|
// example return of the "hand_status" object
|
||||||
|
// !!!! Note the properties contain ': ' within the property name !!!
|
||||||
|
//"hand_status": {
|
||||||
|
// "is_raise_hand: ": false,
|
||||||
|
// "is_valid: ": "on",
|
||||||
|
// "time_stamp: ": "11825083"
|
||||||
|
//},
|
||||||
|
[JsonProperty("is_raise_hand: ")]
|
||||||
public bool IsRaiseHand { get; set; }
|
public bool IsRaiseHand { get; set; }
|
||||||
[JsonProperty("optimize_vis_validideo_sharing")]
|
[JsonProperty("is_valid: ")]
|
||||||
public string IsValid { get; set; }
|
public string IsValid { get; set; }
|
||||||
[JsonProperty("time_stamp")]
|
[JsonProperty("time_stamp: ")]
|
||||||
public string TimeStamp { get; set; }
|
public string TimeStamp { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Retuns a boolean value if the participant hand state is raised and is valid (both need to be true)
|
||||||
|
/// </summary>
|
||||||
|
public bool HandIsRaisedAndValid
|
||||||
|
{
|
||||||
|
get { return IsValid != null && IsValid == "on" && IsRaiseHand; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ListParticipant
|
public class ListParticipant
|
||||||
{
|
{
|
||||||
[JsonProperty("audio_status state")]
|
[JsonProperty("audio_status state")]
|
||||||
@@ -1205,22 +1411,87 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
HandStatus = new HandStatus();
|
HandStatus = new HandStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts ZoomRoom pariticpant list response to an Essentials participant list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="participants"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static List<Participant> GetGenericParticipantListFromParticipantsResult(
|
public static List<Participant> GetGenericParticipantListFromParticipantsResult(
|
||||||
List<ListParticipant> participants)
|
List<ListParticipant> participants)
|
||||||
{
|
{
|
||||||
return
|
//return participants.Select(p => new Participant
|
||||||
participants.Select(
|
// {
|
||||||
p =>
|
// UserId = p.UserId,
|
||||||
new Participant
|
// Name = p.UserName,
|
||||||
|
// IsHost = p.IsHost,
|
||||||
|
// CanMuteVideo = p.IsVideoCanMuteByHost,
|
||||||
|
// CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
||||||
|
// AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
||||||
|
// VideoMuteFb = p.VideoStatusIsSending,
|
||||||
|
// HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid,
|
||||||
|
// }).ToList();
|
||||||
|
|
||||||
|
var sortedParticipants = SortParticipantListByHandStatus(participants);
|
||||||
|
return sortedParticipants.Select(p => new Participant
|
||||||
{
|
{
|
||||||
|
UserId = p.UserId,
|
||||||
Name = p.UserName,
|
Name = p.UserName,
|
||||||
IsHost = p.IsHost,
|
IsHost = p.IsHost,
|
||||||
CanMuteVideo = p.IsVideoCanMuteByHost,
|
CanMuteVideo = p.IsVideoCanMuteByHost,
|
||||||
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
||||||
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
||||||
VideoMuteFb = p.VideoStatusIsSending
|
VideoMuteFb = !p.VideoStatusIsSending,
|
||||||
|
HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will sort by hand-raise status and then alphabetically
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="participants">Zoom Room response list of participants</param>
|
||||||
|
/// <returns>List</returns>
|
||||||
|
public static List<ListParticipant> SortParticipantListByHandStatus(List<ListParticipant> participants)
|
||||||
|
{
|
||||||
|
if (participants == null)
|
||||||
|
{
|
||||||
|
//Debug.Console(1, "SortParticiapntListByHandStatu(participants == null)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug testing
|
||||||
|
//foreach (ListParticipant participant in participants)
|
||||||
|
//{
|
||||||
|
// Debug.Console(1, "{0} | IsValid: {1} | IsRaiseHand: {2} | HandIsRaisedAndValid: {3}",
|
||||||
|
// participant.UserName, participant.HandStatus.IsValid, participant.HandStatus.IsRaiseHand.ToString(), participant.HandStatus.HandIsRaisedAndValid.ToString());
|
||||||
|
//}
|
||||||
|
|
||||||
|
List<ListParticipant> handRaisedParticipantsList = participants.Where(p => p.HandStatus.HandIsRaisedAndValid).ToList();
|
||||||
|
|
||||||
|
if (handRaisedParticipantsList != null)
|
||||||
|
{
|
||||||
|
IOrderedEnumerable<ListParticipant> orderByDescending = handRaisedParticipantsList.OrderByDescending(p => p.HandStatus.TimeStamp);
|
||||||
|
|
||||||
|
//foreach (var participant in handRaisedParticipantsList)
|
||||||
|
// Debug.Console(1, "handRaisedParticipantList: {0} | {1}", participant.UserName, participant.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ListParticipant> allOtherParticipantsList = participants.Where(p => !p.HandStatus.HandIsRaisedAndValid).ToList();
|
||||||
|
|
||||||
|
if (allOtherParticipantsList != null)
|
||||||
|
{
|
||||||
|
allOtherParticipantsList.OrderBy(p => p.UserName);
|
||||||
|
|
||||||
|
//foreach (var participant in allOtherParticipantsList)
|
||||||
|
// Debug.Console(1, "allOtherParticipantsList: {0} | {1}", participant.UserName, participant.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge the lists
|
||||||
|
List<ListParticipant> sortedList = handRaisedParticipantsList.Union(allOtherParticipantsList).ToList();
|
||||||
|
|
||||||
|
// return the sorted list
|
||||||
|
return sortedList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CallinCountryList
|
public class CallinCountryList
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
using Crestron.SimplSharpPro.CrestronThread;
|
using Crestron.SimplSharpPro.CrestronThread;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Core.Intersystem.Tokens;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Bridges;
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
@@ -23,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
||||||
IRouting,
|
IRouting,
|
||||||
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
|
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
|
||||||
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing
|
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute, IHasSelfviewSize
|
||||||
{
|
{
|
||||||
private const long MeetingRefreshTimer = 60000;
|
private const long MeetingRefreshTimer = 60000;
|
||||||
private const uint DefaultMeetingDurationMin = 30;
|
private const uint DefaultMeetingDurationMin = 30;
|
||||||
@@ -53,7 +55,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
_receiveQueue = new CrestronQueue<string>(1024);
|
_receiveQueue = new CrestronQueue<string>(1024);
|
||||||
|
|
||||||
// The thread responsible for dequeuing and processing the messages
|
// The thread responsible for dequeuing and processing the messages
|
||||||
_receiveThread = new Thread(o => ProcessQueue(), null) {Priority = Thread.eThreadPriority.MediumPriority};
|
_receiveThread = new Thread(o => ProcessQueue(), null) { Priority = Thread.eThreadPriority.MediumPriority };
|
||||||
|
|
||||||
Communication = comm;
|
Communication = comm;
|
||||||
|
|
||||||
@@ -82,7 +84,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync");
|
PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync");
|
||||||
|
|
||||||
PortGather = new CommunicationGather(Communication, "\x0A") {IncludeDelimiter = true};
|
PortGather = new CommunicationGather(Communication, "\x0A") { IncludeDelimiter = true };
|
||||||
PortGather.LineReceived += Port_LineReceived;
|
PortGather.LineReceived += Port_LineReceived;
|
||||||
|
|
||||||
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd,
|
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd,
|
||||||
@@ -107,6 +109,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc);
|
SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc);
|
||||||
|
|
||||||
|
// TODO: #714 [ ] SelfviewPipSizeFeedback
|
||||||
|
SelfviewPipSizeFeedback = new StringFeedback(SelfviewPipSizeFeedbackFunc);
|
||||||
|
|
||||||
SetUpFeedbackActions();
|
SetUpFeedbackActions();
|
||||||
|
|
||||||
Cameras = new List<CameraBase>();
|
Cameras = new List<CameraBase>();
|
||||||
@@ -121,6 +126,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
||||||
CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
|
CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
|
||||||
CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
|
CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
|
||||||
|
|
||||||
|
LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc);
|
||||||
|
|
||||||
|
LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc);
|
||||||
|
LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc);
|
||||||
|
CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc);
|
||||||
|
ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc);
|
||||||
|
|
||||||
|
NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommunicationGather PortGather { get; private set; }
|
public CommunicationGather PortGather { get; private set; }
|
||||||
@@ -216,9 +231,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Func<string> LocalLayoutFeedbackFunc
|
// TODO: #714 [ ] SelfviewPipSizeFeedbackFunc
|
||||||
|
protected Func<string> SelfviewPipSizeFeedbackFunc
|
||||||
{
|
{
|
||||||
get { return () => ""; }
|
get
|
||||||
|
{
|
||||||
|
return
|
||||||
|
() =>
|
||||||
|
_currentSelfviewPipSize != null
|
||||||
|
? _currentSelfviewPipSize.Command ?? "Unknown"
|
||||||
|
: "Unknown";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Func<bool> LocalLayoutIsProminentFeedbackFunc
|
protected Func<bool> LocalLayoutIsProminentFeedbackFunc
|
||||||
@@ -343,7 +366,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public void GetDirectoryFolderContents(string folderId)
|
public void GetDirectoryFolderContents(string folderId)
|
||||||
{
|
{
|
||||||
var directoryResults = new CodecDirectory {ResultsFolderId = folderId};
|
var directoryResults = new CodecDirectory { ResultsFolderId = folderId };
|
||||||
|
|
||||||
directoryResults.AddContactsToDirectory(
|
directoryResults.AddContactsToDirectory(
|
||||||
DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId)));
|
DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId)));
|
||||||
@@ -484,11 +507,64 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
Configuration.Call.Layout.PropertyChanged += (o, a) =>
|
Configuration.Call.Layout.PropertyChanged += (o, a) =>
|
||||||
{
|
{
|
||||||
if (a.PropertyName != "Position") return;
|
switch (a.PropertyName)
|
||||||
|
{
|
||||||
ComputeSelfviewPipStatus();
|
case "Position":
|
||||||
|
{
|
||||||
|
ComputeSelfviewPipPositionStatus();
|
||||||
|
|
||||||
SelfviewPipPositionFeedback.FireUpdate();
|
SelfviewPipPositionFeedback.FireUpdate();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ShareThumb":
|
||||||
|
{
|
||||||
|
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Style":
|
||||||
|
{
|
||||||
|
LocalLayoutFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Size":
|
||||||
|
{
|
||||||
|
// TODO: #714 [ ] SetupFeedbackActions >> Size
|
||||||
|
ComputeSelfviewPipSizeStatus();
|
||||||
|
|
||||||
|
SelfviewPipSizeFeedback.FireUpdate();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3
|
||||||
|
Configuration.Client.Call.Layout.PropertyChanged += (o,a) =>
|
||||||
|
{
|
||||||
|
switch (a.PropertyName)
|
||||||
|
{
|
||||||
|
case "Position":
|
||||||
|
{
|
||||||
|
ComputeSelfviewPipPositionStatus();
|
||||||
|
|
||||||
|
SelfviewPipPositionFeedback.FireUpdate();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ShareThumb":
|
||||||
|
{
|
||||||
|
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Style":
|
||||||
|
{
|
||||||
|
LocalLayoutFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
||||||
@@ -542,12 +618,57 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Status.Layout.PropertyChanged += (o, a) =>
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Status.Layout.PropertyChanged a.PropertyName: {0}", a.PropertyName);
|
||||||
|
switch (a.PropertyName.ToLower())
|
||||||
|
{
|
||||||
|
case "can_switch_speaker_view":
|
||||||
|
case "can_switch_wall_view":
|
||||||
|
case "can_switch_share_on_all_screens":
|
||||||
|
{
|
||||||
|
ComputeAvailableLayouts();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "is_in_first_page":
|
||||||
|
{
|
||||||
|
LayoutViewIsOnFirstPageFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "is_in_last_page":
|
||||||
|
{
|
||||||
|
LayoutViewIsOnLastPageFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//case "video_type":
|
||||||
|
// {
|
||||||
|
// It appears as though the actual value we want to watch is Configuration.Call.Layout.Style
|
||||||
|
// LocalLayoutFeedback.FireUpdate();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Status.NumberOfScreens.PropertyChanged += (o, a) =>
|
||||||
|
{
|
||||||
|
switch (a.PropertyName)
|
||||||
|
{
|
||||||
|
case "NumberOfScreens":
|
||||||
|
{
|
||||||
|
NumberOfScreensFeedback.FireUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetUpDirectory()
|
private void SetUpDirectory()
|
||||||
{
|
{
|
||||||
DirectoryRoot = new CodecDirectory();
|
DirectoryRoot = new CodecDirectory();
|
||||||
|
|
||||||
|
_currentDirectoryResult = DirectoryRoot;
|
||||||
|
|
||||||
DirectoryBrowseHistory = new List<CodecDirectory>();
|
DirectoryBrowseHistory = new List<CodecDirectory>();
|
||||||
DirectoryBrowseHistoryStack = new Stack<CodecDirectory>();
|
DirectoryBrowseHistoryStack = new Stack<CodecDirectory>();
|
||||||
|
|
||||||
@@ -598,6 +719,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
|
CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
|
||||||
"Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
"Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return base.CustomActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of Device
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
var socket = Communication as ISocketStatus;
|
var socket = Communication as ISocketStatus;
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
{
|
{
|
||||||
@@ -609,10 +739,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
Communication.Connect();
|
Communication.Connect();
|
||||||
|
|
||||||
CommunicationMonitor.Start();
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
return base.CustomActivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public void SetCommDebug(string s)
|
public void SetCommDebug(string s)
|
||||||
{
|
{
|
||||||
if (s == "1")
|
if (s == "1")
|
||||||
@@ -777,7 +907,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
_jsonCurlyBraceCounter--;
|
_jsonCurlyBraceCounter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter);
|
//Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter);
|
||||||
|
|
||||||
if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter)
|
if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter)
|
||||||
// Check for the beginning of a new JSON message
|
// Check for the beginning of a new JSON message
|
||||||
@@ -851,9 +981,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
SendText("echo off");
|
SendText("echo off");
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
// set feedback exclusions
|
// set feedback exclusions
|
||||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list");
|
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list");
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list");
|
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list");
|
||||||
|
Thread.Sleep(100);
|
||||||
|
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist");
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
|
|
||||||
if (!_props.DisablePhonebookAutoDownload)
|
if (!_props.DisablePhonebookAutoDownload)
|
||||||
@@ -889,7 +1021,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
var eType =
|
var eType =
|
||||||
(eZoomRoomResponseType)
|
(eZoomRoomResponseType)
|
||||||
Enum.Parse(typeof (eZoomRoomResponseType), message["type"].Value<string>(), true);
|
Enum.Parse(typeof(eZoomRoomResponseType), message["type"].Value<string>(), true);
|
||||||
|
|
||||||
var topKey = message["topKey"].Value<string>();
|
var topKey = message["topKey"].Value<string>();
|
||||||
|
|
||||||
@@ -1220,6 +1352,58 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
case "phonecallstatus":
|
case "phonecallstatus":
|
||||||
{
|
{
|
||||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
|
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "pinstatusofscreennotification":
|
||||||
|
{
|
||||||
|
var status = responseObj.ToObject<zEvent.PinStatusOfScreenNotification>();
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex);
|
||||||
|
|
||||||
|
Participant alreadyPinnedParticipant = null;
|
||||||
|
|
||||||
|
// Check for a participant already pinned to the same screen index.
|
||||||
|
if (status.PinnedUserId > 0)
|
||||||
|
{
|
||||||
|
alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex));
|
||||||
|
|
||||||
|
// Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb.
|
||||||
|
if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.",
|
||||||
|
alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb);
|
||||||
|
alreadyPinnedParticipant.IsPinnedFb = false;
|
||||||
|
alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId));
|
||||||
|
|
||||||
|
if (participant != null)
|
||||||
|
{
|
||||||
|
participant.IsPinnedFb = true;
|
||||||
|
participant.ScreenIndexIsPinnedToFb = status.ScreenIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex));
|
||||||
|
|
||||||
|
if (participant == null && alreadyPinnedParticipant == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (participant != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex);
|
||||||
|
participant.IsPinnedFb = false;
|
||||||
|
participant.ScreenIndexIsPinnedToFb = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire the event as we've modified the participants list
|
||||||
|
Participants.OnParticipantsChanged();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1358,7 +1542,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Console(1, this, "****************************Call Participants***************************");
|
Debug.Console(1, this, "*************************** Call Participants **************************");
|
||||||
foreach (var participant in Participants.CurrentParticipants)
|
foreach (var participant in Participants.CurrentParticipants)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name,
|
Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name,
|
||||||
@@ -1392,7 +1576,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
|
if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Creating new Status.Call object");
|
Debug.Console(1, this, "Creating new Status.Call object");
|
||||||
Status.Call = new zStatus.Call {Status = callStatus};
|
Status.Call = new zStatus.Call { Status = callStatus };
|
||||||
|
|
||||||
|
OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected });
|
||||||
|
|
||||||
SetUpCallFeedbackActions();
|
SetUpCallFeedbackActions();
|
||||||
}
|
}
|
||||||
@@ -1414,7 +1600,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newCall = new CodecActiveCallItem {Status = newStatus};
|
var newCall = new CodecActiveCallItem
|
||||||
|
{
|
||||||
|
Name = Status.Call.Info.meeting_list_item.meetingName,
|
||||||
|
Id = Status.Call.Info.meeting_id,
|
||||||
|
Status = newStatus
|
||||||
|
};
|
||||||
|
|
||||||
ActiveCalls.Add(newCall);
|
ActiveCalls.Add(newCall);
|
||||||
|
|
||||||
@@ -1423,6 +1614,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
OnCallStatusChange(newCall);
|
OnCallStatusChange(newCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1445,7 +1638,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Console(1, this, "****************************Active Calls*********************************");
|
Debug.Console(1, this, "*************************** Active Calls ********************************");
|
||||||
|
|
||||||
// Clean up any disconnected calls left in the list
|
// Clean up any disconnected calls left in the list
|
||||||
for (int i = 0; i < ActiveCalls.Count; i++)
|
for (int i = 0; i < ActiveCalls.Count; i++)
|
||||||
@@ -1461,7 +1654,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
if (!call.IsActiveCall)
|
if (!call.IsActiveCall)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "******Removing Inactive Call: {0}******", call.Name);
|
Debug.Console(1, this, "***** Removing Inactive Call: {0} *****", call.Name);
|
||||||
ActiveCalls.Remove(call);
|
ActiveCalls.Remove(call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1470,7 +1663,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
//clear participants list after call cleanup
|
//clear participants list after call cleanup
|
||||||
if (ActiveCalls.Count == 0)
|
if (ActiveCalls.Count == 0)
|
||||||
{
|
{
|
||||||
Participants.CurrentParticipants = new List<Participant>();
|
var emptyList = new List<Participant>();
|
||||||
|
Participants.CurrentParticipants = emptyList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1524,7 +1718,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public override void MuteOff()
|
public override void MuteOff()
|
||||||
{
|
{
|
||||||
SetVolume((ushort) _previousVolumeLevel);
|
SetVolume((ushort)_previousVolumeLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void MuteOn()
|
public override void MuteOn()
|
||||||
@@ -1600,7 +1794,124 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
{
|
{
|
||||||
LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge);
|
var joinMap = new ZoomRoomJoinMap(joinStart);
|
||||||
|
|
||||||
|
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (customJoins != null)
|
||||||
|
{
|
||||||
|
joinMap.SetCustomJoinData(customJoins);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bridge != null)
|
||||||
|
{
|
||||||
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkVideoCodecToApi(this, trilist, joinMap);
|
||||||
|
|
||||||
|
LinkZoomRoomToApi(trilist, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Links all the specific Zoom functionality to the API bridge
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="trilist"></param>
|
||||||
|
/// <param name="joinMap"></param>
|
||||||
|
public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap)
|
||||||
|
{
|
||||||
|
var layoutsCodec = this as IHasZoomRoomLayouts;
|
||||||
|
if (layoutsCodec != null)
|
||||||
|
{
|
||||||
|
layoutsCodec.AvailableLayoutsChanged += (o, a) =>
|
||||||
|
{
|
||||||
|
trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery));
|
||||||
|
trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker));
|
||||||
|
trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip));
|
||||||
|
trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll
|
||||||
|
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll));
|
||||||
|
|
||||||
|
// pass the names used to set the layout through the bridge
|
||||||
|
trilist.SetString(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery.ToString());
|
||||||
|
trilist.SetString(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker.ToString());
|
||||||
|
trilist.SetString(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip.ToString());
|
||||||
|
trilist.SetString(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll.ToString());
|
||||||
|
};
|
||||||
|
|
||||||
|
trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail());
|
||||||
|
|
||||||
|
layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
|
||||||
|
layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]);
|
||||||
|
|
||||||
|
layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]);
|
||||||
|
layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]);
|
||||||
|
trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage());
|
||||||
|
trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage());
|
||||||
|
trilist.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts());
|
||||||
|
|
||||||
|
trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true);
|
||||||
|
SetLayout(style);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pinCodec = this as IHasParticipantPinUnpin;
|
||||||
|
if (pinCodec != null)
|
||||||
|
{
|
||||||
|
pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]);
|
||||||
|
|
||||||
|
// Set the value of the local property to be used when pinning a participant
|
||||||
|
trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: #714 [ ] LinkZoomRoomToApi >> layoutSizeCoodec
|
||||||
|
var layoutSizeCodec = this as IHasSelfviewSize;
|
||||||
|
if (layoutSizeCodec != null)
|
||||||
|
{
|
||||||
|
trilist.SetSigFalseAction(joinMap.GetSetSelfviewPipSize.JoinNumber, layoutSizeCodec.SelfviewPipSizeToggle);
|
||||||
|
trilist.SetStringSigAction(joinMap.GetSetSelfviewPipSize.JoinNumber, (s) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true);
|
||||||
|
var cmd = SelfviewPipSizes.FirstOrDefault(c => c.Command.Equals(size.ToString()));
|
||||||
|
SelfviewPipSizeSet(cmd);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutSize: {1}", s, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]);
|
||||||
|
}
|
||||||
|
|
||||||
|
trilist.OnlineStatusChange += (device, args) =>
|
||||||
|
{
|
||||||
|
if (!args.DeviceOnLine) return;
|
||||||
|
|
||||||
|
ComputeAvailableLayouts();
|
||||||
|
layoutsCodec.LocalLayoutFeedback.FireUpdate();
|
||||||
|
layoutsCodec.CanSwapContentWithThumbnailFeedback.FireUpdate();
|
||||||
|
layoutsCodec.ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||||
|
layoutsCodec.LayoutViewIsOnFirstPageFeedback.FireUpdate();
|
||||||
|
layoutsCodec.LayoutViewIsOnLastPageFeedback.FireUpdate();
|
||||||
|
pinCodec.NumberOfScreensFeedback.FireUpdate();
|
||||||
|
layoutSizeCodec.SelfviewPipSizeFeedback.FireUpdate();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExecuteSwitch(object selector)
|
public override void ExecuteSwitch(object selector)
|
||||||
@@ -1656,7 +1967,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
public override void Dial(Meeting meeting)
|
public override void Dial(Meeting meeting)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this,"Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title);
|
Debug.Console(1, this, "Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title);
|
||||||
SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id));
|
SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1770,6 +2081,114 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region IHasParticipantAudioMute Members
|
||||||
|
|
||||||
|
public void MuteAudioForParticipant(int userId)
|
||||||
|
{
|
||||||
|
SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnmuteAudioForParticipant(int userId)
|
||||||
|
{
|
||||||
|
SendText(string.Format("zCommand Call MuteParticipant Mute: off Id: {0}", userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleAudioForParticipant(int userId)
|
||||||
|
{
|
||||||
|
var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Unable to find user with id: {0}", userId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.AudioMuteFb)
|
||||||
|
{
|
||||||
|
UnmuteAudioForParticipant(userId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MuteAudioForParticipant(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IHasParticipantVideoMute Members
|
||||||
|
|
||||||
|
public void MuteVideoForParticipant(int userId)
|
||||||
|
{
|
||||||
|
SendText(string.Format("zCommand Call MuteParticipantVideo Mute: on Id: {0}", userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnmuteVideoForParticipant(int userId)
|
||||||
|
{
|
||||||
|
SendText(string.Format("zCommand Call MuteParticipantVideo Mute: off Id: {0}", userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleVideoForParticipant(int userId)
|
||||||
|
{
|
||||||
|
var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Unable to find user with id: {0}", userId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.VideoMuteFb)
|
||||||
|
{
|
||||||
|
UnmuteVideoForParticipant(userId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MuteVideoForParticipant(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IHasParticipantPinUnpin Members
|
||||||
|
|
||||||
|
private Func<int> NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } }
|
||||||
|
|
||||||
|
public IntFeedback NumberOfScreensFeedback { get; private set; }
|
||||||
|
|
||||||
|
public int ScreenIndexToPinUserTo { get; private set; }
|
||||||
|
|
||||||
|
public void PinParticipant(int userId, int screenIndex)
|
||||||
|
{
|
||||||
|
SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnPinParticipant(int userId)
|
||||||
|
{
|
||||||
|
SendText(string.Format("zCommand Call Pin Id: {0} Enable: off", userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleParticipantPinState(int userId, int screenIndex)
|
||||||
|
{
|
||||||
|
var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Unable to find user with id: {0}", userId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.IsPinnedFb)
|
||||||
|
{
|
||||||
|
UnPinParticipant(userId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PinParticipant(userId, screenIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IHasCameraOff
|
#region Implementation of IHasCameraOff
|
||||||
|
|
||||||
public BoolFeedback CameraIsOffFeedback { get; private set; }
|
public BoolFeedback CameraIsOffFeedback { get; private set; }
|
||||||
@@ -1864,18 +2283,63 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
new CodecCommandWithLabel("DownLeft", "Lower Left")
|
new CodecCommandWithLabel("DownLeft", "Lower Left")
|
||||||
};
|
};
|
||||||
|
|
||||||
private void ComputeSelfviewPipStatus()
|
private void ComputeSelfviewPipPositionStatus()
|
||||||
{
|
{
|
||||||
_currentSelfviewPipPosition =
|
_currentSelfviewPipPosition =
|
||||||
SelfviewPipPositions.FirstOrDefault(
|
SelfviewPipPositions.FirstOrDefault(
|
||||||
p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower()));
|
p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// TODO: #714 [ ] Implementation of IHasSelfviewPipSize
|
||||||
|
#region Implementation of IHasSelfviewPipSize
|
||||||
|
|
||||||
|
private CodecCommandWithLabel _currentSelfviewPipSize;
|
||||||
|
|
||||||
|
public StringFeedback SelfviewPipSizeFeedback { get; private set; }
|
||||||
|
|
||||||
|
public void SelfviewPipSizeSet(CodecCommandWithLabel size)
|
||||||
|
{
|
||||||
|
SendText(String.Format("zConfiguration Call Layout Size: {0}", size.Command));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SelfviewPipSizeToggle()
|
||||||
|
{
|
||||||
|
if (_currentSelfviewPipSize != null)
|
||||||
|
{
|
||||||
|
var nextPipSizeIndex = SelfviewPipSizes.IndexOf(_currentSelfviewPipSize) + 1;
|
||||||
|
|
||||||
|
if (nextPipSizeIndex >= SelfviewPipSizes.Count)
|
||||||
|
// Check if we need to loop back to the first item in the list
|
||||||
|
nextPipSizeIndex = 0;
|
||||||
|
|
||||||
|
SelfviewPipSizeSet(SelfviewPipSizes[nextPipSizeIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CodecCommandWithLabel> SelfviewPipSizes = new List<CodecCommandWithLabel>()
|
||||||
|
{
|
||||||
|
new CodecCommandWithLabel("Off", "Off"),
|
||||||
|
new CodecCommandWithLabel("Size1", "Size 1"),
|
||||||
|
new CodecCommandWithLabel("Size2", "Size 2"),
|
||||||
|
new CodecCommandWithLabel("Size3", "Size 3"),
|
||||||
|
new CodecCommandWithLabel("Strip", "Strip")
|
||||||
|
};
|
||||||
|
|
||||||
|
private void ComputeSelfviewPipSizeStatus()
|
||||||
|
{
|
||||||
|
_currentSelfviewPipSize =
|
||||||
|
SelfviewPipSizes.FirstOrDefault(
|
||||||
|
p => p.Command.ToLower().Equals(Configuration.Call.Layout.Size.ToString().ToLower()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IHasPhoneDialing
|
#region Implementation of IHasPhoneDialing
|
||||||
|
|
||||||
private Func<bool> PhoneOffHookFeedbackFunc {get {return () => Status.PhoneCall.OffHook; }}
|
private Func<bool> PhoneOffHookFeedbackFunc { get { return () => Status.PhoneCall.OffHook; } }
|
||||||
private Func<string> CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
|
private Func<string> CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
|
||||||
private Func<string> CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } }
|
private Func<string> CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } }
|
||||||
|
|
||||||
@@ -1899,6 +2363,138 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region IHasZoomRoomLayouts Members
|
||||||
|
|
||||||
|
public event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
|
||||||
|
|
||||||
|
private Func<bool> LayoutViewIsOnFirstPageFeedbackFunc { get { return () => Status.Layout.is_In_First_Page; } }
|
||||||
|
private Func<bool> LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } }
|
||||||
|
private Func<bool> CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } }
|
||||||
|
private Func<bool> ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } }
|
||||||
|
|
||||||
|
public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback LayoutViewIsOnLastPageFeedback { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback CanSwapContentWithThumbnailFeedback { get; private set; }
|
||||||
|
|
||||||
|
public BoolFeedback ContentSwappedWithThumbnailFeedback { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
public zConfiguration.eLayoutStyle LastSelectedLayout { get; private set; }
|
||||||
|
|
||||||
|
public zConfiguration.eLayoutStyle AvailableLayouts { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads individual properties to determine if which layouts are avalailable
|
||||||
|
/// </summary>
|
||||||
|
private void ComputeAvailableLayouts()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Computing available layouts...");
|
||||||
|
zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None;
|
||||||
|
if (Status.Layout.can_Switch_Wall_View)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.Gallery;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status.Layout.can_Switch_Speaker_View)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.Speaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status.Layout.can_Switch_Share_On_All_Screens)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.ShareAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is no property that directly reports if strip mode is valid, but API stipulates
|
||||||
|
// that strip mode is available if the number of screens is 1
|
||||||
|
if (Status.NumberOfScreens.NumOfScreens == 1)
|
||||||
|
{
|
||||||
|
availableLayouts |= zConfiguration.eLayoutStyle.Strip;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, this, "availablelayouts: {0}", availableLayouts);
|
||||||
|
|
||||||
|
var handler = AvailableLayoutsChanged;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts });
|
||||||
|
}
|
||||||
|
|
||||||
|
AvailableLayouts = availableLayouts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetAvailableLayouts()
|
||||||
|
{
|
||||||
|
SendText("zStatus Call Layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLayout(zConfiguration.eLayoutStyle layoutStyle)
|
||||||
|
{
|
||||||
|
LastSelectedLayout = layoutStyle;
|
||||||
|
SendText(String.Format("zConfiguration Call Layout Style: {0}", layoutStyle.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SwapContentWithThumbnail()
|
||||||
|
{
|
||||||
|
if (CanSwapContentWithThumbnailFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state
|
||||||
|
// TODO: #697 [*] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback
|
||||||
|
// to toggle the state
|
||||||
|
SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LayoutTurnNextPage()
|
||||||
|
{
|
||||||
|
SendText("zCommand Call Layout TurnPage Forward: On");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LayoutTurnPreviousPage()
|
||||||
|
{
|
||||||
|
SendText("zCommand Call Layout TurnPage Forward: Off");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IHasCodecLayouts Members
|
||||||
|
|
||||||
|
private Func<string> LocalLayoutFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None)
|
||||||
|
return Configuration.Call.Layout.Style.ToString();
|
||||||
|
else
|
||||||
|
return Configuration.Client.Call.Layout.Style.ToString();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringFeedback LocalLayoutFeedback { get; private set; }
|
||||||
|
|
||||||
|
public void LocalLayoutToggle()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LocalLayoutToggleSingleProminent()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MinMaxLayoutToggle()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -2115,7 +2711,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
|||||||
{
|
{
|
||||||
public ZoomRoomFactory()
|
public ZoomRoomFactory()
|
||||||
{
|
{
|
||||||
TypeNames = new List<string> {"zoomroom"};
|
TypeNames = new List<string> { "zoomroom" };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
|||||||
@@ -0,0 +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
|
||||||
|
|
||||||
|
[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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="PepperDashCore" version="1.0.45" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
|
<package id="PepperDashCore" version="1.0.48" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
|
||||||
</packages>
|
</packages>
|
||||||
Reference in New Issue
Block a user