mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-02 14:24:59 +00:00
Compare commits
349 Commits
1.8.3-alph
...
1.9.8-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3de2ba03c1 | ||
|
|
6fcb47e0ef | ||
|
|
3a162ee9dd | ||
|
|
033f6e12f1 | ||
|
|
f7bf728263 | ||
|
|
493b391d6f | ||
|
|
805022631b | ||
|
|
5442a1db48 | ||
|
|
61be312826 | ||
|
|
fb624ef20c | ||
|
|
025bf7adfb | ||
|
|
a6430a7bfe | ||
|
|
b71c83bac0 | ||
|
|
5940ec17c2 | ||
|
|
10445508b2 | ||
|
|
66ecf43508 | ||
|
|
e855359f61 | ||
|
|
5f50f14a71 | ||
|
|
1e9139f38e | ||
|
|
c521a1d551 | ||
|
|
d22c1bf344 | ||
|
|
fd232beae1 | ||
|
|
35edbeacfc | ||
|
|
b5cabfc644 | ||
|
|
bead782bd5 | ||
|
|
e7915b1e99 | ||
|
|
23600d8bc9 | ||
|
|
a165ba911f | ||
|
|
16db2663a6 | ||
|
|
8d1f187643 | ||
|
|
a6741e47e4 | ||
|
|
5a81ce9137 | ||
|
|
77c4272219 | ||
|
|
d78a378859 | ||
|
|
eec4484f78 | ||
|
|
49e82f107b | ||
|
|
149c1dd22d | ||
|
|
79f9d09558 | ||
|
|
c5162fb94d | ||
|
|
63b9ffdd26 | ||
|
|
2e76b6ba0a | ||
|
|
cad45c04cb | ||
|
|
70d63a9f99 | ||
|
|
30f63eee03 | ||
|
|
9f1c512909 | ||
|
|
c7d9789ffb | ||
|
|
9c4c1d99b8 | ||
|
|
0d6cd8d55d | ||
|
|
d06c73e994 | ||
|
|
8e64140651 | ||
|
|
54697e0eaf | ||
|
|
0da35c8572 | ||
|
|
3d543dfd09 | ||
|
|
9c22c4cb5f | ||
|
|
f0942a3932 | ||
|
|
9f3a3f64a8 | ||
|
|
fe01842523 | ||
|
|
4ffea1c98f | ||
|
|
73e3b049d8 | ||
|
|
0ae38dddfc | ||
|
|
871894e248 | ||
|
|
fa6cabe246 | ||
|
|
db3d96d448 | ||
|
|
a28a078c4f | ||
|
|
d00a31e3a6 | ||
|
|
77134f0a30 | ||
|
|
93dfb8780b | ||
|
|
f791feb848 | ||
|
|
44509dc5ae | ||
|
|
2d0dcd7336 | ||
|
|
c255ae1525 | ||
|
|
d50027cc82 | ||
|
|
9b64b7b7f3 | ||
|
|
c0cdb09544 | ||
|
|
8c2c58d756 | ||
|
|
44e5753138 | ||
|
|
c71805cfc4 | ||
|
|
5d177104d8 | ||
|
|
147e712a01 | ||
|
|
9a1b069e24 | ||
|
|
d6878df267 | ||
|
|
a379641595 | ||
|
|
d8cd04b35f | ||
|
|
8539a6b79c | ||
|
|
adec25104c | ||
|
|
a54cd9e1df | ||
|
|
8af7b4b1db | ||
|
|
3edb0145d0 | ||
|
|
0a1af09830 | ||
|
|
532f3ba237 | ||
|
|
50aafb088e | ||
|
|
e1d9a46284 | ||
|
|
bfd383dfc7 | ||
|
|
b853e8ed37 | ||
|
|
60c2d4df01 | ||
|
|
8ab87af859 | ||
|
|
47035d8386 | ||
|
|
c84ec4c899 | ||
|
|
4444328600 | ||
|
|
0d3eb42495 | ||
|
|
540a00861c | ||
|
|
0014dd7a14 | ||
|
|
f922b871a1 | ||
|
|
b2331fa1e5 | ||
|
|
8bf4b0d568 | ||
|
|
621205e65c | ||
|
|
62fcf3856f | ||
|
|
dad986414c | ||
|
|
55766b21ba | ||
|
|
21bc6a05de | ||
|
|
f298b5cc41 | ||
|
|
f8129fe7ae | ||
|
|
dbdaedcca3 | ||
|
|
893950d8c4 | ||
|
|
b780351bf0 | ||
|
|
6a1671aae1 | ||
|
|
9a1a23c88a | ||
|
|
3c352bbd20 | ||
|
|
8ab3e45d96 | ||
|
|
11e5123fdf | ||
|
|
2e4bb7466c | ||
|
|
36a41ac477 | ||
|
|
92f4d37cd6 | ||
|
|
b9479bab70 | ||
|
|
c6d10ba87e | ||
|
|
fd94a94ee9 | ||
|
|
3fa2954ca0 | ||
|
|
c4f6afa412 | ||
|
|
6bdda5451b | ||
|
|
f3ab364a4d | ||
|
|
538f81c18e | ||
|
|
3ee8c07ecd | ||
|
|
01b713e6e1 | ||
|
|
002cc07b52 | ||
|
|
16f993852c | ||
|
|
ffd0fbc57b | ||
|
|
9ac1d77c2a | ||
|
|
2dd0c53a08 | ||
|
|
fab1219146 | ||
|
|
23e8280904 | ||
|
|
60d0f50cd2 | ||
|
|
6708be0d15 | ||
|
|
d193de79da | ||
|
|
87ab43c745 | ||
|
|
2a37e44d7d | ||
|
|
efa801137c | ||
|
|
4b4f1f3c3d | ||
|
|
6e7bf061cf | ||
|
|
c26d7d73f8 | ||
|
|
7f6160eb44 | ||
|
|
854a0691d3 | ||
|
|
61c638452b | ||
|
|
072411e4f6 | ||
|
|
7dc9afa119 | ||
|
|
b5004d5b1d | ||
|
|
6f0bfedac1 | ||
|
|
71881addab | ||
|
|
cea1d2fcdd | ||
|
|
22aea3089d | ||
|
|
3aab807631 | ||
|
|
9ec090397f | ||
|
|
86916c4357 | ||
|
|
40151c5f8f | ||
|
|
4210df693a | ||
|
|
56bb872d2b | ||
|
|
43256acfcd | ||
|
|
1696ef3ac1 | ||
|
|
864e0675ea | ||
|
|
19cbe480a6 | ||
|
|
49c1c61a88 | ||
|
|
c306e2c1a1 | ||
|
|
0cd3c1bdc5 | ||
|
|
d64cbc639a | ||
|
|
82af1366df | ||
|
|
56492a00cd | ||
|
|
8404e7d5a4 | ||
|
|
e4135a958c | ||
|
|
f4ac4e6319 | ||
|
|
b026174cd2 | ||
|
|
66ff6b2e07 | ||
|
|
e7bbfbd40a | ||
|
|
eec86fde48 | ||
|
|
7b57ce439e | ||
|
|
28bac18667 | ||
|
|
ea254ef983 | ||
|
|
76e4d4a82d | ||
|
|
4bd777f6b9 | ||
|
|
f607394ee7 | ||
|
|
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 | ||
|
|
e12a5e95bf | ||
|
|
3e7144f7ef | ||
|
|
19e070ed76 | ||
|
|
b818c14713 | ||
|
|
63e7866890 | ||
|
|
922d1d8133 | ||
|
|
d26ea01ed9 | ||
|
|
4ebd1b53b5 | ||
|
|
0226b58b1e | ||
|
|
be41922c54 | ||
|
|
56f93c5491 | ||
|
|
8cfd58bb7e | ||
|
|
6ddfdc4b38 | ||
|
|
7640b95701 | ||
|
|
6c2abc7abd | ||
|
|
1849d118b4 | ||
|
|
22e7f004a5 | ||
|
|
0dcaacb038 | ||
|
|
cf8e673677 | ||
|
|
200080247a | ||
|
|
ba247ee8d6 | ||
|
|
b3617d04c8 | ||
|
|
85cf51876a | ||
|
|
b6f47168c0 | ||
|
|
1e755df9bb | ||
|
|
037f8ed043 | ||
|
|
e327d2d359 | ||
|
|
e832566168 | ||
|
|
252d037380 | ||
|
|
dd0f7a586e | ||
|
|
2feec62052 | ||
|
|
33a1b1697a | ||
|
|
955d68b3f3 | ||
|
|
185f03065e |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,6 +7,9 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Was this bug identified in a specific build version?**
|
||||
Please note the build version where this bug was identified
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
||||
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/scripts/ZipBuildOutput.ps1
vendored
1
.github/scripts/ZipBuildOutput.ps1
vendored
@@ -8,6 +8,7 @@ $destination = "$($Env:GITHUB_HOME)\output"
|
||||
New-Item -ItemType Directory -Force -Path ($destination)
|
||||
Get-ChildItem ($destination)
|
||||
$exclusions = @(git submodule foreach --quiet 'echo $name')
|
||||
$exclusions += "Newtonsoft.Compact.Json.dll"
|
||||
# Trying to get any .json schema files (not currently working)
|
||||
# Gets any files with the listed extensions.
|
||||
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.dll", "*.nuspec" | ForEach-Object {
|
||||
|
||||
6
.github/workflows/docker.yml
vendored
6
.github/workflows/docker.yml
vendored
@@ -8,12 +8,9 @@ on:
|
||||
- bugfix/*
|
||||
- release/*
|
||||
- development
|
||||
pull_request:
|
||||
branches:
|
||||
- development
|
||||
|
||||
env:
|
||||
# solution path doesn't need slashes unless there it is multiple folders deep
|
||||
# solution path doesn't need slashes unless it is multiple folders deep
|
||||
# solution name does not include extension. .sln is assumed
|
||||
SOLUTION_PATH: PepperDashEssentials
|
||||
SOLUTION_FILE: PepperDashEssentials
|
||||
@@ -90,7 +87,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Upload the build package to the release
|
||||
- name: Upload Release Package
|
||||
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
|
||||
id: upload_release
|
||||
uses: actions/upload-release-asset@v1
|
||||
with:
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace PepperDash.Essentials
|
||||
HttpLogoServer LogoServer;
|
||||
|
||||
private CTimer _startTimer;
|
||||
private CEvent _initializeEvent;
|
||||
private const long StartupTime = 500;
|
||||
|
||||
public ControlSystem()
|
||||
@@ -36,6 +37,7 @@ namespace PepperDash.Essentials
|
||||
Thread.MaxNumberOfUserThreads = 400;
|
||||
Global.ControlSystem = this;
|
||||
DeviceManager.Initialize(this);
|
||||
SecretsManager.Initialize();
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||
}
|
||||
|
||||
@@ -45,6 +47,24 @@ namespace PepperDash.Essentials
|
||||
public override void InitializeSystem()
|
||||
{
|
||||
_startTimer = new CTimer(StartSystem,StartupTime);
|
||||
|
||||
|
||||
// If the control system is a DMPS type, we need to wait to exit this method until all devices have had time to activate
|
||||
// to allow any HD-BaseT DM endpoints to register first.
|
||||
if (Global.ControlSystemIsDmpsType)
|
||||
{
|
||||
Debug.Console(2, "******************* InitializeSystem() Entering **********************");
|
||||
|
||||
_initializeEvent = new CEvent();
|
||||
|
||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
||||
{
|
||||
_initializeEvent.Set();
|
||||
Debug.Console(2, "******************* InitializeSystem() Exiting **********************");
|
||||
};
|
||||
|
||||
_initializeEvent.Wait(30000);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartSystem(object obj)
|
||||
@@ -71,7 +91,7 @@ namespace PepperDash.Essentials
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -85,8 +105,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
||||
"System URL: {0}\r" +
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" +
|
||||
"System URL: {0}\r\n" +
|
||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
||||
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
@@ -130,29 +150,46 @@ namespace PepperDash.Essentials
|
||||
|
||||
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
|
||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
|
||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + userFolder
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
|
||||
{
|
||||
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "User"
|
||||
Debug.Console(0, @"{0}/program{1} directory found", userFolder, InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + userFolder
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||
}
|
||||
// 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)))
|
||||
{
|
||||
Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
|
||||
Debug.Console(0, @"{0}/program{1} directory found", nvramFolder, InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + nvramFolder
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||
}
|
||||
// If neither exists, set path to User/ProgramX
|
||||
else
|
||||
{
|
||||
Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + "User"
|
||||
Debug.Console(0, @"No previous directory found. Using {0}/program{1}", userFolder, InitialParametersClass.ApplicationNumber);
|
||||
filePathPrefix = directoryPrefix + dirSeparator + userFolder
|
||||
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
|
||||
}
|
||||
}
|
||||
@@ -325,7 +362,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
var prompt = Global.ControlSystem.ControllerPrompt;
|
||||
|
||||
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) &&
|
||||
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) ||
|
||||
String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!typeMatch)
|
||||
@@ -343,9 +380,7 @@ namespace PepperDash.Essentials
|
||||
if(propertiesConfig == null)
|
||||
propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig();
|
||||
|
||||
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig);
|
||||
|
||||
DeviceManager.AddDevice(dmpsRoutingController);
|
||||
DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig));
|
||||
}
|
||||
else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
|
||||
{
|
||||
@@ -432,14 +467,13 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
}
|
||||
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
|
||||
{
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
|
||||
if (room != null)
|
||||
{
|
||||
// default IPID
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
// default to no join map key
|
||||
string fusionJoinMapKey = string.Empty;
|
||||
|
||||
@@ -456,11 +490,11 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
if (room is IEssentialsHuddleSpaceRoom)
|
||||
{
|
||||
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));
|
||||
|
||||
|
||||
@@ -468,12 +502,12 @@ namespace PepperDash.Essentials
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else if (room is EssentialsHuddleVtc1Room)
|
||||
else if (room is IEssentialsHuddleVtc1Room)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
|
||||
@@ -484,7 +518,7 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
@@ -497,22 +531,35 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
}
|
||||
|
||||
fusionIpId += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
|
||||
|
||||
}
|
||||
|
||||
private static void CreateMobileControlBridge(EssentialsRoomBase room)
|
||||
private static void CreateMobileControlBridge(object room)
|
||||
{
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
|
||||
var mobileControl3 = mobileControl as IMobileControl3;
|
||||
|
||||
if (mobileControl3 != null)
|
||||
{
|
||||
mobileControl3.CreateMobileControlRoomBridge(room as IEssentialsRoom, mobileControl);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobileControl.CreateMobileControlRoomBridge(room as EssentialsRoomBase, mobileControl);
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
BooleanSigData CodecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||
public EssentialsHuddleVtc1FusionController(IEssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||
: base(room, ipId, joinMapKey)
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
try
|
||||
{
|
||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
@@ -141,7 +141,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -150,7 +150,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
@@ -174,11 +174,11 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Moved to
|
||||
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.
|
||||
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
(Room as IEssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
|
||||
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as IEssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||
|
||||
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||
@@ -187,7 +187,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
protected override void SetUpSources()
|
||||
{
|
||||
// Sources
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as IEssentialsHuddleVtc1Room).SourceListKey);
|
||||
if (dict != null)
|
||||
{
|
||||
// NEW PROCESS:
|
||||
@@ -238,7 +238,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||
var defaultDisplay = (Room as IEssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||
if (defaultDisplay == 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);
|
||||
|
||||
|
||||
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
|
||||
if (display == (Room as IEssentialsHuddleVtc1Room).DefaultDisplay)
|
||||
{
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||
@@ -351,7 +351,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
// Current Source
|
||||
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\Config\EssentialsRoomConfig.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\EssentialsLightingDriver.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.
|
||||
/// Returns null if there is no emergency defined
|
||||
/// </summary>
|
||||
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room)
|
||||
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room)
|
||||
{
|
||||
// This emergency
|
||||
var emergency = props.Emergency;
|
||||
@@ -96,7 +96,7 @@ namespace PepperDash.Essentials.Room.Config
|
||||
if (behaviour == "trackroomstate")
|
||||
{
|
||||
// Tie LED enable to room power state
|
||||
var essRoom = room as EssentialsRoomBase;
|
||||
var essRoom = room as IEssentialsRoom;
|
||||
essRoom.OnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (essRoom.OnFeedback.BoolValue)
|
||||
|
||||
@@ -17,11 +17,11 @@ namespace PepperDash.Essentials.Room
|
||||
|
||||
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
||||
{
|
||||
EssentialsRoomBase Room;
|
||||
IEssentialsRoom Room;
|
||||
string Behavior;
|
||||
bool TriggerOnClose;
|
||||
|
||||
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, EssentialsRoomBase room) :
|
||||
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
|
||||
base(key)
|
||||
{
|
||||
Room = room;
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
|
||||
|
||||
Initialize();
|
||||
InitializeRoom();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -215,7 +215,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
void InitializeRoom()
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
@@ -645,9 +645,9 @@ namespace PepperDash.Essentials
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
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)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey);
|
||||
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as IEssentialsHuddleSpaceRoom).SourceListKey);
|
||||
}
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
@@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IEssentialsHuddleSpaceRoom
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
@@ -156,7 +156,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
Initialize();
|
||||
InitializeRoom();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -164,7 +164,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
void InitializeRoom()
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
|
||||
@@ -17,9 +17,9 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange,
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||
{
|
||||
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
|
||||
{
|
||||
private bool _codecExternalSourceChange;
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
@@ -178,10 +178,12 @@ namespace PepperDash.Essentials
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
|
||||
var vc = VideoCodec as IHasExternalSourceSwitching;
|
||||
if (vc != null)
|
||||
if (vc != null && !_codecExternalSourceChange)
|
||||
{
|
||||
vc.SetSelectedSource(CurrentSourceInfoKey);
|
||||
}
|
||||
|
||||
_codecExternalSourceChange = false;
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
@@ -224,7 +226,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
|
||||
|
||||
Initialize();
|
||||
InitializeRoom();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -232,7 +234,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
void InitializeRoom()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -421,6 +423,12 @@ namespace PepperDash.Essentials
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RunRouteActionCodec(string routeKey, string sourceListKey)
|
||||
{
|
||||
_codecExternalSourceChange = true;
|
||||
RunRouteAction(routeKey, sourceListKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -446,7 +454,8 @@ namespace PepperDash.Essentials
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
throw new NotImplementedException();
|
||||
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +472,11 @@ namespace PepperDash.Essentials
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -724,10 +737,10 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
|
||||
|
||||
@@ -750,7 +763,7 @@ namespace PepperDash.Essentials
|
||||
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
|
||||
|
||||
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
|
||||
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||
|
||||
foreach (var kvp in srcList)
|
||||
|
||||
@@ -107,14 +107,18 @@ namespace PepperDash.Essentials
|
||||
|
||||
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
||||
{
|
||||
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
|
||||
|
||||
if (!_currentPresets.ContainsKey(device.Key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
|
||||
|
||||
_currentPresets[device.Key] = channel;
|
||||
|
||||
if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||
if (CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||
{
|
||||
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay
|
||||
{
|
||||
bool ExcludeFromGlobalFunctions { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
IBasicVolumeControls CurrentVolumeControls { get; }
|
||||
|
||||
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
}
|
||||
|
||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
|
||||
IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay
|
||||
{
|
||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
IHasScheduleAwareness ScheduleSource { get; }
|
||||
|
||||
string DefaultCodecRouteString { get; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
else if (type == "tsw1060")
|
||||
Panel = new Tsw1060(id, Global.ControlSystem);
|
||||
else if (type == "tsw570")
|
||||
Panel = new Tsw570(id, Global.ControlSystem);
|
||||
else if (type == "tsw770")
|
||||
Panel = new Tsw770(id, Global.ControlSystem);
|
||||
else if (type == "ts770")
|
||||
Panel = new Ts770(id, Global.ControlSystem);
|
||||
else if (type == "tsw1070")
|
||||
Panel = new Tsw1070(id, Global.ControlSystem);
|
||||
else if (type == "ts1070")
|
||||
Panel = new Ts1070(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
@@ -203,7 +213,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
public EssentialsTouchpanelControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" };
|
||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
@@ -222,7 +232,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
// spin up different room drivers depending on room type
|
||||
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
if (room is IEssentialsHuddleSpaceRoom)
|
||||
{
|
||||
// Screen Saver Driver
|
||||
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props);
|
||||
@@ -236,7 +246,7 @@ namespace PepperDash.Essentials
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
||||
avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom;
|
||||
|
||||
// Environment Driver
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if (room is EssentialsHuddleVtc1Room)
|
||||
else if (room is IEssentialsHuddleVtc1Room)
|
||||
{
|
||||
Debug.Console(0, panelController, "Adding huddle space VTC AV driver");
|
||||
|
||||
@@ -284,11 +294,11 @@ namespace PepperDash.Essentials
|
||||
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props);
|
||||
|
||||
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.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room;
|
||||
avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room;
|
||||
|
||||
// Environment Driver
|
||||
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
|
||||
|
||||
@@ -49,6 +49,16 @@ namespace PepperDash.Essentials
|
||||
/// 1006
|
||||
/// </summary>
|
||||
public const uint CallEndAllConfirmVisible = 1006;
|
||||
/// <summary>
|
||||
/// 1007
|
||||
/// </summary>
|
||||
public const uint MeetingPasswordVisible = 1007;
|
||||
/// <summary>
|
||||
/// 1008
|
||||
/// </summary>
|
||||
public const uint MeetingLeavePress = 1008;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +113,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// 1202
|
||||
/// </summary>
|
||||
public const uint VCStagingInactivePopoverVisible = 1202;
|
||||
public const uint VCStagingInactivePopoverWithRecentsVisible = 1202;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -121,6 +131,11 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCRecentsVisible = 1206;
|
||||
|
||||
/// <summary>
|
||||
/// 1202
|
||||
/// </summary>
|
||||
public const uint VCStagingInactivePopoverWithoutRecentsVisible = 1207;
|
||||
|
||||
/// <summary>
|
||||
/// 1208
|
||||
/// </summary>
|
||||
@@ -148,6 +163,11 @@ namespace PepperDash.Essentials
|
||||
public const uint VCFavoriteVisibleStart = 1221;
|
||||
// RANGE IN USE
|
||||
public const uint VCFavoriteVisibleEnd = 1225;
|
||||
|
||||
/// <summary>
|
||||
/// 1230
|
||||
/// </summary>
|
||||
public const uint VCStagingMeetNowPress = 1230;
|
||||
/// <summary>
|
||||
/// 1231
|
||||
/// </summary>
|
||||
@@ -243,6 +263,10 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCCameraSelectBarWithoutModeVisible = 1261;
|
||||
|
||||
/// <summary>
|
||||
/// 1262
|
||||
/// </summary>
|
||||
public const uint VCCameraAutoModeIsOnFb = 1262;
|
||||
|
||||
/// <summary>
|
||||
/// 1271
|
||||
@@ -744,9 +768,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint SourceBackgroundOverlayClosePress = 15044;
|
||||
/// <summary>
|
||||
/// 15045 - Visibility for the bar containing call navigation button list
|
||||
/// 15045
|
||||
/// </summary>
|
||||
public const uint CallStagingBarVisible = 15045;
|
||||
public const uint ZoomRoomContentSharingVisible = 15045;
|
||||
/// <summary>
|
||||
/// 15046
|
||||
/// </summary>
|
||||
@@ -764,6 +788,10 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint NextMeetingModalVisible = 15049;
|
||||
/// <summary>
|
||||
/// 15050
|
||||
/// </summary>
|
||||
public const uint NextMeetingNotificationRibbonVisible = 15050;
|
||||
/// <summary>
|
||||
/// 15051
|
||||
/// </summary>
|
||||
public const uint Display1SelectPressAndFb = 15051;
|
||||
@@ -831,6 +859,11 @@ namespace PepperDash.Essentials
|
||||
/// 15067
|
||||
/// </summary>
|
||||
public const uint NotificationRibbonVisible = 15067;
|
||||
/// <summary>
|
||||
/// 15068
|
||||
/// </summary>
|
||||
public const uint HeaderMeetingInfoVisible = 15068;
|
||||
|
||||
/// <summary>
|
||||
/// 15083 - Press for Call help desk on AC/VC
|
||||
/// </summary>
|
||||
@@ -935,5 +968,24 @@ namespace PepperDash.Essentials
|
||||
/// 15214
|
||||
/// </summary>
|
||||
public const uint PinDialogDot4 = 15214;
|
||||
|
||||
// Password Prompt Dialog **************************
|
||||
|
||||
/// <summary>
|
||||
/// 15301
|
||||
/// </summary>
|
||||
public const uint PasswordPromptDialogVisible = 15301;
|
||||
/// <summary>
|
||||
/// 15302
|
||||
/// </summary>
|
||||
public const uint PasswordPromptTextPress = 15302;
|
||||
/// <summary>
|
||||
/// 15306
|
||||
/// </summary>
|
||||
public const uint PasswordPromptCancelPress = 15306;
|
||||
/// <summary>
|
||||
/// 15307
|
||||
/// </summary>
|
||||
public const uint PasswordPromptErrorVisible = 15307;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,33 @@ namespace PepperDash.Essentials
|
||||
/// 1004
|
||||
/// </summary>
|
||||
public const uint CallSharedSourceNameText = 1004;
|
||||
/// <summary>
|
||||
/// 1005
|
||||
/// </summary>
|
||||
public const uint MeetingIdText = 1005;
|
||||
/// <summary>
|
||||
/// 1006
|
||||
/// </summary>
|
||||
public const uint MeetingHostText = 1006;
|
||||
/// <summary>
|
||||
/// 1007
|
||||
/// </summary>
|
||||
public const uint MeetingPasswordText = 1007;
|
||||
/// <summary>
|
||||
/// 1008
|
||||
/// </summary>
|
||||
public const uint MeetingLeaveText = 1008;
|
||||
/// <summary>
|
||||
/// 1009
|
||||
/// </summary>
|
||||
public const uint MeetingNameText = 1009;
|
||||
|
||||
///<summary>
|
||||
/// 1240 - Used to determine text for meeting start button
|
||||
///</summary>
|
||||
public const uint MeetingStartButtonText = 1240;
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -118,6 +145,14 @@ namespace PepperDash.Essentials
|
||||
|
||||
//----- through 3120
|
||||
|
||||
/// <summary>
|
||||
/// 3201
|
||||
/// </summary>
|
||||
public const uint PasswordPromptMessageText = 3201;
|
||||
/// <summary>
|
||||
/// 3202
|
||||
/// </summary>
|
||||
public const uint PasswordPromptPasswordText = 3202;
|
||||
|
||||
/// <summary>
|
||||
/// 3812
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
// Video Codec
|
||||
/// <summary>
|
||||
/// 1234: values 0 = Connect, 1 = End
|
||||
/// 1234: values 0 = Connect, 1 = End, 2 = Start Meeting
|
||||
/// </summary>
|
||||
public const uint VCStagingConnectButtonMode = 1234;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
// }
|
||||
|
||||
// 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;
|
||||
// }
|
||||
|
||||
@@ -12,6 +12,7 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
@@ -52,7 +53,7 @@ namespace PepperDash.Essentials
|
||||
CaretInterlock = new JoinedSigInterlock(TriList);
|
||||
}
|
||||
|
||||
void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom)
|
||||
void SetUpGear(IAVDriver avDriver, IEssentialsRoom currentRoom)
|
||||
{
|
||||
// Gear
|
||||
TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear");
|
||||
@@ -105,7 +106,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
string message = null;
|
||||
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
|
||||
as EssentialsHuddleSpaceRoom;
|
||||
as IEssentialsHuddleSpaceRoom;
|
||||
if (room != null)
|
||||
message = room.PropertiesConfig.HelpMessage;
|
||||
else
|
||||
@@ -164,7 +165,7 @@ namespace PepperDash.Essentials
|
||||
CallCaretVisible = tempJoin + 10;
|
||||
TriList.SetSigFalseAction(tempJoin, () =>
|
||||
{
|
||||
avDriver.ShowActiveCallsList();
|
||||
avDriver.ShowActiveCallsListOrMeetingInfo();
|
||||
if(avDriver.CurrentRoom.InCallFeedback.BoolValue)
|
||||
CaretInterlock.ShowInterlocked(CallCaretVisible);
|
||||
});
|
||||
@@ -191,26 +192,30 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
}
|
||||
|
||||
var meetingInfoCodec = codec as IHasMeetingInfo;
|
||||
|
||||
// Set mode of header button
|
||||
if (!codec.IsInCall)
|
||||
{
|
||||
HeaderCallButtonIconSig.StringValue = "DND";
|
||||
//HeaderCallButton.SetIcon(HeaderListButton.OnHook);
|
||||
}
|
||||
else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
|
||||
HeaderCallButtonIconSig.StringValue = "Misc-06_Dark";
|
||||
//HeaderCallButton.SetIcon(HeaderListButton.Camera);
|
||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
|
||||
else
|
||||
HeaderCallButtonIconSig.StringValue = "Misc-09_Dark";
|
||||
//HeaderCallButton.SetIcon(HeaderListButton.Phone);
|
||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
||||
SetHeaderCallIcon(codec);
|
||||
|
||||
// Set the call status text
|
||||
Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count);
|
||||
|
||||
if (codec.ActiveCalls.Count > 0)
|
||||
{
|
||||
if (codec.ActiveCalls.Count == 1)
|
||||
if (codec.ActiveCalls.Count == 1 && meetingInfoCodec == null)
|
||||
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "1 Active Call");
|
||||
else if (codec.ActiveCalls.Count == 1 && meetingInfoCodec != null)
|
||||
{
|
||||
var headerCallStatusLabel = meetingInfoCodec.MeetingInfo.IsSharingMeeting
|
||||
? "Sharing-Only Meeting"
|
||||
: "Active Meeting";
|
||||
|
||||
headerCallStatusLabel = meetingInfoCodec.MeetingInfo.WaitingForHost
|
||||
? "Waiting For Host"
|
||||
: headerCallStatusLabel;
|
||||
|
||||
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, headerCallStatusLabel);
|
||||
}
|
||||
else if (codec.ActiveCalls.Count > 1)
|
||||
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, string.Format("{0} Active Calls", codec.ActiveCalls.Count));
|
||||
}
|
||||
@@ -218,10 +223,31 @@ namespace PepperDash.Essentials
|
||||
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "No Active Calls");
|
||||
}
|
||||
|
||||
private void SetHeaderCallIcon(VideoCodecBase codec)
|
||||
{
|
||||
if (!codec.IsInCall)
|
||||
{
|
||||
HeaderCallButtonIconSig.StringValue = "DND";
|
||||
//HeaderCallButton.SetIcon(HeaderListButton.OnHook);
|
||||
}
|
||||
else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
|
||||
{
|
||||
HeaderCallButtonIconSig.StringValue = "Misc-06_Dark";
|
||||
}
|
||||
//HeaderCallButton.SetIcon(HeaderListButton.Camera);
|
||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
|
||||
else
|
||||
{
|
||||
HeaderCallButtonIconSig.StringValue = "Misc-09_Dark";
|
||||
}
|
||||
//HeaderCallButton.SetIcon(HeaderListButton.Phone);
|
||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up Header Buttons for the EssentialsHuddleVtc1Room type
|
||||
/// </summary>
|
||||
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom)
|
||||
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, IEssentialsHuddleVtc1Room currentRoom)
|
||||
{
|
||||
HeaderButtonsAreSetUp = false;
|
||||
|
||||
@@ -255,7 +281,7 @@ namespace PepperDash.Essentials
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusLabelPress,
|
||||
() =>
|
||||
{
|
||||
avDriver.ShowActiveCallsList();
|
||||
avDriver.ShowActiveCallsListOrMeetingInfo();
|
||||
if (avDriver.CurrentRoom.InCallFeedback.BoolValue)
|
||||
CaretInterlock.ShowInterlocked(CallCaretVisible);
|
||||
});
|
||||
@@ -283,7 +309,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type
|
||||
/// </summary>
|
||||
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom)
|
||||
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, IEssentialsHuddleSpaceRoom currentRoom)
|
||||
{
|
||||
HeaderButtonsAreSetUp = false;
|
||||
|
||||
@@ -353,6 +379,8 @@ namespace PepperDash.Essentials
|
||||
headerPopupShown = true;
|
||||
else if (e.NewJoin == UIBoolJoin.HeaderActiveCallsListVisible)
|
||||
headerPopupShown = true;
|
||||
else if (e.NewJoin == UIBoolJoin.HeaderMeetingInfoVisible)
|
||||
headerPopupShown = true;
|
||||
else if (e.NewJoin == UIBoolJoin.HelpPageVisible)
|
||||
headerPopupShown = true;
|
||||
else if (e.NewJoin == UIBoolJoin.MeetingsOrContacMethodsListVisible)
|
||||
|
||||
@@ -983,7 +983,7 @@
|
||||
// /// <summary>
|
||||
// /// Handles source change
|
||||
// /// </summary>
|
||||
// void _CurrentRoom_SourceInfoChange(EssentialsRoomBase room,
|
||||
// void _CurrentRoom_SourceInfoChange(IEssentialsRoom room,
|
||||
// SourceListItem info, ChangeType change)
|
||||
// {
|
||||
// if (change == ChangeType.WillChange)
|
||||
@@ -995,7 +995,7 @@
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// void _CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
// void _CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||
// {
|
||||
// if (type == ChangeType.DidChange)
|
||||
// {
|
||||
@@ -1021,7 +1021,7 @@
|
||||
// /// <summary>
|
||||
// ///
|
||||
// /// </summary>
|
||||
// void _CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
// void _CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
|
||||
// {
|
||||
// if (type == ChangeType.DidChange)
|
||||
// {
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public EssentialsHuddleSpaceRoom CurrentRoom
|
||||
public IEssentialsHuddleSpaceRoom CurrentRoom
|
||||
{
|
||||
get { return _CurrentRoom; }
|
||||
set
|
||||
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials
|
||||
SetCurrentRoom(value);
|
||||
}
|
||||
}
|
||||
EssentialsHuddleSpaceRoom _CurrentRoom;
|
||||
IEssentialsHuddleSpaceRoom _CurrentRoom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -498,7 +498,7 @@ namespace PepperDash.Essentials
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
CurrentRoom.RunDefaultPresentRoute();
|
||||
(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute();
|
||||
}
|
||||
|
||||
|
||||
@@ -583,7 +583,7 @@ namespace PepperDash.Essentials
|
||||
void UiSelectSource(string key)
|
||||
{
|
||||
// Run the route and when it calls back, show the source
|
||||
CurrentRoom.RunRouteAction(key, new Action(() => { }));
|
||||
CurrentRoom.RunRouteAction(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -745,7 +745,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
|
||||
/// </summary>
|
||||
public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
public void RefreshCurrentRoom(IEssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_CurrentRoom != null)
|
||||
{
|
||||
@@ -836,7 +836,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
|
||||
void SetCurrentRoom(IEssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
if (_CurrentRoom == room) return;
|
||||
// Disconnect current (probably never called)
|
||||
@@ -871,7 +871,7 @@ namespace PepperDash.Essentials
|
||||
UpdateMCJoins(_CurrentRoom);
|
||||
}
|
||||
|
||||
void UpdateMCJoins(EssentialsHuddleSpaceRoom room)
|
||||
void UpdateMCJoins(IEssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
|
||||
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
|
||||
@@ -918,6 +918,7 @@ namespace PepperDash.Essentials
|
||||
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
@@ -316,7 +316,7 @@ namespace PepperDash.Essentials.UIDrivers
|
||||
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
|
||||
{
|
||||
var c = sender as ICommunicationMonitor;
|
||||
if (StatusListDeviceIndexes.ContainsKey(c))
|
||||
if (c != null && StatusListDeviceIndexes.ContainsKey(c))
|
||||
{
|
||||
var i = StatusListDeviceIndexes[c];
|
||||
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
@@ -8,11 +9,13 @@ using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -50,7 +53,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public EssentialsHuddleVtc1Room CurrentRoom
|
||||
public IEssentialsHuddleVtc1Room CurrentRoom
|
||||
{
|
||||
get { return _CurrentRoom; }
|
||||
set
|
||||
@@ -58,7 +61,7 @@ namespace PepperDash.Essentials
|
||||
SetCurrentRoom(value);
|
||||
}
|
||||
}
|
||||
EssentialsHuddleVtc1Room _CurrentRoom;
|
||||
IEssentialsHuddleVtc1Room _CurrentRoom;
|
||||
|
||||
/// <summary>
|
||||
/// For hitting feedbacks
|
||||
@@ -98,6 +101,9 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public SubpageReferenceList MeetingOrContactMethodModalSrl { get; set; }
|
||||
|
||||
public uint CallListOrMeetingInfoPopoverVisibilityJoin { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The list of buttons on the header. Managed with visibility only
|
||||
/// </summary>
|
||||
@@ -173,10 +179,38 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; }
|
||||
|
||||
|
||||
private UiDisplayMode _currentMode;
|
||||
|
||||
private bool _isZoomRoomWithNoExternalSources
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentRoom.VideoCodec is Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom && _sourceListCount <= 1;
|
||||
}
|
||||
}
|
||||
|
||||
private uint _sourceListCount;
|
||||
|
||||
/// <summary>
|
||||
/// The mode showing. Presentation or call.
|
||||
/// </summary>
|
||||
UiDisplayMode CurrentMode = UiDisplayMode.Start;
|
||||
UiDisplayMode CurrentMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentMode;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _currentMode)
|
||||
{
|
||||
_currentMode = value;
|
||||
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CTimer NextMeetingTimer;
|
||||
|
||||
@@ -207,6 +241,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5);
|
||||
|
||||
CurrentMode = UiDisplayMode.Start;
|
||||
|
||||
// buttons are added in SetCurrentRoom
|
||||
//HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]);
|
||||
@@ -331,15 +366,17 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Allows PopupInterlock to be toggled if the calls list is already visible, or if the codec is in a call
|
||||
/// </summary>
|
||||
public void ShowActiveCallsList()
|
||||
public void ShowActiveCallsListOrMeetingInfo()
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.CallEndAllConfirmVisible, true);
|
||||
if(PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible)
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible);
|
||||
|
||||
|
||||
if(PopupInterlock.CurrentJoin == CallListOrMeetingInfoPopoverVisibilityJoin)
|
||||
PopupInterlock.ShowInterlockedWithToggle(CallListOrMeetingInfoPopoverVisibilityJoin);
|
||||
else
|
||||
{
|
||||
if((CurrentRoom.ScheduleSource as VideoCodecBase).IsInCall)
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible);
|
||||
if(CurrentRoom.VideoCodec.IsInCall)
|
||||
PopupInterlock.ShowInterlockedWithToggle(CallListOrMeetingInfoPopoverVisibilityJoin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,79 +472,92 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShowNextMeetingTimerCallback()
|
||||
{
|
||||
//Update calendar for Zoom. Zoom doesn't automatically update when meetings are in the past
|
||||
if (_isZoomRoomWithNoExternalSources)
|
||||
{
|
||||
CurrentRoom.ScheduleSource.GetSchedule();
|
||||
}
|
||||
|
||||
// Every 60 seconds, refresh the calendar
|
||||
RefreshMeetingsList();
|
||||
// check meetings list for the closest, joinable meeting
|
||||
var ss = CurrentRoom.ScheduleSource;
|
||||
var meetings = ss.CodecSchedule.Meetings;
|
||||
|
||||
if (meetings.Count > 0)
|
||||
{
|
||||
// If the room is off pester the user
|
||||
// If the room is on, and the meeting is joinable
|
||||
// and the LastMeetingDismissed != this meeting
|
||||
if (meetings.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If the room is off pester the user
|
||||
// If the room is on, and the meeting is joinable
|
||||
// and the LastMeetingDismissed != this meeting
|
||||
|
||||
var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId);
|
||||
Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*",
|
||||
CurrentRoom.OnFeedback.BoolValue,
|
||||
LastMeetingDismissedId,
|
||||
lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : "");
|
||||
var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId);
|
||||
Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*",
|
||||
CurrentRoom.OnFeedback.BoolValue,
|
||||
LastMeetingDismissedId,
|
||||
lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToString("t", Global.Culture) : "");
|
||||
|
||||
var meeting = meetings.LastOrDefault(m => m.Joinable);
|
||||
if (CurrentRoom.OnFeedback.BoolValue
|
||||
&& lastMeetingDismissed == meeting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var meeting = meetings.LastOrDefault(m => m.Joinable);
|
||||
if (CurrentRoom.OnFeedback.BoolValue
|
||||
&& lastMeetingDismissed == meeting)
|
||||
{
|
||||
// meeting no longer joinable, hide popup
|
||||
if(meeting == null)
|
||||
HideNextMeetingPopup();
|
||||
|
||||
LastMeetingDismissedId = null;
|
||||
// Clear the popup when we run out of meetings
|
||||
if (meeting == null)
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting");
|
||||
TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToShortTimeString());
|
||||
TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToShortTimeString());
|
||||
TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title);
|
||||
TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer);
|
||||
TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingJoinPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
PopupInterlock.Hide();
|
||||
RoomOnAndDialMeeting(meeting);
|
||||
});
|
||||
TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
//CalendarPress();
|
||||
RefreshMeetingsList();
|
||||
PopupInterlock.ShowInterlocked(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
});
|
||||
var indexOfNext = meetings.IndexOf(meeting) + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// indexOf = 3, 4 meetings :
|
||||
if (indexOfNext < meetings.Count)
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText,
|
||||
meetings[indexOfNext].StartTime.ToShortTimeString());
|
||||
else
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today");
|
||||
LastMeetingDismissedId = null;
|
||||
// Clear the popup when we run out of meetings
|
||||
if (meeting == null)
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () =>
|
||||
{
|
||||
// Mark the meeting to not re-harass the user
|
||||
if(CurrentRoom.OnFeedback.BoolValue)
|
||||
LastMeetingDismissedId = meeting.Id;
|
||||
HideNextMeetingPopup();
|
||||
});
|
||||
|
||||
TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, true);
|
||||
}
|
||||
}
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting");
|
||||
TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToString("t", Global.Culture));
|
||||
TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToString("t", Global.Culture));
|
||||
TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title);
|
||||
TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer);
|
||||
TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingJoinPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
PopupInterlock.Hide();
|
||||
RoomOnAndDialMeeting(meeting);
|
||||
});
|
||||
TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule");
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () =>
|
||||
{
|
||||
HideNextMeetingPopup();
|
||||
//CalendarPress();
|
||||
RefreshMeetingsList();
|
||||
PopupInterlock.ShowInterlocked(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
});
|
||||
var indexOfNext = meetings.IndexOf(meeting) + 1;
|
||||
|
||||
// indexOf = 3, 4 meetings :
|
||||
if (indexOfNext < meetings.Count)
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText,
|
||||
meetings[indexOfNext].StartTime.ToString("t", Global.Culture));
|
||||
else
|
||||
TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today");
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () =>
|
||||
{
|
||||
// Mark the meeting to not re-harass the user
|
||||
if(CurrentRoom.OnFeedback.BoolValue)
|
||||
LastMeetingDismissedId = meeting.Id;
|
||||
HideNextMeetingPopup();
|
||||
});
|
||||
|
||||
TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -533,19 +583,26 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void RoomOnAndDialMeeting(Meeting meeting)
|
||||
{
|
||||
Debug.Console(1, "[RoomOnAndDialMeeting] Joining meeting [{0}]", meeting);
|
||||
Action dialAction = () =>
|
||||
{
|
||||
var d = CurrentRoom.ScheduleSource as VideoCodecBase;
|
||||
if (d != null)
|
||||
{
|
||||
Debug.Console(1,
|
||||
"[RoomOnAndDialMeeting] [dialAction] Sending command to codec to join meeting {0}", meeting);
|
||||
d.Dial(meeting);
|
||||
LastMeetingDismissedId = meeting.Id; // To prevent prompts for already-joined call
|
||||
}
|
||||
};
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
dialAction();
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
Debug.Console(1, "[RoomOnAndDialMeeting] Room is on.");
|
||||
dialAction();
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
Debug.Console(1, "RoomOnAndDialMeeting] Room is off or warming. Registering for Warming Feedback");
|
||||
// Rig a one-time handler to catch when the room is warmed and then dial call
|
||||
EventHandler<FeedbackEventArgs> oneTimeHandler = null;
|
||||
oneTimeHandler = (o, a) =>
|
||||
@@ -607,11 +664,39 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void SetActivityFooterFeedbacks()
|
||||
{
|
||||
CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
|
||||
if (CurrentRoom != null)
|
||||
{
|
||||
var startMode = CurrentMode == UiDisplayMode.Start;
|
||||
var presentationMode = CurrentMode == UiDisplayMode.Presentation;
|
||||
var callMode = CurrentMode == UiDisplayMode.Call;
|
||||
|
||||
TriList.SetBool(StartPageVisibleJoin, startMode ? true : false);
|
||||
|
||||
if (presentationMode &&_isZoomRoomWithNoExternalSources)
|
||||
{
|
||||
// For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, show the staging bar
|
||||
TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false);
|
||||
|
||||
}
|
||||
if (!presentationMode)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
}
|
||||
|
||||
CallButtonSig.BoolValue = callMode
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
ShareButtonSig.BoolValue = presentationMode
|
||||
&& CurrentRoom.ShutdownType == eShutdownType.None;
|
||||
EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -623,14 +708,13 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
HideLogo();
|
||||
HideNextMeetingPopup();
|
||||
TriList.SetBool(StartPageVisibleJoin, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
//TriList.SetBool(StartPageVisibleJoin, false);
|
||||
//TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
//TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
if (CurrentSourcePageManager != null)
|
||||
CurrentSourcePageManager.Hide();
|
||||
PowerOnFromCall();
|
||||
CurrentMode = UiDisplayMode.Call;
|
||||
SetActivityFooterFeedbacks();
|
||||
VCDriver.Show();
|
||||
}
|
||||
|
||||
@@ -643,29 +727,63 @@ namespace PepperDash.Essentials
|
||||
if (VCDriver.IsVisible)
|
||||
VCDriver.Hide();
|
||||
HideNextMeetingPopup();
|
||||
TriList.SetBool(StartPageVisibleJoin, false);
|
||||
TriList.SetBool(UIBoolJoin.CallStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true);
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
// If there's no default, show UI elements
|
||||
if (!CurrentRoom.RunDefaultPresentRoute())
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
}
|
||||
}
|
||||
else // room is on show what's active or select a source if nothing is yet active
|
||||
|
||||
|
||||
if (_isZoomRoomWithNoExternalSources)
|
||||
{
|
||||
if(CurrentRoom.CurrentSourceInfo == null || CurrentRoom.CurrentSourceInfoKey == CurrentRoom.DefaultCodecRouteString)
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
else if (CurrentSourcePageManager != null)
|
||||
CurrentSourcePageManager.Show();
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
CurrentRoom.RunDefaultPresentRoute();
|
||||
}
|
||||
// For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage
|
||||
TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, true);
|
||||
|
||||
var presentationMeetingCodec = CurrentRoom.VideoCodec as IHasPresentationOnlyMeeting;
|
||||
var farEndContentStatusCodec = CurrentRoom.VideoCodec as IHasFarEndContentStatus;
|
||||
var receivingContent = false;
|
||||
|
||||
if (farEndContentStatusCodec != null)
|
||||
{
|
||||
receivingContent = farEndContentStatusCodec.ReceivingContent.BoolValue;
|
||||
}
|
||||
|
||||
if (presentationMeetingCodec != null && !CurrentRoom.VideoCodec.IsInCall)
|
||||
{
|
||||
presentationMeetingCodec.StartSharingOnlyMeeting(eSharingMeetingMode.Laptop);
|
||||
}
|
||||
else if (CurrentRoom.VideoCodec.IsInCall && !CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue &&
|
||||
!receivingContent)
|
||||
{
|
||||
CurrentRoom.VideoCodec.StartSharing();
|
||||
}
|
||||
|
||||
if (CurrentSourcePageManager != null)
|
||||
CurrentSourcePageManager.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
// If there's no default, show UI elements
|
||||
if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute())
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
}
|
||||
else // room is on show what's active or select a source if nothing is yet active
|
||||
{
|
||||
if (CurrentRoom.CurrentSourceInfo == null ||
|
||||
(CurrentRoom.VideoCodec != null &&
|
||||
CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key))
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
else if (CurrentSourcePageManager != null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
CurrentSourcePageManager.Show();
|
||||
}
|
||||
}
|
||||
SetupSourceList();
|
||||
}
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
SetupSourceList();
|
||||
SetActivityFooterFeedbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -704,9 +822,11 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void ShowCurrentSource()
|
||||
{
|
||||
if (CurrentRoom.CurrentSourceInfo == null)
|
||||
if (CurrentRoom.CurrentSourceInfo == null || _isZoomRoomWithNoExternalSources)
|
||||
return;
|
||||
|
||||
CurrentMode = UiDisplayMode.Presentation;
|
||||
|
||||
if (CurrentRoom.CurrentSourceInfo.SourceDevice == null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
@@ -743,7 +863,7 @@ namespace PepperDash.Essentials
|
||||
void UiSelectSource(string key)
|
||||
{
|
||||
// Run the route and when it calls back, show the source
|
||||
CurrentRoom.RunRouteAction(key, new Action(() => { }));
|
||||
CurrentRoom.RunRouteAction(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -894,7 +1014,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
|
||||
/// </summary>
|
||||
void RefreshCurrentRoom(EssentialsHuddleVtc1Room room)
|
||||
void RefreshCurrentRoom(IEssentialsHuddleVtc1Room room)
|
||||
{
|
||||
|
||||
if (_CurrentRoom != null)
|
||||
@@ -912,6 +1032,18 @@ namespace PepperDash.Essentials
|
||||
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
|
||||
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange;
|
||||
_CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange;
|
||||
|
||||
var scheduleAwareCodec = _CurrentRoom.VideoCodec as IHasScheduleAwareness;
|
||||
if (scheduleAwareCodec != null)
|
||||
{
|
||||
scheduleAwareCodec.CodecSchedule.MeetingsListHasChanged -= CodecSchedule_MeetingsListHasChanged;
|
||||
}
|
||||
|
||||
var meetingInfoCodec = _CurrentRoom.VideoCodec as IHasMeetingInfo;
|
||||
if (meetingInfoCodec != null)
|
||||
{
|
||||
meetingInfoCodec.MeetingInfoChanged -= meetingInfoCodec_MeetingInfoChanged;
|
||||
}
|
||||
}
|
||||
|
||||
_CurrentRoom = room;
|
||||
@@ -944,9 +1076,23 @@ namespace PepperDash.Essentials
|
||||
_CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
|
||||
RefreshSourceInfo();
|
||||
|
||||
if (_CurrentRoom.VideoCodec is IHasScheduleAwareness)
|
||||
|
||||
var scheduleAwareCodec = _CurrentRoom.VideoCodec as IHasScheduleAwareness;
|
||||
if (scheduleAwareCodec != null)
|
||||
{
|
||||
(_CurrentRoom.VideoCodec as IHasScheduleAwareness).CodecSchedule.MeetingsListHasChanged += CodecSchedule_MeetingsListHasChanged;
|
||||
scheduleAwareCodec.CodecSchedule.MeetingsListHasChanged += CodecSchedule_MeetingsListHasChanged;
|
||||
}
|
||||
|
||||
var meetingInfoCodec = _CurrentRoom.VideoCodec as IHasMeetingInfo;
|
||||
if (meetingInfoCodec != null)
|
||||
{
|
||||
meetingInfoCodec.MeetingInfoChanged += new EventHandler<MeetingInfoEventArgs>(meetingInfoCodec_MeetingInfoChanged);
|
||||
|
||||
CallListOrMeetingInfoPopoverVisibilityJoin = UIBoolJoin.HeaderMeetingInfoVisible;
|
||||
}
|
||||
else
|
||||
{
|
||||
CallListOrMeetingInfoPopoverVisibilityJoin = UIBoolJoin.HeaderActiveCallsListVisible;
|
||||
}
|
||||
|
||||
CallSharingInfoVisibleFeedback = new BoolFeedback(() => _CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
@@ -958,7 +1104,8 @@ namespace PepperDash.Essentials
|
||||
if (_CurrentRoom != null)
|
||||
_CurrentRoom.CurrentSourceChange += new SourceInfoChangeHandler(CurrentRoom_CurrentSingleSourceChange);
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd", _CurrentRoom.SourceListKey));
|
||||
// Moved to EssentialsVideoCodecUiDriver
|
||||
//TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd", _CurrentRoom.SourceListKey));
|
||||
|
||||
(Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
|
||||
}
|
||||
@@ -969,7 +1116,27 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
void SetCurrentRoom(EssentialsHuddleVtc1Room room)
|
||||
void meetingInfoCodec_MeetingInfoChanged(object sender, MeetingInfoEventArgs e)
|
||||
{
|
||||
if (e.Info == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TriList.SetString(UIStringJoin.MeetingIdText, e.Info.Id);
|
||||
TriList.SetString(UIStringJoin.MeetingHostText, e.Info.Host);
|
||||
TriList.SetString(UIStringJoin.MeetingNameText, e.Info.Name);
|
||||
|
||||
TriList.SetString(UIStringJoin.MeetingPasswordText, e.Info.Password);
|
||||
// Show the password fields if one is present
|
||||
TriList.SetBool(UIBoolJoin.MeetingPasswordVisible, !string.IsNullOrEmpty(e.Info.Password));
|
||||
|
||||
TriList.SetString(UIStringJoin.CallSharedSourceNameText, e.Info.ShareStatus);
|
||||
|
||||
TriList.SetString(UIStringJoin.MeetingLeaveText, e.Info.IsHost ? "End Meeting" : "Leave Meeting");
|
||||
}
|
||||
|
||||
void SetCurrentRoom(IEssentialsHuddleVtc1Room room)
|
||||
{
|
||||
if (_CurrentRoom == room) return;
|
||||
// Disconnect current (probably never called)
|
||||
@@ -1004,7 +1171,7 @@ namespace PepperDash.Essentials
|
||||
UpdateMCJoins(_CurrentRoom);
|
||||
}
|
||||
|
||||
void UpdateMCJoins(EssentialsHuddleVtc1Room room)
|
||||
void UpdateMCJoins(IEssentialsHuddleVtc1Room room)
|
||||
{
|
||||
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
|
||||
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
|
||||
@@ -1035,7 +1202,7 @@ namespace PepperDash.Essentials
|
||||
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
||||
CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey);
|
||||
CurrentRoom.RunRouteAction("codecOsd");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,7 +1249,8 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(1, "**** KEY {0}", kvp.Key);
|
||||
|
||||
}
|
||||
SourceStagingSrl.Count = (ushort)(i - 1);
|
||||
_sourceListCount = (i - 1);
|
||||
SourceStagingSrl.Count = (ushort)_sourceListCount;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1105,6 +1273,30 @@ namespace PepperDash.Essentials
|
||||
/// <param name="type"></param>
|
||||
void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type)
|
||||
{
|
||||
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange");
|
||||
|
||||
// Show the Select a source subpage
|
||||
if (TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue)
|
||||
{
|
||||
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange SourceStagingBarVisisble: true");
|
||||
|
||||
if (_CurrentRoom.CurrentSourceInfo == null || (_CurrentRoom.VideoCodec != null && _CurrentRoom.CurrentSourceInfo.SourceDevice.Key == _CurrentRoom.VideoCodec.OsdSource.Key))
|
||||
{
|
||||
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Showing SelectASourceVisible");
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible");
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
}
|
||||
|
||||
if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null)
|
||||
TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = _CurrentRoom.CurrentSourceInfo.PreferredName;
|
||||
}
|
||||
@@ -1147,17 +1339,16 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
// See if this is helpful or if the callback response in the codec class maybe doesn't come it time?
|
||||
// Let's build list from event
|
||||
// CurrentRoom.ScheduleSource.GetSchedule();
|
||||
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListIcon, "Calendar");
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListIcon, "Calendar");
|
||||
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Today's Meetings");
|
||||
|
||||
ushort i = 0;
|
||||
foreach (var m in CurrentRoom.ScheduleSource.CodecSchedule.Meetings)
|
||||
{
|
||||
i++;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = m.StartTime.ToShortTimeString();
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = m.EndTime.ToShortTimeString();
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = m.StartTime.ToString("t", Global.Culture);
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = m.EndTime.ToString("t", Global.Culture);
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 3).StringValue = m.Title;
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 4).StringValue = string.Format("<br>{0}",m.Organizer);
|
||||
MeetingOrContactMethodModalSrl.StringInputSig(i, 5).StringValue = "Join";
|
||||
@@ -1202,12 +1393,12 @@ namespace PepperDash.Essentials
|
||||
var value = _CurrentRoom.OnFeedback.BoolValue;
|
||||
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
|
||||
|
||||
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value;
|
||||
//TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value;
|
||||
|
||||
if (value) //ON
|
||||
{
|
||||
SetupActivityFooterWhenRoomOn();
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = true;
|
||||
|
||||
}
|
||||
@@ -1218,9 +1409,8 @@ namespace PepperDash.Essentials
|
||||
VCDriver.Hide();
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
ShowLogo();
|
||||
SetActivityFooterFeedbacks();
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false;
|
||||
//TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
// Clear this so that the pesky meeting warning can resurface every minute when off
|
||||
LastMeetingDismissedId = null;
|
||||
}
|
||||
@@ -1443,7 +1633,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public interface IAVWithVCDriver : IAVDriver
|
||||
{
|
||||
EssentialsHuddleVtc1Room CurrentRoom { get; }
|
||||
IEssentialsHuddleVtc1Room CurrentRoom { get; }
|
||||
|
||||
PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; }
|
||||
/// <summary>
|
||||
@@ -1455,6 +1645,8 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
void PrepareForCodecIncomingCall();
|
||||
|
||||
uint CallListOrMeetingInfoPopoverVisibilityJoin { get; }
|
||||
|
||||
SubpageReferenceList MeetingOrContactMethodModalSrl { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Sets feedback for the given room
|
||||
/// </summary>
|
||||
public void SetFeedbackForRoom(EssentialsHuddleSpaceRoom room)
|
||||
public void SetFeedbackForRoom(IEssentialsHuddleSpaceRoom room)
|
||||
{
|
||||
var itemToSet = Items.FirstOrDefault(i => i.Room == room);
|
||||
if (itemToSet != null)
|
||||
@@ -48,11 +48,11 @@ namespace PepperDash.Essentials
|
||||
|
||||
public class SmartObjectRoomsListItem
|
||||
{
|
||||
public EssentialsHuddleSpaceRoom Room { get; private set; }
|
||||
public IEssentialsHuddleSpaceRoom Room { get; private set; }
|
||||
SmartObjectRoomsList Parent;
|
||||
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)
|
||||
{
|
||||
Room = room;
|
||||
|
||||
@@ -12,5 +12,5 @@ namespace PepperDash.Essentials
|
||||
///// <summary>
|
||||
///// The handler type for a Room's SourceInfoChange
|
||||
///// </summary>
|
||||
//public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
|
||||
//public delegate void SourceInfoChangeHandler(IEssentialsRoom room, SourceListItem info, ChangeType type);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
@@ -14,6 +15,7 @@ using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers.VC
|
||||
@@ -83,6 +85,9 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
StringBuilder SearchStringBuilder = new StringBuilder();
|
||||
BoolFeedback SearchStringBackspaceVisibleFeedback;
|
||||
|
||||
StringFeedback PasswordStringFeedback;
|
||||
StringBuilder PasswordStringBuilder = new StringBuilder();
|
||||
|
||||
ModalDialog IncomingCallModal;
|
||||
|
||||
eKeypadMode KeypadMode;
|
||||
@@ -123,26 +128,24 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(Codec_CallStatusChange);
|
||||
|
||||
// If the codec is ready, then get the values we want, otherwise wait
|
||||
if (Codec.IsReady)
|
||||
Codec_IsReady();
|
||||
else
|
||||
codec.IsReadyChange += (o, a) => Codec_IsReady();
|
||||
|
||||
//InCall = new BoolFeedback(() => false);
|
||||
LocalPrivacyIsMuted = new BoolFeedback(() => false);
|
||||
|
||||
VCControlsInterlock = new JoinedSigInterlock(triList);
|
||||
VCCameraControlModeInterlock = new JoinedSigInterlock(triList);
|
||||
|
||||
VCControlsInterlock.HideAndClear();
|
||||
|
||||
if (CodecHasFavorites)
|
||||
/* if (CodecHasFavorites || codec is IHasZoomRoomLayouts) //Checking for Zoom Room...picked a ZoomRoom specific interface to check for
|
||||
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadWithFavoritesVisible);
|
||||
else
|
||||
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible);
|
||||
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible); */
|
||||
|
||||
StagingBarsInterlock = new JoinedSigInterlock(triList);
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible);
|
||||
if(Codec is IHasCallHistory)
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible);
|
||||
else
|
||||
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible);
|
||||
|
||||
StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList);
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
||||
@@ -150,7 +153,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
// Return formatted when dialing, straight digits when in call
|
||||
DialStringFeedback = new StringFeedback(() =>
|
||||
{
|
||||
if (KeypadMode == eKeypadMode.Dial)
|
||||
// Format the number feedback if in dial mode and the codec is not IHasStartMeeting (ZoomRoom)
|
||||
if (KeypadMode == eKeypadMode.Dial && !(Codec is IHasStartMeeting))
|
||||
return GetFormattedDialString(DialStringBuilder.ToString());
|
||||
else
|
||||
return DialStringBuilder.ToString();
|
||||
@@ -177,8 +181,22 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
});
|
||||
SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]);
|
||||
|
||||
SetupDirectoryList();
|
||||
PasswordStringFeedback = new StringFeedback(() =>
|
||||
{
|
||||
if (PasswordStringBuilder.Length > 0)
|
||||
{
|
||||
Parent.Keyboard.EnableGoButton();
|
||||
return PasswordStringBuilder.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
Parent.Keyboard.DisableGoButton();
|
||||
return "";
|
||||
}
|
||||
});
|
||||
PasswordStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.PasswordPromptPasswordText]);
|
||||
|
||||
SetupDirectoryList();
|
||||
|
||||
SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0);
|
||||
SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]);
|
||||
@@ -196,6 +214,18 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
triList.SetSigHeldAction(UIBoolJoin.VCDirectoryBackspacePress, 500,
|
||||
StartSearchBackspaceRepeat, StopSearchBackspaceRepeat, SearchKeypadBackspacePress);
|
||||
|
||||
|
||||
if (Codec is IPasswordPrompt)
|
||||
{
|
||||
SetupPasswordPrompt();
|
||||
}
|
||||
|
||||
|
||||
// If the codec is ready, then get the values we want, otherwise wait
|
||||
if (Codec.IsReady)
|
||||
Codec_IsReady();
|
||||
else
|
||||
codec.IsReadyChange += (o, a) => Codec_IsReady();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -291,24 +321,20 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
|
||||
{
|
||||
var call = e.CallItem;
|
||||
var meetingInfoSender = sender as IHasMeetingInfo;
|
||||
|
||||
switch (e.CallItem.Status)
|
||||
{
|
||||
case eCodecCallStatus.Connected:
|
||||
// fire at SRL item
|
||||
KeypadMode = eKeypadMode.DTMF;
|
||||
DialStringBuilder.Remove(0, DialStringBuilder.Length);
|
||||
DialStringFeedback.FireUpdate();
|
||||
DialStringTextCheckEnables();
|
||||
Parent.ShowNotificationRibbon("Connected", 2000);
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
||||
ShowKeypad();
|
||||
((Parent.CurrentRoom as IHasCurrentVolumeControls).CurrentVolumeControls as IBasicVolumeWithFeedback).MuteOff();
|
||||
OnCallConnected();
|
||||
//VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible);
|
||||
break;
|
||||
case eCodecCallStatus.Connecting:
|
||||
// fire at SRL item
|
||||
Parent.ShowNotificationRibbon("Connecting", 0);
|
||||
OnCallConnected();
|
||||
break;
|
||||
case eCodecCallStatus.Dialing:
|
||||
Parent.ShowNotificationRibbon("Connecting", 0);
|
||||
@@ -324,7 +350,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
DialStringBuilder.Remove(0, DialStringBuilder.Length);
|
||||
DialStringFeedback.FireUpdate();
|
||||
Parent.ShowNotificationRibbon("Disconnected", 2000);
|
||||
Debug.Console(0, "Setting Connect Button mode to 0");
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case eCodecCallStatus.Disconnecting:
|
||||
break;
|
||||
@@ -345,16 +374,32 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
ShowIncomingModal(call);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0);
|
||||
|
||||
uint stageJoin;
|
||||
if (Codec.IsInCall)
|
||||
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
|
||||
else
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverVisible;
|
||||
|
||||
if (meetingInfoSender != null && Codec.IsInCall)
|
||||
{
|
||||
var meetingInfo = meetingInfoSender.MeetingInfo;
|
||||
|
||||
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue =
|
||||
(ushort) (meetingInfo.IsSharingMeeting ? 2 : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue =
|
||||
(ushort) (Codec.IsInCall ? 1 : 0);
|
||||
}
|
||||
|
||||
uint stageJoin;
|
||||
if (Codec.IsInCall)
|
||||
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
|
||||
else
|
||||
{
|
||||
if (Codec is IHasCallHistory)
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible;
|
||||
else
|
||||
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible;
|
||||
}
|
||||
if (IsVisible)
|
||||
StagingBarsInterlock.ShowInterlocked(stageJoin);
|
||||
else
|
||||
@@ -366,6 +411,36 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
UpdateHeaderActiveCallList();
|
||||
}
|
||||
|
||||
private void OnCallConnected()
|
||||
{
|
||||
HidePasswordPrompt();
|
||||
KeypadMode = eKeypadMode.DTMF;
|
||||
DialStringBuilder.Remove(0, DialStringBuilder.Length);
|
||||
DialStringFeedback.FireUpdate();
|
||||
DialStringTextCheckEnables();
|
||||
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
||||
ShowKeypad();
|
||||
|
||||
UnmuteRoomOnCallConnect();
|
||||
}
|
||||
|
||||
private void UnmuteRoomOnCallConnect()
|
||||
{
|
||||
var volControl = Parent.CurrentRoom as IHasCurrentVolumeControls;
|
||||
|
||||
if (volControl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var currentVolControls = volControl.CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
|
||||
if (currentVolControls != null)
|
||||
{
|
||||
currentVolControls.MuteOff();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraws the calls list on the header
|
||||
/// </summary>
|
||||
@@ -389,8 +464,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
ActiveCallsSRL.Count = (ushort)activeList.Count;
|
||||
|
||||
// If Active Calls list is visible and codec is not in a call, hide the list
|
||||
if (!Codec.IsInCall && Parent.PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible)
|
||||
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible);
|
||||
if (!Codec.IsInCall && Parent.PopupInterlock.CurrentJoin == Parent.CallListOrMeetingInfoPopoverVisibilityJoin)
|
||||
Parent.PopupInterlock.ShowInterlockedWithToggle(Parent.CallListOrMeetingInfoPopoverVisibilityJoin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -481,20 +556,67 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingRecentsPress, ShowRecents);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingCameraPress, ShowCameraControls);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingConnectPress, ConnectPress);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingMeetNowPress, MeetNowPress);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, CallStopSharingPress);
|
||||
|
||||
var meetingInfoCodec = Codec as IHasMeetingInfo;
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CallEndPress, () =>
|
||||
{
|
||||
if (Codec.ActiveCalls.Count > 1)
|
||||
{
|
||||
Parent.PopupInterlock.ShowInterlocked(UIBoolJoin.HeaderActiveCallsListVisible);
|
||||
Parent.PopupInterlock.ShowInterlocked(Parent.CallListOrMeetingInfoPopoverVisibilityJoin);
|
||||
}
|
||||
else if (meetingInfoCodec != null && Codec.ActiveCalls.Count == 1)
|
||||
{
|
||||
var meetingInfo = meetingInfoCodec.MeetingInfo;
|
||||
|
||||
if (meetingInfo != null && meetingInfo.IsSharingMeeting)
|
||||
{
|
||||
var presentationMeetingCodec = Codec as IHasPresentationOnlyMeeting;
|
||||
if (presentationMeetingCodec != null)
|
||||
{
|
||||
presentationMeetingCodec.StartNormalMeetingFromSharingOnlyMeeting();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Codec.EndAllCalls();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Codec.EndAllCalls();
|
||||
}
|
||||
});
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, () =>
|
||||
{
|
||||
Parent.PopupInterlock.HideAndClear();
|
||||
Codec.EndAllCalls();
|
||||
});
|
||||
|
||||
|
||||
if (meetingInfoCodec != null)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.MeetingLeavePress, () =>
|
||||
{
|
||||
Parent.PopupInterlock.HideAndClear();
|
||||
|
||||
if (meetingInfoCodec.MeetingInfo.IsHost)
|
||||
{
|
||||
Codec.EndAllCalls();
|
||||
}
|
||||
else
|
||||
{
|
||||
var startMeetingCodec = Codec as IHasStartMeeting;
|
||||
if (startMeetingCodec != null)
|
||||
{
|
||||
startMeetingCodec.LeaveMeeting();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void SetupCameraControls()
|
||||
@@ -513,13 +635,18 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var supportsCameraOffMode = Codec.SupportsCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
if (codecAutoCameras != null)
|
||||
var supportsAutoCameraMode = Codec.SupportsCameraAutoMode;
|
||||
|
||||
if (codecAutoCameras != null && supportsAutoCameraMode)
|
||||
{
|
||||
CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn());
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true;
|
||||
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]);
|
||||
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCCameraAutoModeIsOnFb]);
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 1 Pressed"].SetSigFalseAction(
|
||||
//() => codecAutoCameras.CameraAutoModeOn());
|
||||
|
||||
@@ -554,7 +681,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction(
|
||||
// () => ShowCameraManualMode());
|
||||
|
||||
if (codecOffCameras != null)
|
||||
if (codecOffCameras != null && supportsCameraOffMode)
|
||||
{
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true;
|
||||
codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]);
|
||||
@@ -769,12 +896,14 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
if (camerasCodec != null && camerasCodec.SelectedCamera != null)
|
||||
{
|
||||
|
||||
Debug.Console(2, "Attempting to map camera actions to selected camera: '{0}'", camerasCodec.SelectedCamera.Key);
|
||||
var dpad = CameraPtzPad;
|
||||
|
||||
var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl;
|
||||
if (camera != null)
|
||||
{
|
||||
|
||||
Debug.Console(2, "Selected camera is IHasCameraPtzControl");
|
||||
if (camerasCodec.SelectedCamera.CanTilt)
|
||||
{
|
||||
dpad.SigUp.SetBoolSigAction((b) =>
|
||||
@@ -839,25 +968,46 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Selected Camera is not IHasCameraPtzControl. No controls to map");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Codec does not have cameras of selected camera is null");
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if codec is in manual camera control mode and shows feedback
|
||||
void ShowCameraManualMode()
|
||||
{
|
||||
Debug.Console(2, "ShowCameraManualMode");
|
||||
|
||||
var inManualMode = true;
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
var supportsAutoCameras = codecAutoCameras != null && Codec.SupportsCameraAutoMode;
|
||||
|
||||
if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
inManualMode = false;
|
||||
|
||||
var codecCameraMute = Codec as IHasCameraMute;
|
||||
|
||||
if (codecCameraMute != null)
|
||||
{
|
||||
codecCameraMute.CameraMuteOff();
|
||||
inManualMode = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Clear auto mode
|
||||
if (codecAutoCameras != null )
|
||||
if (supportsAutoCameras)
|
||||
{
|
||||
if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue)
|
||||
{
|
||||
@@ -948,7 +1098,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
// if it's today, show a simpler string
|
||||
string timeText = null;
|
||||
if (c.StartTime.Date == DateTime.Now.Date)
|
||||
timeText = c.StartTime.ToShortTimeString();
|
||||
timeText = c.StartTime.ToString("t", Global.Culture);
|
||||
else if (c.StartTime == DateTime.MinValue)
|
||||
timeText = "";
|
||||
else
|
||||
@@ -1005,22 +1155,21 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
void SetupDirectoryList()
|
||||
{
|
||||
var codec = Codec as IHasDirectory;
|
||||
if (codec != null)
|
||||
{
|
||||
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
||||
true, 1300);
|
||||
codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
|
||||
if (codec == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (codec.PhonebookSyncState.InitialSyncComplete)
|
||||
SetCurrentDirectoryToRoot();
|
||||
else
|
||||
{
|
||||
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
|
||||
}
|
||||
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
||||
true, 1300);
|
||||
codec.DirectoryResultReturned += dir_DirectoryResultReturned;
|
||||
|
||||
RefreshDirectory();
|
||||
|
||||
}
|
||||
if (codec.PhonebookSyncState.InitialSyncComplete)
|
||||
SetCurrentDirectoryToRoot();
|
||||
else
|
||||
{
|
||||
codec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1028,11 +1177,15 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
void SetCurrentDirectoryToRoot()
|
||||
{
|
||||
(Codec as IHasDirectory).SetCurrentDirectoryToRoot();
|
||||
var hasDirectory = Codec as IHasDirectory;
|
||||
|
||||
if (hasDirectory == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hasDirectory.SetCurrentDirectoryToRoot();
|
||||
SearchKeypadClear();
|
||||
|
||||
RefreshDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1044,10 +1197,17 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
{
|
||||
var codec = Codec as IHasDirectory;
|
||||
|
||||
SetCurrentDirectoryToRoot();
|
||||
if (codec == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshDirectory();
|
||||
|
||||
if (!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetCurrentDirectoryToRoot();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1057,8 +1217,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// <param name="e"></param>
|
||||
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
||||
{
|
||||
|
||||
RefreshDirectory();
|
||||
RefreshDirectory(e.Directory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1087,16 +1246,27 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dir"></param>
|
||||
void RefreshDirectory()
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void RefreshDirectory()
|
||||
{
|
||||
if ((Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults.Count > 0)
|
||||
var codec = Codec as IHasDirectory;
|
||||
|
||||
if (codec == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshDirectory(codec.CurrentDirectoryResult);
|
||||
}
|
||||
|
||||
void RefreshDirectory(CodecDirectory directory)
|
||||
{
|
||||
if (directory.CurrentDirectoryResults.Count > 0)
|
||||
{
|
||||
ushort i = 0;
|
||||
foreach (var r in (Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults)
|
||||
foreach (var r in directory.CurrentDirectoryResults)
|
||||
{
|
||||
if (i == DirectoryList.MaxCount)
|
||||
{
|
||||
@@ -1116,19 +1286,33 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
// If more than one contact method, show contact method modal dialog
|
||||
DirectoryList.SetItemButtonAction(i, b =>
|
||||
{
|
||||
if (!b)
|
||||
if (b)
|
||||
{
|
||||
// Refresh the contact methods list
|
||||
RefreshContactMethodsModalList(dc);
|
||||
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
return;
|
||||
}
|
||||
// Refresh the contact methods list
|
||||
RefreshContactMethodsModalList(dc);
|
||||
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
||||
});
|
||||
|
||||
}
|
||||
else if (dc.ContactMethods.Count == 1)
|
||||
{
|
||||
var invitableContact = dc as IInvitableContact;
|
||||
|
||||
if (invitableContact != null)
|
||||
{
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(invitableContact); });
|
||||
}
|
||||
else
|
||||
{
|
||||
// If only one contact method, just dial that method
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If only one contact method, just dial that method
|
||||
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
|
||||
Debug.Console(1, "Unable to dial contact. No availble ContactMethod(s) specified");
|
||||
}
|
||||
}
|
||||
else // is DirectoryFolder
|
||||
@@ -1155,8 +1339,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
DirectoryList.SetItemMainText(1, "No Results Found");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshContactMethodsModalList(DirectoryContact contact)
|
||||
{
|
||||
@@ -1201,7 +1384,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
var lc = Codec as IHasCodecLayouts;
|
||||
if (lc != null)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
|
||||
|
||||
lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]);
|
||||
lc.LocalLayoutFeedback.OutputChange += (o,a) =>
|
||||
{
|
||||
@@ -1214,14 +1397,24 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
var cisco = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec;
|
||||
if (cisco != null)
|
||||
{
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
|
||||
// Cisco has min/max buttons that need special sauce
|
||||
cisco.SharingContentIsOnFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
|
||||
//cisco.PresentationViewMaximizedFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCMinMaxPress, cisco.MinMaxLayoutToggle);
|
||||
}
|
||||
|
||||
var zoomRoom = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom;
|
||||
if (zoomRoom != null)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.VCLayoutToggleEnable].BoolValue = true;
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1249,7 +1442,21 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
void RevealKeyboard()
|
||||
{
|
||||
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial)
|
||||
if (_passwordPromptDialogVisible)
|
||||
{
|
||||
Debug.Console(2, "Attaching Keyboard to PasswordPromptDialog");
|
||||
DetachDialKeyboard();
|
||||
DetachSearchKeyboard();
|
||||
var kb = Parent.Keyboard;
|
||||
kb.KeyPress -= Keyboard_PasswordKeyPress;
|
||||
kb.KeyPress += Keyboard_PasswordKeyPress;
|
||||
kb.HideAction = this.DetachPasswordKeyboard;
|
||||
kb.GoButtonText = "Submit";
|
||||
kb.GoButtonVisible = true;
|
||||
PasswordStringCheckEnables();
|
||||
kb.Show();
|
||||
}
|
||||
else if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial)
|
||||
{
|
||||
var kb = Parent.Keyboard;
|
||||
kb.KeyPress -= Keyboard_DialKeyPress;
|
||||
@@ -1271,6 +1478,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
SearchStringKeypadCheckEnables();
|
||||
kb.Show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1326,6 +1534,32 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for keyboard dialing
|
||||
/// </summary>
|
||||
void Keyboard_PasswordKeyPress(object sender, PepperDash.Essentials.Core.Touchpanels.Keyboards.KeyboardControllerPressEventArgs e)
|
||||
{
|
||||
if (_passwordPromptDialogVisible)
|
||||
{
|
||||
if (e.Text != null)
|
||||
PasswordStringBuilder.Append(e.Text);
|
||||
else
|
||||
{
|
||||
if (e.SpecialKey == KeyboardSpecialKey.Backspace)
|
||||
PasswordKeypadBackspacePress();
|
||||
else if (e.SpecialKey == KeyboardSpecialKey.Clear)
|
||||
PasswordKeypadClear();
|
||||
else if (e.SpecialKey == KeyboardSpecialKey.GoButton)
|
||||
{
|
||||
(Codec as IPasswordPrompt).SubmitPassword(PasswordStringBuilder.ToString());
|
||||
HidePasswordPrompt();
|
||||
}
|
||||
}
|
||||
PasswordStringFeedback.FireUpdate();
|
||||
PasswordStringCheckEnables();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call
|
||||
/// </summary>
|
||||
@@ -1339,6 +1573,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
Parent.Keyboard.KeyPress -= Keyboard_SearchKeyPress;
|
||||
}
|
||||
|
||||
void DetachPasswordKeyboard()
|
||||
{
|
||||
Parent.Keyboard.KeyPress -= Keyboard_PasswordKeyPress;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the camera controls subpage
|
||||
/// </summary>
|
||||
@@ -1416,6 +1655,22 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingRecentsPress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Meet Now button
|
||||
/// </summary>
|
||||
void MeetNowPress()
|
||||
{
|
||||
var startMeetingCodec = Codec as IHasStartMeeting;
|
||||
if (startMeetingCodec != null)
|
||||
{
|
||||
startMeetingCodec.StartMeeting(startMeetingCodec.DefaultMeetingDurationMin);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Codce does not implment IHasStartMeeting. Cannot meet now");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connect call button
|
||||
/// </summary>
|
||||
@@ -1426,6 +1681,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
Codec.Dial(DialStringBuilder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop Sharing button
|
||||
/// </summary>
|
||||
void CallStopSharingPress()
|
||||
{
|
||||
Codec.StopSharing();
|
||||
Parent.CurrentRoom.RunRouteAction("codecOsd", Parent.CurrentRoom.SourceListKey);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -1592,6 +1857,40 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
Parent.Keyboard.DisableGoButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the Password keypad
|
||||
/// </summary>
|
||||
void PasswordKeypadClear()
|
||||
{
|
||||
PasswordStringBuilder.Remove(0, PasswordStringBuilder.Length);
|
||||
PasswordStringFeedback.FireUpdate();
|
||||
PasswordStringCheckEnables();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void PasswordKeypadBackspacePress()
|
||||
{
|
||||
PasswordStringBuilder.Remove(PasswordStringBuilder.Length - 1, 1);
|
||||
|
||||
PasswordStringFeedback.FireUpdate();
|
||||
PasswordStringCheckEnables();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the enabled states of various elements around the keypad
|
||||
/// </summary>
|
||||
void PasswordStringCheckEnables()
|
||||
{
|
||||
var textIsEntered = PasswordStringBuilder.Length > 0;
|
||||
if (textIsEntered)
|
||||
Parent.Keyboard.EnableGoButton();
|
||||
else
|
||||
Parent.Keyboard.DisableGoButton();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the text value for the keypad dial entry field
|
||||
@@ -1637,5 +1936,62 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
Dial = 0,
|
||||
DTMF
|
||||
}
|
||||
|
||||
void SetupPasswordPrompt()
|
||||
{
|
||||
var passwordPromptCodec = Codec as IPasswordPrompt;
|
||||
|
||||
passwordPromptCodec.PasswordRequired += new EventHandler<PasswordPromptEventArgs>(passwordPromptCodec_PasswordRequired);
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptCancelPress, HidePasswordPrompt);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptTextPress, RevealKeyboard);
|
||||
}
|
||||
|
||||
void passwordPromptCodec_PasswordRequired(object sender, PasswordPromptEventArgs e)
|
||||
{
|
||||
if (e.LoginAttemptCancelled)
|
||||
{
|
||||
HidePasswordPrompt();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(e.Message))
|
||||
{
|
||||
TriList.SetString(UIStringJoin.PasswordPromptMessageText, e.Message);
|
||||
}
|
||||
|
||||
if (e.LoginAttemptFailed)
|
||||
{
|
||||
// TODO: Show a message modal to indicate the login attempt failed
|
||||
return;
|
||||
}
|
||||
|
||||
TriList.SetBool(UIBoolJoin.PasswordPromptErrorVisible, e.LastAttemptWasIncorrect);
|
||||
|
||||
ShowPasswordPrompt();
|
||||
}
|
||||
|
||||
private bool _passwordPromptDialogVisible;
|
||||
|
||||
void ShowPasswordPrompt()
|
||||
{
|
||||
// Clear out any previous data
|
||||
PasswordKeypadClear();
|
||||
|
||||
_passwordPromptDialogVisible = true;
|
||||
TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible);
|
||||
RevealKeyboard();
|
||||
}
|
||||
|
||||
void HidePasswordPrompt()
|
||||
{
|
||||
if (_passwordPromptDialogVisible)
|
||||
{
|
||||
_passwordPromptDialogVisible = false;
|
||||
Parent.Keyboard.Hide();
|
||||
TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible);
|
||||
PasswordKeypadClear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,7 +385,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
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)
|
||||
@@ -403,6 +403,16 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
||||
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 "vceiscapiadvanced":
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "DM Chassis enable audio breakaway routing",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "DM Chassis enable USB breakaway routing",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("SystemPowerOn")]
|
||||
public JoinDataComplete SystemPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "DMPS System Power On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("SystemPowerOff")]
|
||||
public JoinDataComplete SystemPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "DMPS System Power Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VideoSyncStatus")]
|
||||
public JoinDataComplete VideoSyncStatus = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Input Video Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
@@ -61,5 +69,5 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
protected DmpsRoutingControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ namespace PepperDash.Essentials.Core
|
||||
public GenericComm(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
|
||||
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
||||
|
||||
var commPort = CommFactory.CreateCommForDevice(config);
|
||||
|
||||
@@ -30,7 +30,19 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
[JsonProperty("properties")]
|
||||
[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>
|
||||
|
||||
@@ -1,162 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Responsible for updating config at runtime, and writing the updates out to a local file
|
||||
/// </summary>
|
||||
public class ConfigWriter
|
||||
{
|
||||
public const string LocalConfigFolder = "LocalConfig";
|
||||
|
||||
public const long WriteTimeout = 30000;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Responsible for updating config at runtime, and writing the updates out to a local file
|
||||
/// </summary>
|
||||
public class ConfigWriter
|
||||
{
|
||||
public const string LocalConfigFolder = "LocalConfig";
|
||||
|
||||
public const long WriteTimeout = 30000;
|
||||
|
||||
public static CTimer WriteTimer;
|
||||
static CCriticalSection fileLock = new CCriticalSection();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the config properties of a device
|
||||
/// </summary>
|
||||
/// <param name="deviceKey"></param>
|
||||
/// <param name="properties"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// Get the current device config
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
// Replace the current properties JToken with the new one passed into this method
|
||||
deviceConfig.Properties = properties;
|
||||
|
||||
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateDeviceConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
deviceConfig = config;
|
||||
|
||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateRoomConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
deviceConfig = config;
|
||||
|
||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets (or starts) the write timer
|
||||
/// </summary>
|
||||
static void ResetTimer()
|
||||
{
|
||||
if (WriteTimer == null)
|
||||
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
|
||||
|
||||
WriteTimer.Reset(WriteTimeout);
|
||||
|
||||
Debug.Console(1, "Config File write timer has been reset.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the current config to a file in the LocalConfig subfolder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static void WriteConfigFile(object o)
|
||||
{
|
||||
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
|
||||
|
||||
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
|
||||
|
||||
WriteFile(filePath, configData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes
|
||||
/// </summary>
|
||||
/// <param name="filepath"></param>
|
||||
/// <param name="o"></param>
|
||||
public static void WriteFile(string filePath, string configData)
|
||||
{
|
||||
if (WriteTimer != null)
|
||||
WriteTimer.Stop();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
|
||||
|
||||
try
|
||||
{
|
||||
if (fileLock.TryEnter())
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(filePath))
|
||||
{
|
||||
sw.Write(configData);
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileLock != null && !fileLock.Disposed)
|
||||
fileLock.Leave();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
static CCriticalSection fileLock = new CCriticalSection();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the config properties of a device
|
||||
/// </summary>
|
||||
/// <param name="deviceKey"></param>
|
||||
/// <param name="properties"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// Get the current device config
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
// Replace the current properties JToken with the new one passed into this method
|
||||
deviceConfig.Properties = properties;
|
||||
|
||||
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateDeviceConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (deviceConfigIndex >= 0)
|
||||
{
|
||||
ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config;
|
||||
|
||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateRoomConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (roomConfigIndex >= 0)
|
||||
{
|
||||
ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config;
|
||||
|
||||
Debug.Console(1, "Updated room of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets (or starts) the write timer
|
||||
/// </summary>
|
||||
static void ResetTimer()
|
||||
{
|
||||
if (WriteTimer == null)
|
||||
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
|
||||
|
||||
WriteTimer.Reset(WriteTimeout);
|
||||
|
||||
Debug.Console(1, "Config File write timer has been reset.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the current config to a file in the LocalConfig subfolder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static void WriteConfigFile(object o)
|
||||
{
|
||||
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
|
||||
|
||||
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
|
||||
|
||||
WriteFile(filePath, configData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes
|
||||
/// </summary>
|
||||
/// <param name="filepath"></param>
|
||||
/// <param name="o"></param>
|
||||
public static void WriteFile(string filePath, string configData)
|
||||
{
|
||||
if (WriteTimer != null)
|
||||
WriteTimer.Stop();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
|
||||
|
||||
try
|
||||
{
|
||||
if (fileLock.TryEnter())
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(filePath))
|
||||
{
|
||||
sw.Write(configData);
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileLock != null && !fileLock.Disposed)
|
||||
fileLock.Leave();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,19 +69,28 @@ namespace PepperDash.Essentials.Core
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Debug.Console(0, this, "Activating");
|
||||
if (!PreventRegistration)
|
||||
{
|
||||
if (!PreventRegistration)
|
||||
{
|
||||
//Debug.Console(1, this, " Does not require registration. Skipping");
|
||||
|
||||
var response = Hardware.RegisterWithLogging(Key);
|
||||
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
{
|
||||
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
|
||||
return false;
|
||||
}
|
||||
var response = Hardware.RegisterWithLogging(Key);
|
||||
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
{
|
||||
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
|
||||
return false;
|
||||
}
|
||||
|
||||
IsRegistered.FireUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
var response = Hardware.RegisterWithLogging(Key);
|
||||
|
||||
IsRegistered.FireUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var f in Feedbacks)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,14 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
void LinkSystemMonitorToAppServer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a MobileSystemController that accepts IEssentialsRoom
|
||||
/// </summary>
|
||||
public interface IMobileControl3 : IMobileControl
|
||||
{
|
||||
void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a MobileControl Room Bridge
|
||||
/// </summary>
|
||||
@@ -20,6 +28,10 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
event EventHandler<EventArgs> UserCodeChanged;
|
||||
|
||||
event EventHandler<EventArgs> UserPromptedForCode;
|
||||
|
||||
event EventHandler<EventArgs> ClientJoined;
|
||||
|
||||
string UserCode { get; }
|
||||
|
||||
string QrCodeUrl { get; }
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the functionality required to prompt a user to enter a password
|
||||
/// </summary>
|
||||
public interface IPasswordPrompt
|
||||
{
|
||||
/// <summary>
|
||||
/// Notifies when a password is required or is entered incorrectly
|
||||
/// </summary>
|
||||
event EventHandler<PasswordPromptEventArgs> PasswordRequired;
|
||||
|
||||
/// <summary>
|
||||
/// Submits the password
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
void SubmitPassword(string password);
|
||||
}
|
||||
|
||||
public class PasswordPromptEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if the last submitted password was incorrect
|
||||
/// </summary>
|
||||
public bool LastAttemptWasIncorrect { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the login attempt has failed
|
||||
/// </summary>
|
||||
public bool LoginAttemptFailed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the process was cancelled and the prompt should be dismissed
|
||||
/// </summary>
|
||||
public bool LoginAttemptCancelled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A message to be displayed to the user
|
||||
/// </summary>
|
||||
public string Message { get; private set; }
|
||||
|
||||
public PasswordPromptEventArgs(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message)
|
||||
{
|
||||
LastAttemptWasIncorrect = lastAttemptIncorrect;
|
||||
LoginAttemptFailed = loginFailed;
|
||||
LoginAttemptCancelled = loginCancelled;
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,23 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="json"></param>
|
||||
public static void DoDeviceActionWithJson(string json)
|
||||
{
|
||||
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
|
||||
DoDeviceAction(action);
|
||||
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);
|
||||
|
||||
DoDeviceAction(action);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,31 +48,65 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
var key = action.DeviceKey;
|
||||
var obj = FindObjectOnPath(key);
|
||||
if (obj == null)
|
||||
return;
|
||||
if (obj == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key);
|
||||
return;
|
||||
}
|
||||
|
||||
CType t = obj.GetType();
|
||||
var method = t.GetMethod(action.MethodName);
|
||||
if (method == null)
|
||||
{
|
||||
Debug.Console(0, "Method '{0}' not found", action.MethodName);
|
||||
return;
|
||||
}
|
||||
var mParams = method.GetParameters();
|
||||
// Add empty params if not provided
|
||||
if (action.Params == null) action.Params = new object[0];
|
||||
if (mParams.Length > action.Params.Length)
|
||||
{
|
||||
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();
|
||||
object ret = method.Invoke(obj, convertedParams);
|
||||
if (action.Params == null)
|
||||
{
|
||||
//no params, so setting action.Params to empty array
|
||||
action.Params = new object[0];
|
||||
}
|
||||
|
||||
CType t = obj.GetType();
|
||||
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)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(
|
||||
"Unable to find method with name {0} and that matches parameters {1}", action.MethodName,
|
||||
action.Params);
|
||||
return;
|
||||
}
|
||||
var mParams = method.GetParameters();
|
||||
|
||||
var convertedParams = mParams
|
||||
.Select((p, i) => ConvertType(action.Params[i], p.ParameterType))
|
||||
.ToArray();
|
||||
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>
|
||||
/// Gets the properties on a device
|
||||
/// </summary>
|
||||
@@ -242,6 +291,8 @@ namespace PepperDash.Essentials.Core
|
||||
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
|
||||
//return JsonConvert.SerializeObject(props, Formatting.Indented);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class DeviceActionWrapper
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace PepperDash.Essentials.Core
|
||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(SetDeviceStreamDebugging, "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace PepperDash.Essentials.Core
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
Debug.Console(0,"****PreActivation starting...****");
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
@@ -69,9 +70,12 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} PreActivation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "****PreActivation complete****");
|
||||
Debug.Console(0, "****Activation starting...****");
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
@@ -83,10 +87,14 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} Activation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "****Activation complete****");
|
||||
Debug.Console(0, "****PostActivation starting...****");
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
@@ -97,10 +105,13 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} PostActivation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "****PostActivation complete****");
|
||||
|
||||
OnAllDevicesActivated();
|
||||
}
|
||||
finally
|
||||
@@ -387,6 +398,15 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="s"></param>
|
||||
public static void SetDeviceStreamDebugging(string s)
|
||||
{
|
||||
if (String.IsNullOrEmpty(s) || s.Contains("?"))
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(
|
||||
@"SETDEVICESTREAMDEBUG [{deviceKey}] [OFF |TX | RX | BOTH] [timeOutInMinutes]
|
||||
{deviceKey} [OFF | TX | RX | BOTH] - Device to set stream debugging on, and which setting to use
|
||||
timeOutInMinutes - Set timeout for stream debugging. Default is 30 minutes");
|
||||
return;
|
||||
}
|
||||
|
||||
var args = s.Split(' ');
|
||||
|
||||
var deviceKey = args[0];
|
||||
@@ -426,7 +446,7 @@ namespace PepperDash.Essentials.Core
|
||||
var min = Convert.ToUInt32(timeout);
|
||||
|
||||
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)
|
||||
@@ -437,7 +457,7 @@ namespace PepperDash.Essentials.Core
|
||||
else
|
||||
{
|
||||
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1} for default time (30 minutes)", deviceKey, debugSetting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,113 +1,134 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class
|
||||
/// </summary>
|
||||
[Description("The base Essentials Device Class")]
|
||||
public abstract class EssentialsDevice : Device
|
||||
{
|
||||
protected EssentialsDevice(string key)
|
||||
: base(key)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected EssentialsDevice(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
|
||||
public class DescriptionAttribute : Attribute
|
||||
{
|
||||
private string _Description;
|
||||
|
||||
public DescriptionAttribute(string description)
|
||||
{
|
||||
Debug.Console(2, "Setting Description: {0}", description);
|
||||
_Description = description;
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return _Description; }
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
|
||||
public class ConfigSnippetAttribute : Attribute
|
||||
{
|
||||
private string _ConfigSnippet;
|
||||
|
||||
public ConfigSnippetAttribute(string configSnippet)
|
||||
{
|
||||
Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
|
||||
_ConfigSnippet = configSnippet;
|
||||
}
|
||||
|
||||
public string ConfigSnippet
|
||||
{
|
||||
get { return _ConfigSnippet; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devices the basic needs for a Device Factory
|
||||
/// </summary>
|
||||
public abstract class EssentialsDeviceFactory<T> : IDeviceFactory where T:EssentialsDevice
|
||||
{
|
||||
#region IDeviceFactory Members
|
||||
|
||||
/// <summary>
|
||||
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
|
||||
/// </summary>
|
||||
public List<string> TypeNames { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list
|
||||
/// </summary>
|
||||
public void LoadTypeFactories()
|
||||
{
|
||||
foreach (var typeName in TypeNames)
|
||||
{
|
||||
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
|
||||
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class
|
||||
/// </summary>
|
||||
[Description("The base Essentials Device Class")]
|
||||
public abstract class EssentialsDevice : Device
|
||||
{
|
||||
protected EssentialsDevice(string key)
|
||||
: base(key)
|
||||
{
|
||||
SubscribeToActivateComplete();
|
||||
}
|
||||
|
||||
protected EssentialsDevice(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
SubscribeToActivateComplete();
|
||||
}
|
||||
|
||||
private void SubscribeToActivateComplete()
|
||||
{
|
||||
DeviceManager.AllDevicesActivated += DeviceManagerOnAllDevicesActivated;
|
||||
}
|
||||
|
||||
private void DeviceManagerOnAllDevicesActivated(object sender, EventArgs eventArgs)
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Exception initializing device: {0}", ex.Message);
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
|
||||
public class DescriptionAttribute : Attribute
|
||||
{
|
||||
private string _Description;
|
||||
|
||||
public DescriptionAttribute(string description)
|
||||
{
|
||||
//Debug.Console(2, "Setting Description: {0}", description);
|
||||
_Description = description;
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return _Description; }
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
|
||||
public class ConfigSnippetAttribute : Attribute
|
||||
{
|
||||
private string _ConfigSnippet;
|
||||
|
||||
public ConfigSnippetAttribute(string configSnippet)
|
||||
{
|
||||
//Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
|
||||
_ConfigSnippet = configSnippet;
|
||||
}
|
||||
|
||||
public string ConfigSnippet
|
||||
{
|
||||
get { return _ConfigSnippet; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devices the basic needs for a Device Factory
|
||||
/// </summary>
|
||||
public abstract class EssentialsDeviceFactory<T> : IDeviceFactory where T:EssentialsDevice
|
||||
{
|
||||
#region IDeviceFactory Members
|
||||
|
||||
/// <summary>
|
||||
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
|
||||
/// </summary>
|
||||
public List<string> TypeNames { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list
|
||||
/// </summary>
|
||||
public void LoadTypeFactories()
|
||||
{
|
||||
foreach (var typeName in TypeNames)
|
||||
{
|
||||
//Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
|
||||
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
|
||||
string description = descriptionAttribute[0].Description;
|
||||
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
|
||||
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method that will build the device
|
||||
/// </summary>
|
||||
/// <param name="dc">The device config</param>
|
||||
/// <returns>An instance of the device</returns>
|
||||
public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devices the basic needs for a Device Factory
|
||||
/// </summary>
|
||||
public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33")
|
||||
/// </summary>
|
||||
public string MinimumEssentialsFrameworkVersion { get; protected set; }
|
||||
}
|
||||
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
|
||||
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The method that will build the device
|
||||
/// </summary>
|
||||
/// <param name="dc">The device config</param>
|
||||
/// <returns>An instance of the device</returns>
|
||||
public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devices the basic needs for a Device Factory
|
||||
/// </summary>
|
||||
public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33")
|
||||
/// </summary>
|
||||
public string MinimumEssentialsFrameworkVersion { get; protected set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
|
||||
@@ -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.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class ReconfigurableDevice : EssentialsDevice
|
||||
public abstract class ReconfigurableDevice : EssentialsDevice, IReconfigurableDevice
|
||||
{
|
||||
public event EventHandler<EventArgs> ConfigChanged;
|
||||
|
||||
@@ -52,6 +54,8 @@ namespace PepperDash.Essentials.Core.Devices
|
||||
Name = config.Name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
|
||||
/// </summary>
|
||||
|
||||
@@ -59,6 +59,9 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
|
||||
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
|
||||
|
||||
WarmupTime = 10000;
|
||||
CooldownTime = 5000;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,149 +1,208 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using PepperDash.Essentials.Core.Touchpanels;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class DeviceFactoryWrapper
|
||||
{
|
||||
public CType CType { get; set; }
|
||||
public string Description { get; set; }
|
||||
public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; }
|
||||
|
||||
public DeviceFactoryWrapper()
|
||||
{
|
||||
CType = null;
|
||||
Description = "Not Available";
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceFactory
|
||||
{
|
||||
public DeviceFactory()
|
||||
{
|
||||
var assy = Assembly.GetExecutingAssembly();
|
||||
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
|
||||
|
||||
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
|
||||
|
||||
if (types != null)
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||
factory.LoadTypeFactories();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of factory methods, keyed by config types, added by plugins.
|
||||
/// These methods are looked up and called by GetDevice in this class.
|
||||
/// </summary>
|
||||
static Dictionary<string, DeviceFactoryWrapper> FactoryMethods =
|
||||
new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a plugin factory method
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
|
||||
}
|
||||
|
||||
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
|
||||
if(FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
|
||||
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The factory method for Core "things". Also iterates the Factory methods that have
|
||||
/// been loaded from plugins
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static IKeyed GetDevice(DeviceConfig dc)
|
||||
{
|
||||
var key = dc.Key;
|
||||
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);
|
||||
return FactoryMethods[typeName].FactoryMethod(dc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public static void GetDeviceFactoryTypes(string filter)
|
||||
{
|
||||
Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>();
|
||||
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
{
|
||||
types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
types = FactoryMethods;
|
||||
}
|
||||
|
||||
Debug.Console(0, "Device Types:");
|
||||
|
||||
foreach (var type in types.OrderBy(t => t.Key))
|
||||
{
|
||||
var description = type.Value.Description;
|
||||
var cType = "Not Specified by Plugin";
|
||||
|
||||
if(type.Value.CType != null)
|
||||
{
|
||||
cType = type.Value.CType.FullName;
|
||||
}
|
||||
|
||||
Debug.Console(0,
|
||||
@"Type: '{0}'
|
||||
CType: '{1}'
|
||||
Description: {2}", type.Key, cType, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
using PepperDash.Essentials.Core.Touchpanels;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class DeviceFactoryWrapper
|
||||
{
|
||||
public CType CType { get; set; }
|
||||
public string Description { get; set; }
|
||||
public Func<DeviceConfig, IKeyed> FactoryMethod { get; set; }
|
||||
|
||||
public DeviceFactoryWrapper()
|
||||
{
|
||||
CType = null;
|
||||
Description = "Not Available";
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceFactory
|
||||
{
|
||||
public DeviceFactory()
|
||||
{
|
||||
var assy = Assembly.GetExecutingAssembly();
|
||||
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
|
||||
|
||||
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
|
||||
|
||||
if (types != null)
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||
factory.LoadTypeFactories();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of factory methods, keyed by config types, added by plugins.
|
||||
/// These methods are looked up and called by GetDevice in this class.
|
||||
/// </summary>
|
||||
static Dictionary<string, DeviceFactoryWrapper> FactoryMethods =
|
||||
new Dictionary<string, DeviceFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a plugin factory method
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
//Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
|
||||
}
|
||||
|
||||
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
//Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
|
||||
if(FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
|
||||
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
||||
}
|
||||
|
||||
private static void CheckForSecrets(IEnumerable<JProperty> obj)
|
||||
{
|
||||
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>
|
||||
/// The factory method for Core "things". Also iterates the Factory methods that have
|
||||
/// been loaded from plugins
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static IKeyed GetDevice(DeviceConfig dc)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
||||
|
||||
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);
|
||||
|
||||
if (ex.InnerException == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Inner exception while creating device {0}: {1}", dc.Key,
|
||||
ex.InnerException.Message);
|
||||
Debug.Console(2, "{0}", ex.InnerException.StackTrace);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public static void GetDeviceFactoryTypes(string filter)
|
||||
{
|
||||
Dictionary<string, DeviceFactoryWrapper> types = new Dictionary<string, DeviceFactoryWrapper>();
|
||||
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
{
|
||||
types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
types = FactoryMethods;
|
||||
}
|
||||
|
||||
Debug.Console(0, "Device Types:");
|
||||
|
||||
foreach (var type in types.OrderBy(t => t.Key))
|
||||
{
|
||||
var description = type.Value.Description;
|
||||
var cType = "Not Specified by Plugin";
|
||||
|
||||
if(type.Value.CType != null)
|
||||
{
|
||||
cType = type.Value.CType.FullName;
|
||||
}
|
||||
|
||||
Debug.Console(0,
|
||||
@"Type: '{0}'
|
||||
CType: '{1}'
|
||||
Description: {2}", type.Key, cType, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,11 @@ namespace PepperDash.Essentials.Core
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
public void SetValueFunc(Func<bool> newFunc)
|
||||
{
|
||||
ValueFunc = newFunc;
|
||||
}
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
bool newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
protected bool ComputedValue;
|
||||
|
||||
public BoolFeedbackLogic()
|
||||
protected BoolFeedbackLogic()
|
||||
{
|
||||
Output = new BoolFeedback(() => ComputedValue);
|
||||
}
|
||||
@@ -40,21 +40,18 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public void AddOutputsIn(List<BoolFeedback> outputs)
|
||||
{
|
||||
foreach (var o in outputs)
|
||||
{
|
||||
// skip existing
|
||||
if (OutputsIn.Contains(o)) continue;
|
||||
|
||||
OutputsIn.Add(o);
|
||||
o.OutputChange += AnyInput_OutputChange;
|
||||
}
|
||||
Evaluate();
|
||||
foreach (var o in outputs.Where(o => !OutputsIn.Contains(o)))
|
||||
{
|
||||
OutputsIn.Add(o);
|
||||
o.OutputChange += AnyInput_OutputChange;
|
||||
}
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
public void RemoveOutputIn(BoolFeedback output)
|
||||
public void RemoveOutputIn(BoolFeedback output)
|
||||
{
|
||||
// Don't double up outputs
|
||||
if (OutputsIn.Contains(output)) return;
|
||||
if (!OutputsIn.Contains(output)) return;
|
||||
|
||||
OutputsIn.Remove(output);
|
||||
output.OutputChange -= AnyInput_OutputChange;
|
||||
@@ -71,6 +68,12 @@ namespace PepperDash.Essentials.Core
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
public void ClearOutputs()
|
||||
{
|
||||
OutputsIn.Clear();
|
||||
Evaluate();
|
||||
}
|
||||
|
||||
void AnyInput_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
Evaluate();
|
||||
@@ -85,11 +88,12 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
var prevValue = ComputedValue;
|
||||
var newValue = OutputsIn.All(o => o.BoolValue);
|
||||
if (newValue != prevValue)
|
||||
{
|
||||
ComputedValue = newValue;
|
||||
Output.FireUpdate();
|
||||
}
|
||||
if (newValue == prevValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ComputedValue = newValue;
|
||||
Output.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,33 +103,35 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
var prevValue = ComputedValue;
|
||||
var newValue = OutputsIn.Any(o => o.BoolValue);
|
||||
if (newValue != prevValue)
|
||||
{
|
||||
ComputedValue = newValue;
|
||||
Output.FireUpdate();
|
||||
}
|
||||
if (newValue == prevValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ComputedValue = newValue;
|
||||
Output.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public class BoolFeedbackLinq : BoolFeedbackLogic
|
||||
{
|
||||
Func<IEnumerable<BoolFeedback>, bool> Predicate;
|
||||
readonly Func<IEnumerable<BoolFeedback>, bool> _predicate;
|
||||
|
||||
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
|
||||
: base()
|
||||
{
|
||||
Predicate = predicate;
|
||||
_predicate = predicate;
|
||||
}
|
||||
|
||||
protected override void Evaluate()
|
||||
{
|
||||
var prevValue = ComputedValue;
|
||||
var newValue = Predicate(OutputsIn);
|
||||
if (newValue != prevValue)
|
||||
{
|
||||
ComputedValue = newValue;
|
||||
Output.FireUpdate();
|
||||
}
|
||||
var newValue = _predicate(OutputsIn);
|
||||
if (newValue == prevValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ComputedValue = newValue;
|
||||
Output.FireUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,12 @@ namespace PepperDash.Essentials.Core
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
public void SetValueFunc(Func<int> newFunc)
|
||||
{
|
||||
ValueFunc = newFunc;
|
||||
}
|
||||
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
var newValue = InTestMode ? TestValue : ValueFunc.Invoke();
|
||||
|
||||
@@ -52,7 +52,10 @@ namespace PepperDash.Essentials.Core
|
||||
ValueFunc = valueFunc;
|
||||
}
|
||||
|
||||
|
||||
public void SetValueFunc(Func<string> newFunc)
|
||||
{
|
||||
ValueFunc = newFunc;
|
||||
}
|
||||
|
||||
public override void FireUpdate()
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
protected FusionRoom FusionRoom;
|
||||
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
||||
public long PushNotificationTimeout = 5000;
|
||||
protected EssentialsRoomBase Room;
|
||||
protected IEssentialsRoom Room;
|
||||
public long SchedulePollInterval = 300000;
|
||||
|
||||
private Event _currentMeeting;
|
||||
@@ -86,7 +86,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
#endregion
|
||||
|
||||
public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey)
|
||||
public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey)
|
||||
: base(room.Key + "-fusion")
|
||||
{
|
||||
try
|
||||
@@ -119,9 +119,21 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
var slot = Global.ControlSystem.ProgramNumber;
|
||||
|
||||
var guidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
var oldGuidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
|
||||
if (File.Exists(oldGuidFilePath))
|
||||
{
|
||||
Debug.Console(0, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
|
||||
|
||||
File.Copy(oldGuidFilePath, guidFilePath);
|
||||
|
||||
File.Delete(oldGuidFilePath);
|
||||
}
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
|
||||
// Check if file exists
|
||||
if (!_guidFileExists)
|
||||
@@ -149,19 +161,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
});
|
||||
AddPostActivationAction(() => PostActivate(guidFilePath));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -169,6 +169,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
}
|
||||
|
||||
private void PostActivate(string guidFilePath)
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
}
|
||||
|
||||
protected string RoomGuid
|
||||
{
|
||||
get { return _guiDs.RoomGuid; }
|
||||
@@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
deviceConfig.Properties = JToken.FromObject(devProps);
|
||||
}
|
||||
else if (device is EssentialsRoomBase)
|
||||
else if (device is IEssentialsRoom)
|
||||
{
|
||||
// Set the room name
|
||||
if (!string.IsNullOrEmpty(roomInfo.Name))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Globalization;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
@@ -28,6 +29,31 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } }
|
||||
|
||||
// TODO: consider making this configurable later
|
||||
public static IFormatProvider Culture = CultureInfo.CreateSpecificCulture("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// True when the processor type is a DMPS variant
|
||||
/// </summary>
|
||||
public static bool ControlSystemIsDmpsType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ControlSystem.ControllerPrompt.ToLower().IndexOf("dmps") > -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True when the processor type is a DMPS 4K variant
|
||||
/// </summary>
|
||||
public static bool ControlSystemIsDmps4kType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ControlSystemIsDmpsType && ControlSystem.ControllerPrompt.ToLower().IndexOf("4k") > -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the folder containing configuration files
|
||||
/// </summary>
|
||||
|
||||
@@ -88,11 +88,6 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
else
|
||||
Debug.Console(0, this, "Unable to add Red LED device");
|
||||
|
||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
};
|
||||
|
||||
AddPostActivationAction(() => {
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||
@@ -103,6 +98,15 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetPrivacyDevice(IPrivacy privacyDevice)
|
||||
{
|
||||
PrivacyDevice = privacyDevice;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Resources;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
@@ -199,6 +200,27 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState);
|
||||
}
|
||||
|
||||
// TODO [ ] feature/cenoodtcpoe-sensor-sensitivity-configuration
|
||||
if (PropertiesConfig.UsSensitivityOccupied != null)
|
||||
{
|
||||
SetUsSensitivityOccupied((ushort)PropertiesConfig.UsSensitivityOccupied);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.UsSensitivityVacant != null)
|
||||
{
|
||||
SetUsSensitivityVacant((ushort)PropertiesConfig.UsSensitivityVacant);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.PirSensitivityOccupied != null)
|
||||
{
|
||||
SetPirSensitivityOccupied((ushort)PropertiesConfig.PirSensitivityOccupied);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.PirSensitivityVacant != null)
|
||||
{
|
||||
SetPirSensitivityVacant((ushort)PropertiesConfig.PirSensitivityVacant);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -279,7 +301,21 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Sets the identity mode on or off
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetIdentityMode(bool state)
|
||||
{
|
||||
if (state)
|
||||
OccSensor.IdentityModeOn();
|
||||
else
|
||||
OccSensor.IdentityModeOff();
|
||||
|
||||
Debug.Console(1, this, "Identity Mode: {0}", OccSensor.IdentityModeOnFeedback.BoolValue ? "On" : "Off");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the PIR sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
@@ -506,6 +542,54 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the US sensor sensitivity for occupied state
|
||||
/// </summary>
|
||||
/// <param name="sensitivity"></param>
|
||||
public void SetUsSensitivityOccupied(ushort sensitivity)
|
||||
{
|
||||
var level = (eSensitivityLevel) sensitivity;
|
||||
if (level == 0) return;
|
||||
|
||||
OccSensor.UltrasonicSensorSensitivityInOccupiedState = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the US sensor sensitivity for vacant state
|
||||
/// </summary>
|
||||
/// <param name="sensitivity"></param>
|
||||
public void SetUsSensitivityVacant(ushort sensitivity)
|
||||
{
|
||||
var level = (eSensitivityLevel)sensitivity;
|
||||
if (level == 0) return;
|
||||
|
||||
OccSensor.UltrasonicSensorSensitivityInVacantState = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the PIR sensor sensitivity for occupied state
|
||||
/// </summary>
|
||||
/// <param name="sensitivity"></param>
|
||||
public void SetPirSensitivityOccupied(ushort sensitivity)
|
||||
{
|
||||
var level = (eSensitivityLevel)sensitivity;
|
||||
if (level == 0) return;
|
||||
|
||||
OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the PIR sensor sensitivity for vacant state
|
||||
/// </summary>
|
||||
/// <param name="sensitivity"></param>
|
||||
public void SetPirSensitivityVacant(ushort sensitivity)
|
||||
{
|
||||
var level = (eSensitivityLevel)sensitivity;
|
||||
if (level == 0) return;
|
||||
|
||||
OccSensor.PassiveInfraredSensorSensitivityInVacantState = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to print current settings to console
|
||||
/// </summary>
|
||||
@@ -647,8 +731,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
//Sensor Raw States
|
||||
occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
|
||||
occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
|
||||
|
||||
occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
|
||||
}
|
||||
|
||||
public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<CenOdtOccupancySensorBaseController>
|
||||
|
||||
@@ -47,5 +47,35 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
[JsonProperty("andWhenVacatedState")]
|
||||
public bool? AndWhenVacatedState { get; set; }
|
||||
|
||||
// PoE Sensors: CenOdtCPoe
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sensitivity level for US while sensor is in occupied state
|
||||
/// 1 = low; 2 = medium; 3 = high; 4 = xlow; 5 = 2xlow; 6 = 3xlow
|
||||
/// </summary>
|
||||
[JsonProperty("usSensitivityOccupied")]
|
||||
public ushort? UsSensitivityOccupied { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sensitivity level for US while sensor is in vacant state
|
||||
/// 1 = low; 2 = medium; 3 = high; 4 = xlow; 5 = 2xlow; 6 = 3xlow
|
||||
/// </summary>
|
||||
[JsonProperty("usSensitivityVacant")]
|
||||
public ushort? UsSensitivityVacant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sensitivity level for PIR while sensor is in occupied state
|
||||
/// 1 = low; 2 = medium; 3 = high
|
||||
/// </summary>
|
||||
[JsonProperty("pirSensitivityOccupied")]
|
||||
public ushort? PirSensitivityOccupied { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sensitivity level for PIR while sensor is in vacant state
|
||||
/// 1 = low; 2 = medium; 3 = high
|
||||
/// </summary>
|
||||
[JsonProperty("PirSensitivityVacant")]
|
||||
public ushort? PirSensitivityVacant { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,18 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects
|
||||
/// </summary>
|
||||
public class IOccupancyStatusProviderAggregator : Device, IOccupancyStatusProvider
|
||||
public class IOccupancyStatusProviderAggregator : EssentialsDevice, IOccupancyStatusProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Aggregated feedback of all linked IOccupancyStatusProvider devices
|
||||
@@ -21,16 +22,51 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
return AggregatedOccupancyStatus.Output;
|
||||
return _aggregatedOccupancyStatus.Output;
|
||||
}
|
||||
}
|
||||
|
||||
private BoolFeedbackOr AggregatedOccupancyStatus;
|
||||
private readonly BoolFeedbackOr _aggregatedOccupancyStatus;
|
||||
|
||||
public IOccupancyStatusProviderAggregator(string key, string 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>
|
||||
@@ -39,7 +75,35 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="statusProvider"></param>
|
||||
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
|
||||
{
|
||||
[Description("Wrapper class for GLS Cresnet Partition Sensor")]
|
||||
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice
|
||||
public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice, IPartitionStateProvider
|
||||
{
|
||||
private GlsPartCn _partitionSensor;
|
||||
|
||||
public StringFeedback NameFeedback { get; private set; }
|
||||
public BoolFeedback EnableFeedback { get; private set; }
|
||||
public BoolFeedback PartitionSensedFeedback { get; private set; }
|
||||
public BoolFeedback PartitionPresentFeedback { get; private set; }
|
||||
public BoolFeedback PartitionNotSensedFeedback { get; private set; }
|
||||
public IntFeedback SensitivityFeedback { get; private set; }
|
||||
|
||||
@@ -39,10 +39,10 @@ namespace PepperDash.Essentials.Core
|
||||
RegisterCrestronGenericBase(_partitionSensor);
|
||||
|
||||
NameFeedback = new StringFeedback(() => Name);
|
||||
EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue);
|
||||
PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||
PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||
SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue);
|
||||
EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue);
|
||||
PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||
PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||
SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue);
|
||||
|
||||
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
|
||||
});
|
||||
@@ -61,7 +61,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
case (GlsPartCn.PartitionSensedFeedbackEventId):
|
||||
{
|
||||
PartitionSensedFeedback.FireUpdate();
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case (GlsPartCn.PartitionNotSensedFeedbackEventId):
|
||||
@@ -93,6 +93,9 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestEnableFeedback = state;
|
||||
|
||||
EnableFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
|
||||
return;
|
||||
}
|
||||
@@ -105,6 +108,10 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestPartitionSensedFeedback = state;
|
||||
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
PartitionNotSensedFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
|
||||
return;
|
||||
}
|
||||
@@ -117,6 +124,8 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestSensitivityFeedback = value;
|
||||
|
||||
SensitivityFeedback.FireUpdate();
|
||||
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
|
||||
return;
|
||||
}
|
||||
@@ -126,6 +135,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public void SetEnableState(bool state)
|
||||
{
|
||||
Debug.Console(2, this, "Sensor is {0}, SetEnableState: {1}", _partitionSensor == null ? "null" : "not null", state);
|
||||
if (_partitionSensor == null)
|
||||
return;
|
||||
|
||||
@@ -134,6 +144,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public void IncreaseSensitivity()
|
||||
{
|
||||
Debug.Console(2, this, "Sensor is {0}, IncreaseSensitivity", _partitionSensor == null ? "null" : "not null");
|
||||
if (_partitionSensor == null)
|
||||
return;
|
||||
|
||||
@@ -142,6 +153,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public void DecreaseSensitivity()
|
||||
{
|
||||
Debug.Console(2, this, "Sensor is {0}, DecreaseSensitivity", _partitionSensor == null ? "null" : "not null");
|
||||
if (_partitionSensor == null)
|
||||
return;
|
||||
|
||||
@@ -150,6 +162,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public void SetSensitivity(ushort value)
|
||||
{
|
||||
Debug.Console(2, this, "Sensor is {0}, SetSensitivity: {1}", _partitionSensor == null ? "null" : "not null", value);
|
||||
if (_partitionSensor == null)
|
||||
return;
|
||||
|
||||
@@ -177,8 +190,7 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, this, "Linking to Bridge Type {0}", GetType().Name);
|
||||
|
||||
// link input from simpl
|
||||
trilist.SetSigTrueAction(joinMap.Enable.JoinNumber, () => SetEnableState(true));
|
||||
trilist.SetSigFalseAction(joinMap.Enable.JoinNumber, () => SetEnableState(false));
|
||||
trilist.SetBoolSigAction(joinMap.Enable.JoinNumber, SetEnableState);
|
||||
trilist.SetSigTrueAction(joinMap.IncreaseSensitivity.JoinNumber, IncreaseSensitivity);
|
||||
trilist.SetSigTrueAction(joinMap.DecreaseSensitivity.JoinNumber, DecreaseSensitivity);
|
||||
trilist.SetUShortSigAction(joinMap.Sensitivity.JoinNumber, SetSensitivity);
|
||||
@@ -186,7 +198,7 @@ namespace PepperDash.Essentials.Core
|
||||
// link output to simpl
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]);
|
||||
PartitionSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
|
||||
PartitionPresentFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]);
|
||||
PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]);
|
||||
SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]);
|
||||
|
||||
@@ -216,7 +228,7 @@ namespace PepperDash.Essentials.Core
|
||||
IsOnline.FireUpdate();
|
||||
NameFeedback.FireUpdate();
|
||||
EnableFeedback.FireUpdate();
|
||||
PartitionSensedFeedback.FireUpdate();
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
PartitionNotSensedFeedback.FireUpdate();
|
||||
SensitivityFeedback.FireUpdate();
|
||||
}
|
||||
@@ -257,7 +269,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
|
||||
Debug.Console(1, "Factory Attempting to create new GlsPartitionSensorController Device");
|
||||
|
||||
return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc);
|
||||
}
|
||||
|
||||
@@ -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\EssentialsConfig.cs" />
|
||||
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
|
||||
<Compile Include="Crestron IO\C2nIo\C2nIoController.cs" />
|
||||
<Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3CardControllerBase.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3Com3Controller.cs" />
|
||||
@@ -197,10 +198,12 @@
|
||||
<Compile Include="Devices\GenericIRController.cs" />
|
||||
<Compile Include="Devices\IDspPreset.cs" />
|
||||
<Compile Include="Devices\IProjectorInterfaces.cs" />
|
||||
<Compile Include="Devices\IReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\PC\InRoomPc.cs" />
|
||||
<Compile Include="Devices\PC\Laptop.cs" />
|
||||
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" />
|
||||
@@ -209,6 +212,7 @@
|
||||
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
|
||||
<Compile Include="Extensions\JsonExtensions.cs" />
|
||||
<Compile Include="Factory\DeviceFactory.cs" />
|
||||
<Compile Include="Factory\IDeviceFactory.cs" />
|
||||
<Compile Include="Factory\ReadyEventArgs.cs" />
|
||||
@@ -231,6 +235,9 @@
|
||||
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
|
||||
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
|
||||
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
|
||||
<Compile Include="PartitionSensor\EssentialsPartitionController.cs" />
|
||||
<Compile Include="PartitionSensor\IPartitionStateProvider.cs" />
|
||||
<Compile Include="Occupancy\OccupancyAggregatorConfig.cs" />
|
||||
<Compile Include="Queues\ComsMessage.cs" />
|
||||
<Compile Include="Queues\ProcessStringMessage.cs" />
|
||||
<Compile Include="Queues\GenericQueue.cs" />
|
||||
@@ -285,8 +292,13 @@
|
||||
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
|
||||
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
|
||||
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
|
||||
<Compile Include="Room\Combining\EssentialsRoomCombiner.cs" />
|
||||
<Compile Include="Room\Combining\EssentialsRoomCombinerPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Combining\IEssentialsRoomCombiner.cs" />
|
||||
<Compile Include="Room\Combining\RoomCombinationScenario.cs" />
|
||||
<Compile Include="Room\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
|
||||
<Compile Include="Room\IEssentialsRoom.cs" />
|
||||
<Compile Include="Room\Interfaces.cs" />
|
||||
<Compile Include="Room\iOccupancyStatusProvider.cs" />
|
||||
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
|
||||
@@ -320,6 +332,10 @@
|
||||
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
|
||||
<Compile Include="Routing\RoutingPortNames.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\ShadeBase.cs" />
|
||||
<Compile Include="Shades\ShadeController.cs" />
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tags>crestron 3series 4series</tags>
|
||||
<repository type="git" url="https://github.com/PepperDash/Essentials"/>
|
||||
<dependencies>
|
||||
<dependency id="PepperDashCore" version="[1.0.45, 1.1.0)"/>
|
||||
<dependency id="PepperDashCore" version="[1.0.45, 2.0.0)"/>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace PepperDash.Essentials
|
||||
/// <param name="fileName"></param>
|
||||
static LoadedAssembly LoadAssembly(string filePath)
|
||||
{
|
||||
Debug.Console(2, "Attempting to load {0}", filePath);
|
||||
//Debug.Console(2, "Attempting to load {0}", filePath);
|
||||
var assembly = Assembly.LoadFrom(filePath);
|
||||
if (assembly != null)
|
||||
{
|
||||
@@ -358,14 +358,27 @@ namespace PepperDash.Essentials
|
||||
try
|
||||
{
|
||||
var assy = loadedAssembly.Assembly;
|
||||
var types = assy.GetTypes();
|
||||
CType[] types = {};
|
||||
try
|
||||
{
|
||||
types = assy.GetTypes();
|
||||
}
|
||||
catch (TypeLoadException e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "Unable to get types for assembly {0}: {1}",
|
||||
loadedAssembly.Name, e.Message);
|
||||
Debug.Console(2, e.StackTrace);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (typeof(IPluginDeviceFactory).IsAssignableFrom(type))
|
||||
if (typeof (IPluginDeviceFactory).IsAssignableFrom(type) && !type.IsAbstract)
|
||||
{
|
||||
var plugin = (IPluginDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||
var plugin =
|
||||
(IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||
LoadCustomPlugin(plugin, loadedAssembly);
|
||||
}
|
||||
else
|
||||
@@ -378,6 +391,11 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
//this happens for dlls that aren't PD dlls, like ports of Mono classes into S#. Swallowing.
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Load Plugin not found. {0}.{2} is not a plugin factory. Exception: {1}",
|
||||
@@ -389,7 +407,9 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Error Loading Assembly: {0} Exception: {1} ", loadedAssembly.Name, e);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "Error Loading assembly {0}: {1}",
|
||||
loadedAssembly.Name, e.Message);
|
||||
Debug.Console(2, "{0}", e.StackTrace);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace PepperDash.Essentials.Core.Queues
|
||||
protected readonly CrestronQueue<IQueueMessage> _queue;
|
||||
protected readonly Thread _worker;
|
||||
protected readonly CEvent _waitHandle = new CEvent();
|
||||
|
||||
|
||||
private bool _delayEnabled;
|
||||
private int _delayTime;
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace PepperDash.Essentials.Core.Queues
|
||||
Dispose(true);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Thread callback
|
||||
/// </summary>
|
||||
@@ -180,7 +180,7 @@ namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString());
|
||||
//Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString());
|
||||
item.Dispatch();
|
||||
|
||||
if (_delayEnabled)
|
||||
@@ -231,8 +231,13 @@ namespace PepperDash.Essentials.Core.Queues
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Enqueue(null);
|
||||
_worker.Join();
|
||||
Debug.Console(2, this, "Disposing...");
|
||||
if (_queue != null && !_queue.Disposed)
|
||||
{
|
||||
_queue.Clear();
|
||||
Enqueue(null);
|
||||
}
|
||||
_worker.Abort();
|
||||
_waitHandle.Close();
|
||||
}
|
||||
|
||||
@@ -241,7 +246,7 @@ namespace PepperDash.Essentials.Core.Queues
|
||||
|
||||
~GenericQueue()
|
||||
{
|
||||
Dispose(false);
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -477,8 +482,13 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Enqueue(null);
|
||||
_worker.Join();
|
||||
Debug.Console(2, this, "Disposing...");
|
||||
if (_queue != null && !_queue.Disposed)
|
||||
{
|
||||
_queue.Clear();
|
||||
Enqueue(null);
|
||||
}
|
||||
_worker.Abort();
|
||||
_waitHandle.Close();
|
||||
}
|
||||
|
||||
@@ -487,7 +497,7 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
|
||||
~GenericQueue()
|
||||
{
|
||||
Dispose(false);
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
ScheduledEventGroup FeatureEventGroup;
|
||||
|
||||
public EssentialsRoomBase Room { get; private set; }
|
||||
public IEssentialsRoom Room { get; private set; }
|
||||
|
||||
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
void SetUpDevice()
|
||||
{
|
||||
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as EssentialsRoomBase;
|
||||
Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as IEssentialsRoom;
|
||||
|
||||
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>
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice, IEssentialsRoom
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the basic functionality of an EssentialsRoom
|
||||
/// </summary>
|
||||
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute
|
||||
{
|
||||
BoolFeedback OnFeedback { get; }
|
||||
|
||||
event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||
|
||||
BoolFeedback IsWarmingUpFeedback { get; }
|
||||
BoolFeedback IsCoolingDownFeedback { get; }
|
||||
|
||||
IOccupancyStatusProvider RoomOccupancy { get; }
|
||||
bool OccupancyStatusProviderIsRemote { get; }
|
||||
|
||||
bool IsMobileControlEnabled { get; }
|
||||
IMobileControlRoomBridge MobileControlRoomBridge { get; }
|
||||
|
||||
string SourceListKey { get; }
|
||||
|
||||
SecondsCountdownTimer ShutdownPromptTimer { get; }
|
||||
int ShutdownPromptSeconds { get; }
|
||||
int ShutdownVacancySeconds { get; }
|
||||
eShutdownType ShutdownType { get; }
|
||||
|
||||
EssentialsRoomEmergencyBase Emergency { get; }
|
||||
|
||||
Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; }
|
||||
|
||||
string LogoUrlLightBkgnd { get; }
|
||||
string LogoUrlDarkBkgnd { get; }
|
||||
|
||||
eVacancyMode VacancyMode { get; }
|
||||
|
||||
bool ZeroVolumeWhenSwtichingVolumeDevices { get; }
|
||||
|
||||
void StartShutdown(eShutdownType type);
|
||||
void StartRoomVacancyTimer(eVacancyMode mode);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes);
|
||||
|
||||
void PowerOnToDefaultOrLastSource();
|
||||
|
||||
void SetDefaultLevels();
|
||||
|
||||
void RoomVacatedForTimeoutPeriod(object o);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
@@ -64,5 +65,7 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
bool RunDefaultCallRoute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -123,25 +123,34 @@ namespace PepperDash.Essentials.Core
|
||||
// No direct tie? Run back out on the inputs' attached devices...
|
||||
// Only the ones that are routing devices
|
||||
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)
|
||||
{
|
||||
Debug.Console(2, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key);
|
||||
var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
|
||||
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
|
||||
if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice)))
|
||||
{
|
||||
// haven't seen this device yet. Do it. Pass the output port to the next
|
||||
// level to enable switching on success
|
||||
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
|
||||
alreadyCheckedDevices, signalType, cycle, routeTable);
|
||||
if (upstreamRoutingSuccess)
|
||||
{
|
||||
Debug.Console(2, destination, "Upstream device route found");
|
||||
goodInputPort = inputTieToTry.DestinationPort;
|
||||
break; // Stop looping the inputs in this cycle
|
||||
}
|
||||
}
|
||||
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
|
||||
// level to enable switching on success
|
||||
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
|
||||
alreadyCheckedDevices, signalType, cycle, routeTable);
|
||||
if (upstreamRoutingSuccess)
|
||||
{
|
||||
Debug.Console(2, destination, "Upstream device route found");
|
||||
goodInputPort = inputTieToTry.DestinationPort;
|
||||
break; // Stop looping the inputs in this cycle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,10 +172,6 @@ namespace PepperDash.Essentials.Core
|
||||
//Debug.Console(2, destination, "Exiting cycle {0}", cycle);
|
||||
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);
|
||||
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.DM.Config;
|
||||
|
||||
namespace PepperDash.Essentials.DM {
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
|
||||
///
|
||||
@@ -75,8 +76,10 @@ namespace PepperDash.Essentials.DM {
|
||||
/// Factory method to create a new chassis controller from config data. Limited to 8x8 right now
|
||||
/// </summary>
|
||||
public static DmBladeChassisController GetDmChassisController(string key, string name,
|
||||
string type, DMChassisPropertiesConfig properties) {
|
||||
try {
|
||||
string type, DMChassisPropertiesConfig properties)
|
||||
{
|
||||
try
|
||||
{
|
||||
type = type.ToLower();
|
||||
uint ipid = properties.Control.IpIdInt;
|
||||
|
||||
@@ -85,7 +88,8 @@ namespace PepperDash.Essentials.DM {
|
||||
else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); }
|
||||
|
||||
|
||||
if (chassis == null) {
|
||||
if (chassis == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -93,11 +97,13 @@ namespace PepperDash.Essentials.DM {
|
||||
// add the cards and port names
|
||||
foreach (var kvp in properties.InputSlots)
|
||||
controller.AddInputBlade(kvp.Value, kvp.Key);
|
||||
foreach (var kvp in properties.OutputSlots) {
|
||||
foreach (var kvp in properties.OutputSlots)
|
||||
{
|
||||
controller.AddOutputBlade(kvp.Value, kvp.Key);
|
||||
}
|
||||
|
||||
foreach (var kvp in properties.VolumeControls) {
|
||||
foreach (var kvp in properties.VolumeControls)
|
||||
{
|
||||
// get the card
|
||||
// check it for an audio-compatible type
|
||||
// make a something-something that will make it work
|
||||
@@ -123,7 +129,8 @@ namespace PepperDash.Essentials.DM {
|
||||
controller.PropertiesConfig = properties;
|
||||
return controller;
|
||||
}
|
||||
catch (System.Exception e) {
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.Console(0, "Error creating DM chassis:\r{0}", e);
|
||||
}
|
||||
return null;
|
||||
@@ -137,7 +144,8 @@ namespace PepperDash.Essentials.DM {
|
||||
/// <param name="name"></param>
|
||||
/// <param name="chassis"></param>
|
||||
public DmBladeChassisController(string key, string name, BladeSwitch chassis)
|
||||
: base(key, name, chassis) {
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
Chassis = chassis;
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
@@ -161,68 +169,87 @@ namespace PepperDash.Essentials.DM {
|
||||
InputCardHdcpCapabilityFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||
InputCardHdcpCapabilityTypes = new Dictionary<uint, eHdcpCapabilityType>();
|
||||
|
||||
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) {
|
||||
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
|
||||
{
|
||||
var tempX = x;
|
||||
|
||||
if (Chassis.Outputs[tempX] != null) {
|
||||
VideoOutputFeedbacks[tempX] = new IntFeedback(() => {
|
||||
if (Chassis.Outputs[tempX] != null)
|
||||
{
|
||||
VideoOutputFeedbacks[tempX] = new IntFeedback(() =>
|
||||
{
|
||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; }
|
||||
else { return 0; };
|
||||
});
|
||||
|
||||
OutputNameFeedbacks[tempX] = new StringFeedback(() => {
|
||||
if (Chassis.Outputs[tempX].NameFeedback != null) {
|
||||
OutputNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||
{
|
||||
if (Chassis.Outputs[tempX].NameFeedback != null)
|
||||
{
|
||||
return Chassis.Outputs[tempX].NameFeedback.StringValue;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => {
|
||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null) {
|
||||
OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||
{
|
||||
if (Chassis.Outputs[tempX].VideoOutFeedback != null)
|
||||
{
|
||||
return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
|
||||
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
|
||||
{
|
||||
//if (Chassis.Outputs[tempX].Endpoint != null)
|
||||
// return Chassis.Outputs[tempX].Endpoint.IsOnline;
|
||||
//else
|
||||
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
|
||||
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
|
||||
});
|
||||
}
|
||||
|
||||
if (Chassis.Inputs[tempX] != null) {
|
||||
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => {
|
||||
if (Chassis.Inputs[tempX] != null)
|
||||
{
|
||||
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() =>
|
||||
{
|
||||
if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; }
|
||||
else { return 0; };
|
||||
});
|
||||
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => {
|
||||
VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() =>
|
||||
{
|
||||
if (Chassis.Inputs[tempX].VideoDetectedFeedback != null)
|
||||
return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
InputNameFeedbacks[tempX] = new StringFeedback(() => {
|
||||
if (Chassis.Inputs[tempX].NameFeedback != null) {
|
||||
InputNameFeedbacks[tempX] = new StringFeedback(() =>
|
||||
{
|
||||
if (Chassis.Inputs[tempX].NameFeedback != null)
|
||||
{
|
||||
return Chassis.Inputs[tempX].NameFeedback.StringValue;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => {
|
||||
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
|
||||
{
|
||||
return Chassis.Inputs[tempX].EndpointOnlineFeedback;
|
||||
});
|
||||
|
||||
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => {
|
||||
InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() =>
|
||||
{
|
||||
var inputCard = Chassis.Inputs[tempX];
|
||||
|
||||
if (inputCard.Card is DmHdmi4kInputBladeCard) {
|
||||
if (inputCard.Card is DmHdmi4kInputBladeCard)
|
||||
{
|
||||
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue)
|
||||
@@ -231,7 +258,8 @@ namespace PepperDash.Essentials.DM {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inputCard.Card is DmC4kInputBladeCard) {
|
||||
if (inputCard.Card is DmC4kInputBladeCard)
|
||||
{
|
||||
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff))
|
||||
@@ -252,45 +280,56 @@ namespace PepperDash.Essentials.DM {
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="number"></param>
|
||||
public void AddInputBlade(string type, uint number) {
|
||||
public void AddInputBlade(string type, uint number)
|
||||
{
|
||||
Debug.Console(2, this, "Adding input blade '{0}', slot {1}", type, number);
|
||||
|
||||
type = type.ToLower();
|
||||
|
||||
if (type == "dmb4kihd") {
|
||||
if (type == "dmb4kihd")
|
||||
{
|
||||
var inputBlade = new Dmb4kIHd(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
|
||||
var cecPort = card as ICec;
|
||||
AddHdmiInBladePorts(item.Number, cecPort);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4kihddnt") {
|
||||
else if (type == "dmb4kihddnt")
|
||||
{
|
||||
var inputBlade = new Dmb4kIHd(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput;
|
||||
var cecPort = card as ICec;
|
||||
AddHdmiInBladePorts(item.Number, cecPort);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4kic") {
|
||||
else if (type == "dmb4kic")
|
||||
{
|
||||
var inputBlade = new Dmb4kIC(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
AddDmInBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmbis") {
|
||||
else if (type == "dmbis")
|
||||
{
|
||||
var inputBlade = new DmbIS(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
AddDmInMmFiberPorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmbis2") {
|
||||
else if (type == "dmbis2")
|
||||
{
|
||||
var inputBlade = new DmbIS2(number, this.Chassis);
|
||||
foreach (var item in inputBlade.Inputs) {
|
||||
foreach (var item in inputBlade.Inputs)
|
||||
{
|
||||
AddDmInSmFiberPorts(item.Number);
|
||||
}
|
||||
}
|
||||
@@ -304,22 +343,26 @@ namespace PepperDash.Essentials.DM {
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AddHdmiInBladePorts(uint number, ICec cecPort) {
|
||||
void AddHdmiInBladePorts(uint number, ICec cecPort)
|
||||
{
|
||||
AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort);
|
||||
}
|
||||
|
||||
void AddDmInBladePorts(uint number) {
|
||||
void AddDmInBladePorts(uint number)
|
||||
{
|
||||
AddInputPortWithDebug(number, "dmCIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat);
|
||||
}
|
||||
|
||||
void AddDmInMmFiberPorts(uint number) {
|
||||
void AddDmInMmFiberPorts(uint number)
|
||||
{
|
||||
AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
|
||||
}
|
||||
|
||||
void AddDmInSmFiberPorts(uint number) {
|
||||
void AddDmInSmFiberPorts(uint number)
|
||||
{
|
||||
AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
|
||||
}
|
||||
|
||||
@@ -328,64 +371,81 @@ namespace PepperDash.Essentials.DM {
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="number"></param>
|
||||
public void AddOutputBlade(string type, uint number) {
|
||||
public void AddOutputBlade(string type, uint number)
|
||||
{
|
||||
type = type.ToLower();
|
||||
|
||||
Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number);
|
||||
if (type == "dmb4kohd") {
|
||||
if (type == "dmb4kohd")
|
||||
{
|
||||
var outputBlade = new Dmb4KOHD(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddHdmiOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4kohddnt") {
|
||||
else if (type == "dmb4kohddnt")
|
||||
{
|
||||
var outputBlade = new Dmb4KOHD(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddHdmiOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "dmb4koc") {
|
||||
else if (type == "dmb4koc")
|
||||
{
|
||||
var outputBlade = new Dmb4KOC(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmb4koc") {
|
||||
else if (type == "dmb4koc")
|
||||
{
|
||||
var outputBlade = new Dmb4KOC(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmbos") {
|
||||
else if (type == "dmbos")
|
||||
{
|
||||
var outputBlade = new DmbOS(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutMmFiberBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
else if (type == "dmbos2") {
|
||||
else if (type == "dmbos2")
|
||||
{
|
||||
var outputBlade = new DmbOS2(number, Chassis);
|
||||
foreach (var item in outputBlade.Outputs) {
|
||||
foreach (var item in outputBlade.Outputs)
|
||||
{
|
||||
AddDmOutSmFiberBladePorts(item.Number);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddHdmiOutBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
|
||||
void AddHdmiOutBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "hdmiOut", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
|
||||
void AddDmOutBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "dmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutMmFiberBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
|
||||
void AddDmOutMmFiberBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "dmMmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutSmFiberBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
|
||||
void AddDmOutSmFiberBladePorts(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, "dmSmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
|
||||
@@ -417,23 +477,44 @@ namespace PepperDash.Essentials.DM {
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds OutputPort
|
||||
/// </summary>
|
||||
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
|
||||
|
||||
/*void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
|
||||
var portKey = string.Format("{0}--{1}", cardName, portName);
|
||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||
{
|
||||
FeedbackMatchObject = Chassis.Outputs[(uint)selector]
|
||||
});
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Adds OutputPort
|
||||
/// </summary>
|
||||
void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
|
||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||
{
|
||||
FeedbackMatchObject = Chassis.Outputs[cardNum]
|
||||
};
|
||||
OutputPorts.Add(outputPort);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, "Exception : {0}", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void AddVolumeControl(uint number, Audio.Output audio) {
|
||||
void AddVolumeControl(uint number, Audio.Output audio)
|
||||
{
|
||||
VolumeControls.Add(number, new DmCardAudioOutputController(audio));
|
||||
}
|
||||
|
||||
@@ -443,35 +524,43 @@ namespace PepperDash.Essentials.DM {
|
||||
//}
|
||||
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args) {
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
|
||||
switch (args.EventId) {
|
||||
case DMInputEventIds.EndpointOnlineEventId: {
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMInputEventIds.EndpointOnlineEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.OnlineFeedbackEventId: {
|
||||
case DMInputEventIds.OnlineFeedbackEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.VideoDetectedEventId: {
|
||||
case DMInputEventIds.VideoDetectedEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
|
||||
VideoInputSyncFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.InputNameEventId: {
|
||||
case DMInputEventIds.InputNameEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
|
||||
InputNameFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.HdcpCapabilityFeedbackEventId: {
|
||||
case DMInputEventIds.HdcpCapabilityFeedbackEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number);
|
||||
InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
{
|
||||
Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
@@ -487,74 +576,74 @@ namespace PepperDash.Essentials.DM {
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMOutputEventIds.VolumeEventId:
|
||||
{
|
||||
if (VolumeControls.ContainsKey(output))
|
||||
{
|
||||
VolumeControls[args.Number].VolumeEventFromChassis();
|
||||
if (VolumeControls.ContainsKey(output))
|
||||
{
|
||||
VolumeControls[args.Number].VolumeEventFromChassis();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.EndpointOnlineEventId:
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
if (Chassis.Outputs[output].Endpoint != null)
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
|
||||
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
if (Chassis.Outputs[output].Endpoint != null)
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
|
||||
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
|
||||
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.OnlineFeedbackEventId:
|
||||
{
|
||||
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
{
|
||||
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
OutputEndpointOnlineFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.VideoOutEventId:
|
||||
{
|
||||
|
||||
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
|
||||
|
||||
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
|
||||
inputNumber, output);
|
||||
|
||||
if (VideoOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
|
||||
|
||||
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
|
||||
|
||||
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
|
||||
inputNumber, output);
|
||||
|
||||
if (VideoOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]);
|
||||
|
||||
|
||||
VideoOutputFeedbacks[output].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(output,
|
||||
inputNumber,
|
||||
localOutputPort,
|
||||
localInputPort,
|
||||
eRoutingSignalType.AudioVideo));
|
||||
VideoOutputFeedbacks[output].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(output,
|
||||
inputNumber,
|
||||
localOutputPort,
|
||||
localInputPort,
|
||||
eRoutingSignalType.AudioVideo));
|
||||
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[output].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[output].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.OutputNameEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
|
||||
OutputNameFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
{
|
||||
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
|
||||
OutputNameFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
|
||||
args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
{
|
||||
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
|
||||
args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -564,7 +653,8 @@ namespace PepperDash.Essentials.DM {
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pnt"></param>
|
||||
void StartOffTimer(PortNumberType pnt) {
|
||||
void StartOffTimer(PortNumberType pnt)
|
||||
{
|
||||
if (RouteOffTimers.ContainsKey(pnt))
|
||||
return;
|
||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime);
|
||||
@@ -572,8 +662,10 @@ namespace PepperDash.Essentials.DM {
|
||||
|
||||
|
||||
// Send out sigs when coming online
|
||||
void IsOnline_OutputChange(object sender, EventArgs e) {
|
||||
if (IsOnline.BoolValue) {
|
||||
void IsOnline_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (IsOnline.BoolValue)
|
||||
{
|
||||
Chassis.EnableUSBBreakaway.BoolValue = true;
|
||||
|
||||
if (InputNames != null)
|
||||
@@ -587,12 +679,13 @@ namespace PepperDash.Essentials.DM {
|
||||
|
||||
#region IRouting Members
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) {
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType);
|
||||
|
||||
var input = inputSelector as DMInput; // Cast can sometimes fail
|
||||
var output = outputSelector as DMOutput;
|
||||
|
||||
|
||||
|
||||
if (output == null)
|
||||
{
|
||||
@@ -605,11 +698,14 @@ namespace PepperDash.Essentials.DM {
|
||||
// Check to see if there's an off timer waiting on this and if so, cancel
|
||||
var key = new PortNumberType(output, sigType);
|
||||
|
||||
if (input == null) {
|
||||
if (input == null)
|
||||
{
|
||||
StartOffTimer(key);
|
||||
}
|
||||
else {
|
||||
if (RouteOffTimers.ContainsKey(key)) {
|
||||
else
|
||||
{
|
||||
if (RouteOffTimers.ContainsKey(key))
|
||||
{
|
||||
Debug.Console(2, this, "{0} cancelling route off due to new source", output);
|
||||
RouteOffTimers[key].Stop();
|
||||
RouteOffTimers.Remove(key);
|
||||
@@ -671,7 +767,7 @@ namespace PepperDash.Essentials.DM {
|
||||
var ioSlotJoin = ioSlot - 1;
|
||||
|
||||
// Control
|
||||
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video));
|
||||
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort)ioSlot, eRoutingSignalType.Video));
|
||||
|
||||
if (TxDictionary.ContainsKey(ioSlot))
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,9 +25,16 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
public CrestronControlSystem Dmps { get; set; }
|
||||
public ISystemControl SystemControl { get; private set; }
|
||||
|
||||
//Check if DMPS is a DMPS3-4K type for endpoint creation
|
||||
public bool Dmps4kType { get; private set; }
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
//Feedback for DMPS System Power
|
||||
public BoolFeedback SystemPowerOnFeedback { get; private set; }
|
||||
public BoolFeedback SystemPowerOffFeedback { get; private set; }
|
||||
|
||||
// Feedbacks for EssentialDM
|
||||
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
|
||||
@@ -112,10 +119,29 @@ namespace PepperDash.Essentials.DM
|
||||
/// <param name="chassis"></param>
|
||||
public DmpsRoutingController(string key, string name, ISystemControl systemControl)
|
||||
: base(key, name)
|
||||
{
|
||||
|
||||
{
|
||||
Dmps = Global.ControlSystem;
|
||||
SystemControl = systemControl;
|
||||
|
||||
switch (name.Replace("-", "").Replace("c", "").Replace("C", ""))
|
||||
{
|
||||
case "dmps34k50":
|
||||
case "dmps34k100":
|
||||
case "dmps34k150":
|
||||
SystemControl = systemControl as Dmps34K150CSystemControl;
|
||||
Dmps4kType = true;
|
||||
break;
|
||||
case "dmps34k200":
|
||||
case "dmps34k250":
|
||||
case "dmps34k300":
|
||||
case "dmps34k350":
|
||||
SystemControl = systemControl as Dmps34K300CSystemControl;
|
||||
Dmps4kType = true;
|
||||
break;
|
||||
default:
|
||||
SystemControl = systemControl as Dmps3SystemControl;
|
||||
Dmps4kType = false;
|
||||
break;
|
||||
}
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
@@ -123,6 +149,29 @@ namespace PepperDash.Essentials.DM
|
||||
TxDictionary = new Dictionary<uint, string>();
|
||||
RxDictionary = new Dictionary<uint, string>();
|
||||
|
||||
SystemPowerOnFeedback = new BoolFeedback(() =>
|
||||
{
|
||||
if (SystemControl is Dmps3SystemControl)
|
||||
{
|
||||
return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
SystemPowerOffFeedback = new BoolFeedback(() =>
|
||||
{
|
||||
if (SystemControl is Dmps3SystemControl)
|
||||
{
|
||||
return ((Dmps3SystemControl)SystemControl).SystemPowerOffFeedBack.BoolValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
VideoOutputFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||
AudioOutputFeedbacks = new Dictionary<uint, IntFeedback>();
|
||||
VideoInputSyncFeedbacks = new Dictionary<uint, BoolFeedback>();
|
||||
@@ -154,6 +203,7 @@ namespace PepperDash.Essentials.DM
|
||||
// Subscribe to events
|
||||
Dmps.DMInputChange += Dmps_DMInputChange;
|
||||
Dmps.DMOutputChange += Dmps_DMOutputChange;
|
||||
Dmps.DMSystemChange += Dmps_DMSystemChange;
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
@@ -191,6 +241,22 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPowerOn(bool a)
|
||||
{
|
||||
if (SystemControl is Dmps3SystemControl)
|
||||
{
|
||||
((Dmps3SystemControl)SystemControl).SystemPowerOn();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPowerOff(bool a)
|
||||
{
|
||||
if (SystemControl is Dmps3SystemControl)
|
||||
{
|
||||
((Dmps3SystemControl)SystemControl).SystemPowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new DmpsRoutingControllerJoinMap(joinStart);
|
||||
@@ -211,9 +277,22 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
//Link up system
|
||||
trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, SetPowerOn);
|
||||
trilist.SetBoolSigAction(joinMap.SystemPowerOff.JoinNumber, SetPowerOff);
|
||||
if (SystemPowerOnFeedback != null)
|
||||
{
|
||||
SystemPowerOnFeedback.LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.SystemPowerOn.JoinNumber]);
|
||||
}
|
||||
if (SystemPowerOffFeedback != null)
|
||||
{
|
||||
SystemPowerOffFeedback.LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.SystemPowerOff.JoinNumber]);
|
||||
}
|
||||
|
||||
// Link up outputs
|
||||
LinkInputsToApi(trilist, joinMap);
|
||||
|
||||
LinkOutputsToApi(trilist, joinMap);
|
||||
}
|
||||
|
||||
@@ -719,28 +798,36 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
void Dmps_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
//Debug.Console(2, this, "DMSwitch:{0} Input:{1} Event:{2}'", this.Name, args.Number, args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
try
|
||||
{
|
||||
case (DMInputEventIds.OnlineFeedbackEventId):
|
||||
{
|
||||
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case (DMInputEventIds.VideoDetectedEventId):
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
|
||||
VideoInputSyncFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case (DMInputEventIds.InputNameEventId):
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
|
||||
InputNameFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
switch (args.EventId)
|
||||
{
|
||||
case (DMInputEventIds.OnlineFeedbackEventId):
|
||||
{
|
||||
Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
|
||||
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case (DMInputEventIds.VideoDetectedEventId):
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
|
||||
VideoInputSyncFeedbacks[args.Number].FireUpdate();
|
||||
break;
|
||||
}
|
||||
case (DMInputEventIds.InputNameEventId):
|
||||
{
|
||||
Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number);
|
||||
if(InputNameFeedbacks.ContainsKey(args.Number))
|
||||
{
|
||||
InputNameFeedbacks[args.Number].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "DMSwitch Input Change:{0} Input:{1} Event:{2}\rException: {3}", this.Name, args.Number, args.EventId.ToString(), e.ToString());
|
||||
}
|
||||
}
|
||||
void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
@@ -812,6 +899,23 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
}
|
||||
|
||||
void Dmps_DMSystemChange(Switch device, DMSystemEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMSystemEventIds.SystemPowerOnEventId:
|
||||
{
|
||||
SystemPowerOnFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case DMSystemEventIds.SystemPowerOffEventId:
|
||||
{
|
||||
SystemPowerOffFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -879,7 +983,6 @@ namespace PepperDash.Essentials.DM
|
||||
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
|
||||
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
{
|
||||
|
||||
output.VideoOut = input;
|
||||
}
|
||||
|
||||
@@ -903,7 +1006,6 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
|
||||
{
|
||||
|
||||
output.USBRoutedTo = input;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
@@ -15,421 +16,489 @@ using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.DM.Chassis
|
||||
{
|
||||
[Description("Wrapper class for all HdMdNxM4E switchers")]
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
|
||||
{
|
||||
private HdMdNxM _Chassis;
|
||||
private HdMd4x14kE _Chassis4x1;
|
||||
[Description("Wrapper class for all HdMdNxM4E switchers")]
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
|
||||
{
|
||||
private HdMdNxM _Chassis;
|
||||
private HdMd4x14kE _Chassis4x1;
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
public Dictionary<uint, string> InputNames { get; set; }
|
||||
public Dictionary<uint, string> OutputNames { get; set; }
|
||||
public Dictionary<uint, string> InputNames { get; set; }
|
||||
public Dictionary<uint, string> OutputNames { get; set; }
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
|
||||
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputRouteNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> InputHdcpEnableFeedback { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> DeviceNameFeedback { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> AutoRouteFeedback { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
|
||||
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<StringFeedback> OutputRouteNameFeedbacks { get; private set; }
|
||||
public FeedbackCollection<BoolFeedback> InputHdcpEnableFeedback { get; private set; }
|
||||
public StringFeedback DeviceNameFeedback { get; private set; }
|
||||
public BoolFeedback AutoRouteFeedback { get; private set; }
|
||||
|
||||
#region Constructor
|
||||
#region Constructor
|
||||
|
||||
public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis,
|
||||
HdMdNxM4kEBridgeablePropertiesConfig props)
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
_Chassis = chassis;
|
||||
var _props = props;
|
||||
public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis,
|
||||
HdMdNxM4kEBridgeablePropertiesConfig props)
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
_Chassis = chassis;
|
||||
Name = name;
|
||||
|
||||
InputNames = props.Inputs;
|
||||
OutputNames = props.Outputs;
|
||||
if (props == null)
|
||||
{
|
||||
Debug.Console(1, this, "HdMdNx4keBridgeableController properties are null, failed to build the device");
|
||||
return;
|
||||
}
|
||||
|
||||
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
|
||||
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
|
||||
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
InputHdcpEnableFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
DeviceNameFeedback = new FeedbackCollection<StringFeedback>();
|
||||
AutoRouteFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
if (props.Inputs != null)
|
||||
{
|
||||
foreach (var kvp in props.Inputs)
|
||||
{
|
||||
Debug.Console(1, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
InputNames = props.Inputs;
|
||||
}
|
||||
if (props.Outputs != null)
|
||||
{
|
||||
foreach (var kvp in props.Outputs)
|
||||
{
|
||||
Debug.Console(1, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
OutputNames = props.Outputs;
|
||||
}
|
||||
|
||||
DeviceNameFeedback.Add(new StringFeedback(this.Name, () => this.Name));
|
||||
DeviceNameFeedback = new StringFeedback(()=>Name);
|
||||
|
||||
if (_Chassis.NumberOfInputs == 1)
|
||||
{
|
||||
_Chassis4x1 = _Chassis as HdMd4x14kE;
|
||||
AutoRouteFeedback.Add(new BoolFeedback(this.Name + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue));
|
||||
}
|
||||
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
|
||||
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
|
||||
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
OutputRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
|
||||
InputHdcpEnableFeedback = new FeedbackCollection<BoolFeedback>();
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var inputName = InputNames[index];
|
||||
_Chassis.Inputs[index].Name.StringValue = inputName;
|
||||
if (_Chassis.NumberOfInputs == 1)
|
||||
{
|
||||
_Chassis4x1 = _Chassis as HdMd4x14kE;
|
||||
AutoRouteFeedback = new BoolFeedback(() => _Chassis4x1.AutoModeOnFeedback.BoolValue);
|
||||
}
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiInputs[index]
|
||||
});
|
||||
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
|
||||
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue));
|
||||
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var inputName = InputNames[index];
|
||||
//_Chassis.Inputs[index].Name.StringValue = inputName;
|
||||
_Chassis.HdmiInputs[index].Name.StringValue = inputName;
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var outputName = OutputNames[index];
|
||||
_Chassis.Outputs[i].Name.StringValue = outputName;
|
||||
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, _Chassis.HdmiInputs[index], this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiInputs[index]
|
||||
});
|
||||
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
|
||||
//InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].NameFeedback.StringValue));
|
||||
InputNameFeedbacks.Add(new StringFeedback(inputName, () => InputNames[index]));
|
||||
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
|
||||
}
|
||||
|
||||
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
|
||||
});
|
||||
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
|
||||
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue));
|
||||
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var index = i;
|
||||
var outputName = OutputNames[index];
|
||||
//_Chassis.Outputs[index].Name.StringValue = outputName;
|
||||
//_Chassis.HdmiOutputs[index].Name.StringValue = outputName;
|
||||
|
||||
_Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange);
|
||||
_Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange);
|
||||
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, _Chassis.HdmiOutputs[index], this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
|
||||
});
|
||||
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
|
||||
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => OutputNames[index]));
|
||||
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
|
||||
}
|
||||
|
||||
AddPostActivationAction(AddFeedbackCollections);
|
||||
}
|
||||
_Chassis.DMInputChange += Chassis_DMInputChange;
|
||||
_Chassis.DMOutputChange += Chassis_DMOutputChange;
|
||||
|
||||
#endregion
|
||||
AddPostActivationAction(AddFeedbackCollections);
|
||||
}
|
||||
|
||||
#region Methods
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
#region Methods
|
||||
|
||||
public void EnableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
public void EnableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
|
||||
public void DisableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
public void DisableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
if (port <= 0) return;
|
||||
|
||||
public void EnableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff();
|
||||
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
|
||||
}
|
||||
|
||||
if (_Chassis4x1 == null) return;
|
||||
public void EnableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
|
||||
_Chassis4x1.AutoModeOn();
|
||||
}
|
||||
if (_Chassis4x1 == null) return;
|
||||
|
||||
public void DisableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
_Chassis4x1.AutoModeOn();
|
||||
}
|
||||
|
||||
if (_Chassis4x1 == null) return;
|
||||
public void DisableAutoRoute()
|
||||
{
|
||||
if (_Chassis.NumberOfInputs != 1) return;
|
||||
|
||||
_Chassis4x1.AutoModeOff();
|
||||
}
|
||||
if (_Chassis4x1 == null) return;
|
||||
|
||||
#region PostActivate
|
||||
_Chassis4x1.AutoModeOff();
|
||||
}
|
||||
|
||||
public void AddFeedbackCollections()
|
||||
{
|
||||
AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback);
|
||||
AddCollectionsToList(VideoOutputRouteFeedbacks);
|
||||
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback);
|
||||
}
|
||||
#region PostActivate
|
||||
|
||||
#endregion
|
||||
public void AddFeedbackCollections()
|
||||
{
|
||||
AddFeedbackToList(DeviceNameFeedback);
|
||||
AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback);
|
||||
AddCollectionsToList(VideoOutputRouteFeedbacks);
|
||||
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks);
|
||||
}
|
||||
|
||||
#region FeedbackCollection Methods
|
||||
#endregion
|
||||
|
||||
//Add arrays of collections
|
||||
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region FeedbackCollection Methods
|
||||
|
||||
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Add arrays of collections
|
||||
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add Collections
|
||||
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
|
||||
{
|
||||
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
|
||||
{
|
||||
foreach (var item in newFbs)
|
||||
{
|
||||
AddCollectionToList(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
//Add Collections
|
||||
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
|
||||
{
|
||||
foreach (var f in newFbs)
|
||||
{
|
||||
if (f == null) continue;
|
||||
|
||||
//Add Individual Feedbacks
|
||||
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
|
||||
{
|
||||
if (newFb == null) return;
|
||||
AddFeedbackToList(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Feedbacks.Contains(newFb))
|
||||
{
|
||||
Feedbacks.Add(newFb);
|
||||
}
|
||||
}
|
||||
//Add Individual Feedbacks
|
||||
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
|
||||
{
|
||||
if (newFb == null) return;
|
||||
|
||||
#endregion
|
||||
if (!Feedbacks.Contains(newFb))
|
||||
{
|
||||
Feedbacks.Add(newFb);
|
||||
}
|
||||
}
|
||||
|
||||
#region IRouting Members
|
||||
#endregion
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
// Try to make switch only when necessary. The unit appears to toggle when already selected.
|
||||
var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut;
|
||||
if (current != _Chassis.HdmiInputs[(uint)inputSelector])
|
||||
_Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector];
|
||||
}
|
||||
#region IRouting Members
|
||||
|
||||
#endregion
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
var input = inputSelector as HdMdNxMHdmiInput; //changed from HdMdNxM4kzEHdmiInput;
|
||||
var output = outputSelector as HdMdNxMHdmiOutput;
|
||||
Debug.Console(2, this, "ExecuteSwitch: input={0} output={1}", input, output);
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
if (output == null)
|
||||
{
|
||||
Debug.Console(0, this, "Unable to make switch. output selector is not HdMdNxMHdmiOutput");
|
||||
return;
|
||||
}
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, signalType);
|
||||
}
|
||||
// Try to make switch only when necessary. The unit appears to toggle when already selected.
|
||||
var current = output.VideoOut;
|
||||
if (current != input)
|
||||
output.VideoOut = input;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
#region Bridge Linking
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
var input = inputSelector == 0 ? null : _Chassis.HdmiInputs[inputSelector];
|
||||
var output = _Chassis.HdmiOutputs[outputSelector];
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart);
|
||||
Debug.Console(2, this, "ExecuteNumericSwitch: input={0} output={1}", input, output);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
ExecuteSwitch(input, output, signalType);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(joinMapSerialized);
|
||||
#endregion
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
DeviceNameFeedback.LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
|
||||
|
||||
if (_Chassis4x1 != null)
|
||||
{
|
||||
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
|
||||
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
|
||||
AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
var input = i;
|
||||
//Digital
|
||||
VideoInputSyncFeedbacks[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[input]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]);
|
||||
trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(input));
|
||||
trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(input));
|
||||
|
||||
//Serial
|
||||
InputNameFeedbacks[InputNames[input]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
var output = i;
|
||||
//Analog
|
||||
VideoOutputRouteFeedbacks[OutputNames[output]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]);
|
||||
trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo));
|
||||
|
||||
//Serial
|
||||
OutputNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]);
|
||||
OutputRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]);
|
||||
}
|
||||
|
||||
_Chassis.OnlineStatusChange += Chassis_OnlineStatusChange;
|
||||
|
||||
trilist.OnlineStatusChange += (d, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
// feedback updates was moved to the Chassis_OnlineStatusChange
|
||||
// due to the amount of time it takes for the device to come online
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
|
||||
{
|
||||
IsOnline.FireUpdate();
|
||||
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (_Chassis4x1 != null)
|
||||
{
|
||||
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
|
||||
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
|
||||
AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
|
||||
}
|
||||
AutoRouteFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
//Digital
|
||||
VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]);
|
||||
InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]);
|
||||
trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i));
|
||||
trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i));
|
||||
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
|
||||
|
||||
//Serial
|
||||
InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]);
|
||||
}
|
||||
var output = args.Number;
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var joinIndex = i - 1;
|
||||
//Analog
|
||||
VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]);
|
||||
trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo));
|
||||
var inputNumber = _Chassis.HdmiOutputs[output].VideoOutFeedback == null
|
||||
? 0
|
||||
: _Chassis.HdmiOutputs[output].VideoOutFeedback.Number;
|
||||
|
||||
//Serial
|
||||
OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]);
|
||||
OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]);
|
||||
}
|
||||
var outputName = OutputNames[output];
|
||||
|
||||
_Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange);
|
||||
var feedback = VideoOutputRouteFeedbacks[outputName];
|
||||
|
||||
trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
{
|
||||
foreach (var feedback in Feedbacks)
|
||||
if (feedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var inPort =
|
||||
InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output].VideoOutFeedback);
|
||||
var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output]);
|
||||
|
||||
feedback.FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMInputEventIds.VideoDetectedEventId:
|
||||
{
|
||||
Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", args.EventId);
|
||||
foreach (var item in VideoInputSyncFeedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
item.FireUpdate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMInputEventIds.InputNameFeedbackEventId:
|
||||
case DMInputEventIds.InputNameEventId:
|
||||
case DMInputEventIds.NameFeedbackEventId:
|
||||
{
|
||||
Debug.Console(1, this, "Event ID {0}: Updating name feedbacks.", args.EventId);
|
||||
Debug.Console(1, this, "Input {0} Name {1}", args.Number,
|
||||
_Chassis.HdmiInputs[args.Number].NameFeedback.StringValue);
|
||||
foreach (var item in InputNameFeedbacks)
|
||||
{
|
||||
item.FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(1, this, "Unhandled DM Input Event ID {0}", args.EventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory
|
||||
|
||||
public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory<HdMdNxM4kEBridgeableController>
|
||||
{
|
||||
public HdMdNxM4kEControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<HdMdNxM4kEBridgeablePropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
var type = dc.Type.ToLower();
|
||||
var control = props.Control;
|
||||
var ipid = control.IpIdInt;
|
||||
var address = control.TcpSshProperties.Address;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ("hdmd4x14ke-bridgeable"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd4x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd6x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
_Chassis.Inputs[i].Name.StringValue = InputNames[i];
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
|
||||
|
||||
for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++)
|
||||
{
|
||||
var index = i;
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]);
|
||||
|
||||
|
||||
VideoOutputRouteFeedbacks[i].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
if (args.EventId != DMInputEventIds.VideoDetectedEventId) return;
|
||||
foreach (var item in VideoInputSyncFeedbacks)
|
||||
{
|
||||
item.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory
|
||||
|
||||
public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory<HdMdNxM4kEBridgeableController>
|
||||
{
|
||||
public HdMdNxM4kEControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<HdMdNxM4kEBridgeablePropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
var type = dc.Type.ToLower();
|
||||
var control = props.Control;
|
||||
var ipid = control.IpIdInt;
|
||||
var address = control.TcpSshProperties.Address;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ("hdmd4x14ke-bridgeable"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd4x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props);
|
||||
case ("hdmd6x24ke"):
|
||||
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Newtonsoft.Json;
|
||||
@@ -13,6 +14,7 @@ using PepperDash.Essentials.DM.Config;
|
||||
|
||||
namespace PepperDash.Essentials.DM.Chassis
|
||||
{
|
||||
[Obsolete("Please use HdMdNxM4kEBridgeable Controller")]
|
||||
public class HdMdNxM4kEController : CrestronGenericBaseDevice, IRoutingInputsOutputs, IRouting
|
||||
{
|
||||
public HdMdNxM Chassis { get; private set; }
|
||||
@@ -31,6 +33,7 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
HdMdNxM4kEPropertiesConfig props)
|
||||
: base(key, name, chassis)
|
||||
{
|
||||
Debug.Console(0, this, "Type hdmd4x14ke is obsolete. Please use hdmd4x14ke-bridgeable");
|
||||
Chassis = chassis;
|
||||
|
||||
// logical ports
|
||||
@@ -43,14 +46,19 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this));
|
||||
|
||||
|
||||
// physical settings
|
||||
if (props != null && props.Inputs != null)
|
||||
{
|
||||
var inputRegex = new Regex(@"(?<InputNum>\d)", RegexOptions.IgnoreCase);
|
||||
foreach (var kvp in props.Inputs)
|
||||
{
|
||||
// strip "hdmiIn"
|
||||
var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
|
||||
// get numnbers from key and convert to int
|
||||
//var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
|
||||
var inputMatch = inputRegex.Match(kvp.Key);
|
||||
if (inputMatch == null) continue;
|
||||
|
||||
var inputNum = Convert.ToUInt32(inputMatch.Groups["InputNum"].Value);
|
||||
|
||||
var port = chassis.HdmiInputs[inputNum].HdmiInputPort;
|
||||
// set hdcp disables
|
||||
|
||||
@@ -329,7 +329,14 @@ namespace PepperDash.Essentials.DM
|
||||
var parentDev = DeviceManager.GetDeviceForKey(pKey);
|
||||
if (parentDev is DmpsRoutingController)
|
||||
{
|
||||
return GetDmRmcControllerForDmps(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber);
|
||||
if ((parentDev as DmpsRoutingController).Dmps4kType)
|
||||
{
|
||||
return GetDmRmcControllerForDmps4k(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetDmRmcControllerForDmps(key, name, typeName, ipid, parentDev as DmpsRoutingController, props.ParentOutputNumber);
|
||||
}
|
||||
}
|
||||
if (!(parentDev is IDmSwitch))
|
||||
{
|
||||
@@ -395,25 +402,47 @@ namespace PepperDash.Essentials.DM
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName,
|
||||
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName,
|
||||
uint ipid, DmpsRoutingController controller, uint num)
|
||||
{
|
||||
Func<string, string, uint, DMOutput, CrestronGenericBaseDevice> dmpsHandler;
|
||||
if (ChassisDict.TryGetValue(typeName.ToLower(), out dmpsHandler))
|
||||
{
|
||||
var output = controller.Dmps.SwitcherOutputs[num] as DMOutput;
|
||||
|
||||
if (output != null)
|
||||
{
|
||||
return dmpsHandler(key, name, ipid, output);
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Cannot attach DM-RMC of type '{0}' to output {1} on DMPS chassis. Output is not a DM Output.",
|
||||
typeName, num);
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS chassis", typeName, num);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps4k(string key, string name, string typeName,
|
||||
DmpsRoutingController controller, uint num)
|
||||
{
|
||||
Func<string, string, DMOutput, CrestronGenericBaseDevice> dmpsHandler;
|
||||
if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmpsHandler))
|
||||
Func<string, string, DMOutput, CrestronGenericBaseDevice> dmps4kHandler;
|
||||
if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmps4kHandler))
|
||||
{
|
||||
var output = controller.Dmps.SwitcherOutputs[num] as DMOutput;
|
||||
|
||||
if (output != null)
|
||||
{
|
||||
return dmpsHandler(key, name, output);
|
||||
return dmps4kHandler(key, name, output);
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Cannot attach DM-RMC of type '{0}' to output {1} on DMPS chassis. Output is not a DM Output.",
|
||||
"Cannot attach DM-RMC of type '{0}' to output {1} on DMPS-4K chassis. Output is not a DM Output.",
|
||||
typeName, num);
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS chassis", typeName, num);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS-4K chassis", typeName, num);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using System;
|
||||
using System.Linq;
|
||||
//using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
using eVst = eX02VideoSourceType;
|
||||
using Crestron.SimplSharpPro;
|
||||
using System;
|
||||
using System.Linq;
|
||||
//using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
using eVst = eX02VideoSourceType;
|
||||
using eAst = eX02AudioSourceType;
|
||||
|
||||
public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback,
|
||||
IIROutputPorts, IComPorts
|
||||
{
|
||||
public DmTx4kz202C Tx { get; private set; }
|
||||
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
|
||||
public RoutingOutputPort DmOut { get; private set; }
|
||||
public RoutingOutputPort HdmiLoopOut { get; private set; }
|
||||
|
||||
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
|
||||
|
||||
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
|
||||
public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback,
|
||||
IIROutputPorts, IComPorts
|
||||
{
|
||||
public DmTx4kz202C Tx { get; private set; }
|
||||
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
|
||||
public RoutingOutputPort DmOut { get; private set; }
|
||||
public RoutingOutputPort HdmiLoopOut { get; private set; }
|
||||
|
||||
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
|
||||
|
||||
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
|
||||
//public override ushort HdcpSupportCapability { get; protected set; }
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
@@ -47,48 +47,48 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helps get the "real" inputs, including when in Auto
|
||||
/// </summary>
|
||||
public eX02VideoSourceType ActualActiveVideoInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tx.VideoSourceFeedback != eVst.Auto)
|
||||
return Tx.VideoSourceFeedback;
|
||||
|
||||
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi1;
|
||||
|
||||
return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled;
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
HdmiIn1,
|
||||
HdmiIn2,
|
||||
AnyVideoInput
|
||||
};
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
|
||||
}
|
||||
}
|
||||
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
|
||||
: base(key, name, tx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helps get the "real" inputs, including when in Auto
|
||||
/// </summary>
|
||||
public eX02VideoSourceType ActualActiveVideoInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tx.VideoSourceFeedback != eVst.Auto)
|
||||
return Tx.VideoSourceFeedback;
|
||||
|
||||
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi1;
|
||||
|
||||
return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled;
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
HdmiIn1,
|
||||
HdmiIn2,
|
||||
AnyVideoInput
|
||||
};
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
|
||||
}
|
||||
}
|
||||
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
|
||||
: base(key, name, tx)
|
||||
{
|
||||
Tx = tx;
|
||||
|
||||
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
|
||||
@@ -104,208 +104,208 @@ namespace PepperDash.Essentials.DM
|
||||
FeedbackMatchObject = eVst.Hdmi2
|
||||
};
|
||||
|
||||
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
|
||||
() => ActualActiveVideoInput.ToString());
|
||||
|
||||
|
||||
|
||||
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
|
||||
|
||||
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
//Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway
|
||||
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
|
||||
|
||||
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpStateFeedback =
|
||||
new IntFeedback(
|
||||
() =>
|
||||
tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
|
||||
? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback
|
||||
: (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
var combinedFuncs = new VideoStatusFuncsWrapper
|
||||
{
|
||||
HdcpActiveFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
|
||||
|
||||
HdcpStateFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
return "";
|
||||
},
|
||||
|
||||
VideoResolutionFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
|
||||
return "";
|
||||
},
|
||||
VideoSyncFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
|
||||
|
||||
};
|
||||
|
||||
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
|
||||
|
||||
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DmCat, null, this);
|
||||
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
|
||||
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
|
||||
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
|
||||
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback);
|
||||
|
||||
// Set Ports for CEC
|
||||
HdmiIn1.Port = Tx.HdmiInputs[1];
|
||||
HdmiIn2.Port = Tx.HdmiInputs[2];
|
||||
HdmiLoopOut.Port = Tx.HdmiOutput;
|
||||
DmOut.Port = Tx.DmOutput;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Link up all of these damned events to the various RoutingPorts via a helper handler
|
||||
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
|
||||
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
|
||||
|
||||
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
|
||||
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
|
||||
|
||||
// Base does register and sets up comm monitoring.
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
|
||||
|
||||
if (Hdmi1VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (Hdmi2VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
|
||||
LinkDmTxToApi(this, trilist, joinMap, bridge);
|
||||
}
|
||||
|
||||
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
|
||||
{
|
||||
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case eRoutingSignalType.Video:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExecuteSwitch(eVst.Auto, null, type);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn1.Selector, null, type);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn2.Selector, null, type);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(eVst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eRoutingSignalType.Audio:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExecuteSwitch(eAst.Auto, null, type);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(eAst.Hdmi1, null, type);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(eAst.Hdmi2, null, type);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(eAst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
if ((signalType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
Tx.VideoSource = (eVst)inputSelector;
|
||||
if(((signalType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
|
||||
Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
|
||||
}
|
||||
|
||||
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
|
||||
() => ActualActiveVideoInput.ToString());
|
||||
|
||||
|
||||
|
||||
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
|
||||
|
||||
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
//Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway
|
||||
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
|
||||
|
||||
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpStateFeedback =
|
||||
new IntFeedback(
|
||||
() =>
|
||||
tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
|
||||
? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback
|
||||
: (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
var combinedFuncs = new VideoStatusFuncsWrapper
|
||||
{
|
||||
HdcpActiveFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
|
||||
|
||||
HdcpStateFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
return "";
|
||||
},
|
||||
|
||||
VideoResolutionFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
|
||||
return "";
|
||||
},
|
||||
VideoSyncFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
|
||||
|
||||
};
|
||||
|
||||
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
|
||||
|
||||
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.DmCat, null, this);
|
||||
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
|
||||
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
|
||||
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
|
||||
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback);
|
||||
|
||||
// Set Ports for CEC
|
||||
HdmiIn1.Port = Tx.HdmiInputs[1];
|
||||
HdmiIn2.Port = Tx.HdmiInputs[2];
|
||||
HdmiLoopOut.Port = Tx.HdmiOutput;
|
||||
DmOut.Port = Tx.DmOutput;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Link up all of these damned events to the various RoutingPorts via a helper handler
|
||||
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
|
||||
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
|
||||
|
||||
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
|
||||
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
|
||||
|
||||
// Base does register and sets up comm monitoring.
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
|
||||
|
||||
if (Hdmi1VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (Hdmi2VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
|
||||
LinkDmTxToApi(this, trilist, joinMap, bridge);
|
||||
}
|
||||
|
||||
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
|
||||
{
|
||||
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case eRoutingSignalType.Video:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExecuteSwitch(eVst.Auto, null, type);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn1.Selector, null, type);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn2.Selector, null, type);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(eVst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eRoutingSignalType.Audio:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExecuteSwitch(eAst.Auto, null, type);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(eAst.Hdmi1, null, type);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(eAst.Hdmi2, null, type);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(eAst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
if ((signalType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
Tx.VideoSource = (eVst)inputSelector;
|
||||
if(((signalType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
|
||||
Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
|
||||
}
|
||||
|
||||
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||
@@ -313,7 +313,7 @@ namespace PepperDash.Essentials.DM
|
||||
var localVideoInputPort =
|
||||
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
|
||||
var localAudioInputPort =
|
||||
InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
|
||||
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
|
||||
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
@@ -338,68 +338,68 @@ namespace PepperDash.Essentials.DM
|
||||
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
|
||||
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
|
||||
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
|
||||
Debug.Console(2, this, " Audio Source: {0}", Tx.VideoSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the input stream change to the appropriate RoutingInputPort.
|
||||
/// </summary>
|
||||
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the VideoAttributes change to a RoutingInputPort
|
||||
/// </summary>
|
||||
void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
//// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
|
||||
//Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
|
||||
// args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
|
||||
switch (eventId)
|
||||
{
|
||||
case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
|
||||
inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
|
||||
break;
|
||||
case VideoAttributeEventIds.HdcpStateFeedbackEventId:
|
||||
inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
|
||||
break;
|
||||
case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
|
||||
case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
|
||||
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
break;
|
||||
case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
|
||||
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region IIROutputPorts Members
|
||||
public CrestronCollection<IROutputPort> IROutputPorts { get { return Tx.IROutputPorts; } }
|
||||
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
|
||||
#endregion
|
||||
|
||||
#region IComPorts Members
|
||||
public CrestronCollection<ComPort> ComPorts { get { return Tx.ComPorts; } }
|
||||
public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the input stream change to the appropriate RoutingInputPort.
|
||||
/// </summary>
|
||||
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the VideoAttributes change to a RoutingInputPort
|
||||
/// </summary>
|
||||
void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
//// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
|
||||
//Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
|
||||
// args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
|
||||
switch (eventId)
|
||||
{
|
||||
case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
|
||||
inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
|
||||
break;
|
||||
case VideoAttributeEventIds.HdcpStateFeedbackEventId:
|
||||
inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
|
||||
break;
|
||||
case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
|
||||
case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
|
||||
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
break;
|
||||
case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
|
||||
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region IIROutputPorts Members
|
||||
public CrestronCollection<IROutputPort> IROutputPorts { get { return Tx.IROutputPorts; } }
|
||||
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
|
||||
#endregion
|
||||
|
||||
#region IComPorts Members
|
||||
public CrestronCollection<ComPort> ComPorts { get { return Tx.ComPorts; } }
|
||||
public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -339,7 +339,7 @@ namespace PepperDash.Essentials.DM
|
||||
var localVideoInputPort =
|
||||
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
|
||||
var localAudioInputPort =
|
||||
InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
|
||||
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
|
||||
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
@@ -364,8 +364,8 @@ namespace PepperDash.Essentials.DM
|
||||
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
|
||||
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
|
||||
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
|
||||
Debug.Console(2, this, " Audio Source: {0}", Tx.VideoSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
|
||||
break;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace PepperDash.Essentials.DM
|
||||
var ipid = props.Control.IpIdInt;
|
||||
var pKey = props.ParentDeviceKey.ToLower();
|
||||
|
||||
if (pKey == "processor")
|
||||
if (pKey == "processor")
|
||||
{
|
||||
// Catch constructor failures, mainly dues to IPID
|
||||
try
|
||||
@@ -65,99 +65,135 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var parentDev = DeviceManager.GetDeviceForKey(pKey);
|
||||
if (!(parentDev is IDmSwitch))
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.",
|
||||
key, pKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
var parentDev = DeviceManager.GetDeviceForKey(pKey);
|
||||
DMInput dmInput;
|
||||
bool isCpu3 = false;
|
||||
|
||||
if (parentDev is IDmSwitch)
|
||||
{
|
||||
// Get the Crestron chassis and link stuff up
|
||||
var switchDev = (parentDev as IDmSwitch);
|
||||
var chassis = switchDev.Chassis;
|
||||
var switchDev = (parentDev as IDmSwitch);
|
||||
var chassis = switchDev.Chassis;
|
||||
|
||||
var num = props.ParentInputNumber;
|
||||
if (num <= 0 || num > chassis.NumberOfInputs)
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
|
||||
key, num);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
//Check that the input is within range of this chassis' possible inputs
|
||||
var num = props.ParentInputNumber;
|
||||
if (num <= 0 || num > chassis.NumberOfInputs)
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
|
||||
key, num);
|
||||
return null;
|
||||
}
|
||||
|
||||
switchDev.TxDictionary.Add(num, key);
|
||||
dmInput = chassis.Inputs[num];
|
||||
|
||||
//Determine if IpId is needed for this chassis type
|
||||
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
|
||||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
|
||||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps ||
|
||||
chassis is DmMd128x128 || chassis is DmMd64x64)
|
||||
{
|
||||
var controller = (parentDev as IDmSwitch);
|
||||
controller.TxDictionary.Add(num, key);
|
||||
isCpu3 = true;
|
||||
}
|
||||
|
||||
// Catch constructor failures, mainly dues to IPID
|
||||
try
|
||||
{
|
||||
// Must use different constructor for CPU3 chassis types. No IPID
|
||||
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
|
||||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
|
||||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps||
|
||||
chassis is DmMd128x128 || chassis is DmMd64x64)
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("hdbasettx"))
|
||||
return new HDBaseTTxController(key, name, new HDTx3CB(chassis.Inputs[num]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("hdbasettx"))
|
||||
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, chassis.Inputs[num]));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
}
|
||||
else if(parentDev is DmpsRoutingController)
|
||||
{
|
||||
// Get the DMPS chassis and link stuff up
|
||||
var dmpsDev = (parentDev as DmpsRoutingController);
|
||||
var chassis = dmpsDev.Dmps;
|
||||
|
||||
//Check that the input is within range of this chassis' possible inputs
|
||||
var num = props.ParentInputNumber;
|
||||
if (num <= 0 || num > chassis.SwitcherInputs.Count)
|
||||
{
|
||||
Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is out of range",
|
||||
key, num);
|
||||
return null;
|
||||
}
|
||||
|
||||
dmpsDev.TxDictionary.Add(num, key);
|
||||
|
||||
try
|
||||
{
|
||||
dmInput = chassis.SwitcherInputs[num] as DMInput;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is not a DM input", key, num);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
// Must use different constructor for CPU3 or DMPS3-4K types. No IPID
|
||||
if (isCpu3 || Global.ControlSystemIsDmps4kType)
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(dmInput));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(dmInput));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(dmInput));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(dmInput));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(dmInput));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(dmInput));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(dmInput));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(dmInput));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(dmInput));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(dmInput));
|
||||
if (typeName.StartsWith("hdbasettx"))
|
||||
return new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, dmInput));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(ipid, dmInput));
|
||||
if (typeName.StartsWith("hdbasettx"))
|
||||
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, dmInput));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,11 +221,12 @@ namespace PepperDash.Essentials.DM
|
||||
protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
|
||||
: base(key, name, hardware)
|
||||
{
|
||||
// if wired to a chassis, skip registration step in base class
|
||||
if (hardware.DMInput != null)
|
||||
{
|
||||
this.PreventRegistration = true;
|
||||
}
|
||||
// if wired to a chassis or DMPS, skip registration step in base class
|
||||
if (hardware.DMInput != null || (Global.ControlSystemIsDmpsType && hardware.DMInput != null))
|
||||
{
|
||||
this.PreventRegistration = true;
|
||||
}
|
||||
|
||||
AddToFeedbackList(ActiveVideoInputFeedback);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
|
||||
/// <summary>
|
||||
/// For rooms that have audio codec
|
||||
/// </summary>
|
||||
public interface IHasAudioCodec
|
||||
public interface IHasAudioCodec:IHasInCallFeedback
|
||||
{
|
||||
AudioCodecBase AudioCodec { get; }
|
||||
BoolFeedback InCallFeedback { get; }
|
||||
|
||||
///// <summary>
|
||||
///// Make this more specific
|
||||
|
||||
@@ -8,6 +8,8 @@ using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
@@ -25,7 +27,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
Focus = 8
|
||||
}
|
||||
|
||||
public abstract class CameraBase : EssentialsDevice, IRoutingOutputs
|
||||
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
|
||||
{
|
||||
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
|
||||
protected eCameraCapabilities Capabilities { get; set; }
|
||||
|
||||
protected CameraBase(string key, string name) :
|
||||
base(key, name)
|
||||
{
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
protected CameraBase(DeviceConfig config) : base(config)
|
||||
{
|
||||
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,
|
||||
@@ -208,21 +216,11 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
var presetsCamera = cameraDevice as IHasCameraPresets;
|
||||
presetsCamera.PresetsListHasChanged += new EventHandler<EventArgs>((o, a) =>
|
||||
{
|
||||
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
|
||||
{
|
||||
int tempNum = i - 1;
|
||||
|
||||
string label = "";
|
||||
|
||||
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
|
||||
|
||||
if (preset != null)
|
||||
label = preset.Description;
|
||||
|
||||
trilist.SetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||
}
|
||||
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
|
||||
});
|
||||
|
||||
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
|
||||
|
||||
for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++)
|
||||
{
|
||||
int tempNum = i;
|
||||
@@ -238,10 +236,35 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
presetsCamera.PresetStore(tempNum, label);
|
||||
});
|
||||
}
|
||||
trilist.OnlineStatusChange += (sender, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine)
|
||||
{ return; }
|
||||
|
||||
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
private void SendCameraPresetNamesToApi(IHasCameraPresets presetsCamera, CameraControllerJoinMap joinMap, BasicTriList trilist)
|
||||
{
|
||||
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
|
||||
{
|
||||
int tempNum = i - 1;
|
||||
|
||||
string label = "";
|
||||
|
||||
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
|
||||
|
||||
if (preset != null)
|
||||
label = preset.Description;
|
||||
|
||||
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CameraPreset : PresetBase
|
||||
{
|
||||
public CameraPreset(int id, string description, bool isDefined, bool isDefinable)
|
||||
|
||||
@@ -525,6 +525,15 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
|
||||
public event EventHandler<EventArgs> PresetsListHasChanged;
|
||||
|
||||
protected void OnPresetsListHasChanged()
|
||||
{
|
||||
var handler = PresetsListHasChanged;
|
||||
if (handler == null)
|
||||
return;
|
||||
|
||||
handler.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public List<CameraPreset> Presets { get; private set; }
|
||||
|
||||
public void PresetSelect(int preset)
|
||||
@@ -537,6 +546,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
SavePreset(preset);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasCameraFocusControl Members
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a device that has Do Not Disturb mode capability
|
||||
/// </summary>
|
||||
public interface IHasDoNotDisturbMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Indictes whether Do Not Disturb mode is on (Activated)
|
||||
/// </summary>
|
||||
BoolFeedback DoNotDisturbModeIsOnFeedback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Activates Do Not Disturb mode
|
||||
/// </summary>
|
||||
void ActivateDoNotDisturbMode();
|
||||
|
||||
/// <summary>
|
||||
/// Deactivates Do Not Disturb mode
|
||||
/// </summary>
|
||||
void DeactivateDoNotDisturbMode();
|
||||
|
||||
/// <summary>
|
||||
/// Toggles Do Not Disturb mode
|
||||
/// </summary>
|
||||
void ToggleDoNotDisturbMode();
|
||||
}
|
||||
|
||||
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Activates Do Not Disturb mode with a timeout
|
||||
/// </summary>
|
||||
/// <param name="timeout"></param>
|
||||
void ActivateDoNotDisturbMode(int timeout);
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
[JsonProperty("directoryResults")]
|
||||
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
|
||||
|
||||
public List<DirectoryItem> Contacts
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryContact>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<DirectoryItem> Folders
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentDirectoryResults.OfType<DirectoryFolder>().Cast<DirectoryItem>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to store the ID of the current folder for CurrentDirectoryResults
|
||||
/// </summary>
|
||||
@@ -104,6 +120,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
SortDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters the CurrentDirectoryResults by the predicate
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
public void FilterContacts(Func<DirectoryItem, bool> predicate)
|
||||
{
|
||||
CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically
|
||||
/// </summary>
|
||||
@@ -135,7 +160,19 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public interface IInvitableContact
|
||||
{
|
||||
bool IsInvitableContact { get; }
|
||||
}
|
||||
|
||||
public class InvitableDirectoryContact : DirectoryContact, IInvitableContact
|
||||
{
|
||||
[JsonProperty("isInvitableContact")]
|
||||
public bool IsInvitableContact
|
||||
{
|
||||
get
|
||||
{
|
||||
return this is IInvitableContact;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -184,8 +221,6 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
|
||||
|
||||
[JsonProperty("contactMethods")]
|
||||
public List<ContactMethod> ContactMethods { get; set; }
|
||||
|
||||
|
||||
@@ -4,15 +4,20 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
[Flags]
|
||||
public enum eMeetingEventChangeType
|
||||
{
|
||||
Unkown = 0,
|
||||
MeetingStartWarning,
|
||||
MeetingStart,
|
||||
MeetingEndWarning,
|
||||
MeetingEnd
|
||||
Unknown = 0,
|
||||
MeetingStartWarning = 1,
|
||||
MeetingStart = 2,
|
||||
MeetingEndWarning = 4,
|
||||
MeetingEnd = 8
|
||||
}
|
||||
|
||||
public interface IHasScheduleAwareness
|
||||
@@ -32,6 +37,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
|
||||
private int _meetingWarningMinutes = 5;
|
||||
|
||||
private Meeting _previousChangedMeeting;
|
||||
|
||||
private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
public int MeetingWarningMinutes
|
||||
{
|
||||
get { return _meetingWarningMinutes; }
|
||||
@@ -75,38 +84,72 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
_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)
|
||||
{
|
||||
var handler = MeetingEventChange;
|
||||
if (handler != null)
|
||||
Debug.Console(2, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType);
|
||||
if (changeType != (changeType & meeting.NotifiedChangeTypes))
|
||||
{
|
||||
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
// Add this change type to the NotifiedChangeTypes
|
||||
meeting.NotifiedChangeTypes |= changeType;
|
||||
|
||||
var handler = MeetingEventChange;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks the schedule to see if any MeetingEventChange updates should be fired
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
private void CheckSchedule(object o)
|
||||
{
|
||||
// Iterate the meeting list and check if any meeting need to do anythingk
|
||||
// Iterate the meeting list and check if any meeting need to do anything
|
||||
|
||||
const double meetingTimeEpsilon = 0.0001;
|
||||
const double meetingTimeEpsilon = 0.05;
|
||||
foreach (var m in Meetings)
|
||||
{
|
||||
var changeType = eMeetingEventChangeType.Unkown;
|
||||
var changeType = eMeetingEventChangeType.Unknown;
|
||||
|
||||
if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start
|
||||
if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start
|
||||
{
|
||||
Debug.Console(2, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds);
|
||||
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
||||
else if (Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
|
||||
{
|
||||
Debug.Console(2, "********************* MeetingStart");
|
||||
changeType = eMeetingEventChangeType.MeetingStart;
|
||||
else if (m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to end
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end
|
||||
{
|
||||
Debug.Console(2, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds);
|
||||
changeType = eMeetingEventChangeType.MeetingEndWarning;
|
||||
else if (Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
||||
}
|
||||
else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
|
||||
{
|
||||
Debug.Console(2, "********************* MeetingEnd");
|
||||
changeType = eMeetingEventChangeType.MeetingEnd;
|
||||
}
|
||||
|
||||
if (changeType != eMeetingEventChangeType.Unkown)
|
||||
OnMeetingChange(changeType, m);
|
||||
if (changeType != eMeetingEventChangeType.Unknown)
|
||||
{
|
||||
OnMeetingChange(changeType, m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,17 +158,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public class Meeting
|
||||
{
|
||||
[JsonProperty("minutesBeforeMeeting")]
|
||||
public int MinutesBeforeMeeting;
|
||||
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
[JsonProperty("organizer")]
|
||||
public string Organizer { get; set; }
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
[JsonProperty("agenda")]
|
||||
public string Agenda { get; set; }
|
||||
|
||||
[JsonProperty("meetingWarningMinutes")]
|
||||
public TimeSpan MeetingWarningMinutes
|
||||
{
|
||||
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
||||
}
|
||||
[JsonProperty("timeToMeetingStart")]
|
||||
public TimeSpan TimeToMeetingStart
|
||||
{
|
||||
get
|
||||
@@ -133,6 +183,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
return StartTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
[JsonProperty("timeToMeetingEnd")]
|
||||
public TimeSpan TimeToMeetingEnd
|
||||
{
|
||||
get
|
||||
@@ -140,8 +191,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
return EndTime - DateTime.Now;
|
||||
}
|
||||
}
|
||||
[JsonProperty("startTime")]
|
||||
public DateTime StartTime { get; set; }
|
||||
[JsonProperty("endTime")]
|
||||
public DateTime EndTime { get; set; }
|
||||
[JsonProperty("duration")]
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
@@ -149,25 +203,47 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
return EndTime - StartTime;
|
||||
}
|
||||
}
|
||||
[JsonProperty("privacy")]
|
||||
public eMeetingPrivacy Privacy { get; set; }
|
||||
[JsonProperty("joinable")]
|
||||
public bool Joinable
|
||||
{
|
||||
get
|
||||
{
|
||||
return StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
|
||||
&& DateTime.Now <= EndTime; //.AddMinutes(-5);
|
||||
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
|
||||
&& DateTime.Now <= EndTime.AddMinutes(-5);
|
||||
//Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable);
|
||||
return joinable;
|
||||
}
|
||||
}
|
||||
//public string ConferenceNumberToDial { get; set; }
|
||||
[JsonProperty("conferencePassword")]
|
||||
public string ConferencePassword { get; set; }
|
||||
[JsonProperty("isOneButtonToPushMeeting")]
|
||||
public bool IsOneButtonToPushMeeting { get; set; }
|
||||
|
||||
[JsonProperty("calls")]
|
||||
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()
|
||||
{
|
||||
Calls = new List<Call>();
|
||||
}
|
||||
|
||||
#region Overrides of Object
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class Call
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Displays
|
||||
{
|
||||
public interface IInputHdmi1 { void InputHdmi1(); }
|
||||
public interface IInputHdmi2 { void InputHdmi2(); }
|
||||
public interface IInputHdmi3 { void InputHdmi3(); }
|
||||
public interface IInputHdmi4 { void InputHdmi4(); }
|
||||
public interface IInputDisplayPort1 { void InputDisplayPort1(); }
|
||||
public interface IInputDisplayPort2 { void InputDisplayPort2(); }
|
||||
public interface IInputVga1 { void InputVga1(); }
|
||||
|
||||
}
|
||||
@@ -108,6 +108,7 @@
|
||||
<Compile Include="Codec\eCodecCallStatus.cs" />
|
||||
<Compile Include="Codec\eMeetingPrivacy.cs" />
|
||||
<Compile Include="Codec\iCodecAudio.cs" />
|
||||
<Compile Include="Codec\IHasDoNotDisturb.cs" />
|
||||
<Compile Include="Codec\IHasExternalSourceSwitching.cs" />
|
||||
<Compile Include="ImageProcessors\TVOneCorio.cs" />
|
||||
<Compile Include="ImageProcessors\TVOneCorioPropertiesConfig.cs" />
|
||||
@@ -117,11 +118,17 @@
|
||||
<Compile Include="ImageProcessors\AnalogWay\AnalogWayLiveCorePropertiesConfig.cs" />
|
||||
<Compile Include="SoftCodec\BlueJeansPc.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\CiscoCamera.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\CiscoCodecJoinMap.cs" />
|
||||
<Compile Include="VideoCodec\CiscoCodec\RoomPresets.cs" />
|
||||
<Compile Include="Cameras\CameraControl.cs" />
|
||||
<Compile Include="Display\PanasonicThDisplay.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasMeetingInfo.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasPresentationOnlyMeeting.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasSelfviewSize.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasStandbyMode.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasStartMeeting.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
|
||||
<Compile Include="Codec\iHasCallFavorites.cs" />
|
||||
<Compile Include="Codec\iHasCallHistory.cs" />
|
||||
@@ -176,6 +183,7 @@
|
||||
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomJoinMap.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
|
||||
<None Include="Properties\ControlSystem.cfg" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges.JoinMaps;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
{
|
||||
public class CiscoCodecJoinMap : VideoCodecControllerJoinMap
|
||||
{
|
||||
#region Digital
|
||||
|
||||
[JoinName("ActivateDoNotDisturbMode")]
|
||||
public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 221,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Activates Do Not Disturb Mode. FB High if active.",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DeactivateDoNotDisturbMode")]
|
||||
public JoinDataComplete DeactivateDoNotDisturbMode = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 222,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Deactivates Do Not Disturb Mode. FB High if deactivated.",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ToggleDoNotDisturbMode")]
|
||||
public JoinDataComplete ToggleDoNotDisturbMode = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 223,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Toggles Do Not Disturb Mode.",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivateStandby")]
|
||||
public JoinDataComplete ActivateStandby = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 226,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Activates Standby Mode. FB High if active.",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DeactivateStandby")]
|
||||
public JoinDataComplete DeactivateStandby = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 227,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Deactivates Standby Mode. FB High if deactivated.",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ActivateHalfWakeMode")]
|
||||
public JoinDataComplete ActivateHalfWakeMode = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 228,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Activates Half Wake Mode. FB High if active.",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("EnteringStandbyMode")]
|
||||
public JoinDataComplete EnteringStandbyMode = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 229,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "High to indicate that the codec is entering standby mode",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Analog
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Serials
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public CiscoCodecJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(CiscoCodecJoinMap))
|
||||
{
|
||||
}
|
||||
|
||||
public CiscoCodecJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user