Compare commits

..

271 Commits

Author SHA1 Message Date
Neil Dorin
2677d63553 Merge pull request #1049 from PepperDash/hotfix/zoom-phonebook-issues
Fix Empty Zoom Phonebook
2022-12-22 13:52:45 -07:00
Andrew Welker
d03581fea8 fix: change contact message handling
On some occasions when the Zoom Room restarted
and Essentials did not, the directory could be
requested while the Zoom Room had no contacts
yet, as it hadn't received them from Zoom Cloud.
This caused the directory to be empty, even
though there may be valid contacts. Now,
Essentials uses the Added Contact and Updated Contact
methods to fire the directory changed event, allowing
for directory updates to be propogated as necessary.
2022-12-22 08:54:24 -07:00
Andrew Welker
decc8ed3a5 refactor: update queue error handling
On some occasions, a ThreadAbortException was being
caught on shutdown and causing exceptions to be printed
needlessly. Messaging has also been updated to remove
personal pronouns.
2022-12-22 08:52:58 -07:00
Andrew Welker
b0637288e9 refactor: move logic for updating directory to method 2022-12-21 12:21:01 -07:00
Andrew Welker
52d945fca3 Merge pull request #1044 from PepperDash/hotfix/ssh-issues
Update PD Core version to fix SSH issues
2022-12-12 12:11:55 -07:00
Andrew Welker
0ef8fcfd27 chore: Update to PD Core 1.1.4 2022-12-12 11:42:16 -07:00
Andrew Welker
042416b470 chore: update PD Core version 2022-12-12 10:01:14 -07:00
jdevito
3d27b0928f Merge pull request #1042 from PepperDash/hotfix/zoomroom-camera-selection
Send command to select camera by ID for Zoom Room
2022-12-09 09:39:33 -06:00
Andrew Welker
860182dbfc Merge branch 'main' into hotfix/zoomroom-camera-selection 2022-12-09 08:12:45 -07:00
Andrew Welker
668cbc430c Merge pull request #1038 from PepperDash/hotfix/occ-sensor-fixes
Prevent vacancy from shutting down the room when a call is active
2022-11-28 16:19:26 -07:00
Andrew Welker
e54de1f1cb Merge branch 'main' into hotfix/occ-sensor-fixes 2022-11-28 15:19:45 -07:00
Neil Dorin
f48b1a2de3 Merge pull request #1039 from PepperDash/hotfix/touchpanelBase
Fix issues with TouchpanelBase
2022-11-23 16:24:28 -07:00
Andrew Welker
8e57e7ec31 fix: add missing LoadSmartObjects call 2022-11-23 14:29:36 -07:00
Andrew Welker
1b43b44d19 fix: typo in TouchpanelBase constructor
The constructor was checking the wrong
variable, leading to it always being null
and failing to build the `EssentialsTouchpanelController`
class.
2022-11-23 13:15:41 -07:00
Andrew Welker
4306128474 refactor: fix abstract method 2022-11-21 10:45:25 -07:00
Andrew Welker
5263b16bb7 refactor: fix issues with log statments 2022-11-21 10:42:33 -07:00
Andrew Welker
a2b67798f3 refactor: add logging statements 2022-11-21 10:37:26 -07:00
Andrew Welker
1b43fba37e fix: add logic to prevent vacancy from triggering room off if room is in
a call
2022-11-21 10:28:08 -07:00
Andrew Welker
f262c1a3bb Merge pull request #1036 from PepperDash/hotfix/PD-core-update-for-vc4
Updates for VC-4
2022-11-16 11:05:40 -07:00
Andrew Welker
93ee695c57 Merge branch 'main' into hotfix/PD-core-update-for-vc4 2022-11-16 10:52:15 -07:00
Andrew Welker
ba0bae3c4e chore: update PD Core to 1.1.3 2022-11-16 10:51:48 -07:00
Trevor Payne
37a98d00af Merge pull request #1037 from PepperDash/hotfix/VideoCodec-ActiveCall-XSig
Fix error with updating call status XSigs
2022-11-14 10:25:28 -06:00
Trevor Payne
247827ac25 fix: UpdateCallStatusXsig() now properly refreshing calls 2022-11-14 10:10:22 -06:00
Andrew Welker
5e797db096 fix: add check for missing/empty roomId 2022-11-11 16:26:37 -07:00
Andrew Welker
57eeeec0fb Merge branch 'main' into hotfix/PD-core-update-for-vc4 2022-11-11 16:23:12 -07:00
Andrew Welker
db19da124c fix: set debug level to 2 on startup
Some plugins and devices are doing their own filtering based on the
debug level that's normally set using the `appdebug` console command.
On VC-4, there's no way to set that value. With this change, when
Essentials starts on a server, the debug level will be set to 2, so that
any of the messages that might be filtered based on the debug level
won't be filtered.
2022-11-11 14:37:46 -07:00
Andrew Welker
c07f52b06f feat: update VC-4 client to use correct RoomID 2022-11-10 12:51:04 -07:00
Neil Dorin
b6675477be Merge pull request #1029 from PepperDash/hotfix/zoom-passcode-and-incoming-call-prompt-states-on-cancel
Update Zoom polling/sending blocks for more scenarios
2022-11-09 09:27:07 -07:00
Andrew Welker
fc3840173e chore: Update PD Core version 2022-11-08 08:44:39 -07:00
Andrew Welker
ce51a62d97 chore: update PD Core version 2022-11-04 14:01:11 -06:00
Andrew Welker
2be42f88bc chore: update PD Core version
In order to fix issues with debug file location for VC-4, the PD Core version needs to be updated
2022-11-04 09:48:17 -06:00
jdevito
6f9a9ee255 fix: moved setting set in event before null check 2022-10-28 16:47:43 -05:00
jdevito
a09212417c fix: removed property sets as recommended in discussion; removed 'if' statements before property sets in leave and end call methods 2022-10-28 16:20:49 -05:00
jdevito
4d6da37c60 fix: added additional evaluations for prompt property tracking and set/reset to handled unknown user scenarios 2022-10-28 08:38:16 -05:00
Andrew Welker
95627df1a6 Merge pull request #1026 from PepperDash/hotfix/zoomroom-block-commands-on-incoming-call
fix(essentials): Block all commands to ZoomRoom on incoming call
2022-10-25 13:40:32 -06:00
Neil Dorin
bef07fe41b fix(essentials): Block all commands to ZoomRoom on incoming call 2022-10-25 10:30:02 -06:00
Andrew Welker
83d2497264 Merge pull request #1021 from PepperDash/hotfix/848-camera-preset-bridge-issue
fix: max number of presets now uses join span rather than join start.
2022-10-20 11:17:39 -06:00
Andrew Welker
50f5145a89 Merge branch 'main' into hotfix/848-camera-preset-bridge-issue 2022-10-20 10:58:10 -06:00
Neil Dorin
a734a869c1 Merge pull request #1023 from PepperDash/hotfix/zoomrooms-passcode-required-prohibits-polling
fix: added bool property tracking if meeting is require, added poll m…
2022-10-20 10:30:14 -06:00
Neil Dorin
c6495577e7 Merge branch 'main' into hotfix/zoomrooms-passcode-required-prohibits-polling 2022-10-20 10:15:46 -06:00
jdevito
5359604098 fix: added bool property tracking if meeting is require, added poll method and updated GetBookings to reference bool property that prohibits polling when meeting password is required 2022-10-20 11:11:07 -05:00
Jason Alborough
70d2633eb0 fix: max number of presets now uses join span rather than join start. 2022-10-20 09:52:58 -04:00
Andrew Welker
6715a680cc Merge pull request #1019 from PepperDash/hotfix/xSigUpdateActiveCall-Fix
fix: update xSig Method for active call status
2022-10-18 10:21:11 -06:00
Trevor Payne
f3fc0f2b26 fix: update xSig Method for active call status 2022-10-18 10:51:24 -05:00
Neil Dorin
330bb2d002 fix(essentials): #1017 -Send command to select camera by ID 2022-10-13 11:13:17 -06:00
Neil Dorin
26b968463b Merge pull request #1015 from PepperDash/hotfix/shade-interface-updates
fix(essentials): Updates to shade interfaces to clarify functionality
2022-10-06 12:44:21 -06:00
Andrew Welker
d33b89f232 Merge branch 'main' into hotfix/shade-interface-updates 2022-10-06 12:29:27 -06:00
Andrew Welker
c19ab76a4c Merge pull request #1013 from PepperDash/hotfix/VideoCodecBase-Xsig-Fixes
Hotfix/video codec base xsig fixes
2022-10-06 11:02:03 -06:00
Neil Dorin
040c57b5e1 fix(essentials): Updates to shade interfaces to clarify functionality 2022-10-06 10:05:44 -06:00
Trevor Payne
d6864bf214 Merge branch 'hotfix/VideoCodecBase-Xsig-Fixes' of https://github.com/PepperDash/Essentials into hotfix/VideoCodecBase-Xsig-Fixes 2022-10-06 00:38:15 -05:00
Trevor Payne
62275890cb style: changed tracking variable in UpdateCallStatusXsig 2022-10-06 00:38:02 -05:00
Trevor Payne
2a6b845fde Merge branch 'main' into hotfix/VideoCodecBase-Xsig-Fixes 2022-10-05 16:51:11 -05:00
Trevor Payne
4fb2d6d755 fix: updated XSig methods in VideoCodecBase 2022-10-05 16:13:53 -05:00
Neil Dorin
5994704fbd Merge pull request #1010 from PepperDash/hotfix/zoomroom-default-layout
Hotfix/zoomroom default layout
2022-09-30 08:27:03 -06:00
Neil Dorin
ca1cbb6e05 fix(essentials): Resolves null ref in LinkZoomRoomToApi 2022-09-29 14:11:41 -06:00
Neil Dorin
f82b7f8f12 refactor(essentials): cleans up some args names for clarity 2022-09-29 13:33:15 -06:00
Neil Dorin
dbd77f5f9f fix(essentials): Switch to SetSigTrueAction for a few joins 2022-09-29 12:35:05 -06:00
Neil Dorin
55031d16af docs(essentials): Add join name to printjoinmap and update description on StartMeetingNow join 2022-09-29 12:33:42 -06:00
Neil Dorin
4938071f70 fix(essentials): Updates the func to return whether sharing content 2022-09-29 11:22:13 -06:00
Neil Dorin
3670bde7cf fix(essentials): Adds extra private field to trigger OnShareInfoChanged 2022-09-29 10:53:55 -06:00
Neil Dorin
4deb9a0828 fix(essentials): Updates to deal with sharing status and adds a property to notify if meeting can be recorded 2022-09-28 14:55:14 -06:00
Neil Dorin
a524b1607d fix(essentials): Updates to deal with layouts and default layout for ZoomRoom 2022-09-28 12:28:37 -06:00
Andrew Welker
93435b60b5 Merge pull request #1005 from PepperDash/release/1.11.0
Release/1.11.0
2022-09-26 14:48:51 -06:00
Neil Dorin
2daf3c0328 Merge pull request #1004 from PepperDash/release/1.11.0
1.11.0
2022-09-26 14:13:50 -06:00
Andrew Welker
eaef8ea616 Merge branch 'main' into release/1.11.0 2022-09-26 11:52:43 -06:00
Andrew Welker
b67eb6325b Merge pull request #1003 from PepperDash/hotfix/add-zoomroom-share-info
Hotfix/add zoomroom share info
2022-09-26 08:40:36 -06:00
Andrew Welker
38cb86218c Merge branch 'development' into hotfix/add-zoomroom-share-info 2022-09-26 08:29:05 -06:00
Andrew Welker
edddf295fe Merge pull request #1002 from PepperDash/hotfix/add-zoomroom-share-info
Various Zoom Room updates
2022-09-23 14:53:22 -06:00
Neil Dorin
05ec0ebac3 fix(essentials): Adds ability to dial up to 10 calls from SIMPL bridge 2022-09-23 12:27:55 -06:00
Neil Dorin
c3d07fe4fd fix(essentials): Adds EndAllCalls to CancelJoinAttempt action 2022-09-23 08:28:32 -06:00
Neil Dorin
eae089cdf5 fix(essentials): updates to password prompt logic 2022-09-22 15:38:11 -06:00
Neil Dorin
b48859d202 adds missing .csproj update 2022-09-22 13:06:00 -06:00
Neil Dorin
bda46eb1b9 fix(essentials): adds cancel method for password prompt and adds wireless share instructions 2022-09-22 13:05:09 -06:00
Neil Dorin
ee735388bb fix(essentials): reworks SIMPL bridging logic for hiding password prompt 2022-09-15 12:44:17 -06:00
Andrew Welker
77f202b9f4 Merge pull request #1000 from PepperDash/hotfix/zoom-room-content-sharing-fb
fix(essentials): Fixes SharingSourceFeedback value to actually read F…
2022-09-14 17:00:09 -06:00
Neil Dorin
939afb7aae fix(essentials): Fixes SharingSourceFeedback value to actually read FB state instead of which on screen instructions are shown 2022-09-14 16:40:26 -06:00
Andrew Welker
4a98b58b60 Merge pull request #997 from PepperDash/hotfix/zoom-passcode-prompt
Update Zoom passcode bridging logic
2022-09-09 10:39:02 -06:00
Andrew Welker
2bf9336712 Merge branch 'main' into hotfix/zoom-passcode-prompt 2022-09-09 10:24:14 -06:00
Andrew Welker
c0c67f6c15 Merge pull request #996 from PepperDash/hotfix/zoom-room-privacy-mute-notincall
Hotfix/zoom room privacy mute notincall
2022-09-08 16:08:13 -06:00
Andrew Welker
eb3922aa43 Merge branch 'development' into hotfix/zoom-room-privacy-mute-notincall 2022-09-08 15:08:44 -06:00
Andrew Welker
598886dfd4 Merge pull request #995 from PepperDash/hotfix/zoom-room-privacy-mute-notincall
Set Zoom Room privacy/mic mute to report unmuted when not in a meeting
2022-09-08 15:08:32 -06:00
Neil Dorin
215cf6696e fix(essentials): Set not in call state to report as unmuted 2022-09-08 14:26:18 -06:00
Neil Dorin
c557400f38 fix(essentials): updates ZoomRoom mute state to report muted when not in call 2022-09-08 14:26:18 -06:00
Trevor Payne
49a96d2632 Merge pull request #993 from PepperDash/feature/Cisco-RoomOS-Codec-Support-Cleanup
Various fixes for VideoCodecBase
2022-09-06 17:36:06 -05:00
Trevor Payne
ccf7acd53d feat: update bridging, device factory, and interfaces
In order to support the way some Smart Objects work, a clear
directory join was needed in order to allow for clearing a
selection in certain circumstances.

In order to support finer-grained dependencies while
developing plugins, the Development Device Factory was added.
2022-09-06 17:16:27 -05:00
jdevito
f1590aeec8 fix: added 'CancelPasswordPrompt' join, updated linkToZoomApi 2022-09-06 14:10:21 -05:00
jdevito
f1d1ce9722 fix: added OnPasswordRequired event call in SubmitPassword method to clear popup when bridged 2022-09-06 14:04:19 -05:00
Neil Dorin
edd55d0349 Merge pull request #992 from PepperDash/feature/touchpanel-plugins
Add TouchpanelBase class and initial implementation
2022-09-02 15:15:20 -06:00
Andrew Welker
384c4c2781 Merge branch 'feature/touchpanel-plugins' of https://github.com/PepperDash/Essentials into feature/touchpanel-plugins 2022-09-02 15:00:12 -06:00
Andrew Welker
9b2611be02 refactor: add error handling for cases where type isn't found 2022-09-02 15:00:00 -06:00
Andrew Welker
26bd49aa85 Merge branch 'development' into feature/touchpanel-plugins 2022-09-02 14:45:06 -06:00
Andrew Welker
1b9f16ea74 fix: add missing event registration 2022-09-02 14:44:15 -06:00
Andrew Welker
88a16b577b refactor: update constructors for touchpanel controller and base class 2022-09-02 14:35:06 -06:00
Andrew Welker
b4ab0c1c32 Merge pull request #991 from PepperDash/hotfix/essentials-cooling-routing
Hotfix/essentials cooling routing
2022-09-02 13:56:05 -06:00
Andrew Welker
d01be57f81 feat: add TouchpanelBase class and initial implementation 2022-09-02 13:54:34 -06:00
Andrew Welker
5ba7abb59b Merge branch 'development' into hotfix/essentials-cooling-routing 2022-09-02 11:49:06 -06:00
Andrew Welker
f5a352cf08 Merge pull request #990 from PepperDash/hotfix/essentials-cooling-routing
Magic Routing holds last requested route until cooling is complete
2022-09-02 11:37:46 -06:00
Neil Dorin
c4a23e0887 feat(essentials): Adds RoomUiBehaviorConfig for disabling activity buttons 2022-09-02 11:19:18 -06:00
Andrew Welker
2622e68afc Merge pull request #957 from PepperDash/feature/dmps-dm-fixes
Feature/dmps dm fixes
2022-09-02 11:00:16 -06:00
Andrew Welker
7fe2d04d31 fix: add removal of RouteRequest when calling ReleaseRoute 2022-09-01 12:29:19 -06:00
Andrew Welker
358f44cfe5 refactor: remove completed request from dictionary 2022-09-01 11:57:40 -06:00
Andrew Welker
d7cccc0709 feat: add cooldown logic to Magic Routing
In some cases, a route can be requested while a sink is cooling down.
In those cases, the routing logic should keep track of requests for a
destination and wait until cooling is complete to request the new
route.
2022-09-01 11:47:52 -06:00
Andrew Welker
72086b57b3 Merge branch 'development' into feature/dmps-dm-fixes 2022-08-31 15:06:34 -06:00
Andrew Welker
f04b93d5e9 Merge pull request #989 from PepperDash/feature/cen-io-ir-104
Feature/cen io ir 104
2022-08-31 15:06:24 -06:00
Andrew Welker
18c52ca199 Merge branch 'development' into feature/dmps-dm-fixes 2022-08-31 14:49:56 -06:00
Andrew Welker
1dcafff8fb Merge branch 'development' into feature/cen-io-ir-104 2022-08-31 14:49:13 -06:00
Andrew Welker
81b1117310 Merge pull request #988 from PepperDash/feature/cen-io-ir-104
Add Support for CEN-IO devices
2022-08-31 14:47:58 -06:00
jdevito
fb689c4484 fix: updated CEN-IO classes inheriting from EssentialsDevice to CrestronGenericBaseDevice to resolve activation issues 2022-08-31 14:43:58 -05:00
jdevito
40cb1b0fcf Merge remote-tracking branch 'origin/hotfix/huddle-room-interfaces' into feature/cen-io-ir-104 2022-08-31 11:55:15 -05:00
Jason DeVito
4574941288 fix: updated debug statement for DinCenCnController class referencing building a temp sensor device 2022-08-30 22:11:33 -05:00
Jason DeVito
122abc56e5 fix: added null checks in BuildDevice with debug statements if null 2022-08-30 22:02:47 -05:00
Jason DeVito
074ee190ad feat: added cen-io-ir-104 device and factory 2022-08-30 21:53:41 -05:00
Andrew Welker
68a0157fbe fix: add missing interface 2022-08-30 13:57:53 -06:00
Alex Johnson
0376943dac Reworks the creation process for DM transmitters 2022-08-20 15:18:39 -04:00
Andrew Welker
62abbdf5e9 Merge pull request #981 from PepperDash/hotfix/zoomroom-bridge-updates
Hotfix/zoomroom bridge updates
2022-08-18 08:50:17 -06:00
Jason DeVito
12248c6393 fix: removed extra debug statements 2022-08-12 17:36:38 -05:00
Jason DeVito
139ecc3e58 fix: (wip) updated VideoCodecBase LinkToApis to resolve issue #983 with call status and directory not updating wtih bridge online status change 2022-08-12 17:32:54 -05:00
jdevito
afa0a4cac2 Merge branch 'development' into hotfix/zoomroom-bridge-updates 2022-08-12 16:04:40 -05:00
Alex Johnson
ed335cc9ae Fixes for offline feedback for DM endpoints that don't provide offline feedback in the hardware definition. Adds offline and name feedback to joinMap for these devices. 2022-08-12 09:26:09 -04:00
Alex Johnson
5d51570018 Merge branch 'development' into feature/dmps-dm-fixes 2022-08-12 09:07:49 -04:00
Andrew Welker
e5393deea8 Merge pull request #980 from PepperDash/hotfix/zoomroom-bridge-updates
Hotfix/zoomroom bridge updates
2022-08-10 16:28:16 -06:00
Jason DeVito
c446c3a976 fix: updates to resolve directory display issues on touch panel when bridged 2022-08-10 17:12:30 -05:00
Jason DeVito
49e44ec850 fix: updated VideoCodecBase UpdateDirectoryXSig to handle directory results that are greater than 1023, XSig maximimum index 2022-08-10 15:49:41 -05:00
Andrew Welker
7298b9b767 Merge pull request #977 from PepperDash/hotfix/fix-lightingScene-scene-select-index
Hotfix/fix lighting scene scene select index
2022-08-08 15:49:19 -06:00
Andrew Welker
5a8914a33f Merge branch 'development' into hotfix/fix-lightingScene-scene-select-index 2022-08-08 13:34:27 -06:00
Andrew Welker
0ec42f8de2 Merge pull request #976 from PepperDash/hotfix/fix-lightingScene-scene-select-index
Lighting and Display Base updates to support extending joinMaps
2022-08-08 13:29:01 -06:00
Jason DeVito
008c82edb9 fix: updated lighting and display base; fix: lightingBase scene recall link to api index out of range exception 2022-08-08 13:54:17 -05:00
Neil Dorin
3033322212 Merge pull request #973 from PepperDash/hotfix/multiple-display-routing-support
Fix interface type check for routing
2022-08-01 12:34:16 -06:00
Neil Dorin
5b350c7a0c Updates interface type for other condition 2022-08-01 12:19:43 -06:00
Neil Dorin
afd2198eef Uses a less specific interface type for routing 2022-08-01 12:19:28 -06:00
Trevor Payne
dccab58a28 Merge pull request #969 from PepperDash/bugfix/CrestronDatastor-Errors
Bugfix/crestron datastor errors
2022-07-19 09:54:53 -05:00
Andrew Welker
19d29a03c8 Merge branch 'development' into bugfix/CrestronDatastor-Errors 2022-07-19 08:33:47 -06:00
Andrew Welker
41bc6a9cd4 Merge pull request #967 from PepperDash/feature/VideoCodec-Improvements
Feature/video codec improvements
2022-07-19 08:33:30 -06:00
Trevor Payne
051d50e8c9 Merge branch 'bugfix/CrestronDatastor-Errors' of https://github.com/PepperDash/Essentials into bugfix/CrestronDatastor-Errors 2022-07-18 15:10:12 -05:00
Trevor Payne
16af75ae0d fix: updated erroneous console responses for Secrets Providers
refactor: updated method by which the Factories assess secret objects

refactor: updated 'SecretsManager' console responses

feat: added 'secretproviderlist' console command

feat: added 'secretproviderinfo' console command

feat: added 'CrestronGlobalSecretsProvider'

feat: Added 'Description' property to 'ISecretProvider'

feat: added 'TestSecret' method to 'ISecretProvider'

docs: added xml comments to 'ISecretProvider'

docs: added xml comments to 'ISecret'

refactor: cleaned up crestron default secrets provider classes

refactor: moved 'CrestronSecret' to its own class file

refactor: overhauled all secrets-related console commands

resolves #968
2022-07-18 15:07:19 -05:00
Trevor Payne
4037fad26b fix: updated erroneous console responses for Secrets Providers
refactor: updated method by which the Factories assess secret objects

refactor: updated 'SecretsManager' console responses

feat: added 'secretproviderlist' console command

feat: added 'secretproviderinfo' console command

feat: added 'CrestronGlobalSecretsProvider'

feat: Added 'Description' property to 'ISecretProvider'

feat: added 'TestSecret' method to 'ISecretProvider'

docs: added xml comments to 'ISecretProvider'

docs: added xml comments to 'ISecret'

refactor: cleaned up crestron default secrets provider classes

refactor: moved 'CrestronSecret' to its own class file

refactor: overhauled all secrets-related console commands
2022-07-18 15:05:08 -05:00
Trevor Payne
5a4cc2fd39 fix:console commands for Secrets Management Modified 2022-07-15 17:40:48 -05:00
Trevor Payne
04e8508c0c fix: requested changes for PR #967 2022-07-15 11:38:19 -05:00
Trevor Payne
cbab051c11 Fixed Merge Issue
Adjusts #966
2022-07-12 15:53:59 -05:00
Trevor Payne
9c8bb66c5e [Fix] - Updated IHasCodecLayoutsAvailable setters
[Adjusts] #966
2022-07-12 15:48:53 -05:00
Trevor Payne
96ec2cbe49 [Fix] - Updated IHasCodecLayoutsAvailable setters
[Adjusts] #966
2022-07-12 15:38:48 -05:00
Trevor Payne
9ecaec5584 [fix] slight change to move CodecCommandWithLabel into the VideoCodec namespace and modify the IHasCodecLayoutsAvailable interface to utilize this class
Modifies #966
2022-07-12 15:02:22 -05:00
Trevor Payne
b505ad467b [feature] added IHasCodecLayoutsAvailable interface and associated bridge linking methods
Modifies #966
2022-07-12 12:34:28 -05:00
Trevor Payne
d8ac302f1c [feature] - Create and Implement IConvertiblePreset within the VideoCodec and the VideoCodec.Cisco namespaces
RESOLVES #966
2022-07-11 17:30:51 -05:00
Alex Johnson
712d38011c Merge branch 'development' into feature/dmps-dm-fixes 2022-06-27 13:30:24 -04:00
Alex Johnson
d849e4185c Fixes clear audio route on DMPS3-4K-150. Fixes output names on join map for DMPS3-4K-150 2022-06-27 09:35:38 -04:00
Neil Dorin
c3818b8bf2 Merge pull request #964 from PepperDash/feature/handle-prs
Feature/handle prs
2022-06-22 09:55:55 -06:00
Neil Dorin
05dadbe8ee Merge pull request #963 from PepperDash/hotfix/typo-in-RoutingPort-constructor
Hotfix/typo in routing port constructor
2022-06-22 09:54:43 -06:00
Neil Dorin
c39fd231bf Merge pull request #914 from Willis1776/bugfix/routingPort-typo-isInternal-Constructor
Typo in RoutingPort Constructor - isInternal
2022-06-22 09:38:30 -06:00
Neil Dorin
bbb31aea23 Merge pull request #959 from ciasia/bugfix/958-SubpageRefernceList-Get__OutputSig
GetStringOutputSig and GetUShortOutputSig return
2022-06-22 09:15:01 -06:00
Neil Dorin
0df587071d Merge branch 'main' into bugfix/routingPort-typo-isInternal-Constructor 2022-06-22 09:14:31 -06:00
Andrew Welker
4a405804c8 Merge pull request #960 from PepperDash/feature/iBasicVolumewFB-better-pull
Fix IBasicVolumeControls
2022-06-21 17:29:31 -05:00
jta
38c4a540a9 fix for IBasicVolumeWithFeedback
fix: for a change that split the interface but could break backwards compatibility #955
2022-06-21 18:05:23 -04:00
jta
4c9a470885 Fix IBasicVolumeControls
fix: revert a change that split the interface but could break backwards compatibility #955
2022-06-21 17:55:18 -04:00
Andrew Welker
be5158d29e Merge pull request #947 from PepperDash/feature/pdu-interface-joinmap
Added new Interfaces and JoinMap for PDUs
2022-06-21 15:40:54 -05:00
Andrew Welker
8ce390d650 Merge branch 'development' into feature/pdu-interface-joinmap 2022-06-21 13:42:17 -05:00
Neil Dorin
05066dc1ea Merge pull request #953 from PepperDash/hotfix/c2nio-factory-reference-update
Hotfix/c2nio factory reference update
2022-06-21 12:27:04 -06:00
Andrew Welker
70a78b540d Merge branch 'development' into feature/pdu-interface-joinmap 2022-06-21 13:12:50 -05:00
Neil Dorin
c56caff1cb Merge branch 'development' into feature/dmps-dm-fixes 2022-06-21 12:12:35 -06:00
Andrew Welker
5e22ca9c59 Merge branch 'development' into hotfix/c2nio-factory-reference-update 2022-06-21 13:12:02 -05:00
Andrew Welker
5131e73567 Merge pull request #944 from PepperDash/hotfix/zoom-recording-prompt
Hotfix/zoom recording prompt
2022-06-21 13:11:45 -05:00
Neil Dorin
e02c267988 Merge branch 'development' into hotfix/zoom-recording-prompt 2022-06-21 11:47:33 -06:00
Alex Johnson
53c9f9e664 Fixes issue where sometimes clear route doesn't work on DMPS3 2022-06-17 14:42:51 -04:00
Rodney Driscoll
794ba7e6dd GetStringOutputSig and GetUShortOutputSig return 2022-06-17 09:38:16 +10:00
Alex Johnson
5b94d89bc3 Improvements for DMPS3-4K-150 types 2022-06-15 20:26:32 -04:00
Alex Johnson
6dbdd0587d Reworks audio routing on DMPS-4K units. 2022-06-15 08:49:52 -04:00
Alex Johnson
1a5d4896e1 Fixes online feedback for DM endpoints that are attached to a 3 series DM chassis or a DMPS-4K unit. 2022-06-14 10:43:29 -04:00
Alex Johnson
50e9a7935f Adds HD-MD-8xn switcher type support 2022-06-14 10:25:06 -04:00
Alex Johnson
03e4c913ac Adds HD-MD-8xn switcher type support 2022-06-14 10:24:19 -04:00
Alex Johnson
b26e1b97aa Removes redundant check for DMPS-4K type. Property exists elsewhere 2022-06-14 10:23:51 -04:00
Alex Johnson
60b6cea697 Adds digital audio output volume control for DMPS to bridge 2022-06-14 10:13:02 -04:00
Alex Johnson
dfc0915fe0 Adds DM switcher name to bridge 2022-06-14 09:56:40 -04:00
Alex Johnson
96e3d52b95 Switch DMPS units to only wait until devices are registered before continuing. No need to wait for devices to be activated. 2022-06-14 09:43:59 -04:00
Neil Dorin
cd4f2d5edd Merge pull request #952 from PepperDash/hotfix/c2nio-factory-reference-update
fix: corrects issue #951, c2nio incorrect factory reference
2022-06-08 14:29:43 -06:00
Jason DeVito
59b18d713b fix: corrects issue #951, c2nio incorrect factory reference 2022-06-08 15:12:32 -05:00
Trevor Payne
1cc37b7521 feature:Converted PduOutlets Dictionary to ReadOnlyDictionary
feature:Removed redundant OutletCount property
2022-06-02 11:17:54 -05:00
Trevor Payne
86dfc395ec Rename IHasPowerReboot to IHasPowerCycle
Update naming scheme to Cycle from Reboot
2022-05-31 17:48:18 -05:00
Trevor Payne
05f3a7eb2c UpdateJoinmap Names 2022-05-31 17:46:13 -05:00
Trevor Payne
20beeb076a add new interfaces for implementing PDUs
added basic join map
2022-05-31 17:19:56 -05:00
Neil Dorin
a7db15d9fd Merge pull request #943 from PepperDash/hotfix/zoom-recording-prompt
Hotfix/zoom recording prompt
2022-05-18 17:14:19 -06:00
Neil Dorin
b8442e7048 feat(essentials): Format update for command 2022-05-18 16:33:21 -06:00
Neil Dorin
1e65c961c6 feat(essentials): Adds new interface capabilities
* ability to admit a participant from waiting room
* ability to acknowledge a meeting recording consent prompt
2022-05-17 15:36:00 -06:00
Neil Dorin
bdc4f0ae28 fix(essentials): updates recording property name 2022-05-17 13:20:53 -06:00
Neil Dorin
82ac34d3b6 fix(essentials): Updates Status.Call subscription mechanism to persist properly
Makes sure all subscriptions are un and resubscribed whenever Status.Call is constructed
2022-05-17 11:26:19 -06:00
Neil Dorin
23555e5174 Merge branch 'main' into hotfix/zoom-osd-device 2022-05-16 14:20:38 -06:00
Andrew Welker
a74753d4a3 Merge pull request #923 from PepperDash/feature/fileio
feature: add static fileio class to read and write files
2022-05-03 15:28:09 -06:00
Andrew Welker
768a93d44d Merge branch 'development' into feature/fileio 2022-05-02 13:40:30 -06:00
Andrew Welker
46cb10f452 Merge pull request #937 from PepperDash/hotfix/zoomroom-duplicate-passwordRequired-eventhandlers
Hotfix/zoomroom duplicate password required eventhandlers
2022-05-02 13:40:12 -06:00
Andrew Welker
5386f0fffb Merge branch 'development' into feature/fileio 2022-04-28 10:07:48 -06:00
Andrew Welker
ad3ae0de69 Merge branch 'development' into hotfix/zoomroom-duplicate-passwordRequired-eventhandlers 2022-04-28 10:07:24 -06:00
Andrew Welker
892167d236 Merge pull request #938 from PepperDash/release/1.10.0
Release/1.10.0
2022-04-28 10:07:06 -06:00
Andrew Welker
e843098ac3 Merge branch 'development' into release/1.10.0 2022-04-28 09:05:25 -06:00
Neil Dorin
7c892b4f71 Merge pull request #936 from PepperDash/hotfix/zoomroom-duplicate-passwordRequired-eventhandlers
fix: removed duplicate PasswordRequired event handler from LinkZoomRo…
2022-04-26 14:50:40 -06:00
Jason DeVito
1abe54fa48 fix: removed duplicate PasswordRequired event handler from LinkZoomRoomToApi method 2022-04-26 15:32:34 -05:00
Jason DeVito
309605ee38 fix: updated packages.config to reference PepperDash Core 1.1.1, previously referencing RC build 2022-03-29 16:04:14 -05:00
Jason DeVito
e2b8e356ff fix: Updated ZoomRoom constructor to build HdmiOutput1,2,3 2022-03-29 16:03:46 -05:00
Jason DeVito
832102f4bb feat: updated ExecuteSwitch to turn the display power on if _PowerIsOn is false 2022-03-29 16:02:59 -05:00
Neil Dorin
b23b7cb813 fix(essentials): #927 moves SetUpRouting() to constructor 2022-03-29 12:49:49 -06:00
Andrew Welker
b42d487c4c Merge pull request #918 from PepperDash/release/1.10.0
Release/1.10.0
2022-03-16 08:05:25 -06:00
Michael Willis
5f668c7173 Typo in RoutingPort Constructor - isInternal 2022-03-08 09:42:53 -07:00
Andrew Welker
6db5a9b2ca Merge pull request #913 from PepperDash/feature/cleanup-debug-statements
Feature/cleanup debug statements
2022-03-03 15:14:34 -07:00
Neil Dorin
89dd098ea6 feat(essentials): #912 Updates to GenericCommunicationMonitor to better monitor socket status 2022-03-03 14:39:54 -07:00
Neil Dorin
787c8eb954 feat(essentials): Adds new interface and event to notify if video unmute is requested 2022-03-01 21:43:38 -07:00
Neil Dorin
97b9ed5016 fix(essentials): Fixes SetupCameras to not add duplicate cameras to the list 2022-02-28 19:21:27 -07:00
Neil Dorin
06fdee313a fix(essentials): adds missing property decorators and unmutes video on camera select 2022-02-25 21:10:44 -07:00
Neil Dorin
b3f7568469 fix(essentials): updates to IHasDirectory and ZoomRoom
Prevents serialization of CurrentDirectoryResults object.
Modified OnDirectoryResultsReturne helper method for ZoomRoom to fix stripping of contacts
2022-02-24 22:03:03 -07:00
Neil Dorin
55ab593d73 feat(essentails): #911 swaps cisco comm monitor poll string 2022-02-24 14:34:38 -07:00
Neil Dorin
a06652ee61 chore(essentials): Cleans up some debug statements no longer needed 2022-02-21 12:06:09 -07:00
Neil Dorin
4f26df3149 Merge pull request #908 from PepperDash/feature/add-cisco-room-kit-features
Feature/add cisco room kit features
2022-02-15 16:16:18 -07:00
Neil Dorin
428edad38a Merge branch 'release/1.10.0' into feature/add-cisco-room-kit-features 2022-02-15 16:05:14 -07:00
Neil Dorin
f3431f287c Merge pull request #907 from PepperDash/feature/refine-zoomroom-addedcontact-feedback-subscription
fix(essentials): #901 Refines initial synchronization sequence
2022-02-15 15:52:14 -07:00
Jonathan Arndt
80b5fb6c7f CiscoSparkCodec > Removed inner IF of processQueuedCommands and added CrestronInvoke to CheckSyncStatus 2022-02-15 11:27:37 -08:00
Jonathan Arndt
6df594dd7f Updates to CiscoSparkCodec queue 2022-02-14 17:21:15 -08:00
Neil Dorin
e39c76001a feat(essentials): Updates to initial sync mechanism
Adds queue for all outgoing commands to codec that blocks until sync is established
2022-02-14 16:16:58 -07:00
Jonathan Arndt
d88a454499 fix(essentials): various bug fixes for hold FB, individual call end, incoming name-number fb, ipv4 address fb 2022-02-11 16:39:47 -08:00
Neil Dorin
b0e3fddec7 fix(essentials): fixes issue with local var scope when assigning actions for ending individual calls
Fixes Incoming call name/number feedback in bridge
2022-02-11 15:50:09 -07:00
Neil Dorin
0e5cecbfc3 fix(essentials): #901 Refines initial synchronization sequence
Makes sure that the AddedContact feedback subscription is excluded right away, but later included after the phonebook is retrieved.  This should ensure we get the initial phonebook and all subsequent additions at runtime while also minimizing initial data volume.
2022-02-11 14:16:40 -07:00
Andrew Welker
57dac392da Merge pull request #906 from PepperDash/feature/revise-zoomroom-gather-methodology
Feature/revise zoomroom gather methodology
2022-02-10 18:05:38 -07:00
Neil Dorin
348981d8cb fix(essntials): Fixes exception in OnLayoutChanged and fixes debug JSON formatting for Zoom responses 2022-02-10 17:33:06 -07:00
Neil Dorin
bee3f0caf3 Merge branch 'release/1.10.0' into feature/revise-zoomroom-gather-methodology 2022-02-10 16:02:55 -07:00
Neil Dorin
79a3a8ed7e fix(essentials): #901 Overhaul's feedback processing for efficiency
Updates to address changes to ZRAAPI v1.1 and ZoomRooms 5.9.4
2022-02-10 15:49:53 -07:00
Neil Dorin
cb3c80ff8f fix(essentials): fixes to on hold feedback and call status xsig 2022-02-09 17:44:53 -07:00
Neil Dorin
0bb4b6edd4 fix(essentials): doh! fixes issue where IsOnHold would get set to false if response contains no PlacedOhHold object 2022-02-09 17:30:26 -07:00
Neil Dorin
e4a4564bbc fix(essentials): Attempts to set OnHold an alternative way 2022-02-09 17:21:19 -07:00
Neil Dorin
b0288951eb fix(essentials): removes logic to disconnect and reinitialize on malformed json response 2022-02-09 17:15:58 -07:00
Neil Dorin
bfdc882eb6 fix(essentials): Adds logic to recover from malformed json response on initial communication.
Adds better formatting for active calls list print to console
2022-02-09 17:07:18 -07:00
Neil Dorin
7a2e99f145 feat(essentials): Adds HoldAllCalls join and action 2022-02-09 16:50:06 -07:00
Neil Dorin
db67f97a1f fix(essentials): add local scope variable for indexer in hold/resume call loop 2022-02-09 16:46:19 -07:00
Neil Dorin
102ae3ad4f fix(essentials): second attempt to get on hold fb working 2022-02-09 16:41:37 -07:00
Neil Dorin
7dd6b3a9b6 fix(essentials): fixes index off by 1 error and updates call status to check for "OnHold" as status value 2022-02-09 16:31:31 -07:00
Neil Dorin
e24965eb54 fix(essentials): fixes ValueChagnedAction to run both feedback updates instead of one 2022-02-09 15:37:55 -07:00
Neil Dorin
9d80954214 fix(essentials): Adds check for SendingMode property value before attempting to set fb 2022-02-09 15:10:39 -07:00
Jonathan Arndt
70c5df9040 Removed add camera to device manager 2022-02-09 14:09:07 -08:00
Neil Dorin
89a7f2aa80 fix(essentials): Add a condition to check for an empty configuration.presentation object response and return to avoid null ref ex 2022-02-09 14:54:19 -07:00
Neil Dorin
90023621dc fix(essentials): Adds some better console log comments and calls SetUpCameras() after reading data from codec. 2022-02-09 14:48:45 -07:00
Neil Dorin
adbce916ba feat(essentials): Adds ability to read camera info from codec rather than just from config 2022-02-09 14:34:25 -07:00
Neil Dorin
b97783603b feat(essentials): Adds analog fb join for recent calls count to VideoCodecControllerJoinMap and bridge 2022-02-09 14:14:44 -07:00
Neil Dorin
db526cdd40 fix(essentials): fixes exception when parsing presentation local instance ghosted response 2022-02-09 14:09:54 -07:00
Neil Dorin
db982f4490 feat(essentials): Adds ability to select and dial contact methods for directory contacts via SIMPL bridge 2022-02-09 14:00:49 -07:00
Jonathan Arndt
c84525ddef Update recent call history and call method to protect for zero value from SIMPL 2022-02-09 11:39:35 -08:00
Andrew Welker
a3b078d327 Merge pull request #904 from PepperDash/hotfix/zoomroom-queue-size
Hotfix/zoomroom queue size
2022-02-09 12:34:29 -07:00
Neil Dorin
b9c07b01e9 Merge pull request #903 from PepperDash/hotfix/zoomroom-fix-phonebook-autodownload
Hotfix/zoomroom fix phonebook autodownload
2022-02-09 09:08:23 -07:00
Jonathan Arndt
faabdde3f7 Update VideoCodecBase class UpdateDirectoryXSig method removing the check if the FolderId is null or empty as that check would be device specific 2022-02-08 16:31:45 -08:00
Jonathan Arndt
402754b69e Update VideoCodecBase class UpdateDirectoryXSig method removing the check if the FolderId is null or empty as that check would be device specific 2022-02-08 16:31:26 -08:00
Jonathan Arndt
84b39a959e Update VideoCodecBase class UpdateDirectoryXSig method removing the check if the FolderId is null or empty as that check would be device specific 2022-02-08 16:31:18 -08:00
Jonathan Arndt
93bfcc7baa Add logic to subscribe to PhoneBookSyncState during the CustomActivate method within CiscoSparkCodec class 2022-02-08 16:24:54 -08:00
Jonathan Arndt
64352811c5 Update VideoCodecBase.LinkVideoCodecCameraToApi FOR loop checking camera names to first check camera count 2022-02-08 13:31:13 -08:00
Alex Johnson
3a74abd061 Merge branch 'hotfix/zoomroom-fix-phonebook-autodownload' into hotfix/zoomroom-queue-size 2022-02-08 16:07:17 -05:00
Jonathan Arndt
b5589364ff Instantiate xConfiguration members of Configuration, AutoAnswer, and Conference classes 2022-02-08 12:15:29 -08:00
Jason DeVito
6cd1a03ee0 fix: Updated LinkVideoCodecToApi trilist.onlinestatus change to fix CameraSupportsAudioMode passing true rather than property. 2022-02-08 09:38:40 -06:00
Jason DeVito
e19b0ba530 fix: updated yaml files to point to windows-2019 to resolve action failures. 2022-02-07 16:58:24 -06:00
Jason DeVito
7b2498ac6b fix: added JSON property decorator to configuration properties. 2022-02-07 16:50:35 -06:00
Jason DeVito
d9181c780f fix: Updated _receiveQueue capacity from 512 to 2048 to help with processing large amounts of push data received from zoom. 2022-02-07 16:45:08 -06:00
Neil Dorin
bc826c9e17 fix(essentials): updates action workflows to specify windows-2019 instead of latest 2022-02-04 16:41:57 -07:00
Neil Dorin
c6023ad700 fix(essentials): Adds missing help message property to tech room config and exposes config 2022-02-04 15:51:29 -07:00
Neil Dorin
742ff4bc1b fix(essentials): Updates config type for Vtc1 type rooms 2022-02-02 10:18:20 -07:00
Neil Dorin
2502947df8 Merge pull request #899 from PepperDash/hotfix/queue-thread-name
Add name to `GenericQueue` Thread
2022-02-02 10:16:38 -07:00
Neil Dorin
7075da5b68 Merge pull request #900 from PepperDash/hotfix/queue-thread-name
Add name to `GenericQueue` Thread - Release Branch
2022-02-02 10:16:17 -07:00
Andrew Welker
abdd1b38f8 feat (Core): #898 Add name to GenericQueue Thread
This name will show up in console using the `SSPTASKS` command and allow for easier troubleshooting.
2022-02-02 09:22:13 -07:00
Neil Dorin
5d5dee2e5e Merge pull request #892 from PepperDash/hotfix/generic-relay-dm-rmc-issues
Add `IRelayPorts` interface to `DmRmc4kzScalerCController`
2022-01-26 11:57:13 -07:00
Neil Dorin
611f0bec2e fix(essentials): #865 Adds DialselectedRecentCallItem join 2021-12-07 19:40:03 -07:00
Neil Dorin
90e22e9136 fix(essentials): #865 Adds SelectedContactMethodCount join to report the number of methods for the selected contact 2021-12-07 16:45:14 -07:00
Neil Dorin
4552a15cbb fix(essentials): #865 Updates to join map and bridging based on feedback from testing 2021-12-07 16:22:15 -07:00
Neil Dorin
c685608f67 fix(essentials): reworks logic for setting up cameras to wait until codec communication sync has finished 2021-11-17 12:24:58 -07:00
Neil Dorin
cdafaf1bcb fix(essentials): Adds missing constructor for Configuration RootObject 2021-11-17 11:37:29 -07:00
Neil Dorin
d8aef1a0da feat(essentials): #865 More updates
Adds ability to disable auto dialing behavior of selected directory contact.
Adds XSig to send contact method info across bridge
Adds XSig to send call history data across bridge and also joins to manipulate
2021-11-12 22:07:11 -07:00
Neil Dorin
0ff29695e7 feat(essentials): #865 Updates join map and bridge for new features
Adds control and feedback for presentation source
Updates camera setup, selection and feedback
Adds ringtone volume control/feedback
Adds call hold/resume/join control to bridge
Adds new config properties for camera info
2021-11-11 21:05:57 -07:00
Neil Dorin
8aae23db9e feat(essentials): #865 Updates to Bridging
Adds ability to end individual calls, report connected call count, report call duration and hold status, send DTMF tones to individual call index and select far end presets
2021-11-11 17:23:11 -07:00
Neil Dorin
a043309bb1 feat(essentials): More updates to add ringtone volume and focus near/far to bridge 2021-11-10 18:02:23 -07:00
Neil Dorin
dc53ce42e7 feat(essentials): Adds interface and implementation to join calls 2021-11-10 14:08:12 -07:00
Neil Dorin
6dd882b1a0 feat(essentials): Adds hold/resume/duration features to call status 2021-11-10 13:49:43 -07:00
114 changed files with 9148 additions and 4120 deletions

View File

@@ -98,7 +98,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-latest
runs-on: windows-2019
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1

View File

@@ -82,7 +82,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-latest
runs-on: windows-2019
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1

View File

@@ -53,14 +53,14 @@ namespace PepperDash.Essentials
// to allow any HD-BaseT DM endpoints to register first.
if (Global.ControlSystemIsDmpsType)
{
Debug.Console(2, "******************* InitializeSystem() Entering **********************");
Debug.Console(1, "******************* InitializeSystem() Entering **********************");
_initializeEvent = new CEvent();
DeviceManager.AllDevicesActivated += (o, a) =>
DeviceManager.AllDevicesRegistered += (o, a) =>
{
_initializeEvent.Set();
Debug.Console(2, "******************* InitializeSystem() Exiting **********************");
Debug.Console(1, "******************* InitializeSystem() Exiting **********************");
};
_initializeEvent.Wait(30000);
@@ -195,6 +195,8 @@ namespace PepperDash.Essentials
}
else // Handles Linux OS (Virtual Control)
{
Debug.SetDebugLevel(2);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", Global.AssemblyVersion);
// Set path to User/

View File

@@ -211,6 +211,9 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("fusion")]
public EssentialsRoomFusionConfig Fusion { get; set; }
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)]
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
@@ -227,6 +230,12 @@ namespace PepperDash.Essentials.Room.Config
}
}
public class EssentialsRoomUiBehaviorConfig
{
[JsonProperty("disableActivityButtonsWhileWarmingCooling")]
public bool DisableActivityButtonsWhileWarmingCooling { get; set; }
}
public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig
{
[JsonProperty("defaultAudioKey")]

View File

@@ -56,6 +56,9 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("mirroredTuners")]
public Dictionary<uint, string> MirroredTuners { get; set; }
[JsonProperty("helpMessage")]
public string HelpMessage { get; set; }
/// <summary>
/// Indicates the room
/// </summary>

View File

@@ -89,7 +89,7 @@ namespace PepperDash.Essentials
}
}
public EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; private set; }
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
private List<IRoutingSinkWithSwitching> Displays;
@@ -199,7 +199,7 @@ namespace PepperDash.Essentials
{
try
{
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsConferenceRoomPropertiesConfig>
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
(config.Properties.ToString());
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
@@ -361,7 +361,7 @@ namespace PepperDash.Essentials
protected override void CustomSetConfig(DeviceConfig config)
{
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsConferenceRoomPropertiesConfig>(config.Properties.ToString());
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
if (newPropertiesConfig != null)
PropertiesConfig = newPropertiesConfig;

View File

@@ -101,7 +101,7 @@ namespace PepperDash.Essentials
}
}
public EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; private set; }
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
@@ -708,11 +708,12 @@ namespace PepperDash.Essentials
IRoutingSink dest = null;
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
dest = DefaultAudioDevice as IRoutingSink;
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
dest = DefaultDisplay;
else
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
if (dest == null)
{
@@ -744,6 +745,28 @@ namespace PepperDash.Essentials
{
//Implement this
}
protected override bool AllowVacancyTimerToStart()
{
bool allowVideo = true;
bool allowAudio = true;
if (VideoCodec != null)
{
Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in a video call", Key, VideoCodec.IsInCall ? "is" : "is not");
allowVideo = !VideoCodec.IsInCall;
}
if (AudioCodec != null)
{
Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in an audio call", Key, AudioCodec.IsInCall ? "is" : "is not");
allowAudio = !AudioCodec.IsInCall;
}
Debug.Console(2, this, "Room {0} allowing vacancy timer to start: {1}", Key, allowVideo && allowAudio);
return allowVideo && allowAudio;
}
/// <summary>
/// Does what it says

View File

@@ -19,7 +19,7 @@ namespace PepperDash.Essentials
{
public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
{
private readonly EssentialsTechRoomConfig _config;
public EssentialsTechRoomConfig PropertiesConfig { get; private set; }
private readonly Dictionary<string, TwoWayDisplayBase> _displays;
private readonly DevicePresetsModel _tunerPresets;
@@ -57,16 +57,16 @@ namespace PepperDash.Essentials
public EssentialsTechRoom(DeviceConfig config) : base(config)
{
_config = config.Properties.ToObject<EssentialsTechRoomConfig>();
PropertiesConfig = config.Properties.ToObject<EssentialsTechRoomConfig>();
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName);
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), PropertiesConfig.PresetsFileName);
_tunerPresets.SetFileName(_config.PresetsFileName);
_tunerPresets.SetFileName(PropertiesConfig.PresetsFileName);
_tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
_tuners = GetDevices<IRSetTopBoxBase>(_config.Tuners);
_displays = GetDevices<TwoWayDisplayBase>(_config.Displays);
_tuners = GetDevices<IRSetTopBoxBase>(PropertiesConfig.Tuners);
_displays = GetDevices<TwoWayDisplayBase>(PropertiesConfig.Displays);
RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
@@ -153,7 +153,7 @@ namespace PepperDash.Essentials
private void CreateOrUpdateScheduledEvents()
{
var eventsConfig = _config.ScheduledEvents;
var eventsConfig = PropertiesConfig.ScheduledEvents;
GetOrCreateScheduleGroup();
@@ -207,21 +207,21 @@ namespace PepperDash.Essentials
{
//update config based on key of scheduleEvent
GetOrCreateScheduleGroup();
var existingEventIndex = _config.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
var existingEventIndex = PropertiesConfig.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
if (existingEventIndex < 0)
{
_config.ScheduledEvents.Add(scheduledEvent);
PropertiesConfig.ScheduledEvents.Add(scheduledEvent);
}
else
{
_config.ScheduledEvents[existingEventIndex] = scheduledEvent;
PropertiesConfig.ScheduledEvents[existingEventIndex] = scheduledEvent;
}
//create or update event based on config
CreateOrUpdateSingleEvent(scheduledEvent);
//save config
Config.Properties = JToken.FromObject(_config);
Config.Properties = JToken.FromObject(PropertiesConfig);
CustomSetConfig(Config);
//Fire Event
@@ -230,7 +230,7 @@ namespace PepperDash.Essentials
public List<ScheduledEventConfig> GetScheduledEvents()
{
return _config.ScheduledEvents ?? new List<ScheduledEventConfig>();
return PropertiesConfig.ScheduledEvents ?? new List<ScheduledEventConfig>();
}
private void OnScheduledEventUpdate()
@@ -242,14 +242,14 @@ namespace PepperDash.Essentials
return;
}
handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.ScheduledEvents});
handler(this, new ScheduledEventEventArgs {ScheduledEvents = PropertiesConfig.ScheduledEvents});
}
public event EventHandler<ScheduledEventEventArgs> ScheduledEventsChanged;
private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
{
var eventConfig = _config.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
var eventConfig = PropertiesConfig.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
if (eventConfig == null)
{
@@ -286,11 +286,11 @@ Params: {2}"
{
Debug.Console(2, this, "Room Powering On");
var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs;
var dummySource = DeviceManager.GetDeviceForKey(PropertiesConfig.DummySourceKey) as IRoutingOutputs;
if (dummySource == null)
{
Debug.Console(1, this, "Unable to get source with key: {0}", _config.DummySourceKey);
Debug.Console(1, this, "Unable to get source with key: {0}", PropertiesConfig.DummySourceKey);
return;
}
@@ -376,12 +376,12 @@ Params: {2}"
bridge.AddJoinMap(Key, joinMap);
}
if (_config.IsPrimary)
if (PropertiesConfig.IsPrimary)
{
Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring");
if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0)
if (PropertiesConfig.MirroredTuners != null && PropertiesConfig.MirroredTuners.Count > 0)
{
foreach (var tuner in _config.MirroredTuners)
foreach (var tuner in PropertiesConfig.MirroredTuners)
{
var f = CurrentPresetsFeedbacks[tuner.Value];
@@ -423,9 +423,9 @@ Params: {2}"
{
Debug.Console(1, this, "Linking Secondary system Tuner Preset Mirroring");
if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0)
if (PropertiesConfig.MirroredTuners != null && PropertiesConfig.MirroredTuners.Count > 0)
{
foreach (var tuner in _config.MirroredTuners)
foreach (var tuner in PropertiesConfig.MirroredTuners)
{
var t = _tuners[tuner.Value];

View File

@@ -7,7 +7,7 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay, IHasCurrentVolumeControls
{
bool ExcludeFromGlobalFunctions { get; }

View File

@@ -10,7 +10,7 @@ namespace PepperDash.Essentials
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
{
EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; }
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
bool ExcludeFromGlobalFunctions { get; }

View File

@@ -11,211 +11,38 @@ using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.PageManagers;
using PepperDash.Essentials.Core.UI;
using Newtonsoft.Json;
namespace PepperDash.Essentials
{
public class EssentialsTouchpanelController : EssentialsDevice, IHasBasicTriListWithSmartObject
{
private CrestronTouchpanelPropertiesConfig _propertiesConfig;
public BasicTriListWithSmartObject Panel { get; private set; }
public class EssentialsTouchpanelController : TouchpanelBase
{
public PanelDriverBase PanelDriver { get; private set; }
CTimer BacklightTransitionedOnTimer;
public EssentialsTouchpanelController(string key, string name, Tswx52ButtonVoiceControl tsw,
string projectName, string sgdPath)
: base(key, name)
{
Panel = tsw;
if (!string.IsNullOrEmpty(sgdPath))
Panel.LoadSmartObjects(sgdPath);
else
Debug.Console(1, this, "No SGD file path defined");
tsw.SigChange += Panel_SigChange;
}
public EssentialsTouchpanelController(string key, string name, Dge100 dge, string projectName, string sgdPath)
: base(key, name)
{
Panel = dge;
if (!string.IsNullOrEmpty(sgdPath))
Panel.LoadSmartObjects(sgdPath);
else
Debug.Console(1, this, "No SGD file path defined");
dge.SigChange += Panel_SigChange;
}
/// <summary>
/// Config constructor
/// </summary>
public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id)
: base(key, name)
public EssentialsTouchpanelController(string key, string name, BasicTriListWithSmartObject panel, CrestronTouchpanelPropertiesConfig config)
: base(key, name, panel, config)
{
_propertiesConfig = props;
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating touchpanel hardware...");
type = type.ToLower();
try
{
if (type == "crestronapp")
{
var app = new CrestronApp(id, Global.ControlSystem);
app.ParameterProjectName.Value = props.ProjectName;
Panel = app;
}
else if (type == "xpanel")
Panel = new XpanelForSmartGraphics(id, Global.ControlSystem);
else if (type == "tsw550")
Panel = new Tsw550(id, Global.ControlSystem);
else if (type == "tsw552")
Panel = new Tsw552(id, Global.ControlSystem);
else if (type == "tsw560")
Panel = new Tsw560(id, Global.ControlSystem);
else if (type == "tsw750")
Panel = new Tsw750(id, Global.ControlSystem);
else if (type == "tsw752")
Panel = new Tsw752(id, Global.ControlSystem);
else if (type == "tsw760")
Panel = new Tsw760(id, Global.ControlSystem);
else if (type == "tsw1050")
Panel = new Tsw1050(id, Global.ControlSystem);
else if (type == "tsw1052")
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);
return;
}
}
catch (Exception e)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
return;
}
// Reserved sigs
if (Panel is TswFt5ButtonSystem)
{
var tsw = Panel as TswFt5ButtonSystem;
tsw.ExtenderSystemReservedSigs.Use();
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
}
if (Panel.Register() != eDeviceRegistrationUnRegistrationResponse.Success)
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Registration failed. Continuing, but panel may not function: {0}", Panel.RegistrationFailureReason);
// Give up cleanly if SGD is not present.
var sgdName = Global.FilePathPrefix + "sgd" + Global.DirectorySeparator + props.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "Smart object file '{0}' not present in User folder. Looking for embedded file", sgdName);
sgdName = Global.ApplicationDirectoryPathPrefix + Global.DirectorySeparator + "SGD" + Global.DirectorySeparator + props.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "Unable to find SGD file '{0}' in User sgd or application SGD folder. Exiting touchpanel load.", sgdName);
return;
}
}
Panel.LoadSmartObjects(sgdName);
Panel.SigChange += Panel_SigChange;
AddPostActivationAction(() =>
{
// Check for IEssentialsRoomCombiner in DeviceManager and if found, subscribe to its event
var roomCombiner = DeviceManager.AllDevices.FirstOrDefault((d) => d is IEssentialsRoomCombiner) as IEssentialsRoomCombiner;
if (roomCombiner != null)
{
// Subscribe to the even
roomCombiner.RoomCombinationScenarioChanged += new EventHandler<EventArgs>(roomCombiner_RoomCombinationScenarioChanged);
// Connect to the initial roomKey
if (roomCombiner.CurrentScenario != null)
{
// Use the current scenario
DetermineRoomKeyFromScenario(roomCombiner.CurrentScenario);
}
else
{
// Current Scenario not yet set. Use default
SetupPanelDrivers(_propertiesConfig.DefaultRoomKey);
}
}
else
{
// No room combiner, use the default key
SetupPanelDrivers(_propertiesConfig.DefaultRoomKey);
}
});
}
void roomCombiner_RoomCombinationScenarioChanged(object sender, EventArgs e)
{
var roomCombiner = sender as IEssentialsRoomCombiner;
DetermineRoomKeyFromScenario(roomCombiner.CurrentScenario);
}
/// <summary>
/// Determines the room key to use based on the scenario
/// </summary>
/// <param name="scenario"></param>
void DetermineRoomKeyFromScenario(IRoomCombinationScenario scenario)
{
string newRoomKey = null;
if (scenario.UiMap.ContainsKey(Key))
{
newRoomKey = scenario.UiMap[Key];
}
else if (scenario.UiMap.ContainsKey(_propertiesConfig.DefaultRoomKey))
{
newRoomKey = scenario.UiMap[_propertiesConfig.DefaultRoomKey];
}
SetupPanelDrivers(newRoomKey);
}
/// <summary>
/// Sets up drivers and links them to the room specified
/// </summary>
/// <param name="roomKey">key of room to link the drivers to</param>
void SetupPanelDrivers(string roomKey)
protected override void SetupPanelDrivers(string roomKey)
{
// Clear out any existing actions
Panel.ClearAllSigActions();
Debug.Console(0, this, "Linking TP '{0}' to Room '{1}'", Key, roomKey);
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, _propertiesConfig);
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, _config);
// Then the sub drivers
// spin up different room drivers depending on room type
@@ -224,15 +51,15 @@ namespace PepperDash.Essentials
{
// Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _propertiesConfig);
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _config);
// Header Driver
Debug.Console(0, this, "Adding header driver");
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _propertiesConfig);
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _config);
// AV Driver
Debug.Console(0, this, "Adding huddle space AV driver");
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, _propertiesConfig);
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, _config);
avDriver.DefaultRoomKey = roomKey;
mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom;
@@ -241,7 +68,7 @@ namespace PepperDash.Essentials
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, this, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _propertiesConfig);
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _config);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
@@ -270,13 +97,13 @@ namespace PepperDash.Essentials
Debug.Console(0, this, "Adding huddle space VTC AV driver");
// Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _propertiesConfig);
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _config);
// Header Driver
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _propertiesConfig);
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _config);
// AV Driver
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, _propertiesConfig);
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, _config);
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(Panel, avDriver,
(room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
@@ -289,7 +116,7 @@ namespace PepperDash.Essentials
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, this, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _propertiesConfig);
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _config);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
@@ -338,13 +165,7 @@ namespace PepperDash.Essentials
driver.Show();
}
void HomePressed()
{
if (BacklightTransitionedOnTimer == null)
PanelDriver.BackButtonPressed();
}
void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
{
// If the sig is transitioning on, mark it in case it was home button that transitioned it
var blOnSig = (Panel as TswFt5ButtonSystem).ExtenderSystemReservedSigs.BacklightOnFeedback;
@@ -382,26 +203,6 @@ namespace PepperDash.Essentials
act(value);
}
}
void Panel_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level == 2)
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
{
var uo = args.Button.UserObject;
if(uo is Action<bool>)
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
}
}
public class EssentialsTouchpanelControllerFactory : EssentialsDeviceFactory<EssentialsTouchpanelController>
@@ -414,13 +215,74 @@ namespace PepperDash.Essentials
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
var props = Newtonsoft.Json.JsonConvert.DeserializeObject<CrestronTouchpanelPropertiesConfig>(dc.Properties.ToString());
var props = JsonConvert.DeserializeObject<CrestronTouchpanelPropertiesConfig>(dc.Properties.ToString());
var panel = GetPanelForType(dc.Type, comm.IpIdInt, props.ProjectName);
if (panel == null)
{
Debug.Console(0, "Unable to create Touchpanel for type {0}. Touchpanel Controller WILL NOT function correctly", dc.Type);
}
Debug.Console(1, "Factory Attempting to create new EssentialsTouchpanelController");
var panelController = new EssentialsTouchpanelController(dc.Key, dc.Name, dc.Type, props, comm.IpIdInt);
var panelController = new EssentialsTouchpanelController(dc.Key, dc.Name, panel, props);
return panelController;
}
private BasicTriListWithSmartObject GetPanelForType(string type, uint id, string projectName)
{
type = type.ToLower();
try
{
if (type == "crestronapp")
{
var app = new CrestronApp(id, Global.ControlSystem);
app.ParameterProjectName.Value = projectName;
return app;
}
else if (type == "xpanel")
return new XpanelForSmartGraphics(id, Global.ControlSystem);
else if (type == "tsw550")
return new Tsw550(id, Global.ControlSystem);
else if (type == "tsw552")
return new Tsw552(id, Global.ControlSystem);
else if (type == "tsw560")
return new Tsw560(id, Global.ControlSystem);
else if (type == "tsw750")
return new Tsw750(id, Global.ControlSystem);
else if (type == "tsw752")
return new Tsw752(id, Global.ControlSystem);
else if (type == "tsw760")
return new Tsw760(id, Global.ControlSystem);
else if (type == "tsw1050")
return new Tsw1050(id, Global.ControlSystem);
else if (type == "tsw1052")
return new Tsw1052(id, Global.ControlSystem);
else if (type == "tsw1060")
return new Tsw1060(id, Global.ControlSystem);
else if (type == "tsw570")
return new Tsw570(id, Global.ControlSystem);
else if (type == "tsw770")
return new Tsw770(id, Global.ControlSystem);
else if (type == "ts770")
return new Ts770(id, Global.ControlSystem);
else if (type == "tsw1070")
return new Tsw1070(id, Global.ControlSystem);
else if (type == "ts1070")
return new Ts1070(id, Global.ControlSystem);
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
return null;
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
return null;
}
}
}
}

View File

@@ -97,10 +97,10 @@ namespace PepperDash.Essentials
{
TriList.SetSigFalseAction(ButtonPressJoinBase + 1, ShadeDevice.Open);
TriList.SetSigFalseAction(ButtonPressJoinBase + 2, (ShadeDevice as IShadesOpenCloseStop).StopOrPreset);
if(ShadeDevice is RelayControlledShade)
TriList.SetString(StringJoinBase + 2, (ShadeDevice as RelayControlledShade).StopOrPresetButtonLabel);
TriList.SetSigFalseAction(ButtonPressJoinBase + 2, (ShadeDevice as IShadesOpenCloseStop).Stop);
if (ShadeDevice is IShadesOpenCloseStop)
TriList.SetString(StringJoinBase + 2, "Stop");
TriList.SetSigFalseAction(ButtonPressJoinBase + 3, ShadeDevice.Close);
}

View File

@@ -493,10 +493,10 @@ namespace PepperDash.Essentials
// 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.ToString("t", Global.Culture) : "");
//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

View File

@@ -52,7 +52,7 @@ namespace PepperDash.Essentials
{
var prevJoin = CurrentJoin;
var wasShown = _IsShown;
Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
//Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
if (CurrentJoin == join && TriList.BooleanInput[join].BoolValue)
return;
SetButDontShow(join);
@@ -71,7 +71,7 @@ namespace PepperDash.Essentials
var prevJoin = CurrentJoin;
var wasShown = IsShown;
Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
//Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
if (CurrentJoin == join)
HideAndClear();
else
@@ -92,7 +92,7 @@ namespace PepperDash.Essentials
{
var prevJoin = CurrentJoin;
var wasShown = IsShown;
Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
//Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
Hide();
CurrentJoin = 0;
@@ -108,7 +108,7 @@ namespace PepperDash.Essentials
var prevJoin = CurrentJoin;
var wasShown = IsShown;
Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
//Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
if (CurrentJoin > 0)
{
TriList.BooleanInput[CurrentJoin].BoolValue = false;
@@ -125,7 +125,7 @@ namespace PepperDash.Essentials
var prevJoin = CurrentJoin;
var wasShown = IsShown;
Debug.Console(2, "Trilist {0:X2}, interlock showing {1}", TriList.ID, CurrentJoin);
//Debug.Console(2, "Trilist {0:X2}, interlock showing {1}", TriList.ID, CurrentJoin);
if (CurrentJoin > 0)
{
TriList.BooleanInput[CurrentJoin].BoolValue = true;

View File

@@ -51,7 +51,7 @@ namespace PepperDash.Essentials
public override void Show()
{
Debug.Console(2, "Showing ScreenSaverController: {0:X2}", TriList.ID);
//Debug.Console(2, "Showing ScreenSaverController: {0:X2}", TriList.ID);
if (_parent.AvDriver != null)
{
@@ -67,11 +67,11 @@ namespace PepperDash.Essentials
public override void Hide()
{
Debug.Console(2, "Hiding ScreenSaverController: {0:X2}", TriList.ID);
//Debug.Console(2, "Hiding ScreenSaverController: {0:X2}", TriList.ID);
if (PositionTimer != null)
{
Debug.Console(2, "Stopping PositionTimer: {0:X2}", TriList.ID);
//Debug.Console(2, "Stopping PositionTimer: {0:X2}", TriList.ID);
PositionTimer.Stop();
PositionTimer.Dispose();
PositionTimer = null;
@@ -89,7 +89,7 @@ namespace PepperDash.Essentials
void StartPositionTimer()
{
Debug.Console(2, "Starting Position Timer: {0:X2}", TriList.ID);
//Debug.Console(2, "Starting Position Timer: {0:X2}", TriList.ID);
if (PositionTimer == null)
{
@@ -122,7 +122,7 @@ namespace PepperDash.Essentials
CurrentPositionIndex = 0;
}
Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0} ID: {1:X2}", CurrentPositionIndex, TriList.ID);
//Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0} ID: {1:X2}", CurrentPositionIndex, TriList.ID);
}
//
@@ -134,7 +134,7 @@ namespace PepperDash.Essentials
void ClearAllPositions()
{
Debug.Console(2, "Hiding all screensaver positions: {0:X2}", TriList.ID);
//Debug.Console(2, "Hiding all screensaver positions: {0:X2}", TriList.ID);
PositionInterlock.HideAndClear();
}

View File

@@ -394,35 +394,51 @@ namespace PepperDash.Essentials.Core.Bridges
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
BasicTriList eisc;
switch (dc.Type.ToLower())
{
case "eiscapiadv":
case "eiscapiadvanced":
{
var eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
break;
}
case "eiscapiadvancedserver":
{
var eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
break;
}
case "eiscapiadvancedclient":
{
var eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
break;
}
case "vceiscapiadv":
case "vceiscapiadvanced":
{
var eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, InitialParametersClass.RoomId,
if (string.IsNullOrEmpty(controlProperties.RoomId))
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to build VC-4 EISC Client for device {0}. Room ID is missing or empty", dc.Key);
eisc = null;
break;
}
eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, controlProperties.RoomId,
Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
break;
}
default:
return null;
eisc = null;
break;
}
if (eisc == null)
{
return null;
}
return new EiscApiAdvanced(dc, eisc);
}
}

View File

@@ -24,6 +24,10 @@ namespace PepperDash.Essentials.Core.Bridges
JoinType = eJoinType.Digital
});
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("SystemId")]
public JoinDataComplete SystemId = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis SystemId Get/Set/Trigger/", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalog });

View File

@@ -17,6 +17,10 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MixerEqPresetRecall")]
public JoinDataComplete MixerEqPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Eq Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MasterVolumeMuteOn")]
public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });

View File

@@ -0,0 +1,60 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class PduJoinMapBase : JoinMapBaseAdvanced
{
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("Online")]
public JoinDataComplete Online = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletCount")]
public JoinDataComplete OutletCount = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Number of COntrolled Outlets", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("OutletName")]
public JoinDataComplete OutletName = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("OutletEnabled")]
public JoinDataComplete OutletEnabled = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Enabled", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerCycle")]
public JoinDataComplete OutletPowerCycle = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Cycle", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOn")]
public JoinDataComplete OutletPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOff")]
public JoinDataComplete OutletPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
public PduJoinMapBase(uint joinStart)
:base(joinStart, typeof(PduJoinMapBase))
{
}
/// <summary>
/// Constructor to use when extending this Join map
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
/// <param name="type">Type of the child join map</param>
public PduJoinMapBase(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
{
@@ -20,7 +20,21 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("1")]
[JoinName("SendDtmfToSpecificCallIndex")]
public JoinDataComplete SendDtmfToSpecificCallIndex = new JoinDataComplete(
new JoinData
{
JoinNumber = 10,
JoinSpan = 1
},
new JoinMetadata
{
Description = "If High, will send DTMF tones to the call set by SelectCall analog. If low sends DTMF tones to last connected call.",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Dtmf1")]
public JoinDataComplete Dtmf1 = new JoinDataComplete(
new JoinData
{
@@ -34,7 +48,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("2")]
[JoinName("Dtmf2")]
public JoinDataComplete Dtmf2 = new JoinDataComplete(
new JoinData
{
@@ -48,7 +62,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("3")]
[JoinName("Dtmf3")]
public JoinDataComplete Dtmf3 = new JoinDataComplete(
new JoinData
{
@@ -62,7 +76,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("4")]
[JoinName("Dtmf4")]
public JoinDataComplete Dtmf4 = new JoinDataComplete(
new JoinData
{
@@ -76,7 +90,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("5")]
[JoinName("Dtmf5")]
public JoinDataComplete Dtmf5 = new JoinDataComplete(
new JoinData
{
@@ -90,7 +104,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("6")]
[JoinName("Dtmf6")]
public JoinDataComplete Dtmf6 = new JoinDataComplete(
new JoinData
{
@@ -104,7 +118,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("7")]
[JoinName("Dtmf7")]
public JoinDataComplete Dtmf7 = new JoinDataComplete(
new JoinData
{
@@ -118,7 +132,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("8")]
[JoinName("Dtmf8")]
public JoinDataComplete Dtmf8 = new JoinDataComplete(
new JoinData
{
@@ -132,7 +146,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("9")]
[JoinName("Dtmf9")]
public JoinDataComplete Dtmf9 = new JoinDataComplete(
new JoinData
{
@@ -146,7 +160,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("0")]
[JoinName("Dtmf0")]
public JoinDataComplete Dtmf0 = new JoinDataComplete(
new JoinData
{
@@ -160,7 +174,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("*")]
[JoinName("DtmfStar")]
public JoinDataComplete DtmfStar = new JoinDataComplete(
new JoinData
{
@@ -174,7 +188,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("#")]
[JoinName("DtmfPound")]
public JoinDataComplete DtmfPound = new JoinDataComplete(
new JoinData
{
@@ -188,8 +202,8 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("EndCall")]
public JoinDataComplete EndCall = new JoinDataComplete(
[JoinName("EndAllCalls")]
public JoinDataComplete EndAllCalls = new JoinDataComplete(
new JoinData
{
JoinNumber = 24,
@@ -197,7 +211,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Hang Up",
Description = "End All Calls",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
@@ -226,7 +240,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
new JoinMetadata
{
Description = "Speed Dial",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
@@ -281,12 +295,12 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Dial manual string",
Description = "Dial manual string specified by CurrentDialString serial join",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DialPhoneCall")]
[JoinName("DialPhone")]
public JoinDataComplete DialPhone = new JoinDataComplete(
new JoinData
{
@@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("EndPhoneCall")]
[JoinName("HangUpPhone")]
public JoinDataComplete HangUpPhone = new JoinDataComplete(
new JoinData
{
@@ -323,11 +337,53 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Hang Up PHone",
Description = "Hang Up Phone",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("EndCallStart")]
public JoinDataComplete EndCallStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 81,
JoinSpan = 8
},
new JoinMetadata
{
Description = "End a specific call by call index. ",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("JoinAllCalls")]
public JoinDataComplete JoinAllCalls = new JoinDataComplete(
new JoinData
{
JoinNumber = 90,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Join all calls",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("JoinCallStart")]
public JoinDataComplete JoinCallStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 91,
JoinSpan = 8
},
new JoinMetadata
{
Description = "Join a specific call by call index. ",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DirectorySearchBusy")]
public JoinDataComplete DirectorySearchBusy = new JoinDataComplete(
new JoinData
@@ -342,6 +398,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("DirectoryEntryIsContact")]
public JoinDataComplete DirectoryEntryIsContact = new JoinDataComplete(
new JoinData
@@ -408,7 +465,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
new JoinMetadata
{
Description = "Go to Directory Root",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
@@ -440,6 +497,48 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("DirectoryDisableAutoDialSelectedLine")]
public JoinDataComplete DirectoryDisableAutoDialSelectedLine = new JoinDataComplete(
new JoinData
{
JoinNumber = 107,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Set high to disable automatic dialing of a contact when selected",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DirectoryDialSelectedContactMethod")]
public JoinDataComplete DirectoryDialSelectedContactMethod = new JoinDataComplete(
new JoinData
{
JoinNumber = 108,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Pulse to dial the selected contact method",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DirectoryClearSelected")]
public JoinDataComplete DirectoryClearSelected = new JoinDataComplete(
new JoinData
{
JoinNumber = 110,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Clear Selected Entry and String from Search",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("CameraTiltUp")]
public JoinDataComplete CameraTiltUp = new JoinDataComplete(
@@ -525,6 +624,48 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("CameraFocusNear")]
public JoinDataComplete CameraFocusNear = new JoinDataComplete(
new JoinData
{
JoinNumber = 117,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Camera Focus Near",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("CameraFocusFar")]
public JoinDataComplete CameraFocusFar = new JoinDataComplete(
new JoinData
{
JoinNumber = 118,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Camera Focus Far",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("CameraFocusAuto")]
public JoinDataComplete CameraFocusAuto = new JoinDataComplete(
new JoinData
{
JoinNumber = 119,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Camera Auto Focus Trigger",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("CameraPresetSave")]
public JoinDataComplete CameraPresetSave = new JoinDataComplete(
new JoinData
@@ -534,7 +675,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Save Selected Preset",
Description = "Pulse to save selected preset spcified by CameraPresetSelect analog join. FB will pulse for 3s when preset saved.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
@@ -548,7 +689,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Camera Mode Auto",
Description = "Camera Mode Auto. Enables camera auto tracking mode, with feedback",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
@@ -562,7 +703,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Camera Mode Manual",
Description = "Camera Mode Manual. Disables camera auto tracking mode, with feedback",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
@@ -576,7 +717,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Camera Mode Off",
Description = "Camera Mode Off. Disables camera video, with feedback. Works like video mute.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
@@ -651,44 +792,16 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("DialMeeting1")]
public JoinDataComplete DialMeeting1 = new JoinDataComplete(
[JoinName("DialMeetingStart")]
public JoinDataComplete DialMeetingStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 161,
JoinSpan = 1
JoinSpan = 10
},
new JoinMetadata
{
Description = "Join first meeting",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DialMeeting2")]
public JoinDataComplete DialMeeting2 = new JoinDataComplete(
new JoinData
{
JoinNumber = 162,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Join second meeting",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DialMeeting3")]
public JoinDataComplete DialMeeting3 = new JoinDataComplete(
new JoinData
{
JoinNumber = 163,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Join third meeting",
Description = "Join meeting",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
@@ -805,6 +918,34 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("RemoveSelectedRecentCallItem")]
public JoinDataComplete RemoveSelectedRecentCallItem = new JoinDataComplete(
new JoinData
{
JoinNumber = 181,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Pulse to remove the selected recent call item specified by the SelectRecentCallItem analog join",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DialSelectedRecentCallItem")]
public JoinDataComplete DialSelectedRecentCallItem = new JoinDataComplete(
new JoinData
{
JoinNumber = 182,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Pulse to dial the selected recent call item specified by the SelectRecentCallItem analog join",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("SourceShareStart")]
public JoinDataComplete SourceShareStart = new JoinDataComplete(
new JoinData
@@ -870,11 +1011,81 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "advance selfview position",
Description = "Toggles selfview position",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("HoldAllCalls")]
public JoinDataComplete HoldAllCalls = new JoinDataComplete(
new JoinData
{
JoinNumber = 220,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Holds all calls",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("HoldCallsStart")]
public JoinDataComplete HoldCallsStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinSpan = 8
},
new JoinMetadata
{
Description = "Holds Call at specified index. FB reported on Call Status XSIG",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ResumeCallsStart")]
public JoinDataComplete ResumeCallsStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 231,
JoinSpan = 8
},
new JoinMetadata
{
Description = "Resume Call at specified index",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("MultiSiteOptionIsEnabled")]
public JoinDataComplete MultiSiteOptionIsEnabled = new JoinDataComplete(
new JoinData
{
JoinNumber = 301,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Multi site option is enabled FB",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("AutoAnswerEnabled")]
public JoinDataComplete AutoAnswerEnabled = new JoinDataComplete(
new JoinData
{
JoinNumber = 302,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Auto Answer is enabled FB",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ParticipantAudioMuteToggleStart")]
public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
new JoinData
@@ -939,6 +1150,35 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Analog
});
[JoinName("SelectCall")]
public JoinDataComplete SelectCall = new JoinDataComplete(
new JoinData
{
JoinNumber = 24,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets the selected Call for DTMF commands. Valid values 1-8",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("ConnectedCallCount")]
public JoinDataComplete ConnectedCallCount = new JoinDataComplete(
new JoinData
{
JoinNumber = 25,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Reports the number of currently connected calls",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("MinutesBeforeMeetingStart")]
public JoinDataComplete MinutesBeforeMeetingStart = new JoinDataComplete(
new JoinData
@@ -962,11 +1202,25 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Camera Number Select/FB",
Description = "Camera Number Select/FB. 1 based index. Valid range is 1 to the value reported by CameraCount.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("CameraCount")]
public JoinDataComplete CameraCount = new JoinDataComplete(
new JoinData
{
JoinNumber = 61,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Reports the number of cameras",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("DirectoryRowCount")]
public JoinDataComplete DirectoryRowCount = new JoinDataComplete(
new JoinData
@@ -990,11 +1244,56 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Directory Select Row",
Description = "Directory Select Row and Feedback",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("SelectedContactMethodCount")]
public JoinDataComplete SelectedContactMethodCount = new JoinDataComplete(
new JoinData
{
JoinNumber = 102,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Reports the number of contact methods for the selected contact",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("SelectContactMethod")]
public JoinDataComplete SelectContactMethod = new JoinDataComplete(
new JoinData
{
JoinNumber = 103,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Selects a contact method by index",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("DirectorySelectRowFeedback")]
public JoinDataComplete DirectorySelectRowFeedback = new JoinDataComplete(
new JoinData
{
JoinNumber = 104,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Directory Select Row and Feedback",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("CameraPresetSelect")]
public JoinDataComplete CameraPresetSelect = new JoinDataComplete(
new JoinData
@@ -1005,10 +1304,24 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
new JoinMetadata
{
Description = "Camera Preset Select",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("FarEndPresetSelect")]
public JoinDataComplete FarEndPresetSelect = new JoinDataComplete(
new JoinData
{
JoinNumber = 122,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Far End Preset Preset Select",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("ParticipantCount")]
public JoinDataComplete ParticipantCount = new JoinDataComplete(
new JoinData
@@ -1051,6 +1364,48 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Analog
});
[JoinName("SelectRecentCallItem")]
public JoinDataComplete SelectRecentCallItem = new JoinDataComplete(
new JoinData
{
JoinNumber = 180,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select/FB for Recent Call Item. Valid values 1 - 10",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("RecentCallOccurrenceType")]
public JoinDataComplete RecentCallOccurrenceType = new JoinDataComplete(
new JoinData
{
JoinNumber = 181,
JoinSpan = 10
},
new JoinMetadata
{
Description = "Recent Call Occurrence Type. [0-3] 0 = Unknown, 1 = Placed, 2 = Received, 3 = NoAnswer",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("RecentCallCount")]
public JoinDataComplete RecentCallCount = new JoinDataComplete(
new JoinData
{
JoinNumber = 191,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Recent Call Count",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Analog
});
#endregion
@@ -1066,12 +1421,12 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
Description = "Current Dial String",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
Description = "Value to dial when ManualDial digital join is pulsed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("PhoneString")]
[JoinName("PhoneDialString")]
public JoinDataComplete PhoneDialString = new JoinDataComplete(
new JoinData
{
@@ -1085,7 +1440,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
[JoinName("CurrentCallName")]
[JoinName("CurrentCallData")]
public JoinDataComplete CurrentCallData = new JoinDataComplete(
new JoinData
{
@@ -1184,6 +1539,20 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
[JoinName("ContactMethods")]
public JoinDataComplete ContactMethods = new JoinDataComplete(
new JoinData
{
JoinNumber = 103,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Contact Methods - XSig, 10 entries",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CameraPresetNames")]
public JoinDataComplete CameraPresetNames = new JoinDataComplete(
new JoinData
@@ -1198,8 +1567,8 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
[JoinName("CameraLayoutStringFb")]
public JoinDataComplete CameraLayoutStringFb = new JoinDataComplete(
[JoinName("CurrentLayoutStringFb")]
public JoinDataComplete CurrentLayoutStringFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 141,
@@ -1212,6 +1581,36 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
[JoinName("AvailableLayoutsFb")]
public JoinDataComplete AvailableLayoutsFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "xSig of all available layouts",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectLayout")]
public JoinDataComplete SelectLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select Layout by string",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentParticipants")]
public JoinDataComplete CurrentParticipants = new JoinDataComplete(
new JoinData
@@ -1226,6 +1625,76 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
[JoinName("CameraNamesFb")]
public JoinDataComplete CameraNamesFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 161,
JoinSpan = 10
},
new JoinMetadata
{
Description = "Camera Name Fb",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectedRecentCallName")]
public JoinDataComplete SelectedRecentCallName = new JoinDataComplete(
new JoinData
{
JoinNumber = 171,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Selected Recent Call Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectedRecentCallNumber")]
public JoinDataComplete SelectedRecentCallNumber = new JoinDataComplete(
new JoinData
{
JoinNumber = 172,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Selected Recent Call Number",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("RecentCallNamesStart")]
public JoinDataComplete RecentCallNamesStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 181,
JoinSpan = 10
},
new JoinMetadata
{
Description = "Recent Call Names",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("RecentCallTimesStart")]
public JoinDataComplete RecentCallTimesStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 191,
JoinSpan = 10
},
new JoinMetadata
{
Description = "Recent Calls Times",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentSource")]
public JoinDataComplete CurrentSource = new JoinDataComplete(
new JoinData
@@ -1252,7 +1721,77 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
Description = "advance selfview position",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
});
[JoinName("DeviceIpAddresss")]
public JoinDataComplete DeviceIpAddresss = new JoinDataComplete(
new JoinData
{
JoinNumber = 301,
JoinSpan = 1
},
new JoinMetadata
{
Description = "IP Address of device",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SipPhoneNumber")]
public JoinDataComplete SipPhoneNumber = new JoinDataComplete(
new JoinData
{
JoinNumber = 302,
JoinSpan = 1
},
new JoinMetadata
{
Description = "SIP phone number of device",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("E164Alias")]
public JoinDataComplete E164Alias = new JoinDataComplete(
new JoinData
{
JoinNumber = 303,
JoinSpan = 1
},
new JoinMetadata
{
Description = "E164 alias of device",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("H323Id")]
public JoinDataComplete H323Id = new JoinDataComplete(
new JoinData
{
JoinNumber = 304,
JoinSpan = 1
},
new JoinMetadata
{
Description = "H323 ID of device",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SipUri")]
public JoinDataComplete SipUri = new JoinDataComplete(
new JoinData
{
JoinNumber = 305,
JoinSpan = 1
},
new JoinMetadata
{
Description = "SIP URI of device",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("DirectoryEntrySelectedName")]
public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete(
@@ -2510,6 +3049,35 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
[JoinName("AvailableLayoutsFb")]
public JoinDataComplete AvailableLayoutsFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "xSig of all available layouts",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectLayout")]
public JoinDataComplete SelectLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select Layout by string",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentParticipants")]
public JoinDataComplete CurrentParticipants = new JoinDataComplete(
new JoinData
@@ -2607,4 +3175,4 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
{
}
}
}
}

View File

@@ -1,35 +1,35 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
public class DeviceConfig
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("uid")]
public int Uid { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))]
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
public class DeviceConfig
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("uid")]
public int Uid { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; }
public DeviceConfig(DeviceConfig dc)
@@ -39,39 +39,42 @@ namespace PepperDash.Essentials.Core.Config
Name = dc.Name;
Group = dc.Group;
Type = dc.Type;
Properties = JToken.FromObject(dc.Properties);
Properties = JToken.Parse(dc.Properties.ToString());
//Properties = JToken.FromObject(dc.Properties);
}
public DeviceConfig() {}
}
/// <summary>
///
/// </summary>
public class DevicePropertiesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(JToken);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JToken.ReadFrom(reader);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("SOD OFF HOSER");
}
}
}
/// <summary>
///
/// </summary>
public class DevicePropertiesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(JToken);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JToken.ReadFrom(reader);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("SOD OFF HOSER");
}
}
}

View File

@@ -66,7 +66,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
#endregion
}
public class C2NIoControllerFactory : EssentialsDeviceFactory<C2nRthsController>
public class C2NIoControllerFactory : EssentialsDeviceFactory<C2NIoController>
{
public C2NIoControllerFactory()
{

View File

@@ -34,7 +34,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 DIN-CEN-CN2 Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt;

View File

@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core
/// Wrapper class for CEN-IO-DIGIN-104 digital input module
/// </summary>
[Description("Wrapper class for the CEN-IO-DIGIN-104 diginal input module")]
public class CenIoDigIn104Controller : EssentialsDevice, IDigitalInputPorts
public class CenIoDigIn104Controller : CrestronGenericBaseDevice, IDigitalInputPorts
{
public CenIoDi104 Di104 { get; private set; }
@@ -52,10 +52,17 @@ namespace PepperDash.Essentials.Core
{
Debug.Console(1, "Factory Attempting to create new CEN-DIGIN-104 Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt;
return new CenIoDigIn104Controller(dc.Key, dc.Name, new Crestron.SimplSharpPro.GeneralIO.CenIoDi104(ipid, Global.ControlSystem));
var control = CommFactory.GetControlPropertiesConfig(dc);
if (control == null)
{
Debug.Console(1, "Factory failed to create a new CEN-DIGIN-104 Device, control properties not found");
return null;
}
var ipid = control.IpIdInt;
if (ipid != 0) return new CenIoDigIn104Controller(dc.Key, dc.Name, new CenIoDi104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device using IP-ID-{0}", ipid);
return null;
}
}

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Wrapper class for CEN-IO-IR-104 module
/// </summary>
[Description("Wrapper class for the CEN-IO-IR-104 module")]
public class CenIoIr104Controller : CrestronGenericBaseDevice, IIROutputPorts
{
private readonly CenIoIr104 _ir104;
/// <summary>
/// Constructor
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ir104"></param>
public CenIoIr104Controller(string key, string name, CenIoIr104 ir104)
: base(key, name, ir104)
{
_ir104 = ir104;
}
#region IDigitalInputPorts Members
/// <summary>
/// IR port collection
/// </summary>
public CrestronCollection<IROutputPort> IROutputPorts
{
get { return _ir104.IROutputPorts; }
}
/// <summary>
/// Number of relay ports property
/// </summary>
public int NumberOfIROutputPorts
{
get { return _ir104.NumberOfIROutputPorts; }
}
#endregion
}
/// <summary>
/// CEN-IO-IR-104 controller fatory
/// </summary>
public class CenIoIr104ControllerFactory : EssentialsDeviceFactory<CenIoIr104Controller>
{
/// <summary>
/// Constructor
/// </summary>
public CenIoIr104ControllerFactory()
{
TypeNames = new List<string>() { "cenioir104" };
}
/// <summary>
/// Build device CEN-IO-IR-104
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new CEN-IO-IR-104 Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
if (control == null)
{
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device, control properties not found");
return null;
}
var ipid = control.IpIdInt;
if(ipid != 0) return new CenIoIr104Controller(dc.Key, dc.Name, new CenIoIr104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device using IP-ID-{0}", ipid);
return null;
}
}
}

View File

@@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core
/// Wrapper class for CEN-IO-RY-104 relay module
/// </summary>
[Description("Wrapper class for the CEN-IO-RY-104 relay module")]
public class CenIoRy104Controller : EssentialsDevice, IRelayPorts
public class CenIoRy104Controller : CrestronGenericBaseDevice, IRelayPorts
{
private readonly CenIoRy104 _ry104;
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core
/// <param name="name"></param>
/// <param name="ry104"></param>
public CenIoRy104Controller(string key, string name, CenIoRy104 ry104)
: base(key, name)
: base(key, name, ry104)
{
_ry104 = ry104;
}
@@ -62,8 +62,8 @@ namespace PepperDash.Essentials.Core
var controlPropertiesConfig = CommFactory.GetControlPropertiesConfig(dc);
if (controlPropertiesConfig == null)
{
Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device");
{
Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device, control properties not found");
return null;
}

View File

@@ -73,11 +73,14 @@ namespace PepperDash.Essentials.Core
{
//Debug.Console(1, this, " Does not require registration. Skipping");
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
if (Hardware.Registerable && !Hardware.Registered)
{
//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();
@@ -86,7 +89,10 @@ namespace PepperDash.Essentials.Core
{
AddPostActivationAction(() =>
{
var response = Hardware.RegisterWithLogging(Key);
if (Hardware.Registerable && !Hardware.Registered)
{
var response = Hardware.RegisterWithLogging(Key);
}
IsRegistered.FireUpdate();
});

View File

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

View File

@@ -14,6 +14,7 @@ namespace PepperDash.Essentials.Core
public static class DeviceManager
{
public static event EventHandler<EventArgs> AllDevicesActivated;
public static event EventHandler<EventArgs> AllDevicesRegistered;
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
@@ -57,6 +58,8 @@ namespace PepperDash.Essentials.Core
{
try
{
OnAllDevicesRegistered();
DeviceCriticalSection.Enter();
AddDeviceEnabled = false;
// PreActivate all devices
@@ -129,6 +132,15 @@ namespace PepperDash.Essentials.Core
}
}
private static void OnAllDevicesRegistered()
{
var handler = AllDevicesRegistered;
if (handler != null)
{
handler(null, new EventArgs());
}
}
/// <summary>
/// Calls activate on all Device class items
/// </summary>

View File

@@ -131,4 +131,15 @@ namespace PepperDash.Essentials.Core
/// </summary>
public string MinimumEssentialsFrameworkVersion { get; protected set; }
}
public abstract class EssentialsPluginDevelopmentDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDevelopmentDeviceFactory 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; }
public List<string> DevelopmentEssentialsFrameworkVersions { get; protected set; }
}
}

View File

@@ -9,8 +9,11 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// Defines minimal volume and mute control methods
/// </summary>
public interface IBasicVolumeControls : IHasVolumeControl, IHasMuteControl
public interface IBasicVolumeControls
{
void VolumeUp(bool pressRelease);
void VolumeDown(bool pressRelease);
void MuteToggle();
}
/// <summary>
@@ -52,8 +55,13 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// Adds feedback and direct volume level set to IBasicVolumeControls
/// </summary>
public interface IBasicVolumeWithFeedback : IBasicVolumeControls, IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback
public interface IBasicVolumeWithFeedback : IBasicVolumeControls
{
BoolFeedback MuteFeedback { get; }
void MuteOn();
void MuteOff();
void SetVolume(ushort level);
IntFeedback VolumeLevelFeedback { get; }
}
/// <summary>

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash_Essentials_Core.Devices
{
/// <summary>
/// Interface for any device that is able to control it'spower and has a configurable reboot time
/// </summary>
public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
{
/// <summary>
/// Delay between power off and power on for reboot
/// </summary>
int PowerCycleTimeMs { get;}
/// <summary>
/// Reboot outlet
/// </summary>
void PowerCycle();
}
/// <summary>
/// Interface for any device that contains a collection of IHasPowerReboot Devices
/// </summary>
public interface IHasControlledPowerOutlets : IKeyName
{
/// <summary>
/// Collection of IPduOutlets
/// </summary>
ReadOnlyDictionary<int, IHasPowerCycle> PduOutlets { get; }
}
}

View File

@@ -59,7 +59,7 @@ namespace PepperDash.Essentials.Core.Devices
/// <summary>
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
/// </summary>
/// <param name="Config"></param>
/// <param name="config"></param>
protected virtual void CustomSetConfig(DeviceConfig config)
{
ConfigWriter.UpdateDeviceConfig(config);

View File

@@ -105,9 +105,6 @@ namespace PepperDash.Essentials.Core
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge)
{
var inputNumber = 0;
var inputKeys = new List<string>();
var joinMap = new DisplayControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
@@ -124,133 +121,141 @@ namespace PepperDash.Essentials.Core
Debug.Console(0,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
var commMonitor = displayDevice as ICommunicationMonitor;
if (commMonitor != null)
{
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
}
var inputNumberFeedback = new IntFeedback(() => inputNumber);
// Two way feedbacks
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
if (twoWayDisplay != null)
{
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
}
// Power Off
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOff();
});
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
if (twoWayDisplayDevice != null)
{
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (!a.BoolValue)
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
}
else
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
}
};
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
}
// PowerOn
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOn();
});
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
{
if (i < joinMap.InputNamesOffset.JoinSpan)
{
inputKeys.Add(displayDevice.InputPorts[i].Key);
var tempKey = inputKeys.ElementAt(i);
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
}
else
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
}
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
{
if (a == 0)
{
displayDevice.PowerOff();
inputNumber = 0;
}
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
{
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
inputNumber = a;
}
else if (a == 102)
{
displayDevice.PowerToggle();
}
if (twoWayDisplay != null)
inputNumberFeedback.FireUpdate();
});
var volumeDisplay = displayDevice as IBasicVolumeControls;
if (volumeDisplay == null) return;
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
if (volumeDisplayWithFeedback == null) return;
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
LinkDisplayToApi(displayDevice, trilist, joinMap);
}
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, DisplayControllerJoinMap joinMap)
{
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
var commMonitor = displayDevice as ICommunicationMonitor;
if (commMonitor != null)
{
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
}
var inputNumber = 0;
var inputKeys = new List<string>();
var inputNumberFeedback = new IntFeedback(() => inputNumber);
// Two way feedbacks
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
if (twoWayDisplay != null)
{
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
}
// Power Off
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOff();
});
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
if (twoWayDisplayDevice != null)
{
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (!a.BoolValue)
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
}
else
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
}
};
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
}
// PowerOn
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOn();
});
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
{
if (i < joinMap.InputNamesOffset.JoinSpan)
{
inputKeys.Add(displayDevice.InputPorts[i].Key);
var tempKey = inputKeys.ElementAt(i);
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
}
else
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
}
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
{
if (a == 0)
{
displayDevice.PowerOff();
inputNumber = 0;
}
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
{
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
inputNumber = a;
}
else if (a == 102)
{
displayDevice.PowerToggle();
}
if (twoWayDisplay != null)
inputNumberFeedback.FireUpdate();
});
var volumeDisplay = displayDevice as IBasicVolumeControls;
if (volumeDisplay == null) return;
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
if (volumeDisplayWithFeedback == null) return;
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
}
}
/// <summary>

View File

@@ -30,11 +30,40 @@ namespace PepperDash.Essentials.Core
bool _PowerIsOn;
bool _IsWarmingUp;
bool _IsCoolingDown;
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
bool _IsCoolingDown;
protected override Func<bool> PowerIsOnFeedbackFunc
{
get
{
return () =>
{
Debug.Console(2, this, "*************************************************** Display Power is {0}", _PowerIsOn ? "on" : "off");
return _PowerIsOn;
};
} }
protected override Func<bool> IsCoolingDownFeedbackFunc
{
get
{
return () =>
{
Debug.Console(2, this, "*************************************************** {0}", _IsCoolingDown ? "Display is cooling down" : "Display has finished cooling down");
return _IsCoolingDown;
};
}
}
protected override Func<bool> IsWarmingUpFeedbackFunc
{
get
{
return () =>
{
Debug.Console(2, this, "*************************************************** {0}", _IsWarmingUp ? "Display is warming up" : "Display has finished warming up");
return _IsWarmingUp;
};
}
}
protected override Func<string> CurrentInputFeedbackFunc { get { return () => "Not Implemented"; } }
int VolumeHeldRepeatInterval = 200;
@@ -61,7 +90,7 @@ namespace PepperDash.Essentials.Core
MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted);
WarmupTime = 10000;
CooldownTime = 5000;
CooldownTime = 10000;
}
public override void PowerOn()
@@ -88,15 +117,15 @@ namespace PepperDash.Essentials.Core
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsCoolingDown = true;
_PowerIsOn = false;
PowerIsOnFeedback.InvokeFireUpdate();
IsCoolingDownFeedback.InvokeFireUpdate();
// Fake cool-down cycle
CooldownTimer = new CTimer(o =>
{
Debug.Console(2, this, "Cooldown timer ending");
_IsCoolingDown = false;
IsCoolingDownFeedback.InvokeFireUpdate();
IsCoolingDownFeedback.InvokeFireUpdate();
_PowerIsOn = false;
PowerIsOnFeedback.InvokeFireUpdate();
}, CooldownTime);
}
}
@@ -111,7 +140,12 @@ namespace PepperDash.Essentials.Core
public override void ExecuteSwitch(object selector)
{
Debug.Console(2, this, "ExecuteSwitch: {0}", selector);
Debug.Console(2, this, "ExecuteSwitch: {0}", selector);
if (!_PowerIsOn)
{
PowerOn();
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
public static class StringExtensions
{
public static string NullIfEmpty(this string s)
{
return string.IsNullOrEmpty(s) ? null : s;
}
public static string NullIfWhiteSpace(this string s)
{
return string.IsNullOrEmpty(s.Trim()) ? null : s;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Globalization;
using Crestron.SimplSharp;
@@ -6,6 +7,7 @@ using System.Collections.Generic;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.CrestronDataStore;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM;
using PepperDash.Core;
using PepperDash.Essentials.License;
@@ -39,7 +41,14 @@ namespace PepperDash.Essentials.Core
{
get
{
return ControlSystem.ControllerPrompt.ToLower().IndexOf("dmps") > -1;
if(ControlSystem.SystemControl != null)
{
if(ControlSystem.SystemControl.SystemControlType > 0)
{
return true;
}
}
return false;
}
}
@@ -50,7 +59,39 @@ namespace PepperDash.Essentials.Core
{
get
{
return ControlSystemIsDmpsType && ControlSystem.ControllerPrompt.ToLower().IndexOf("4k") > -1;
if(ControlSystem.SystemControl != null)
{
if(ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K150CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K200CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K300CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
{
return true;
}
}
return false;
}
}
/// <summary>
/// True when the processor type is a DMPS 4K 200/300/250/350 variant
/// </summary>
public static bool ControlSystemIsDmps4k3xxType
{
get
{
if(ControlSystem.SystemControl != null)
{
if(ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K200CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K300CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
{
return true;
}
}
return false;
}
}
@@ -122,6 +163,38 @@ namespace PepperDash.Essentials.Core
AssemblyVersion = assemblyVersion;
}
public static bool IsRunningDevelopmentVersion(List<string> developmentVersions, string minimumVersion)
{
if (Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*").Groups[1].Value == "0")
{
Debug.Console(2, "Running Local Build. Bypassing Dependency Check.");
return true;
}
if (developmentVersions == null)
{
Debug.Console(0,
"Development Plugin does not specify a list of versions. Loading plugin may not work as expected. Checking Minumum version");
return IsRunningMinimumVersionOrHigher(minimumVersion);
}
Debug.Console(2, "Comparing running version '{0}' to minimum versions '{1}'", AssemblyVersion, developmentVersions);
var versionMatch = developmentVersions.FirstOrDefault(x => x == AssemblyVersion);
if (String.IsNullOrEmpty(versionMatch))
{
Debug.Console(0, "Essentials Build does not match any builds required for plugin load. Bypassing Plugin Load.");
return false;
}
Debug.Console(2, "Essentials Build {0} matches list of development builds", AssemblyVersion);
return IsRunningMinimumVersionOrHigher(minimumVersion);
}
/// <summary>
/// Checks to see if the running version meets or exceed the minimum specified version. For beta versions (0.xx.yy), will always return true.
/// </summary>

View File

@@ -283,9 +283,10 @@ namespace PepperDash.Essentials.Core
foreach (var join in joins)
{
Debug.Console(0,
@"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'",
@"Join Number: {0} | JoinSpan: '{1}' | JoinName: {2} | Description: '{3}' | Type: '{4}' | Capabilities: '{5}'",
join.Value.JoinNumber,
join.Value.JoinSpan,
join.Key,
String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName,
join.Value.Metadata.JoinType.ToString(),
join.Value.Metadata.JoinCapabilities.ToString());

View File

@@ -70,50 +70,69 @@ namespace PepperDash.Essentials.Core.Lighting
}
}
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge)
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GenericLightingJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(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.");
}
return LinkLightingToApi(lightingDevice, trilist, joinMap);
}
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
{
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
// GenericLighitng Actions & FeedBack
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
var joinMap = new GenericLightingJoinMap(joinStart);
var index = sceneIndex;
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(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.");
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
// GenericLighitng Actions & FeedBack
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
var index1 = sceneIndex;
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () =>
{
var index = index1;
Debug.Console(2, this, "LightingDevice: sceneIndex: {0} index: {1} > inside action", index1, index);
lightingDevice.SelectScene(lightingDevice.LightingScenes[index]);
});
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)]);
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true;
sceneIndex++;
}
return joinMap;
sceneIndex++;
}
trilist.OnlineStatusChange += (sender, args) =>
{
if (!args.DeviceOnLine) return;
sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
var index = sceneIndex;
trilist.StringInput[(uint) (joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
trilist.BooleanInput[(uint) (joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
scene.IsActiveFeedback.FireUpdate();
sceneIndex++;
}
};
return joinMap;
}
}
public class LightingScene

View File

@@ -16,11 +16,28 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// Used for monitoring comms that are IBasicCommunication. Will send a poll string and provide an event when
/// statuses change.
/// Default monitoring uses TextReceived event on Client.
/// </summary>
public class GenericCommunicationMonitor : StatusMonitorBase
{
public IBasicCommunication Client { get; private set; }
/// <summary>
/// Will monitor Client.BytesReceived if set to true. Otherwise the default is to monitor Client.TextReceived
/// </summary>
public bool MonitorBytesReceived { get; private set; }
/// <summary>
/// Return true if the Client is ISocketStatus
/// </summary>
public bool IsSocket
{
get
{
return Client is ISocketStatus;
}
}
long PollTime;
CTimer PollTimer;
string PollString;
@@ -46,8 +63,20 @@ namespace PepperDash.Essentials.Core
Client = client;
PollTime = pollTime;
PollString = pollString;
if (IsSocket)
{
(Client as ISocketStatus).ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
}
}
public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, long pollTime,
long warningTime, long errorTime, string pollString, bool monitorBytesReceived) :
this(parent, client, pollTime, warningTime, errorTime, pollString)
{
SetMonitorBytesReceived(monitorBytesReceived);
}
/// <summary>
/// Poll is a provided action instead of string
/// </summary>
@@ -69,6 +98,19 @@ namespace PepperDash.Essentials.Core
Client = client;
PollTime = pollTime;
PollAction = pollAction;
if (IsSocket)
{
(Client as ISocketStatus).ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
}
}
public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, long pollTime,
long warningTime, long errorTime, Action pollAction, bool monitorBytesReceived) :
this(parent, client, pollTime, warningTime, errorTime, pollAction)
{
SetMonitorBytesReceived(monitorBytesReceived);
}
@@ -79,23 +121,96 @@ namespace PepperDash.Essentials.Core
CommunicationMonitorConfig props) :
this(parent, client, props.PollInterval, props.TimeToWarning, props.TimeToError, props.PollString)
{
if (IsSocket)
{
(Client as ISocketStatus).ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
}
}
/// <summary>
/// Builds the monitor from a config object and takes a bool to specify whether to monitor BytesReceived
/// Default is to monitor TextReceived
/// </summary>
/// <param name="parent"></param>
/// <param name="client"></param>
/// <param name="props"></param>
/// <param name="monitorBytesReceived"></param>
public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, CommunicationMonitorConfig props, bool monitorBytesReceived) :
this(parent, client, props.PollInterval, props.TimeToWarning, props.TimeToError, props.PollString)
{
SetMonitorBytesReceived(monitorBytesReceived);
}
void SetMonitorBytesReceived(bool monitorBytesReceived)
{
MonitorBytesReceived = monitorBytesReceived;
}
public override void Start()
{
Client.BytesReceived += Client_BytesReceived;
Poll();
PollTimer = new CTimer(o => Poll(), null, PollTime, PollTime);
if (MonitorBytesReceived)
{
Client.BytesReceived += Client_BytesReceived;
}
else
{
Client.TextReceived += Client_TextReceived;
}
if (!IsSocket)
{
BeginPolling();
}
}
void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
{
if (!e.Client.IsConnected)
{
// Immediately stop polling and notify that device is offline
Stop();
Status = MonitorStatus.InError;
ResetErrorTimers();
}
else
{
// Start polling and set status to unknow and let poll result update the status to IsOk when a response is received
Status = MonitorStatus.StatusUnknown;
Start();
BeginPolling();
}
}
void BeginPolling()
{
Poll();
PollTimer = new CTimer(o => Poll(), null, PollTime, PollTime);
}
public override void Stop()
{
Client.BytesReceived -= this.Client_BytesReceived;
PollTimer.Stop();
PollTimer = null;
StopErrorTimers();
if(MonitorBytesReceived)
{
Client.BytesReceived -= this.Client_BytesReceived;
}
else
{
Client.TextReceived -= Client_TextReceived;
}
if (PollTimer != null)
{
PollTimer.Stop();
PollTimer = null;
StopErrorTimers();
}
}
void Client_TextReceived(object sender, GenericCommMethodReceiveTextArgs e)
{
DataReceived();
}
/// <summary>
/// Upon any receipt of data, set everything to ok!
/// </summary>
@@ -103,10 +218,14 @@ namespace PepperDash.Essentials.Core
/// <param name="e"></param>
void Client_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
{
Status = MonitorStatus.IsOk;
ResetErrorTimers();
//
}
DataReceived();
}
void DataReceived()
{
Status = MonitorStatus.IsOk;
ResetErrorTimers();
}
void Poll()
{
@@ -124,19 +243,6 @@ namespace PepperDash.Essentials.Core
Debug.Console(2, this, "Comm not connected");
}
}
/// <summary>
/// When the client connects, and we're waiting for it, respond and disconect from event
/// </summary>
void OneTimeConnectHandler(object o, EventArgs a)
{
if (Client.IsConnected)
{
//Client.IsConnected -= OneTimeConnectHandler;
Debug.Console(2, this, "Comm connected");
Poll();
}
}
}

View File

@@ -123,6 +123,7 @@
<Compile Include="Bridges\IBridge.cs" />
<Compile Include="Bridges\JoinMaps\AirMediaControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\AppleTvJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\PduJoinMapBase.cs" />
<Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\CameraControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\CenOdtOccupancySensorBaseJoinMap.cs" />
@@ -183,6 +184,7 @@
<Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" />
<Compile Include="Crestron IO\Inputs\IDigitalInput.cs" />
<Compile Include="Crestron IO\IOPortConfig.cs" />
<Compile Include="Crestron IO\Ir\CenIoIr104Controller.cs" />
<Compile Include="Crestron IO\Relay\CenIoRy104Controller.cs" />
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
@@ -203,6 +205,7 @@
<Compile Include="Devices\IReconfigurableDevice.cs" />
<Compile Include="Devices\PC\InRoomPc.cs" />
<Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\PduInterfaces.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" />
@@ -215,6 +218,7 @@
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
<Compile Include="Extensions\JsonExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Factory\DeviceFactory.cs" />
<Compile Include="Factory\IDeviceFactory.cs" />
<Compile Include="Factory\ReadyEventArgs.cs" />
@@ -336,7 +340,9 @@
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
<Compile Include="Routing\RoutingPortNames.cs" />
<Compile Include="Routing\TieLineConfig.cs" />
<Compile Include="Secrets\CrestronSecretsProvider.cs" />
<Compile Include="Secrets\CrestronGlobalSecretsProvider.cs" />
<Compile Include="Secrets\CrestronLocalSecretsProvider.cs" />
<Compile Include="Secrets\CrestronSecret.cs" />
<Compile Include="Secrets\Interfaces.cs" />
<Compile Include="Secrets\SecretsManager.cs" />
<Compile Include="Secrets\SecretsPropertiesConfig.cs" />
@@ -361,6 +367,7 @@
<Compile Include="UI PageManagers\SinglePageManager.cs" />
<Compile Include="UI PageManagers\PageManager.cs" />
<Compile Include="UI PageManagers\SetTopBoxTwoPanelPageManager.cs" />
<Compile Include="UI\TouchpanelBase.cs" />
<Compile Include="Utilities\ActionSequence.cs" />
<Compile Include="VideoStatus\VideoStatusOutputs.cs" />
<Compile Include="Crestron\CrestronGenericBaseDevice.cs" />

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using PepperDash.Core;
@@ -15,5 +16,10 @@ namespace PepperDash.Essentials.Core
}
public interface IPluginDevelopmentDeviceFactory : IPluginDeviceFactory
{
List<string> DevelopmentEssentialsFrameworkVersions { get; }
}
}
}

View File

@@ -425,7 +425,11 @@ namespace PepperDash.Essentials
/// <param name="loadedAssembly"></param>
static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly)
{
var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
var developmentPlugin = plugin as IPluginDevelopmentDeviceFactory;
var passed = developmentPlugin != null ? Global.IsRunningDevelopmentVersion
(developmentPlugin.DevelopmentEssentialsFrameworkVersions, developmentPlugin.MinimumEssentialsFrameworkVersion)
: Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
if (!passed)
{

View File

@@ -1,5 +1,6 @@
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro.CrestronThread;
using PepperDash.Core;
@@ -118,7 +119,7 @@ namespace PepperDash.Essentials.Core.Queues
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, pacing)
{
{
}
/// <summary>
@@ -139,7 +140,8 @@ namespace PepperDash.Essentials.Core.Queues
_queue = new CrestronQueue<IQueueMessage>(cap);
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
{
Priority = priority
Priority = priority,
Name = _key
};
SetDelayValues(pacing);
@@ -186,9 +188,20 @@ namespace PepperDash.Essentials.Core.Queues
if (_delayEnabled)
Thread.Sleep(_delayTime);
}
catch (System.Threading.ThreadAbortException)
{
//swallowing this exception, as it should only happen on shut down
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue: {1}:{0}", ex.Message, ex);
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
if (ex.InnerException != null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "---\r\n{0}", ex.InnerException.Message);
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.InnerException.StackTrace);
}
}
}
else _waitHandle.Wait();
@@ -201,7 +214,7 @@ namespace PepperDash.Essentials.Core.Queues
{
if (Disposed)
{
Debug.Console(1, this, "I've been disposed so you can't enqueue any messages. Are you trying to dispatch a message while the program is stopping?");
Debug.Console(1, this, "Queue has been disposed. Enqueuing messages not allowed while program is stopping.");
return;
}
@@ -445,7 +458,14 @@ namespace PepperDash_Essentials_Core.Queues
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}", ex.Message);
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
if (ex.InnerException != null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}", ex.InnerException.Message);
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.InnerException.StackTrace);
}
}
}
else _waitHandle.Wait();

View File

@@ -343,7 +343,7 @@ namespace PepperDash.Essentials.Core
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
{
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false && AllowVacancyTimerToStart())
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
// Trigger the timer when the room is vacant
@@ -362,6 +362,15 @@ namespace PepperDash.Essentials.Core
/// </summary>
/// <param name="o"></param>
public abstract void RoomVacatedForTimeoutPeriod(object o);
/// <summary>
/// Allow the vacancy event from an occupancy sensor to turn the room off.
/// </summary>
/// <returns>If the timer should be allowed. Defaults to true</returns>
protected virtual bool AllowVacancyTimerToStart()
{
return true;
}
}
/// <summary>

View File

@@ -11,12 +11,34 @@ using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class RouteRequest
{
public IRoutingSink Destination {get; set;}
public IRoutingOutputs Source {get; set;}
public eRoutingSignalType SignalType {get; set;}
public void HandleCooldown(object sender, FeedbackEventArgs args)
{
var coolingDevice = sender as IWarmingCooling;
if(args.BoolValue == false)
{
Destination.ReleaseAndMakeRoute(Source, SignalType);
if(sender == null) return;
coolingDevice.IsCoolingDownFeedback.OutputChange -= HandleCooldown;
}
}
}
/// <summary>
/// Extensions added to any IRoutingInputs classes to provide discovery-based routing
/// on those destinations.
/// </summary>
public static class IRoutingInputsExtensions
{
private static Dictionary<string, RouteRequest> RouteRequests = new Dictionary<string, RouteRequest>();
/// <summary>
/// Gets any existing RouteDescriptor for a destination, clears it using ReleaseRoute
/// and then attempts a new Route and if sucessful, stores that RouteDescriptor
@@ -24,16 +46,64 @@ namespace PepperDash.Essentials.Core
/// </summary>
public static void ReleaseAndMakeRoute(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
{
destination.ReleaseRoute();
var routeRequest = new RouteRequest {
Destination = destination,
Source = source,
SignalType = signalType
};
if (source == null) return;
var newRoute = destination.GetRouteToSource(source, signalType);
if (newRoute == null) return;
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute);
Debug.Console(2, destination, "Executing full route");
newRoute.ExecuteRoutes();
var coolingDevice = destination as IWarmingCooling;
RouteRequest existingRouteRequest;
//We already have a route request for this device, and it's a cooling device and is cooling
if (RouteRequests.TryGetValue(destination.Key, out existingRouteRequest) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
{
coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRouteRequest.HandleCooldown;
coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
RouteRequests[destination.Key] = routeRequest;
Debug.Console(2, "******************************************************** Device: {0} is cooling down and already has a routing request stored. Storing new route request to route to source key: {1}", destination.Key, routeRequest.Source.Key);
return;
}
//New Request
if (coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
{
coolingDevice.IsCoolingDownFeedback.OutputChange -= routeRequest.HandleCooldown;
coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
RouteRequests.Add(destination.Key, routeRequest);
Debug.Console(2, "******************************************************** Device: {0} is cooling down. Storing route request to route to source key: {1}", destination.Key, routeRequest.Source.Key);
return;
}
if (RouteRequests.ContainsKey(destination.Key) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == false)
{
RouteRequests.Remove(destination.Key);
Debug.Console(2, "******************************************************** Device: {0} is NOT cooling down. Removing stored route request and routing to source key: {1}", destination.Key, routeRequest.Source.Key);
}
destination.ReleaseRoute();
RunRouteRequest(routeRequest);
}
public static void RunRouteRequest(RouteRequest request)
{
if (request.Source == null) return;
var newRoute = request.Destination.GetRouteToSource(request.Source, request.SignalType);
if (newRoute == null) return;
RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute);
Debug.Console(2, request.Destination, "Executing full route");
newRoute.ExecuteRoutes();
}
/// <summary>
/// Will release the existing route on the destination, if it is found in
/// RouteDescriptorCollection.DefaultCollection
@@ -41,6 +111,17 @@ namespace PepperDash.Essentials.Core
/// <param name="destination"></param>
public static void ReleaseRoute(this IRoutingSink destination)
{
RouteRequest existingRequest;
if (RouteRequests.TryGetValue(destination.Key, out existingRequest) && destination is IWarmingCooling)
{
var coolingDevice = destination as IWarmingCooling;
coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRequest.HandleCooldown;
}
RouteRequests.Remove(destination.Key);
var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination);
if (current != null)
{

View File

@@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core
Type = type;
ConnectionType = connType;
Selector = selector;
IsInternal = IsInternal;
IsInternal = isInternal;
}
}

View File

@@ -0,0 +1,102 @@
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class CrestronGlobalSecretsProvider : ISecretProvider
{
public string Key { get; set; }
//Added for reference
public string Description { get; private set; }
public CrestronGlobalSecretsProvider(string key)
{
Key = key;
Description = String.Format("Default secret provider serving all local applications");
}
static CrestronGlobalSecretsProvider()
{
//Added for future encrypted reference
var 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;
CrestronDataStore.CDS_ERROR returnCode;
if (String.IsNullOrEmpty(secret))
{
returnCode = CrestronDataStoreStatic.clearGlobal(key);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret);
return true;
}
}
else
{
returnCode = CrestronDataStoreStatic.SetGlobalStringValue(key, secret);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully set secret \"{0}\"", secret);
return true;
}
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.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.GetGlobalStringValue(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>
/// Determine if a secret is present within the provider without retrieving it
/// </summary>
/// <param name="key">Secret Key</param>
/// <returns>bool if present</returns>
public bool TestSecret(string key)
{
string mySecret;
return CrestronDataStoreStatic.GetGlobalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS;
}
}
}

View File

@@ -1,97 +1,103 @@
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;
}
}
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public class CrestronLocalSecretsProvider : ISecretProvider
{
public string Key { get; set; }
//Added for reference
public string Description { get; private set; }
public CrestronLocalSecretsProvider(string key)
{
Key = key;
Description = String.Format("Default secret provider serving Essentials Application {0}", InitialParametersClass.ApplicationNumber);
}
static CrestronLocalSecretsProvider()
{
//Added for future encrypted reference
var 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;
CrestronDataStore.CDS_ERROR returnCode;
if (String.IsNullOrEmpty(secret))
{
returnCode = CrestronDataStoreStatic.clearLocal(key);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret);
return true;
}
}
else
{
returnCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully set secret \"{0}\"", secret);
return true;
}
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.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>
/// Determine if a secret is present within the provider without retrieving it
/// </summary>
/// <param name="key">Secret Key</param>
/// <returns>bool if present</returns>
public bool TestSecret(string key)
{
string mySecret;
return CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS;
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <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;
}
}
}

View File

@@ -7,9 +7,32 @@ namespace PepperDash.Essentials.Core
/// </summary>
public interface ISecretProvider : IKeyed
{
/// <summary>
/// Set secret value for provider by key
/// </summary>
/// <param name="key">key of secret to set</param>
/// <param name="value">value to set secret to</param>
/// <returns></returns>
bool SetSecret(string key, object value);
/// <summary>
/// Return object containing secret from provider
/// </summary>
/// <param name="key">key of secret to retrieve</param>
/// <returns></returns>
ISecret GetSecret(string key);
/// <summary>
/// Verifies presence of secret
/// </summary>
/// <param name="key">key of secret to chek</param>
/// <returns></returns>
bool TestSecret(string key);
/// <summary>
/// Description of the secrets provider
/// </summary>
string Description { get; }
}
/// <summary>
@@ -17,8 +40,19 @@ namespace PepperDash.Essentials.Core
/// </summary>
public interface ISecret
{
/// <summary>
/// Instance of ISecretProvider that the secret belongs to
/// </summary>
ISecretProvider Provider { get; }
/// <summary>
/// Key of the secret in the provider
/// </summary>
string Key { get; }
/// <summary>
/// Value of the secret
/// </summary>
object Value { get; }
}
}

View File

@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public static class SecretsManager
@@ -16,18 +16,28 @@ namespace PepperDash.Essentials.Core
public static void Initialize()
{
AddSecretProvider("default", new CrestronSecretsProvider("default"));
AddSecretProvider("default", new CrestronLocalSecretsProvider("default"));
AddSecretProvider("CrestronGlobalSecrets", new CrestronGlobalSecretsProvider("CrestronGlobalSecrets"));
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
"Adds secrets to secret provider",
"Adds secret to secrets provider",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret",
"Updates secrets in secret provider",
"Updates secret in secrets provider",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
"Deletes secrets in secret provider",
"Deletes secret from secrest provider",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(ListProviders, "secretproviderlist",
"Return list of all valid secrets providers",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(GetProviderInfo, "secretproviderinfo",
"Return data about secrets provider",
ConsoleAccessLevelEnum.AccessAdministrator);
}
@@ -54,6 +64,79 @@ namespace PepperDash.Essentials.Core
return secret;
}
public static void GetProviderInfo(string cmd)
{
string response;
var args = cmd.Split(' ');
if (cmd.Length == 0 || (args.Length == 1 && args[0] == "?"))
{
response = "Returns data about secrets provider. Format 'secretproviderinfo <provider>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1)
{
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
response = "Invalid secrets provider key";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = String.Format("{0} : {1}", provider.Key, provider.Description);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
}
/// <summary>
/// Console Command that returns all valid secrets in the essentials program.
/// </summary>
/// <param name="cmd"></param>
public static void ListProviders(string cmd)
{
var response = String.Empty;
var args = cmd.Split(' ');
if (cmd.Length == 0)
{
if (Secrets != null && Secrets.Count > 0)
{
response = Secrets.Aggregate(response,
(current, secretProvider) => current + (secretProvider.Key + "\n\r"));
}
else
{
response = "No Secrets Providers Available";
}
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1 && args[0] == "?")
{
response = "Reports all valid and preset Secret providers";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
}
/// <summary>
/// Add secret provider to secrets dictionary
/// </summary>
@@ -100,14 +183,14 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0)
{
//some Instructional Text
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
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>";
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
@@ -134,23 +217,7 @@ namespace PepperDash.Essentials.Core
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);
CrestronConsole.ConsoleCommandResponse(SetSecret(provider, key, secret));
}
private static void UpdateSecretProcess(string cmd)
@@ -161,7 +228,7 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0)
{
//some Instructional Text
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
@@ -169,7 +236,7 @@ namespace PepperDash.Essentials.Core
if (args.Length == 1 && args[0] == "?")
{
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
@@ -198,23 +265,49 @@ namespace PepperDash.Essentials.Core
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;
}
CrestronConsole.ConsoleCommandResponse(UpdateSecret(provider, key, secret));
}
private static string UpdateSecret(ISecretProvider provider, string key, string secret)
{
var secretPresent = provider.TestSecret(key);
Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key);
if (!secretPresent)
return
String.Format(
"Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to modify it");
var 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);
return response;
}
private static string SetSecret(ISecretProvider provider, string key, string secret)
{
var secretPresent = provider.TestSecret(key);
Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key);
if (secretPresent)
return
String.Format(
"Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it");
var 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);
return response;
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)
@@ -225,14 +318,14 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0)
{
//some Instructional Text
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
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>";
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
}

View File

@@ -19,6 +19,7 @@ namespace PepperDash.Essentials.Core.Shades
/// <summary>
/// Requirements for a device that implements basic Open/Close shade control
/// </summary>
[Obsolete("Please use IShadesOpenCloseStop instead")]
public interface IShadesOpenClose
{
void Open();
@@ -28,15 +29,26 @@ namespace PepperDash.Essentials.Core.Shades
/// <summary>
/// Requirements for a device that implements basic Open/Close/Stop shade control (Uses 3 relays)
/// </summary>
public interface IShadesOpenCloseStop : IShadesOpenClose
{
void StopOrPreset();
string StopOrPresetButtonLabel { get; }
public interface IShadesOpenCloseStop
{
void Open();
void Close();
void Stop();
}
public interface IShadesOpenClosePreset : IShadesOpenCloseStop
{
void RecallPreset(uint presetNumber);
void SavePreset(uint presetNumber);
string StopOrPresetButtonLabel { get; }
event EventHandler PresetSaved;
}
/// <summary>
/// Requirements for a shade that implements press/hold raise/lower functions
/// </summary>
/// </summary>
[Obsolete("Please use IShadesOpenCloseStop instead")]
public interface IShadesRaiseLower
{
void Raise(bool state);
@@ -55,7 +67,7 @@ namespace PepperDash.Essentials.Core.Shades
/// <summary>
/// Requirements for a shade/scene that is open or closed
/// </summary>
public interface IShadesOpenClosedFeedback: IShadesOpenClose
public interface IShadesOpenClosedFeedback: IShadesOpenCloseStop
{
BoolFeedback ShadeIsOpenFeedback { get; }
BoolFeedback ShadeIsClosedFeedback { get; }
@@ -63,15 +75,16 @@ namespace PepperDash.Essentials.Core.Shades
/// <summary>
///
/// </summary>
public interface IShadesStop
/// </summary>
[Obsolete("Please use IShadesOpenCloseStop instead")]
public interface IShadesStop
{
void Stop();
}
/// <summary>
///
/// </summary>
/// Used to implement raise/stop/lower/stop from single button
/// </summary>
public interface IShadesStopOrMove
{
void OpenOrStop();
@@ -82,7 +95,7 @@ namespace PepperDash.Essentials.Core.Shades
/// <summary>
/// Basic feedback for shades/scene stopped
/// </summary>
public interface IShadesStopFeedback
public interface IShadesStopFeedback : IShadesOpenCloseStop
{
BoolFeedback IsStoppedFeedback { get; }
}

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core.Shades
/// <summary>
/// Base class for a shade device
/// </summary>
public abstract class ShadeBase : EssentialsDevice, IShadesOpenClose
public abstract class ShadeBase : EssentialsDevice, IShadesOpenCloseStop
{
public ShadeBase(string key, string name)
: base(key, name)
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core.Shades
#region iShadesOpenClose Members
public abstract void Open();
public abstract void StopOrPreset();
public abstract void Stop();
public abstract void Close();
#endregion

View File

@@ -144,7 +144,7 @@ namespace PepperDash.Essentials.Core
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
{
if (sigNum > UShortIncrement) return null;
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum)));
}
/// <summary>
@@ -159,7 +159,7 @@ namespace PepperDash.Essentials.Core
public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
{
if (sigNum > StringIncrement) return null;
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum)));
}
/// <summary>

View File

@@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using Crestron.SimplSharpPro.UI;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core.UI
{
public abstract class TouchpanelBase: EssentialsDevice, IHasBasicTriListWithSmartObject
{
protected CrestronTouchpanelPropertiesConfig _config;
public BasicTriListWithSmartObject Panel { get; private set; }
/// <summary>
/// Constructor for use with device Factory. A touch panel device will be created based on the provided IP-ID and the
/// type of the panel. The SGD File path can be specified using the config property, or a default one located in the program directory if none
/// is provided.
/// </summary>
/// <param name="key">Essentials Device Key</param>
/// <param name="name">Essentials Device Name</param>
/// <param name="type">Touchpanel Type to build</param>
/// <param name="config">Touchpanel Configuration</param>
/// <param name="id">IP-ID to use for touch panel</param>
protected TouchpanelBase(string key, string name, BasicTriListWithSmartObject panel, CrestronTouchpanelPropertiesConfig config)
:base(key, name)
{
if (panel == null)
{
Debug.Console(0, this, "Panel is not valid. Touchpanel class WILL NOT work correctly");
return;
}
Panel = panel;
Panel.SigChange += Panel_SigChange;
if (Panel is TswFt5ButtonSystem)
{
var tsw = Panel as TswFt5ButtonSystem;
tsw.ExtenderSystemReservedSigs.Use();
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
tsw.ButtonStateChange += Tsw_ButtonStateChange;
}
_config = config;
AddPreActivationAction(() => {
if (Panel.Register() != eDeviceRegistrationUnRegistrationResponse.Success)
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Registration failed. Continuing, but panel may not function: {0}", Panel.RegistrationFailureReason);
// Give up cleanly if SGD is not present.
var sgdName = Global.FilePathPrefix + "sgd" + Global.DirectorySeparator + _config.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "Smart object file '{0}' not present in User folder. Looking for embedded file", sgdName);
sgdName = Global.ApplicationDirectoryPathPrefix + Global.DirectorySeparator + "SGD" + Global.DirectorySeparator + _config.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "Unable to find SGD file '{0}' in User sgd or application SGD folder. Exiting touchpanel load.", sgdName);
return;
}
}
Panel.LoadSmartObjects(sgdName);
});
AddPostActivationAction(() =>
{
// Check for IEssentialsRoomCombiner in DeviceManager and if found, subscribe to its event
var roomCombiner = DeviceManager.AllDevices.FirstOrDefault((d) => d is IEssentialsRoomCombiner) as IEssentialsRoomCombiner;
if (roomCombiner != null)
{
// Subscribe to the even
roomCombiner.RoomCombinationScenarioChanged += new EventHandler<EventArgs>(roomCombiner_RoomCombinationScenarioChanged);
// Connect to the initial roomKey
if (roomCombiner.CurrentScenario != null)
{
// Use the current scenario
DetermineRoomKeyFromScenario(roomCombiner.CurrentScenario);
}
else
{
// Current Scenario not yet set. Use default
SetupPanelDrivers(_config.DefaultRoomKey);
}
}
else
{
// No room combiner, use the default key
SetupPanelDrivers(_config.DefaultRoomKey);
}
});
}
/// <summary>
/// Setup Panel operation
/// </summary>
/// <param name="roomKey">Room Key for this panel</param>
protected abstract void SetupPanelDrivers(string roomKey);
/// <summary>
/// Event handler for System Extender Events
/// </summary>
/// <param name="currentDeviceExtender"></param>
/// <param name="args"></param>
protected abstract void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args);
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void roomCombiner_RoomCombinationScenarioChanged(object sender, EventArgs e)
{
var roomCombiner = sender as IEssentialsRoomCombiner;
DetermineRoomKeyFromScenario(roomCombiner.CurrentScenario);
}
/// <summary>
/// Determines the room key to use based on the scenario
/// </summary>
/// <param name="scenario"></param>
protected virtual void DetermineRoomKeyFromScenario(IRoomCombinationScenario scenario)
{
string newRoomKey = null;
if (scenario.UiMap.ContainsKey(Key))
{
newRoomKey = scenario.UiMap[Key];
}
else if (scenario.UiMap.ContainsKey(_config.DefaultRoomKey))
{
newRoomKey = scenario.UiMap[_config.DefaultRoomKey];
}
SetupPanelDrivers(newRoomKey);
}
private void Panel_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level == 2)
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
private void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
{
var uo = args.Button.UserObject;
if(uo is Action<bool>)
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
}
}
}

View File

@@ -1482,6 +1482,8 @@ namespace PepperDash.Essentials.DM
LinkChassisToApi(trilist, joinMap);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
// Link up inputs & outputs
for (uint i = 1; i <= Chassis.NumberOfOutputs; i++)
{

View File

@@ -17,52 +17,89 @@ using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM
{
/// <summary>
/// Exposes the volume levels for Program, Aux1 or Aux2 outputs on a DMPS3 chassis
/// Exposes the volume levels for Program, Aux1, Aux2, Codec1, Codec2, and Digital outputs on a DMPS3 chassis
/// </summary>
public class DmpsAudioOutputController : EssentialsBridgeableDevice
{
Card.Dmps3OutputBase OutputCard;
public DmpsAudioOutput MasterVolumeLevel { get; private set; }
public DmpsAudioOutput SourceVolumeLevel { get; private set; }
public DmpsAudioOutput MicsMasterVolumeLevel { get; private set; }
public DmpsAudioOutput Codec1VolumeLevel { get; private set; }
public DmpsAudioOutput Codec2VolumeLevel { get; private set; }
public DmpsAudioOutputController(string key, string name, DMOutput card, Card.Dmps3DmHdmiAudioOutput.Dmps3AudioOutputStream stream)
: base(key, name)
{
card.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
var output = new Dmps3AudioOutputWithMixerBase(stream);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
}
public DmpsAudioOutputController(string key, string name, DMOutput card, Card.Dmps3DmHdmiAudioOutput.Dmps3DmHdmiOutputStream stream)
: base(key, name)
{
card.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
var output = new Dmps3AudioOutputWithMixerBase(stream);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
}
public DmpsAudioOutputController(string key, string name, Card.Dmps3OutputBase card)
: base(key, name)
{
OutputCard = card;
OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
card.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
if (card is Card.Dmps3ProgramOutput)
{
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3ProgramOutput).OutputMixer);
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1);
Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2);
var programOutput = card as Card.Dmps3ProgramOutput;
var output = new Dmps3AudioOutputWithMixerBase(card, programOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(output, eDmpsLevelType.Master, programOutput.OutputEqualizer);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec1);
Codec2VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec2);
}
else if (card is Card.Dmps3Aux1Output)
{
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux1Output).OutputMixer);
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2);
var auxOutput = card as Card.Dmps3Aux1Output;
var output = new Dmps3AudioOutputWithMixerBase(card, auxOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(output, eDmpsLevelType.Master, auxOutput.OutputEqualizer);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
Codec2VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec2);
}
else if (card is Card.Dmps3Aux2Output)
{
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux2Output).OutputMixer);
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1);
var auxOutput = card as Card.Dmps3Aux2Output;
var output = new Dmps3AudioOutputWithMixerBase(card, auxOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(output, eDmpsLevelType.Master, auxOutput.OutputEqualizer);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec1);
}
else //Digital Outputs
else if (card is Card.Dmps3DigitalMixOutput)
{
MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
var mixOutput = card as Card.Dmps3DigitalMixOutput;
var output = new Dmps3AudioOutputWithMixerBase(card, mixOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
}
else if (card is Card.Dmps3HdmiOutput)
{
var hdmiOutput = card as Card.Dmps3HdmiOutput;
var output = new Dmps3AudioOutputWithMixerBase(card, hdmiOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
}
else if (card is Card.Dmps3DmOutput)
{
var dmOutput = card as Card.Dmps3DmOutput;
var output = new Dmps3AudioOutputWithMixerBase(card, dmOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
}
}
@@ -185,6 +222,11 @@ namespace PepperDash.Essentials.DM
{
trilist.SetUShortSigAction(joinMap.MixerPresetRecall.JoinNumber, mixer.RecallPreset);
}
var eq = MasterVolumeLevel as DmpsAudioOutputWithMixerAndEq;
if (eq != null)
{
trilist.SetUShortSigAction(joinMap.MixerEqPresetRecall.JoinNumber, eq.RecallEqPreset);
}
}
if (SourceVolumeLevel != null)
@@ -234,21 +276,37 @@ namespace PepperDash.Essentials.DM
}
}
public class DmpsAudioOutputWithMixer : DmpsAudioOutput
public class DmpsAudioOutputWithMixerAndEq : DmpsAudioOutputWithMixer
{
CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo Mixer;
public DmpsAudioOutputWithMixer(Card.Dmps3OutputBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo mixer)
private CrestronControlSystem.Dmps3OutputEqualizer Eq;
public DmpsAudioOutputWithMixerAndEq(Dmps3AudioOutputWithMixerBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputEqualizer eq)
: base(output, type)
{
Mixer = mixer;
Eq = eq;
}
public void RecallEqPreset(ushort preset)
{
Eq.PresetNumber.UShortValue = preset;
Eq.RecallPreset();
}
}
public class DmpsAudioOutputWithMixer : DmpsAudioOutput
{
Dmps3AudioOutputWithMixerBase Output;
public DmpsAudioOutputWithMixer(Dmps3AudioOutputWithMixerBase output, eDmpsLevelType type)
: base(output, type)
{
Output = output;
GetVolumeMax();
GetVolumeMin();
}
public void GetVolumeMin()
{
MinLevel = (short)Mixer.MinVolumeFeedback.UShortValue;
MinLevel = (short)Output.MinVolumeFeedback.UShortValue;
if (VolumeLevelScaledFeedback != null)
{
VolumeLevelScaledFeedback.FireUpdate();
@@ -257,7 +315,7 @@ namespace PepperDash.Essentials.DM
public void GetVolumeMax()
{
MaxLevel = (short)Mixer.MaxVolumeFeedback.UShortValue;
MaxLevel = (short)Output.MaxVolumeFeedback.UShortValue;
if (VolumeLevelScaledFeedback != null)
{
VolumeLevelScaledFeedback.FireUpdate();
@@ -266,23 +324,36 @@ namespace PepperDash.Essentials.DM
public void RecallPreset(ushort preset)
{
Debug.Console(1, "DMPS Recalling Preset {0}", preset);
Mixer.PresetNumber.UShortValue = preset;
Mixer.RecallPreset();
Output.PresetNumber.UShortValue = preset;
Output.RecallPreset();
if (!Global.ControlSystemIsDmps4k3xxType)
{
//Recall startup volume for main volume level as DMPS3(non-4K) presets don't affect the main volume
RecallStartupVolume();
}
}
public void RecallStartupVolume()
{
ushort startupVol = Output.StartupVolumeFeedback.UShortValue;
//Reset startup vol due to bug on DMPS3 where getting the value from above method clears the startup volume
Output.StartupVolume.UShortValue = startupVol;
Debug.Console(1, "DMPS Recalling Startup Volume {0}", startupVol);
SetVolume(startupVol);
MuteOff();
}
}
public class DmpsAudioOutput : IBasicVolumeWithFeedback
{
Card.Dmps3OutputBase Output;
eDmpsLevelType Type;
UShortInputSig Level;
private UShortInputSig Level;
private bool EnableVolumeSend;
private ushort VolumeLevelInput;
protected short MinLevel { get; set; }
protected short MaxLevel { get; set; }
public eDmpsLevelType Type { get; private set; }
public BoolFeedback MuteFeedback { get; private set; }
public IntFeedback VolumeLevelFeedback { get; private set; }
public IntFeedback VolumeLevelScaledFeedback { get; private set; }
@@ -292,9 +363,8 @@ namespace PepperDash.Essentials.DM
Action<bool> VolumeUpAction;
Action<bool> VolumeDownAction;
public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type)
public DmpsAudioOutput(Dmps3AudioOutputBase output, eDmpsLevelType type)
{
Output = output;
VolumeLevelInput = 0;
EnableVolumeSend = false;
Type = type;
@@ -306,47 +376,46 @@ namespace PepperDash.Essentials.DM
case eDmpsLevelType.Master:
{
Level = output.MasterVolume;
MuteFeedback = new BoolFeedback(new Func<bool>(() => Output.MasterMuteOnFeedBack.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => Output.MasterVolumeFeedBack.UShortValue));
MuteOnAction = new Action(Output.MasterMuteOn);
MuteOffAction = new Action(Output.MasterMuteOff);
VolumeUpAction = new Action<bool>((b) => Output.MasterVolumeUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => Output.MasterVolumeDown.BoolValue = b);
MuteFeedback = new BoolFeedback(new Func<bool>(() => output.MasterMuteOnFeedBack.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => output.MasterVolumeFeedBack.UShortValue));
MuteOnAction = new Action(output.MasterMuteOn);
MuteOffAction = new Action(output.MasterMuteOff);
VolumeUpAction = new Action<bool>((b) => output.MasterVolumeUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => output.MasterVolumeDown.BoolValue = b);
break;
}
case eDmpsLevelType.MicsMaster:
{
Level = output.MicMasterLevel;
MuteFeedback = new BoolFeedback(new Func<bool>(() => Output.MicMasterMuteOnFeedBack.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => Output.MicMasterLevelFeedBack.UShortValue));
MuteOnAction = new Action(Output.MicMasterMuteOn);
MuteOffAction = new Action(Output.MicMasterMuteOff);
VolumeUpAction = new Action<bool>((b) => Output.MicMasterLevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => Output.MicMasterLevelDown.BoolValue = b);
if (output.Card is Card.Dmps3OutputBase)
{
var micOutput = output.Card as Card.Dmps3OutputBase;
Level = micOutput.MicMasterLevel;
MuteFeedback = new BoolFeedback(new Func<bool>(() => micOutput.MicMasterMuteOnFeedBack.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => micOutput.MicMasterLevelFeedBack.UShortValue));
MuteOnAction = new Action(micOutput.MicMasterMuteOn);
MuteOffAction = new Action(micOutput.MicMasterMuteOff);
VolumeUpAction = new Action<bool>((b) => micOutput.MicMasterLevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => micOutput.MicMasterLevelDown.BoolValue = b);
}
break;
}
case eDmpsLevelType.Source:
{
Level = output.SourceLevel;
MuteFeedback = new BoolFeedback(new Func<bool>(() => Output.SourceMuteOnFeedBack.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => Output.SourceLevelFeedBack.UShortValue));
MuteOnAction = new Action(Output.SourceMuteOn);
MuteOffAction = new Action(Output.SourceMuteOff);
VolumeUpAction = new Action<bool>((b) => Output.SourceLevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => Output.SourceLevelDown.BoolValue = b);
MuteFeedback = new BoolFeedback(new Func<bool>(() => output.SourceMuteOnFeedBack.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => output.SourceLevelFeedBack.UShortValue));
MuteOnAction = new Action(output.SourceMuteOn);
MuteOffAction = new Action(output.SourceMuteOff);
VolumeUpAction = new Action<bool>((b) => output.SourceLevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => output.SourceLevelDown.BoolValue = b);
break;
}
case eDmpsLevelType.Codec1:
{
var programOutput = output as Card.Dmps3ProgramOutput;
if (programOutput != null)
if (output.Card is Card.Dmps3ProgramOutput)
{
var programOutput = output.Card as Card.Dmps3ProgramOutput;
Level = programOutput.Codec1Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => programOutput.CodecMute1OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => programOutput.Codec1LevelFeedback.UShortValue));
MuteOnAction = new Action(programOutput.Codec1MuteOn);
@@ -354,12 +423,10 @@ namespace PepperDash.Essentials.DM
VolumeUpAction = new Action<bool>((b) => programOutput.Codec1LevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => programOutput.Codec1LevelDown.BoolValue = b);
}
else
else if (output.Card is Card.Dmps3Aux2Output)
{
var auxOutput = output as Card.Dmps3Aux2Output;
var auxOutput = output.Card as Card.Dmps3Aux2Output;
Level = auxOutput.Codec1Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => auxOutput.CodecMute1OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => auxOutput.Codec1LevelFeedback.UShortValue));
MuteOnAction = new Action(auxOutput.Codec1MuteOn);
@@ -371,12 +438,10 @@ namespace PepperDash.Essentials.DM
}
case eDmpsLevelType.Codec2:
{
var programOutput = output as Card.Dmps3ProgramOutput;
if (programOutput != null)
if (output.Card is Card.Dmps3ProgramOutput)
{
var programOutput = output.Card as Card.Dmps3ProgramOutput;
Level = programOutput.Codec2Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => programOutput.CodecMute1OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => programOutput.Codec2LevelFeedback.UShortValue));
MuteOnAction = new Action(programOutput.Codec2MuteOn);
@@ -384,12 +449,11 @@ namespace PepperDash.Essentials.DM
VolumeUpAction = new Action<bool>((b) => programOutput.Codec2LevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => programOutput.Codec2LevelDown.BoolValue = b);
}
else
else if (output.Card is Card.Dmps3Aux1Output)
{
var auxOutput = output as Card.Dmps3Aux1Output;
var auxOutput = output.Card as Card.Dmps3Aux1Output;
Level = auxOutput.Codec2Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => auxOutput.CodecMute2OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => auxOutput.Codec2LevelFeedback.UShortValue));
MuteOnAction = new Action(auxOutput.Codec2MuteOn);
@@ -410,19 +474,26 @@ namespace PepperDash.Essentials.DM
public void SetVolumeScaled(ushort level)
{
Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString());
VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel);
if (EnableVolumeSend == true)
if (ushort.MaxValue + MinLevel != 0)
{
Level.UShortValue = VolumeLevelInput;
VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel);
if (EnableVolumeSend == true)
{
Level.UShortValue = VolumeLevelInput;
}
}
}
public ushort ScaleVolumeFeedback(ushort level)
{
short signedLevel = (short)level;
Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString());
return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel));
if (MaxLevel - MinLevel != 0)
{
return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel));
}
else
return (ushort)MinLevel;
}
public void SendScaledVolume(bool pressRelease)
@@ -476,6 +547,150 @@ namespace PepperDash.Essentials.DM
#endregion
}
public class Dmps3AudioOutputWithMixerBase : Dmps3AudioOutputBase
{
public UShortOutputSig MinVolumeFeedback { get; private set; }
public UShortOutputSig MaxVolumeFeedback { get; private set; }
public UShortInputSig StartupVolume { get; private set; }
public UShortOutputSig StartupVolumeFeedback { get; private set; }
public UShortInputSig PresetNumber { get; private set; }
public Action RecallPreset { get; private set; }
public Dmps3AudioOutputWithMixerBase(Card.Dmps3OutputBase card, CrestronControlSystem.Dmps3OutputMixer mixer)
: base(card)
{
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = mixer.PresetNumber;
RecallPreset = new Action(mixer.RecallPreset);
}
public Dmps3AudioOutputWithMixerBase(Card.Dmps3OutputBase card, CrestronControlSystem.Dmps3AttachableOutputMixer mixer)
: base(card)
{
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = mixer.PresetNumber;
RecallPreset = new Action(mixer.RecallPreset);
}
public Dmps3AudioOutputWithMixerBase(Card.Dmps3DmHdmiAudioOutput.Dmps3AudioOutputStream stream)
: base(stream)
{
var mixer = stream.OutputMixer;
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = stream.PresetNumber;
RecallPreset = new Action(stream.RecallPreset);
}
public Dmps3AudioOutputWithMixerBase(Card.Dmps3DmHdmiAudioOutput.Dmps3DmHdmiOutputStream stream)
: base(stream)
{
var mixer = stream.OutputMixer;
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = stream.PresetNumber;
RecallPreset = new Action(stream.RecallPreset);
}
}
public class Dmps3AudioOutputBase
{
public DMOutput Card { get; private set; }
public BoolOutputSig MasterMuteOffFeedBack { get; private set; }
public BoolOutputSig MasterMuteOnFeedBack { get; private set; }
public UShortInputSig MasterVolume { get; private set; }
public UShortOutputSig MasterVolumeFeedBack { get; private set; }
public BoolInputSig MasterVolumeUp { get; private set; }
public BoolInputSig MasterVolumeDown { get; private set; }
public BoolOutputSig SourceMuteOffFeedBack { get; private set; }
public BoolOutputSig SourceMuteOnFeedBack { get; private set; }
public UShortInputSig SourceLevel { get; private set; }
public UShortOutputSig SourceLevelFeedBack { get; private set; }
public BoolInputSig SourceLevelUp { get; private set; }
public BoolInputSig SourceLevelDown { get; private set; }
public Action MasterMuteOff { get; private set; }
public Action MasterMuteOn { get; private set; }
public Action SourceMuteOff { get; private set; }
public Action SourceMuteOn { get; private set; }
public Dmps3AudioOutputBase(Card.Dmps3OutputBase card)
{
Card = card;
MasterMuteOffFeedBack = card.MasterMuteOffFeedBack;
MasterMuteOnFeedBack = card.MasterMuteOnFeedBack;
MasterVolume = card.MasterVolume;
MasterVolumeFeedBack = card.MasterVolumeFeedBack;
MasterVolumeUp = card.MasterVolumeUp;
MasterVolumeDown = card.MasterVolumeDown;
SourceMuteOffFeedBack = card.SourceMuteOffFeedBack;
SourceMuteOnFeedBack = card.SourceMuteOnFeedBack;
SourceLevel = card.SourceLevel;
SourceLevelFeedBack = card.SourceLevelFeedBack;
SourceLevelUp = card.SourceLevelUp;
SourceLevelDown = card.SourceLevelDown;
MasterMuteOff = new Action(card.MasterMuteOff);
MasterMuteOn = new Action(card.MasterMuteOn);
SourceMuteOff = new Action(card.SourceMuteOff);
SourceMuteOn = new Action(card.SourceMuteOn);
}
public Dmps3AudioOutputBase(Card.Dmps3DmHdmiAudioOutput.Dmps3AudioOutputStream stream)
{
MasterMuteOffFeedBack = stream.MasterMuteOffFeedBack;
MasterMuteOnFeedBack = stream.MasterMuteOnFeedBack;
MasterVolume = stream.MasterVolume;
MasterVolumeFeedBack = stream.MasterVolumeFeedBack;
MasterVolumeUp = stream.MasterVolumeUp;
MasterVolumeDown = stream.MasterVolumeDown;
SourceMuteOffFeedBack = stream.SourceMuteOffFeedBack;
SourceMuteOnFeedBack = stream.SourceMuteOnFeedBack;
SourceLevel = stream.SourceLevel;
SourceLevelFeedBack = stream.SourceLevelFeedBack;
SourceLevelUp = stream.SourceLevelUp;
SourceLevelDown = stream.SourceLevelDown;
MasterMuteOff = new Action(stream.MasterMuteOff);
MasterMuteOn = new Action(stream.MasterMuteOn);
SourceMuteOff = new Action(stream.SourceMuteOff);
SourceMuteOn = new Action(stream.SourceMuteOn);
}
public Dmps3AudioOutputBase(Card.Dmps3DmHdmiAudioOutput.Dmps3DmHdmiOutputStream stream)
{
MasterMuteOffFeedBack = stream.MasterMuteOffFeedBack;
MasterMuteOnFeedBack = stream.MasterMuteOnFeedBack;
MasterVolume = stream.MasterVolume;
MasterVolumeFeedBack = stream.MasterVolumeFeedBack;
MasterVolumeUp = stream.MasterVolumeUp;
MasterVolumeDown = stream.MasterVolumeDown;
SourceMuteOffFeedBack = stream.SourceMuteOffFeedBack;
SourceMuteOnFeedBack = stream.SourceMuteOnFeedBack;
SourceLevel = stream.SourceLevel;
SourceLevelFeedBack = stream.SourceLevelFeedBack;
SourceLevelUp = stream.SourceLevelUp;
SourceLevelDown = stream.SourceLevelDown;
MasterMuteOff = new Action(stream.MasterMuteOff);
MasterMuteOn = new Action(stream.MasterMuteOn);
SourceMuteOff = new Action(stream.SourceMuteOff);
SourceMuteOn = new Action(stream.SourceMuteOn);
}
}
public enum eDmpsLevelType
{
Master,

View File

@@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Cards;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.DM
{
/// <summary>
///
/// </summary>
public class DmpsDigitalOutputController : Device, IRoutingNumeric, IHasFeedback
{
public Card.Dmps3OutputBase OutputCard { get; protected set; }
public RoutingInputPort None { get; protected set; }
public RoutingInputPort DigitalMix1 { get; protected set; }
public RoutingInputPort DigitalMix2 { get; protected set; }
public RoutingInputPort AudioFollowsVideo { get; protected set; }
public RoutingOutputPort DigitalAudioOut { get; protected set; }
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
public virtual RoutingPortCollection<RoutingInputPort> InputPorts
{
get
{
return new RoutingPortCollection<RoutingInputPort>
{
None,
DigitalMix1,
DigitalMix2,
AudioFollowsVideo
};
}
}
public RoutingPortCollection<RoutingOutputPort> OutputPorts
{
get
{
return new RoutingPortCollection<RoutingOutputPort> { DigitalAudioOut };
}
}
public DmpsDigitalOutputController(string key, string name, Card.Dmps3OutputBase outputCard)
: base(key, name)
{
Feedbacks = new FeedbackCollection<Feedback>();
OutputCard = outputCard;
if (outputCard is Card.Dmps3DmOutputBackend)
{
AudioSourceNumericFeedback = new IntFeedback(() =>
{
return (int)(outputCard as Card.Dmps3DmOutputBackend).AudioOutSourceDeviceFeedback;
});
DigitalAudioOut = new RoutingOutputPort(DmPortName.DmOut + OutputCard.Number, eRoutingSignalType.Audio, eRoutingPortConnectionType.DmCat, null, this);
}
else if (outputCard is Card.Dmps3HdmiOutputBackend)
{
AudioSourceNumericFeedback = new IntFeedback(() =>
{
return (int)(outputCard as Card.Dmps3HdmiOutputBackend).AudioOutSourceDeviceFeedback;
});
DigitalAudioOut = new RoutingOutputPort(DmPortName.HdmiOut + OutputCard.Number, eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null, this);
}
else
{
return;
}
None = new RoutingInputPort("None", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.NoRoute, this);
DigitalMix1 = new RoutingInputPort("DigitalMix1", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.DigitalMixer1, this);
DigitalMix2 = new RoutingInputPort("DigitalMix2", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.DigitalMixer2, this);
AudioFollowsVideo = new RoutingInputPort("AudioFollowsVideo", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.AudioFollowsVideo, this);
AddToFeedbackList(AudioSourceNumericFeedback);
}
/// <summary>
/// Adds feedback(s) to the list
/// </summary>
/// <param name="newFbs"></param>
public void AddToFeedbackList(params Feedback[] newFbs)
{
foreach (var f in newFbs)
{
if (f != null)
{
if (!Feedbacks.Contains(f))
{
Feedbacks.Add(f);
}
}
}
}
public virtual void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
switch (input)
{
case 0:
{
ExecuteSwitch(None.Selector, null, type);
break;
}
case 1:
{
ExecuteSwitch(DigitalMix1.Selector, null, type);
break;
}
case 2:
{
ExecuteSwitch(DigitalMix2.Selector, null, type);
break;
}
case 3:
{
ExecuteSwitch(AudioFollowsVideo.Selector, null, type);
break;
}
}
}
#region IRouting Members
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
if (OutputCard is Card.Dmps3DmOutputBackend)
{
(OutputCard as Card.Dmps3DmOutputBackend).AudioOutSourceDevice = (eDmps34KAudioOutSourceDevice)inputSelector;
}
else if (OutputCard is Card.Dmps3HdmiOutputBackend)
{
(OutputCard as Card.Dmps3HdmiOutputBackend).AudioOutSourceDevice = (eDmps34KAudioOutSourceDevice)inputSelector;
}
}
}
#endregion
}
}

View File

@@ -47,16 +47,23 @@ namespace PepperDash.Essentials.DM
{
get
{
if (InputCard.VideoSourceFeedback != eDmps3InputVideoSource.Auto)
return InputCard.VideoSourceFeedback;
else // auto
try
{
if (InputCard.HdmiInputPort.SyncDetectedFeedback.BoolValue)
return eDmps3InputVideoSource.Hdmi;
else if (InputCard.VgaInputPort.SyncDetectedFeedback.BoolValue)
return eDmps3InputVideoSource.Vga;
else
return eDmps3InputVideoSource.Bnc;
if (InputCard.VideoSourceFeedback != eDmps3InputVideoSource.Auto)
return InputCard.VideoSourceFeedback;
else // auto
{
if (InputCard.HdmiInputPort.SyncDetectedFeedback.BoolValue)
return eDmps3InputVideoSource.Hdmi;
else if (InputCard.VgaInputPort.SyncDetectedFeedback.BoolValue)
return eDmps3InputVideoSource.Vga;
else
return eDmps3InputVideoSource.Bnc;
}
}
catch
{
return eDmps3InputVideoSource.Bnc;
}
}
}

View File

@@ -38,6 +38,9 @@ namespace PepperDash.Essentials.DM
void Dmps_MicrophoneChange(MicrophoneBase mic, GenericEventArgs args)
{
if (args.EventId == MicrophoneEventIds.VuFeedBackEventId)
return;
Debug.Console(2, "Dmps Microphone Controller Index: {0} EventId: {1}", mic.ID, args.EventId.ToString());
if(Mics.ContainsKey(mic.ID))

View File

@@ -26,13 +26,10 @@ namespace PepperDash.Essentials.DM
public CrestronControlSystem Dmps { get; set; }
public ISystemControl SystemControl { get; private set; }
public bool? EnableRouting { 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 Control
public BoolFeedback SystemPowerOnFeedback { get; private set; }
public BoolFeedback SystemPowerOffFeedback { get; private set; }
@@ -62,6 +59,7 @@ namespace PepperDash.Essentials.DM
public Dictionary<uint, string> InputNames { get; set; }
public Dictionary<uint, string> OutputNames { get; set; }
public Dictionary<uint, DmCardAudioOutputController> VolumeControls { get; private set; }
public Dictionary<uint, DmpsDigitalOutputController> DigitalAudioOutputs { get; private set; }
public DmpsMicrophoneController Microphones { get; private set; }
public const int RouteOffTime = 500;
@@ -123,14 +121,13 @@ namespace PepperDash.Essentials.DM
/// <param name="chassis"></param>
public DmpsRoutingController(string key, string name, ISystemControl systemControl)
: base(key, name)
{
{
Dmps = Global.ControlSystem;
switch (systemControl.SystemControlType)
{
case eSystemControlType.Dmps34K150CSystemControl:
SystemControl = systemControl as Dmps34K150CSystemControl;
Dmps4kType = true;
SystemPowerOnFeedback = new BoolFeedback(() => { return true; });
SystemPowerOffFeedback = new BoolFeedback(() => { return false; });
break;
@@ -139,13 +136,11 @@ namespace PepperDash.Essentials.DM
case eSystemControlType.Dmps34K300CSystemControl:
case eSystemControlType.Dmps34K350CSystemControl:
SystemControl = systemControl as Dmps34K300CSystemControl;
Dmps4kType = true;
SystemPowerOnFeedback = new BoolFeedback(() => { return true; });
SystemPowerOffFeedback = new BoolFeedback(() => { return false; });
break;
default:
SystemControl = systemControl as Dmps3SystemControl;
Dmps4kType = false;
SystemPowerOnFeedback = new BoolFeedback(() =>
{
return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue;
@@ -156,11 +151,12 @@ namespace PepperDash.Essentials.DM
});
break;
}
Debug.Console(1, this, "DMPS Type = {0}, 4K Type = {1}", systemControl.SystemControlType, Dmps4kType);
Debug.Console(1, this, "DMPS Type = {0}, 4K Type = {1}", systemControl.SystemControlType, Global.ControlSystemIsDmps4kType);
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
VolumeControls = new Dictionary<uint, DmCardAudioOutputController>();
DigitalAudioOutputs = new Dictionary<uint, DmpsDigitalOutputController>();
TxDictionary = new Dictionary<uint, string>();
RxDictionary = new Dictionary<uint, string>();
@@ -252,13 +248,15 @@ namespace PepperDash.Essentials.DM
{
return;
}
foreach (var kvp in OutputNames)
{
var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput);
if (output != null && output.Name.Type != eSigType.NA)
if (output != null)
{
output.Name.StringValue = kvp.Value;
if (output.Name.Supported && kvp.Value.Length > 0)
{
output.Name.StringValue = kvp.Value;
}
}
}
}
@@ -272,9 +270,12 @@ namespace PepperDash.Essentials.DM
foreach (var kvp in InputNames)
{
var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput);
if (input != null && input.Name.Type != eSigType.NA)
if (input != null)
{
input.Name.StringValue = kvp.Value;
if (input.Name.Supported && kvp.Value.Length > 0)
{
input.Name.StringValue = kvp.Value;
}
}
}
}
@@ -382,9 +383,21 @@ namespace PepperDash.Essentials.DM
}
if (OutputNameFeedbacks[ioSlot] != null)
{
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputVideoNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]);
if (Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3DmOutput ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3DmOutputBackend ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3HdmiOutput ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3HdmiOutputBackend ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3DmHdmiAudioOutput)
{
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputVideoNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]);
}
else
{
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]);
}
}
if (OutputVideoRouteNameFeedbacks[ioSlot] != null)
{
@@ -406,13 +419,11 @@ namespace PepperDash.Essentials.DM
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
{
if (Dmps4kType)
if (Global.ControlSystemIsDmps4k3xxType)
{
//DMPS-4K audio inputs 1-5 are aux inputs
for (uint i = 1; i <= 5; i++)
{
trilist.StringInput[joinMap.InputAudioNames.JoinNumber + i - 1].StringValue = String.Format("Aux Input {0}", i);
}
//Add DMPS-4K mixer input names to end of inputs
trilist.StringInput[joinMap.InputAudioNames.JoinNumber + (uint)Dmps.SwitcherInputs.Count + 4].StringValue = "Digital Mixer 1";
trilist.StringInput[joinMap.InputAudioNames.JoinNumber + (uint)Dmps.SwitcherInputs.Count + 5].StringValue = "Digital Mixer 2";
}
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
{
@@ -427,18 +438,19 @@ namespace PepperDash.Essentials.DM
trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]);
}
if (InputNameFeedbacks.ContainsKey(ioSlot) && InputNameFeedbacks[ioSlot] != null)
if (InputNameFeedbacks.ContainsKey(ioSlot) && InputNameFeedbacks[ioSlot] != null)
{
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]);
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputVideoNames.JoinNumber + ioSlotJoin]);
if (Dmps4kType)
if (Dmps.SwitcherInputs[ioSlot] is Card.Dmps3AnalogAudioInput)
{
//DMPS-4K Audio Inputs are offset by 5
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin + 5]);
for (uint j = ioSlot; j < ioSlot + 5; j++)
{
InputNameFeedbacks[j].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + j - 1]);
}
}
else
{
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]);
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputVideoNames.JoinNumber + ioSlotJoin]);
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin]);
}
}
@@ -481,69 +493,143 @@ namespace PepperDash.Essentials.DM
{
foreach (var card in Dmps.SwitcherOutputs)
{
Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType);
var outputCard = card as DMOutput;
if (outputCard == null)
try
{
Debug.Console(1, this, "Output card {0} is not a DMOutput", card.CardInputOutputType);
continue;
}
Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType);
Debug.Console(1, this, "Adding Output Card Number {0} Type: {1}", outputCard.Number, outputCard.CardInputOutputType.ToString());
VideoOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{
if (outputCard.VideoOutFeedback != null) { return (ushort)outputCard.VideoOutFeedback.Number; }
return 0;
;
});
AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{
try
var outputCard = card as DMOutput;
if (outputCard == null)
{
if (outputCard.AudioOutFeedback != null)
{
return (ushort) outputCard.AudioOutFeedback.Number;
}
Debug.Console(1, this, "Output card {0} is not a DMOutput", card.CardInputOutputType);
continue;
}
Debug.Console(1, this, "Adding Output Card Number {0} Type: {1}", outputCard.Number, outputCard.CardInputOutputType.ToString());
VideoOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{
if (outputCard.VideoOutFeedback != null) { return (ushort)outputCard.VideoOutFeedback.Number; }
return 0;
}
catch (NotSupportedException)
;
});
AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{
return (ushort) outputCard.AudioOutSourceFeedback;
}
});
if (!Global.ControlSystemIsDmps4k3xxType)
{
if (outputCard.AudioOutFeedback != null)
{
return (ushort)outputCard.AudioOutFeedback.Number;
}
return 0;
}
else
{
OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
//Special cases for DMPS-4K digital audio output
if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 0)
return 0;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 1)
return (ushort)Dmps.SwitcherInputs.Count + 5;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 2)
return (ushort)Dmps.SwitcherInputs.Count + 6;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 3)
return (ushort)outputCard.VideoOutFeedback.Number;
else
return 0;
}
else if (outputCard.AudioOutSourceFeedback == eDmps34KAudioOutSource.NoRoute)
{
//Fixes for weird audio indexing on DMPS3-4K
return 0;
}
else if (outputCard.AudioOutSourceFeedback == eDmps34KAudioOutSource.AirMedia8)
{
//Fixes for weird audio indexing on DMPS3-4K
return 8;
}
else if (outputCard.AudioOutSourceFeedback == eDmps34KAudioOutSource.AirMedia9)
{
//Fixes for weird audio indexing on DMPS3-4K
return 9;
}
else if ((ushort)outputCard.AudioOutSourceFeedback <= 5)
{
//Move analog inputs to after regular dm cards
return (ushort)outputCard.AudioOutSourceFeedback + (ushort)Dmps.SwitcherInputs.Count - 1;
}
else
{
//Fixes for weird audio indexing on DMPS3-4K
return (ushort)outputCard.AudioOutSourceFeedback - 5;
}
}
});
OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{
if(OutputNames.ContainsKey(outputCard.Number))
{
return OutputNames[outputCard.Number];
}
else if (outputCard.NameFeedback != null && outputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
{
Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue);
return outputCard.NameFeedback.StringValue;
}
return "";
});
OutputVideoRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{
if (outputCard.VideoOutFeedback != null && outputCard.VideoOutFeedback.NameFeedback != null)
{
return outputCard.VideoOutFeedback.NameFeedback.StringValue;
}
return NoRouteText;
});
OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{
if (!Global.ControlSystemIsDmps4k3xxType)
{
if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null)
{
return outputCard.AudioOutFeedback.NameFeedback.StringValue;
}
}
else
{
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
//Special cases for DMPS-4K digital audio output
if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 0)
return NoRouteText;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 1)
return "Digital Mix 1";
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 2)
return "Digital Mix 2";
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 3)
return outputCard.VideoOutFeedback.NameFeedback.StringValue;
else
return NoRouteText;
}
else
{
return outputCard.AudioOutSourceFeedback.ToString();
}
}
return NoRouteText;
});
OutputEndpointOnlineFeedbacks[outputCard.Number] = new BoolFeedback(() => outputCard.EndpointOnlineFeedback);
AddOutputCard(outputCard.Number, outputCard);
}
catch (Exception ex)
{
if (outputCard.NameFeedback != null && outputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
{
Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue);
return outputCard.NameFeedback.StringValue;
}
return "";
});
OutputVideoRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{
if (outputCard.VideoOutFeedback != null && outputCard.VideoOutFeedback.NameFeedback != null)
{
return outputCard.VideoOutFeedback.NameFeedback.StringValue;
}
return NoRouteText;
});
OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{
if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null)
{
return outputCard.AudioOutFeedback.NameFeedback.StringValue;
}
return NoRouteText;
});
OutputEndpointOnlineFeedbacks[outputCard.Number] = new BoolFeedback(() => outputCard.EndpointOnlineFeedback);
AddOutputCard(outputCard.Number, outputCard);
Debug.LogError(Debug.ErrorLogLevel.Error, string.Format("DMPS Controller exception creating output card: {0}", ex));
}
}
}
@@ -569,13 +655,15 @@ namespace PepperDash.Essentials.DM
InputNameFeedbacks[inputCard.Number] = new StringFeedback(() =>
{
if (inputCard.NameFeedback != null && inputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue))
if (InputNames.ContainsKey(inputCard.Number))
{
return InputNames[inputCard.Number];
}
else if (inputCard.NameFeedback != null && inputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue))
{
Debug.Console(2, this, "Input Card {0} Name: {1}", inputCard.Number, inputCard.NameFeedback.StringValue);
return inputCard.NameFeedback.StringValue;
}
Debug.Console(2, this, "Input Card {0} Name is null", inputCard.Number);
return "";
});
@@ -609,7 +697,6 @@ namespace PepperDash.Essentials.DM
else if (inputCard is Card.Dmps3HdmiInput)
{
var hdmiInputCard = inputCard as Card.Dmps3HdmiInput;
var cecPort = hdmiInputCard.HdmiInputPort;
AddInputPortWithDebug(number, string.Format("HdmiIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort);
@@ -641,17 +728,37 @@ namespace PepperDash.Essentials.DM
else if (inputCard is Card.Dmps3DmInput)
{
var hdmiInputCard = inputCard as Card.Dmps3DmInput;
var cecPort = hdmiInputCard.DmInputPort;
AddInputPortWithDebug(number, string.Format("DmIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort);
}
else if (inputCard is Card.Dmps3VgaInput)
{
AddInputPortWithDebug(number, string.Format("VgaIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Vga);
}
else if (inputCard is Card.Dmps3AirMediaInput)
{
var airMediaInputCard = inputCard as Card.Dmps3AirMediaInput;
AddInputPortWithDebug(number, string.Format("AirMediaIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming);
}
else if (inputCard is Card.Dmps3AnalogAudioInput)
{
for (uint i = 0; i <= 4; i++)
{
uint j = i + 1;
uint input = i + number;
InputNameFeedbacks[input] = new StringFeedback(() =>
{
if (InputNames.ContainsKey(input))
{
return InputNames[input];
}
else
{
return String.Format("Aux Input {0}", j);
}
});
}
}
}
@@ -697,22 +804,44 @@ namespace PepperDash.Essentials.DM
var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort);
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Hdmi Audio Output {0}", number), outputCard as Card.Dmps3HdmiOutput);
DeviceManager.AddDevice(audioOutput);
}
else if (outputCard is Card.Dmps3HdmiOutputBackend)
{
var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend;
var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort);
var audioOutput = new DmpsDigitalOutputController(string.Format("processor-avRouting-HdmiAudioOut{0}", number), string.Format("Hdmi Audio Output {0} Router", number), hdmiOutputCard);
DigitalAudioOutputs.Add(number, audioOutput);
DeviceManager.AddDevice(audioOutput);
}
else if (outputCard is Card.Dmps3DmOutput)
{
AddDmOutputPort(number);
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Dm Audio Output {0}", number), outputCard as Card.Dmps3DmOutput);
DeviceManager.AddDevice(audioOutput);
}
else if (outputCard is Card.Dmps3DmOutputBackend)
{
AddDmOutputPort(number);
var audioOutput = new DmpsDigitalOutputController(string.Format("processor-avRouting-DmAudioOut{0}", number), string.Format("Dm Audio Output {0} Router", number), outputCard as Card.Dmps3DmOutputBackend);
DigitalAudioOutputs.Add(number, audioOutput);
DeviceManager.AddDevice(audioOutput);
}
else if (outputCard is Card.Dmps3DmHdmiAudioOutput)
{
var hdmiOutputCard = outputCard as Card.Dmps3DmHdmiAudioOutput;
var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort);
AddDmOutputPort(number);
AddAudioOnlyOutputPort(number, "Program");
var audioOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput", number), string.Format("Program Audio Output {0}", number), hdmiOutputCard, hdmiOutputCard.AudioOutputStream);
DeviceManager.AddDevice(audioOutput);
var digitalAudioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Hdmi Audio Output {0}", number), hdmiOutputCard, hdmiOutputCard.DmHdmiOutputStream);
DeviceManager.AddDevice(digitalAudioOutput);
}
else if (outputCard is Card.Dmps3ProgramOutput)
{
@@ -727,22 +856,22 @@ namespace PepperDash.Essentials.DM
switch (outputCard.CardInputOutputType)
{
case eCardInputOutputType.Dmps3Aux1Output:
{
AddAudioOnlyOutputPort(number, "Aux1");
{
AddAudioOnlyOutputPort(number, "Aux1");
var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3Aux1Output);
var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Aux1 Audio Output", outputCard as Card.Dmps3Aux1Output);
DeviceManager.AddDevice(aux1Output);
}
DeviceManager.AddDevice(aux1Output);
}
break;
case eCardInputOutputType.Dmps3Aux2Output:
{
AddAudioOnlyOutputPort(number, "Aux2");
{
AddAudioOnlyOutputPort(number, "Aux2");
var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3Aux2Output);
var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Aux2 Audio Output", outputCard as Card.Dmps3Aux2Output);
DeviceManager.AddDevice(aux2Output);
}
DeviceManager.AddDevice(aux2Output);
}
break;
}
}
@@ -766,6 +895,10 @@ namespace PepperDash.Essentials.DM
{
AddAudioOnlyOutputPort(number, "Dialer");
}
else if (outputCard is Card.Dmps3AecOutput)
{
AddAudioOnlyOutputPort(number, "Aec");
}
else if (outputCard is Card.Dmps3DigitalMixOutput)
{
if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix1
@@ -776,10 +909,9 @@ namespace PepperDash.Essentials.DM
|| number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2
|| number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2)
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString());
}
else if (outputCard is Card.Dmps3AecOutput)
{
AddAudioOnlyOutputPort(number, "Aec");
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number % 2 + 1), string.Format("Digital Audio Mix {0}", number % 2 + 1), outputCard as Card.Dmps3DigitalMixOutput);
DeviceManager.AddDevice(audioOutput);
}
else
{
@@ -851,6 +983,7 @@ namespace PepperDash.Essentials.DM
void Dmps_DMInputChange(Switch device, DMInputEventArgs args)
{
Debug.Console(2, this, "DMInputChange Input: {0} EventId: {1}", args.Number, args.EventId.ToString());
try
{
switch (args.EventId)
@@ -861,6 +994,12 @@ namespace PepperDash.Essentials.DM
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break;
}
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.VideoDetectedEventId):
{
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
@@ -885,14 +1024,13 @@ namespace PepperDash.Essentials.DM
}
void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args)
{
Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString());
if (args.EventId == DMOutputEventIds.OutputVuFeedBackEventId)
{
//Frequently called event that isn't needed
return;
}
Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString());
var output = args.Number;
DMOutput outputCard = Dmps.SwitcherOutputs[output] as DMOutput;
@@ -906,6 +1044,11 @@ namespace PepperDash.Essentials.DM
{
OutputEndpointOnlineFeedbacks[output].FireUpdate();
}
else if (args.EventId == DMOutputEventIds.EndpointOnlineEventId
&& OutputEndpointOnlineFeedbacks.ContainsKey(output))
{
OutputEndpointOnlineFeedbacks[output].FireUpdate();
}
else if (args.EventId == DMOutputEventIds.VideoOutEventId)
{
if (outputCard != null && outputCard.VideoOutFeedback != null)
@@ -920,41 +1063,68 @@ namespace PepperDash.Essentials.DM
{
OutputVideoRouteNameFeedbacks[output].FireUpdate();
}
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
}
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
{
OutputAudioRouteNameFeedbacks[output].FireUpdate();
}
}
}
else if (args.EventId == DMOutputEventIds.AudioOutEventId)
{
try
if (!Global.ControlSystemIsDmps4k3xxType)
{
if (outputCard != null && outputCard.AudioOutFeedback != null)
{
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name,
outputCard.AudioOutFeedback.Number, output);
}
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
}
}
catch (NotSupportedException)
else
{
if (outputCard != null)
{
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name,
outputCard.AudioOutSourceFeedback, output);
}
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
DigitalAudioOutputs[output].AudioSourceNumericFeedback.FireUpdate();
}
else
{
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name,
outputCard.AudioOutSourceFeedback, output);
}
}
}
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
}
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
{
OutputAudioRouteNameFeedbacks[output].FireUpdate();
}
}
else if (args.EventId == DMOutputEventIds.OutputNameEventId
&& OutputNameFeedbacks.ContainsKey(output))
{
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
OutputNameFeedbacks[output].FireUpdate();
}
else if (args.EventId == DMOutputEventIds.DigitalMixerAudioSourceFeedBackEventId)
{
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
}
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
{
OutputAudioRouteNameFeedbacks[output].FireUpdate();
}
}
}
void Dmps_DMSystemChange(Switch device, DMSystemEventArgs args)
@@ -1002,9 +1172,6 @@ namespace PepperDash.Essentials.DM
Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType);
//var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail
//var output = Convert.ToUInt32(outputSelector);
var input = inputSelector as DMInput;
var output = outputSelector as DMOutput;
@@ -1022,7 +1189,7 @@ namespace PepperDash.Essentials.DM
if (input == null || (input.Number <= Dmps.NumberOfSwitcherInputs && output.Number <= Dmps.NumberOfSwitcherOutputs &&
sigTypeIsUsbOrVideo) ||
(input.Number <= Dmps.NumberOfSwitcherInputs + 5 && output.Number <= Dmps.NumberOfSwitcherOutputs &&
(input.Number <= (Dmps.NumberOfSwitcherInputs) && output.Number <= Dmps.NumberOfSwitcherOutputs &&
(sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
{
// Check to see if there's an off timer waiting on this and if so, cancel
@@ -1041,11 +1208,6 @@ namespace PepperDash.Essentials.DM
}
}
//DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput;
//if (inCard != null)
//{
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
@@ -1054,19 +1216,34 @@ namespace PepperDash.Essentials.DM
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
try
if (!Global.ControlSystemIsDmps4k3xxType)
{
output.AudioOut = input;
}
catch (NotSupportedException)
else
{
Debug.Console(1, this, "Routing input {0} audio to output {1}",
(eDmps34KAudioOutSource) (input == null ? 0 : input.Number),
(CrestronControlSystem.eDmps34K350COutputs) output.Number);
output.AudioOutSource = input == null
? eDmps34KAudioOutSource.NoRoute
: (eDmps34KAudioOutSource)input.Number;
if (input == null)
{
output.AudioOutSource = eDmps34KAudioOutSource.NoRoute;
}
else if (input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaInput || input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaNoStreamingInput)
{
//Special case for weird AirMedia indexing
if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia8;
else if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia9;
}
else if (input.Number < Dmps.SwitcherInputs.Count)
{
//Shift video inputs by 5 for weird DMPS3-4K indexing
output.AudioOutSource = (eDmps34KAudioOutSource)(input.Number + 5);
}
else
{
//Shift analog inputs back to inputs 1-5
output.AudioOutSource = (eDmps34KAudioOutSource)(input.Number - Dmps.SwitcherInputs.Count + 1);
}
}
}
@@ -1100,10 +1277,91 @@ namespace PepperDash.Essentials.DM
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
{
var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector];
var output = Dmps.SwitcherOutputs[outputSelector];
if (EnableRouting == false)
{
return;
}
ExecuteSwitch(input, output, sigType);
Debug.Console(1, this, "Attempting a numeric switch from input {0} to output {1} {2}", inputSelector, outputSelector, sigType);
if((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
if (inputSelector <= Dmps.SwitcherInputs.Count && outputSelector <= Dmps.SwitcherOutputs.Count)
{
var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector];
var output = Dmps.SwitcherOutputs[outputSelector];
ExecuteSwitch(input, output, sigType);
}
}
else if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
//Special case for DMPS-4K digital audio output
if (Global.ControlSystemIsDmps4k3xxType)
{
if (DigitalAudioOutputs.ContainsKey(outputSelector))
{
if (inputSelector == 0) //Clear action
{
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(0, 0, eRoutingSignalType.Audio);
}
else if (inputSelector < Dmps.SwitcherInputs.Count) //DMPS-4K video inputs, set to audio follows video
{
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(3, 0, eRoutingSignalType.Audio);
//Force video route since it is now set so audio follows video
ExecuteNumericSwitch(inputSelector, outputSelector, eRoutingSignalType.Video);
}
else if (inputSelector == Dmps.SwitcherInputs.Count + 5)
{
//Set to mix 1
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(1, 0, eRoutingSignalType.Audio);
}
else if (inputSelector == Dmps.SwitcherInputs.Count + 6)
{
//Set to mix 2
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(2, 0, eRoutingSignalType.Audio);
}
}
else if (inputSelector <= (Dmps.SwitcherInputs.Count + 4) && outputSelector <= Dmps.SwitcherOutputs.Count)
{
var output = Dmps.SwitcherOutputs[outputSelector] as DMOutput;
if (inputSelector == 0)
{
output.AudioOutSource = eDmps34KAudioOutSource.NoRoute;
}
else if(inputSelector >= (Dmps.SwitcherInputs.Count))
{
//Shift analog inputs back to inputs 1-5
Debug.Console(1, this, "Attempting analog route input {0} to output {1}", inputSelector - Dmps.SwitcherInputs.Count + 1, outputSelector);
output.AudioOutSource = (eDmps34KAudioOutSource)(inputSelector - Dmps.SwitcherInputs.Count + 1);
}
else if (inputSelector < Dmps.SwitcherInputs.Count)
{
var input = Dmps.SwitcherInputs[inputSelector] as DMInput;
if (input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaInput || input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaNoStreamingInput)
{
//Special case for weird AirMedia indexing
if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia8;
else if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia9;
}
else
{
//Shift video inputs by 5 for weird DMPS3-4K indexing
output.AudioOutSource = (eDmps34KAudioOutSource)(inputSelector + 5);
}
}
}
}
else if (inputSelector <= Dmps.SwitcherInputs.Count && outputSelector <= Dmps.SwitcherOutputs.Count)
{
var output = Dmps.SwitcherOutputs[outputSelector] as DMOutput;
var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector] as DMInput;
output.AudioOut = input;
}
}
}
#endregion

View File

@@ -0,0 +1,516 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM.Config;
using Crestron.SimplSharpPro.DM.Cards;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM.Chassis
{
[Description("Wrapper class for all HdMd8xN switchers")]
public class HdMd8xNController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
{
private HdMd8xN _Chassis;
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
public Dictionary<uint, string> InputNames { get; set; }
public Dictionary<uint, string> OutputNames { get; set; }
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
public FeedbackCollection<IntFeedback> AudioOutputRouteFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputVideoRouteNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputAudioRouteNameFeedbacks { get; private set; }
public StringFeedback DeviceNameFeedback { get; private set; }
#region Constructor
public HdMd8xNController(string key, string name, HdMd8xN chassis,
DMChassisPropertiesConfig props)
: base(key, name, chassis)
{
_Chassis = chassis;
Name = name;
_Chassis.EnableAudioBreakaway.BoolValue = true;
if (props == null)
{
Debug.Console(1, this, "HdMd8xNController properties are null, failed to build the device");
return;
}
InputNames = new Dictionary<uint, string>();
if (props.InputNames != null)
{
InputNames = props.InputNames;
}
OutputNames = new Dictionary<uint, string>();
if (props.OutputNames != null)
{
OutputNames = props.OutputNames;
}
DeviceNameFeedback = new StringFeedback(()=> Name);
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
AudioOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputVideoRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputAudioRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
//Inputs - should always be 8 audio/video inputs
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
try
{
var index = i;
if (!InputNames.ContainsKey(index))
{
InputNames.Add(index, string.Format("Input{0}", index));
}
string inputName = InputNames[index];
_Chassis.Inputs[index].Name.StringValue = inputName;
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, _Chassis.Inputs[index], this)
{
FeedbackMatchObject = _Chassis.Inputs[index]
});
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].NameFeedback.StringValue));
}
catch (Exception ex)
{
ErrorLog.Error("Exception creating input {0} on HD-MD8xN Chassis: {1}", i, ex);
}
}
//Outputs. Either 2 outputs (1 audio, 1 audio/video) for HD-MD8x1 or 4 outputs (2 audio, 2 audio/video) for HD-MD8x2
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
try
{
var index = i;
if (!OutputNames.ContainsKey(index))
{
OutputNames.Add(index, string.Format("Output{0}", index));
}
string outputName = OutputNames[index];
_Chassis.Outputs[index].Name.StringValue = outputName;
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, _Chassis.Outputs[index], this)
{
FeedbackMatchObject = _Chassis.Outputs[index]
});
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].NameFeedback.StringValue));
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
AudioOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].AudioOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].AudioOutFeedback.Number));
OutputVideoRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? "None" : _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
OutputAudioRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].AudioOutFeedback == null ? "None" : _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
}
catch (Exception ex)
{
ErrorLog.Error("Exception creating output {0} on HD-MD8xN Chassis: {1}", i, ex);
}
}
_Chassis.DMInputChange += Chassis_DMInputChange;
_Chassis.DMOutputChange += Chassis_DMOutputChange;
AddPostActivationAction(AddFeedbackCollections);
}
#endregion
#region Methods
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
#region PostActivate
public void AddFeedbackCollections()
{
AddFeedbackToList(DeviceNameFeedback);
AddCollectionsToList(VideoInputSyncFeedbacks);
AddCollectionsToList(VideoOutputRouteFeedbacks, AudioOutputRouteFeedbacks);
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputVideoRouteNameFeedbacks, OutputAudioRouteNameFeedbacks);
}
#endregion
#region FeedbackCollection Methods
//Add arrays of collections
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
{
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
{
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
{
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
//Add Collections
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
//Add Individual Feedbacks
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
{
if (newFb == null) return;
if (!Feedbacks.Contains(newFb))
{
Feedbacks.Add(newFb);
}
}
#endregion
#region IRouting Members
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType)
{
var input = inputSelector as DMInput;
var output = outputSelector as DMOutput;
Debug.Console(2, this, "ExecuteSwitch: input={0} output={1} sigType={2}", input, output, sigType.ToString());
if (output == null)
{
Debug.Console(0, this, "Unable to make switch. Output selector is not DMOutput");
return;
}
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
_Chassis.VideoEnter.BoolValue = true;
if (output != null)
{
output.VideoOut = input;
}
}
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
_Chassis.AudioEnter.BoolValue = true;
if (output != null)
{
output.AudioOut = input;
}
}
}
#endregion
#region IRoutingNumeric Members
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
{
var input = inputSelector == 0 ? null : _Chassis.Inputs[inputSelector];
var output = _Chassis.Outputs[outputSelector];
Debug.Console(2, this, "ExecuteNumericSwitch: input={0} output={1}", input, output);
ExecuteSwitch(input, output, signalType);
}
#endregion
#endregion
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmChassisControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmChassisControllerJoinMap>(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]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
var joinIndex = i - 1;
var input = i;
//Digital
VideoInputSyncFeedbacks[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + joinIndex]);
//Serial
InputNameFeedbacks[InputNames[input]].LinkInputSig(trilist.StringInput[joinMap.InputNames.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.OutputVideo.JoinNumber + joinIndex]);
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort)output, eRoutingSignalType.Video));
AudioOutputRouteFeedbacks[OutputNames[output]].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + joinIndex]);
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort)output, eRoutingSignalType.Audio));
//Serial
OutputNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + joinIndex]);
OutputVideoRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + joinIndex]);
OutputAudioRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + joinIndex]);
}
_Chassis.OnlineStatusChange += Chassis_OnlineStatusChange;
trilist.OnlineStatusChange += (d, args) =>
{
if (!args.DeviceOnLine) return;
};
}
#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();
}
}
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
{
switch (args.EventId)
{
case DMOutputEventIds.VideoOutEventId:
{
var output = args.Number;
var inputNumber = _Chassis.Outputs[output].VideoOutFeedback == null ? 0 : _Chassis.Outputs[output].VideoOutFeedback.Number;
var outputName = OutputNames[output];
var feedback = VideoOutputRouteFeedbacks[outputName];
if (feedback == null)
{
return;
}
var inPort = InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output].VideoOutFeedback);
var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output]);
feedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.Video));
break;
}
case DMOutputEventIds.AudioOutEventId:
{
var output = args.Number;
var inputNumber = _Chassis.Outputs[output].AudioOutFeedback == null ? 0 : _Chassis.Outputs[output].AudioOutFeedback.Number;
var outputName = OutputNames[output];
var feedback = AudioOutputRouteFeedbacks[outputName];
if (feedback == null)
{
return;
}
var inPort = InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output].AudioOutFeedback);
var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output]);
feedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.Audio));
break;
}
case DMOutputEventIds.OutputNameEventId:
case DMOutputEventIds.NameFeedbackEventId:
{
Debug.Console(1, this, "Event ID {0}: Updating name feedbacks.", args.EventId);
Debug.Console(1, this, "Output {0} Name {1}", args.Number,
_Chassis.Outputs[args.Number].NameFeedback.StringValue);
foreach (var item in OutputNameFeedbacks)
{
item.FireUpdate();
}
break;
}
default:
{
Debug.Console(1, this, "Unhandled DM Output Event ID {0}", args.EventId);
break;
}
}
}
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)
{
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.Inputs[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 HdMd8xNControllerFactory : EssentialsDeviceFactory<HdMd8xNController>
{
public HdMd8xNControllerFactory()
{
TypeNames = new List<string>() { "hdmd8x2", "hdmd8x1" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new HD-MD-8xN Device");
var props = JsonConvert.DeserializeObject<DMChassisPropertiesConfig>(dc.Properties.ToString());
var type = dc.Type.ToLower();
var control = props.Control;
var ipid = control.IpIdInt;
switch (type)
{
case ("hdmd8x2"):
return new HdMd8xNController(dc.Key, dc.Name, new HdMd8x2(ipid, Global.ControlSystem), props);
case ("hdmd8x1"):
return new HdMd8xNController(dc.Key, dc.Name, new HdMd8x1(ipid, Global.ControlSystem), props);
default:
return null;
}
}
}
#endregion
}
}

View File

@@ -1,8 +1,10 @@
using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.DM
{
@@ -28,6 +30,30 @@ namespace PepperDash.Essentials.DM
OutputPorts = new RoutingPortCollection<RoutingOutputPort> {HDBaseTSink};
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmRmcControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmRmcControllerJoinMap>(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.");
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
}
#region IComPorts Members
public CrestronCollection<ComPort> ComPorts { get { return Rmc.ComPorts; } }
public int NumberOfComPorts { get { return Rmc.NumberOfComPorts; } }

View File

@@ -1,9 +1,11 @@
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using PepperDash.Essentials.Core;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.DM
{
@@ -31,6 +33,30 @@ namespace PepperDash.Essentials.DM
InputPorts = new RoutingPortCollection<RoutingInputPort> {DmIn};
OutputPorts = new RoutingPortCollection<RoutingOutputPort> {HdmiOut};
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmRmcControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmRmcControllerJoinMap>(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.");
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
}
#region IIROutputPorts Members

View File

@@ -30,14 +30,15 @@ namespace PepperDash.Essentials.DM
: base(key, name, device)
{
_rmc = device;
// if wired to a chassis, skip registration step in base class
PreventRegistration = _rmc.DMOutput != null;
AddToFeedbackList(VideoOutputResolutionFeedback, EdidManufacturerFeedback, EdidSerialNumberFeedback, EdidNameFeedback, EdidPreferredTimingFeedback);
DeviceInfo = new DeviceInfo();
_rmc.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
IsOnline.OutputChange += (currentDevice, args) => { if (args.BoolValue) UpdateDeviceInfo(); };
}
protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
@@ -60,7 +61,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = rmc.Name;
if (rmc.VideoOutputResolutionFeedback != null)
rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution.JoinNumber]);
@@ -187,7 +188,7 @@ namespace PepperDash.Essentials.DM
#endregion
}
public abstract class DmHdBaseTControllerBase : CrestronGenericBaseDevice
public abstract class DmHdBaseTControllerBase : CrestronGenericBridgeableBaseDevice
{
protected HDBaseTBase Rmc;
@@ -330,53 +331,85 @@ namespace PepperDash.Essentials.DM
var parentDev = DeviceManager.GetDeviceForKey(pKey);
if (parentDev is DmpsRoutingController)
{
if ((parentDev as DmpsRoutingController).Dmps4kType)
var dmps = parentDev as DmpsRoutingController;
//Check that the input is within range of this chassis' possible inputs
var num = props.ParentOutputNumber;
Debug.Console(1, "Creating DMPS device '{0}'. Output number '{1}'.", key, num);
if (num <= 0 || num > dmps.Dmps.SwitcherOutputs.Count)
{
return GetDmRmcControllerForDmps4k(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber);
Debug.Console(0, "Cannot create DMPS device '{0}'. Output number '{1}' is out of range",
key, num);
return null;
}
else
// Must use different constructor for DMPS4K types. No IPID
if (Global.ControlSystemIsDmps4kType || typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
{
return GetDmRmcControllerForDmps(key, name, typeName, ipid, parentDev as DmpsRoutingController, props.ParentOutputNumber);
var rmc = GetDmRmcControllerForDmps4k(key, name, typeName, dmps, props.ParentOutputNumber);
Debug.Console(0, "DM endpoint output {0} is for Dmps4k, changing online feedback to chassis", num);
rmc.IsOnline.SetValueFunc(() => dmps.OutputEndpointOnlineFeedbacks[num].BoolValue);
dmps.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
{
foreach (var feedback in rmc.Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
return rmc;
}
return GetDmRmcControllerForDmps(key, name, typeName, ipid, dmps, props.ParentOutputNumber);
}
if (!(parentDev is IDmSwitch))
{
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.",
key, pKey);
return null;
}
else if (parentDev is DmChassisController)
{
var controller = parentDev as DmChassisController;
var chassis = controller.Chassis;
var num = props.ParentOutputNumber;
Debug.Console(1, "Creating DM Chassis device '{0}'. Output number '{1}'.", key, num);
var chassis = (parentDev as IDmSwitch).Chassis;
var num = props.ParentOutputNumber;
if (num <= 0 || num > chassis.NumberOfOutputs)
{
Debug.Console(0, "Cannot create DM device '{0}'. Output number '{1}' is out of range",
key, num);
return null;
}
var controller = parentDev as IDmSwitch;
controller.RxDictionary.Add(num, key);
// 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)
{
return GetDmRmcControllerForCpu3Chassis(key, name, typeName, chassis, num, parentDev);
}
return GetDmRmcControllerForCpu2Chassis(key, name, typeName, ipid, chassis, num, parentDev);
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-RMC device: {1}", key, e.Message);
return null;
}
if (num <= 0 || num > chassis.NumberOfOutputs)
{
Debug.Console(0, "Cannot create DM device '{0}'. Output number '{1}' is out of range",
key, num);
return null;
}
controller.RxDictionary.Add(num, key);
// 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
|| typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
{
var rmc = GetDmRmcControllerForCpu3Chassis(key, name, typeName, chassis, num, parentDev);
Debug.Console(0, "DM endpoint output {0} is for Cpu3, changing online feedback to chassis", num);
rmc.IsOnline.SetValueFunc(() => controller.OutputEndpointOnlineFeedbacks[num].BoolValue);
controller.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
{
foreach (var feedback in rmc.Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
return rmc;
}
return GetDmRmcControllerForCpu2Chassis(key, name, typeName, ipid, chassis, num, parentDev);
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-RMC device: {1}", key, e.Message);
return null;
}
}
else
{
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis or DMPS.",
key, pKey);
return null;
}
}
private static CrestronGenericBaseDevice GetDmRmcControllerForCpu2Chassis(string key, string name, string typeName,
@@ -489,8 +522,7 @@ namespace PepperDash.Essentials.DM
var props = JsonConvert.DeserializeObject
<DmRmcPropertiesConfig>(dc.Properties.ToString());
return DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props);
return DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props);
}
}

View File

@@ -97,10 +97,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="tx"></param>
public DmTx200Controller(string key, string name, DmTx200C2G tx)
public DmTx200Controller(string key, string name, DmTx200C2G tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,

View File

@@ -99,11 +99,12 @@ namespace PepperDash.Essentials.DM
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="tx"></param>
public DmTx201CController(string key, string name, DmTx201C tx)
/// <param name="tx"></param>
public DmTx201CController(string key, string name, DmTx201C tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,

View File

@@ -102,10 +102,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="tx"></param>
public DmTx201SController(string key, string name, DmTx201S tx)
public DmTx201SController(string key, string name, DmTx201S tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,

View File

@@ -111,10 +111,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="tx"></param>
public DmTx401CController(string key, string name, DmTx401C tx)
public DmTx401CController(string key, string name, DmTx401C tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this,

View File

@@ -6,6 +6,7 @@ using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
namespace PepperDash.Essentials.DM
{
@@ -20,14 +21,6 @@ namespace PepperDash.Essentials.DM
public RoutingInputPort HdmiIn { get; private set; }
public RoutingOutputPort DmOut { get; private 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 override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; }
/// <summary>
/// Helps get the "real" inputs, including when in Auto
/// </summary>
@@ -70,11 +63,34 @@ namespace PepperDash.Essentials.DM
HdmiIn.Port = Tx;
PreventRegistration = true;
var parentDev = DeviceManager.GetDeviceForKey(key);
var num = tx.DMInputOutput.Number;
if (parentDev is DmpsRoutingController)
{
var dmps = parentDev as DmpsRoutingController;
IsOnline.SetValueFunc(() => dmps.InputEndpointOnlineFeedbacks[num].BoolValue);
dmps.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
else if (parentDev is DmChassisController)
{
var controller = parentDev as DmChassisController;
IsOnline.SetValueFunc(() => controller.InputEndpointOnlineFeedbacks[num].BoolValue);
controller.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
Debug.Console(1, this, "No properties to link. Skipping device {0}", Name);
var joinMap = new HDBaseTTxControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<HDBaseTTxControllerJoinMap>(joinMapSerialized);
this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
}
#region IIROutputPorts Members

View File

@@ -96,10 +96,11 @@ namespace PepperDash.Essentials.DM
}
}
public DmTx4k202CController(string key, string name, DmTx4k202C tx)
public DmTx4k202CController(string key, string name, DmTx4k202C tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View File

@@ -101,11 +101,12 @@ namespace PepperDash.Essentials.DM
{
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
}
}
public DmTx4k302CController(string key, string name, DmTx4k302C tx)
}
public DmTx4k302CController(string key, string name, DmTx4k302C tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View File

@@ -86,10 +86,11 @@ namespace PepperDash.Essentials.DM
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
}
}
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View File

@@ -91,10 +91,11 @@ namespace PepperDash.Essentials.DM
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
}
}
public DmTx4kz302CController(string key, string name, DmTx4kz302C tx)
public DmTx4kz302CController(string key, string name, DmTx4kz302C tx, bool preventRegistration)
: base(key, name, tx)
{
Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View File

@@ -20,6 +20,63 @@ namespace PepperDash.Essentials.DM
{
public class DmTxHelper
{
public static BasicDmTxControllerBase GetDmTxForChassisWithoutIpId(string key, string name, string typeName, DMInput dmInput)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(dmInput), true);
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(dmInput), true);
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(dmInput), true);
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), true);
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(dmInput), true);
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(dmInput), true);
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(dmInput), true);
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(dmInput), true);
if (typeName.StartsWith("hdbasettx"))
new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
return null;
}
public static BasicDmTxControllerBase GetDmTxForChassisWithIpId(string key, string name, string typeName, uint ipid, DMInput dmInput)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, dmInput), true);
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, dmInput), true);
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), true);
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, dmInput), true);
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, dmInput));
return null;
}
/// <summary>
/// A factory method for various DmTxControllers
/// </summary>
@@ -27,7 +84,7 @@ namespace PepperDash.Essentials.DM
/// <param name="name"></param>
/// <param name="props"></param>
/// <returns></returns>
public static BasicDmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props)
public static BasicDmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props)
{
// switch on type name... later...
@@ -42,23 +99,21 @@ namespace PepperDash.Essentials.DM
try
{
if(typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, Global.ControlSystem));
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem));
return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem));
return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, Global.ControlSystem));
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, Global.ControlSystem));
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem));
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem));
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem));
return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem), false);
Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key);
}
catch (Exception e)
@@ -70,12 +125,12 @@ namespace PepperDash.Essentials.DM
var parentDev = DeviceManager.GetDeviceForKey(pKey);
DMInput dmInput;
bool isCpu3 = false;
BasicDmTxControllerBase tx;
if (parentDev is IDmSwitch)
if (parentDev is DmChassisController)
{
// Get the Crestron chassis and link stuff up
var switchDev = (parentDev as IDmSwitch);
var switchDev = (parentDev as DmChassisController);
var chassis = switchDev.Chassis;
//Check that the input is within range of this chassis' possible inputs
@@ -90,15 +145,31 @@ namespace PepperDash.Essentials.DM
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)
{
isCpu3 = true;
}
try
{
//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)
{
tx = GetDmTxForChassisWithoutIpId(key, name, typeName, dmInput);
Debug.Console(0, "DM endpoint output {0} is for Cpu3, changing online feedback to chassis", num);
tx.IsOnline.SetValueFunc(() => switchDev.InputEndpointOnlineFeedbacks[num].BoolValue);
switchDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
return tx;
}
else
{
return GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device for chassis: {1}", key, e);
return null;
}
}
else if(parentDev is DmpsRoutingController)
{
@@ -126,6 +197,27 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is not a DM input", key, num);
return null;
}
try
{
if(Global.ControlSystemIsDmps4kType)
{
tx = GetDmTxForChassisWithoutIpId(key, name, typeName, dmInput);
Debug.Console(0, "DM endpoint output {0} is for DMPS3-4K, changing online feedback to chassis", num);
tx.IsOnline.SetValueFunc(() => dmpsDev.InputEndpointOnlineFeedbacks[num].BoolValue);
dmpsDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
return tx;
}
else
{
return GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device for dmps: {1}", key, e);
return null;
}
}
else
@@ -133,67 +225,6 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey);
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;
}
}
@@ -221,13 +252,16 @@ namespace PepperDash.Essentials.DM
protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
: base(key, name, hardware)
{
// 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);
IsOnline.OutputChange += (currentDevice, args) =>
{
foreach (var feedback in Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
}
protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware)

View File

@@ -6,6 +6,7 @@ using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using Crestron.SimplSharpPro.DM;
using Newtonsoft.Json;
using PepperDash.Core;
@@ -18,7 +19,7 @@ namespace PepperDash.Essentials.DM
/// Controller class for suitable for HDBaseT transmitters
/// </summary>
[Description("Wrapper Class for HDBaseT devices based on HDTx3CB class")]
public class HDBaseTTxController: BasicDmTxControllerBase, IRoutingInputsOutputs, IComPorts
public class HDBaseTTxController : BasicDmTxControllerBase, IRoutingInputsOutputs, IComPorts
{
public RoutingInputPort HdmiIn { get; private set; }
public RoutingOutputPort DmOut { get; private set; }
@@ -26,6 +27,8 @@ namespace PepperDash.Essentials.DM
public HDBaseTTxController(string key, string name, HDTx3CB tx)
: base(key, name, tx)
{
PreventRegistration = true;
HdmiIn = new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this) { Port = tx };
@@ -34,6 +37,21 @@ namespace PepperDash.Essentials.DM
InputPorts = new RoutingPortCollection<RoutingInputPort> { HdmiIn };
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { DmOut };
var parentDev = DeviceManager.GetDeviceForKey(key);
var num = tx.DMInputOutput.Number;
if (parentDev is DmpsRoutingController)
{
var dmps = parentDev as DmpsRoutingController;
IsOnline.SetValueFunc(() => dmps.InputEndpointOnlineFeedbacks[num].BoolValue);
dmps.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
else if (parentDev is DmChassisController)
{
var controller = parentDev as DmChassisController;
IsOnline.SetValueFunc(() => controller.InputEndpointOnlineFeedbacks[num].BoolValue);
controller.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
}
#region IRoutingInputs Members
@@ -79,7 +97,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
}
#endregion
@@ -100,6 +118,10 @@ namespace PepperDash.Essentials.DM
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
new JoinMetadata { Description = "DM Tx Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
/// <summary>
/// Plugin device BridgeJoinMap constructor

View File

@@ -93,6 +93,7 @@
<ItemGroup>
<Compile Include="AirMedia\AirMediaPropertiesConfig.cs" />
<Compile Include="AirMedia\AirMediaController.cs" />
<Compile Include="Chassis\DmpsDigitalOutputController.cs" />
<Compile Include="Chassis\DmpsMicrophoneController.cs" />
<Compile Include="Chassis\DmBladeChassisController.cs" />
<Compile Include="Chassis\DmCardAudioOutput.cs" />
@@ -100,6 +101,7 @@
<Compile Include="Chassis\DmpsAudioOutputController.cs" />
<Compile Include="Chassis\DmpsInternalVirtualDmTxController.cs" />
<Compile Include="Chassis\DmpsRoutingController.cs" />
<Compile Include="Chassis\HdMd8xNController.cs" />
<Compile Include="Chassis\HdMdNxM4kEBridgeableController.cs" />
<Compile Include="Chassis\HdMdNxM4kEController.cs" />
<Compile Include="Config\InputPropertiesConfig.cs" />

View File

@@ -29,6 +29,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
{
[JsonProperty("controlMode", NullValueHandling = NullValueHandling.Ignore)]
public eCameraControlMode ControlMode { get; protected set; }
#region IRoutingOutputs Members
@@ -37,6 +38,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
#endregion
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
public bool CanPan
{
get
@@ -44,7 +46,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
return (Capabilities & eCameraCapabilities.Pan) == eCameraCapabilities.Pan;
}
}
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
public bool CanTilt
{
get
@@ -52,7 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
return (Capabilities & eCameraCapabilities.Tilt) == eCameraCapabilities.Tilt;
}
}
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
public bool CanZoom
{
get
@@ -60,7 +62,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
return (Capabilities & eCameraCapabilities.Zoom) == eCameraCapabilities.Zoom;
}
}
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
public bool CanFocus
{
get
@@ -221,7 +223,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist);
for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++)
for (int i = 0; i < joinMap.NumberOfPresets.JoinSpan; i++)
{
int tempNum = i;

View File

@@ -57,6 +57,11 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
void CameraMuteToggle();
}
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
{
event EventHandler VideoUnmuteRequested;
}
public class CameraSelectedEventArgs : EventArgs
{
public CameraBase SelectedCamera { get; private set; }

View File

@@ -12,34 +12,40 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{
public class CodecActiveCallItem
{
[JsonProperty("name")]
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
[JsonProperty("number")]
[JsonProperty("number", NullValueHandling = NullValueHandling.Ignore)]
public string Number { get; set; }
[JsonProperty("type")]
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallType Type { get; set; }
[JsonProperty("status")]
[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallStatus Status { get; set; }
[JsonProperty("direction")]
[JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallDirection Direction { get; set; }
[JsonProperty("id")]
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public string Id { get; set; }
[JsonProperty("isOnHold", NullValueHandling = NullValueHandling.Ignore)]
public bool IsOnHold { get; set; }
[JsonProperty("duration", NullValueHandling = NullValueHandling.Ignore)]
public TimeSpan Duration { get; set; }
//public object CallMetaData { get; set; }
/// <summary>
/// Returns true when this call is any status other than
/// Unknown, Disconnected, Disconnecting
/// </summary>
[JsonProperty("isActiveCall")]
[JsonProperty("isActiveCall", NullValueHandling = NullValueHandling.Ignore)]
public bool IsActiveCall
{
get

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
{
public interface IHasCallHold
{
/// <summary>
/// Put the specified call on hold
/// </summary>
/// <param name="activeCall"></param>
void HoldCall(CodecActiveCallItem activeCall);
/// <summary>
/// Resume the specified call
/// </summary>
/// <param name="activeCall"></param>
void ResumeCall(CodecActiveCallItem activeCall);
}
}

View File

@@ -23,9 +23,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
public enum eCodecOccurrenceType
{
Unknown = 0,
Placed,
Received,
NoAnswer
Placed = 1,
Received = 2,
NoAnswer = 3,
}
/// <summary>

View File

@@ -49,6 +49,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
Stack<CodecDirectory> DirectoryBrowseHistoryStack { get; }
}
/// <summary>
///
/// </summary>
@@ -65,8 +66,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Represents the contents of the directory
/// We don't want to serialize this for messages to MobileControl. MC can combine Contacts and Folders to get the same data
/// </summary>
[JsonProperty("directoryResults")]
[JsonIgnore]
public List<DirectoryItem> CurrentDirectoryResults { get; private set; }
[JsonProperty("contacts")]

View File

@@ -211,7 +211,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
get
{
var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now
&& DateTime.Now <= EndTime.AddMinutes(-5);
&& DateTime.Now <= EndTime.AddSeconds(-_joinableCooldownSeconds);
//Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable);
return joinable;
}
@@ -231,11 +231,23 @@ namespace PepperDash.Essentials.Devices.Common.Codec
[JsonIgnore]
public eMeetingEventChangeType NotifiedChangeTypes { get; set; }
[JsonIgnore] private readonly int _joinableCooldownSeconds;
public Meeting()
{
Calls = new List<Call>();
_joinableCooldownSeconds = 300;
}
public Meeting(int joinableCooldownSeconds)
{
Calls = new List<Call>();
_joinableCooldownSeconds = joinableCooldownSeconds;
}
#region Overrides of Object
public override string ToString()

View File

@@ -99,7 +99,7 @@ namespace PepperDash.Essentials.Devices.Displays
WarmupTime = 10000;
CooldownTime = 8000;
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 2000, 120000, 300000, StatusGet);
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 2000, 120000, 300000, StatusGet, true);
DeviceManager.AddDevice(CommunicationMonitor);
VolumeIncrementer = new ActionIncrementer(655, 0, 65535, 800, 80,

View File

@@ -56,9 +56,9 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Somfy
PulseOutput(OpenRelay, RelayPulseTime);
}
public override void StopOrPreset()
public override void Stop()
{
Debug.Console(1, this, "Stopping or recalling preset on Shade: '{0}'", this.Name);
Debug.Console(1, this, "Stopping Shade: '{0}'", this.Name);
PulseOutput(StopOrPresetRelay, RelayPulseTime);
}

View File

@@ -108,6 +108,8 @@
<Compile Include="Codec\eCodecCallStatus.cs" />
<Compile Include="Codec\eMeetingPrivacy.cs" />
<Compile Include="Codec\iCodecAudio.cs" />
<Compile Include="VideoCodec\ConvertiblePreset.cs" />
<Compile Include="Codec\IHasCallHold.cs" />
<Compile Include="Codec\IHasDoNotDisturb.cs" />
<Compile Include="Codec\IHasExternalSourceSwitching.cs" />
<Compile Include="ImageProcessors\TVOneCorio.cs" />
@@ -131,6 +133,7 @@
<Compile Include="VideoCodec\Interfaces\IHasSelfviewSize.cs" />
<Compile Include="VideoCodec\Interfaces\IHasStandbyMode.cs" />
<Compile Include="VideoCodec\Interfaces\IHasStartMeeting.cs" />
<Compile Include="VideoCodec\Interfaces\IJoinCalls.cs" />
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
<Compile Include="Codec\iHasCallFavorites.cs" />
<Compile Include="Codec\iHasCallHistory.cs" />
@@ -182,6 +185,7 @@
<Compile Include="VideoCodec\MockVC\MockVC.cs" />
<Compile Include="VideoCodec\CiscoCodec\xStatus.cs" />
<Compile Include="VideoCodec\VideoCodecBase.cs" />
<Compile Include="VideoCodec\ZoomRoom\IZoomWirelessShareInstructions.cs" />
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />

View File

@@ -377,5 +377,70 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
return meetings;
}
public static List<Meeting> GetGenericMeetingsFromBookingResult(List<Booking> bookings, int joinableCooldownSeconds)
{
var meetings = new List<Meeting>();
if (Debug.Level > 0)
{
Debug.Console(1, "Meetings List:\n");
}
foreach (Booking b in bookings)
{
var meeting = new Meeting(joinableCooldownSeconds);
if (b.Id != null)
meeting.Id = b.Id.Value;
if (b.Organizer != null)
meeting.Organizer = string.Format("{0}, {1}", b.Organizer.LastName.Value, b.Organizer.FirstName.Value);
if (b.Title != null)
meeting.Title = b.Title.Value;
if (b.Agenda != null)
meeting.Agenda = b.Agenda.Value;
if (b.Time != null)
{
meeting.StartTime = b.Time.StartTime.Value;
meeting.EndTime = b.Time.EndTime.Value;
}
if (b.Privacy != null)
meeting.Privacy = CodecCallPrivacy.ConvertToDirectionEnum(b.Privacy.Value);
//#warning Update this ConnectMode conversion after testing onsite. Expected value is "OBTP", but in PD NYC Test scenarios, "Manual" is being returned for OBTP meetings
if (b.DialInfo.ConnectMode != null)
if (b.DialInfo.ConnectMode.Value.ToLower() == "obtp" || b.DialInfo.ConnectMode.Value.ToLower() == "manual")
meeting.IsOneButtonToPushMeeting = true;
if (b.DialInfo.Calls.Call != null)
{
foreach (Call c in b.DialInfo.Calls.Call)
{
meeting.Calls.Add(new PepperDash.Essentials.Devices.Common.Codec.Call()
{
Number = c.Number.Value,
Protocol = c.Protocol.Value,
CallRate = c.CallRate.Value,
CallType = c.CallType.Value
});
}
}
meetings.Add(meeting);
if (Debug.Level > 0)
{
Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}, Agenda: {3}", meeting.Title, meeting.Id, meeting.Organizer, meeting.Agenda);
Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration);
Debug.Console(1, " Joinable: {0}\n", meeting.Joinable);
}
}
meetings.OrderBy(m => m.StartTime);
return meetings;
}
}
}

View File

@@ -41,12 +41,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void PanLeft()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Left CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Move Value: Left CallId: {0}", CallId));
}
public void PanRight()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Right CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Move Value: Right CallId: {0}", CallId));
}
public void PanStop()
@@ -60,12 +60,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void TiltDown()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Down CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Move Value: Down CallId: {0}", CallId));
}
public void TiltUp()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Up CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Move Value: Up CallId: {0}", CallId));
}
public void TiltStop()
@@ -79,12 +79,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void ZoomIn()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: ZoomIn CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Move Value: ZoomIn CallId: {0}", CallId));
}
public void ZoomOut()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: ZoomOut CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Move Value: ZoomOut CallId: {0}", CallId));
}
public void ZoomStop()
@@ -97,7 +97,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
void Stop()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Stop CallId: {0}", CallId));
ParentCodec.EnqueueCommand(string.Format("xCommand Call FarEndControl Camera Stop CallId: {0}", CallId));
}
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
@@ -116,7 +116,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
/// <summary>
/// The ID of the camera on the codec
/// </summary>
protected uint CameraId { get; private set; }
public uint CameraId { get; private set; }
/// <summary>
/// Valid range 1-15
@@ -202,7 +202,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Left PanSpeed: {1}", CameraId, PanSpeed));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Left PanSpeed: {1}", CameraId, PanSpeed));
isPanning = true;
}
}
@@ -211,14 +211,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Right PanSpeed: {1}", CameraId, PanSpeed));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Right PanSpeed: {1}", CameraId, PanSpeed));
isPanning = true;
}
}
public void PanStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Stop", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Stop", CameraId));
isPanning = false;
}
@@ -232,7 +232,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Down TiltSpeed: {1}", CameraId, TiltSpeed));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Down TiltSpeed: {1}", CameraId, TiltSpeed));
isTilting = true;
}
}
@@ -241,14 +241,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Up TiltSpeed: {1}", CameraId, TiltSpeed));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Up TiltSpeed: {1}", CameraId, TiltSpeed));
isTilting = true;
}
}
public void TiltStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Stop", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Stop", CameraId));
isTilting = false;
}
@@ -260,7 +260,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: In ZoomSpeed: {1}", CameraId, ZoomSpeed));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: In ZoomSpeed: {1}", CameraId, ZoomSpeed));
isZooming = true;
}
}
@@ -269,14 +269,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: Out ZoomSpeed: {1}", CameraId, ZoomSpeed));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: Out ZoomSpeed: {1}", CameraId, ZoomSpeed));
isZooming = true;
}
}
public void ZoomStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: Stop", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: Stop", CameraId));
isZooming = false;
}
@@ -288,7 +288,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Near", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Near", CameraId));
isFocusing = true;
}
}
@@ -297,20 +297,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Far", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Far", CameraId));
isFocusing = true;
}
}
public void FocusStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Stop", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Stop", CameraId));
isFocusing = false;
}
public void TriggerAutoFocus()
{
ParentCodec.SendText(string.Format("xCommand Camera TriggerAutofocus CameraId: {0}", CameraId));
ParentCodec.EnqueueCommand(string.Format("xCommand Camera TriggerAutofocus CameraId: {0}", CameraId));
}
#endregion

View File

@@ -9,11 +9,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
#region Digital
[JoinName("PresentationLocalOnly")]
public JoinDataComplete PresentationLocalOnly = new JoinDataComplete(
new JoinData
{
JoinNumber = 205,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Presentation Local Only Feedback",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PresentationLocalRemote")]
public JoinDataComplete PresentationLocalRemote = new JoinDataComplete(
new JoinData
{
JoinNumber = 206,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Presentation Local and Remote Feedback",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ActivateDoNotDisturbMode")]
public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinNumber = 241,
JoinSpan = 1
},
new JoinMetadata
@@ -27,7 +55,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public JoinDataComplete DeactivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 222,
JoinNumber = 242,
JoinSpan = 1
},
new JoinMetadata
@@ -41,7 +69,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public JoinDataComplete ToggleDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 223,
JoinNumber = 243,
JoinSpan = 1
},
new JoinMetadata
@@ -55,7 +83,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public JoinDataComplete ActivateStandby = new JoinDataComplete(
new JoinData
{
JoinNumber = 226,
JoinNumber = 246,
JoinSpan = 1
},
new JoinMetadata
@@ -69,7 +97,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public JoinDataComplete DeactivateStandby = new JoinDataComplete(
new JoinData
{
JoinNumber = 227,
JoinNumber = 247,
JoinSpan = 1
},
new JoinMetadata
@@ -83,7 +111,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public JoinDataComplete ActivateHalfWakeMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 228,
JoinNumber = 248,
JoinSpan = 1
},
new JoinMetadata
@@ -97,7 +125,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public JoinDataComplete EnteringStandbyMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 229,
JoinNumber = 249,
JoinSpan = 1
},
new JoinMetadata
@@ -112,12 +140,55 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
#region Analog
[JoinName("RingtoneVolume")]
public JoinDataComplete RingtoneVolume = new JoinDataComplete(
new JoinData
{
JoinNumber = 21,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Ringtone volume set/FB. Valid values are 0 - 100 in increments of 5 (5, 10, 15, 20, etc.)",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
[JoinName("PresentationSource")]
public JoinDataComplete PresentationSource = new JoinDataComplete(
new JoinData
{
JoinNumber = 201,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Presentation set/FB. Valid values are 0 - 6 depending on the codec model.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
#endregion
#region Serials
[JoinName("CommandToDevice")]
public JoinDataComplete CommandToDevice = new JoinDataComplete(
new JoinData
{
JoinNumber = 5,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sends a serial command to the device. Do not include the delimiter, it will be added automatically.",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
#endregion

View File

@@ -50,8 +50,16 @@ namespace PepperDash.Essentials.Devices.Common.Codec
public uint PhonebookResultsLimit { get; set; }
[JsonProperty("UiBranding")]
public BrandingLogoProperties UiBranding { get; set; }
public BrandingLogoProperties UiBranding { get; set; }
[JsonProperty("cameraInfo")]
public List<CameraInfo> CameraInfo { get; set; }
public CiscoSparkCodecPropertiesConfig()
{
CameraInfo = new List<CameraInfo>();
}
}
public class SharingProperties
@@ -68,4 +76,14 @@ namespace PepperDash.Essentials.Devices.Common.Codec
[JsonProperty("brandingUrl")]
public string BrandingUrl { get; set; }
}
/// <summary>
/// Describes configuration information for the near end cameras
/// </summary>
public class CameraInfo
{
public int CameraNumber { get; set; }
public string Name { get; set; }
public int SourceId { get; set; }
}
}

View File

@@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
@@ -26,44 +21,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
void CodecRoomPresetSelect(int preset);
void CodecRoomPresetStore(int preset, string description);
void SelectFarEndPreset(int preset);
}
public static class RoomPresets
{
/// <summary>
/// Converts Cisco RoomPresets to generic CameraPresets
/// Converts non-generic RoomPresets to generic CameraPresets
/// </summary>
/// <param name="presets"></param>
/// <returns></returns>
public static List<CodecRoomPreset> GetGenericPresets(List<CiscoCodecStatus.RoomPreset> presets)
public static List<TDestination> GetGenericPresets<TSource, TDestination>(this List<TSource> presets) where TSource : ConvertiblePreset where TDestination : PresetBase
{
var cameraPresets = new List<CodecRoomPreset>();
if (Debug.Level > 0)
{
Debug.Console(1, "Presets List:");
}
foreach (CiscoCodecStatus.RoomPreset preset in presets)
{
try
{
var cameraPreset = new CodecRoomPreset(UInt16.Parse(preset.id), preset.Description.Value, preset.Defined.BoolValue, true);
cameraPresets.Add(cameraPreset);
if (Debug.Level > 0)
{
Debug.Console(1, "Added Preset ID: {0}, Description: {1}, IsDefined: {2}, isDefinable: {3}", cameraPreset.ID, cameraPreset.Description, cameraPreset.Defined, cameraPreset.IsDefinable);
}
}
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", preset.id, e);
}
}
return cameraPresets;
return
presets.Select(preset => preset.ConvertCodecPreset())
.Where(newPreset => newPreset != null)
.Cast<TDestination>()
.ToList();
}
}

View File

@@ -112,16 +112,46 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public string Value { get; set; }
}
public class RingVolume
public class RingVolume : ValueProperty
{
public string valueSpaceRef { get; set; }
public string Value { get; set; }
string _Value;
/// <summary>
/// Sets Value and triggers the action when set
/// </summary>
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
OnValueChanged();
}
}
public int Volume
{
get
{
return Int32.Parse(_Value);
}
}
}
public class SoundsAndAlerts
{
public RingTone RingTone { get; set; }
public RingVolume RingVolume { get; set; }
public SoundsAndAlerts()
{
RingVolume = new RingVolume();
}
}
public class Audio
@@ -131,6 +161,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Microphones Microphones { get; set; }
public Output Output { get; set; }
public SoundsAndAlerts SoundsAndAlerts { get; set; }
public Audio()
{
SoundsAndAlerts = new SoundsAndAlerts();
}
}
public class DefaultMode
@@ -340,6 +376,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Delay Delay { get; set; }
public Mode9 Mode { get; set; }
public Mute2 Mute { get; set; }
public AutoAnswer()
{
Mode = new Mode9();
Delay = new Delay();
Mute = new Mute2();
}
}
public class Protocol
@@ -440,6 +483,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public MaxTotalTransmitCallRate MaxTotalTransmitCallRate { get; set; }
public MaxTransmitCallRate MaxTransmitCallRate { get; set; }
public MultiStream MultiStream { get; set; }
public Conference()
{
AutoAnswer = new AutoAnswer();
}
}
public class LoginName
@@ -690,6 +738,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Assignment Assignment { get; set; }
public Gateway Gateway { get; set; }
public SubnetMask SubnetMask { get; set; }
public IPv4()
{
Address = new Address4();
}
}
public class Address5
@@ -841,6 +894,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public RemoteAccess RemoteAccess { get; set; }
public Speed Speed { get; set; }
public VLAN VLAN { get; set; }
public Network()
{
IPv4 = new IPv4();
}
}
public class Mode19
@@ -1797,11 +1855,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public UserInterface UserInterface { get; set; }
public UserManagement UserManagement { get; set; }
public Video2 Video { get; set; }
public Configuration()
{
Audio = new Audio();
Conference = new Conference();
Network = new List<Network>();
}
}
public class RootObject
{
public Configuration Configuration { get; set; }
public RootObject()
{
Configuration = new Configuration();
}
}
}
}

View File

@@ -9,31 +9,32 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec;
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
// Helper Classes for Proerties
public abstract class ValueProperty
{
/// <summary>
/// Triggered when Value is set
/// </summary>
public Action ValueChangedAction { get; set; }
protected void OnValueChanged()
{
var a = ValueChangedAction;
if (a != null)
a();
}
}
/// <summary>
/// This class exists to capture serialized data sent back by a Cisco codec in JSON output mode
/// </summary>
public class CiscoCodecStatus
{
// Helper Classes for Proerties
public abstract class ValueProperty
{
/// <summary>
/// Triggered when Value is set
/// </summary>
public Action ValueChangedAction { get; set; }
protected void OnValueChanged()
{
var a = ValueChangedAction;
if (a != null)
a();
}
}
public class ConnectionStatus
{
@@ -262,11 +263,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public string Value { get; set; }
}
public class DectectedConnector
{
public string Value { get; set; }
public int ConnectorId
{
get
{
if(!string.IsNullOrEmpty(Value))
{
return Convert.ToUInt16(Value);
}
else
return -1;
}
}
}
public class Camera
{
public string id { get; set; }
public Capabilities Capabilities { get; set; }
public Connected Connected { get; set; }
public DectectedConnector DetectedConnector { get; set; }
public Flip Flip { get; set; }
public HardwareID HardwareID { get; set; }
public MacAddress MacAddress { get; set; }
@@ -275,6 +295,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Position Position { get; set; }
public SerialNumber SerialNumber { get; set; }
public SoftwareID SoftwareID { get; set; }
public Camera()
{
Manufacturer = new Manufacturer();
Model = new Model();
DetectedConnector = new DectectedConnector();
}
}
public class Availability : ValueProperty
@@ -298,11 +325,34 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
}
public class CallStatus : ValueProperty
{
string _Value;
public bool BoolValue { get; private set; }
public string Value
{
get
{
return _Value;
}
set
{
// If the incoming value is "Active" it sets the BoolValue true, otherwise sets it false
_Value = value;
BoolValue = value == "Connected";
OnValueChanged();
}
}
}
public class Status2 : ValueProperty
{
string _Value;
public bool BoolValue { get; private set; }
public string Value
{
get
@@ -558,9 +608,47 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
}
public class SendingMode
public class SendingMode : ValueProperty
{
public string Value { get; set; }
string _Value;
/// <summary>
/// Sets Value and triggers the action when set
/// </summary>
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
OnValueChanged();
}
}
public bool LocalOnly
{
get
{
if(string.IsNullOrEmpty(_Value))
return false;
return _Value.ToLower() == "localonly";
}
}
public bool LocalRemote
{
get
{
if(string.IsNullOrEmpty(_Value))
return false;
return _Value.ToLower() == "localremote";
}
}
}
public class LocalInstance
@@ -573,6 +661,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public LocalInstance()
{
Source = new Source2();
SendingMode = new SendingMode();
}
}
@@ -881,6 +970,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Address4 Address { get; set; }
public Gateway Gateway { get; set; }
public SubnetMask SubnetMask { get; set; }
public IPv4()
{
Address = new Address4();
}
}
public class Address5
@@ -923,6 +1017,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public IPv4 IPv4 { get; set; }
public IPv6 IPv6 { get; set; }
public VLAN VLAN { get; set; }
public Network()
{
IPv4 = new IPv4();
}
}
public class CurrentAddress
@@ -1949,9 +2048,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public string Value { get; set; }
}
public class Duration
public class Duration : ValueProperty
{
public string Value { get; set; }
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
OnValueChanged();
}
}
public TimeSpan DurationValue
{
get
{
return new TimeSpan(0, 0, Int32.Parse(_Value));
}
}
}
public class FacilityServiceId
@@ -1964,9 +2084,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public string Value { get; set; }
}
public class PlacedOnHold
public class PlacedOnHold : ValueProperty
{
public string Value { get; set; }
public bool BoolValue { get; private set; }
public string Value
{
set
{
// If the incoming value is "True" it sets the BoolValue true, otherwise sets it false
BoolValue = value == "True";
OnValueChanged();
}
}
}
public class Protocol
@@ -2007,13 +2137,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Protocol Protocol { get; set; }
public ReceiveCallRate ReceiveCallRate { get; set; }
public RemoteNumber RemoteNumber { get; set; }
public Status2 Status { get; set; }
public CallStatus Status { get; set; }
public TransmitCallRate TransmitCallRate { get; set; }
public Call()
{
CallType = new CallType();
Status = new Status2();
Status = new CallStatus();
Duration = new Duration();
}
}
@@ -2055,7 +2186,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
}
public class RoomPreset
public class RoomPreset : ConvertiblePreset
{
public string id { get; set; }
public Defined Defined { get; set; }
@@ -2068,7 +2199,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Description = new Description2();
Type = new Type5();
}
}
public override PresetBase ConvertCodecPreset()
{
try
{
var preset = new CodecRoomPreset(UInt16.Parse(id), Description.Value, Defined.BoolValue, true);
Debug.Console(2, "Preset ID {0} Converted from Cisco Codec Preset to Essentials Preset");
return preset;
}
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", id, e);
return null;
}
}
}
@@ -2114,6 +2262,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
SystemUnit = new SystemUnit();
Video = new Video();
Conference = new Conference2();
Network = new List<Network>();
}
}

View File

@@ -0,0 +1,9 @@
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public abstract class ConvertiblePreset
{
public abstract PresetBase ConvertCodecPreset();
}
}

View File

@@ -22,6 +22,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
void MinMaxLayoutToggle();
}
/// <summary>
/// Defines the requirements for Zoom Room layout control
/// </summary>

View File

@@ -42,9 +42,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
public Boolean WaitingForHost { get; private set; }
[JsonProperty("isLocked", NullValueHandling = NullValueHandling.Ignore)]
public Boolean IsLocked { get; private set; }
[JsonProperty("isRecording", NullValueHandling = NullValueHandling.Ignore)]
public Boolean IsRecording { get; private set; }
[JsonProperty("canRecord", NullValueHandling = NullValueHandling.Ignore)]
public Boolean CanRecord { get; private set; }
public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked)
public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked, bool isRecording, bool canRecord)
{
Id = id;
Name = name;
@@ -55,6 +59,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
IsSharingMeeting = isSharingMeeting;
WaitingForHost = waitingForHost;
IsLocked = isLocked;
IsRecording = isRecording;
CanRecord = CanRecord;
}
}

View File

@@ -15,4 +15,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
void StopRecording();
void ToggleRecording();
}
public interface IHasMeetingRecordingWithPrompt : IHasMeetingRecording
{
BoolFeedback RecordConsentPromptIsVisible { get; }
/// <summary>
/// Used to agree or disagree to the meeting being recorded when prompted
/// </summary>
/// <param name="agree"></param>
void RecordingPromptAcknowledgement(bool agree);
}
}

Some files were not shown because too many files have changed in this diff Show More